string functions in the VM are now compatible with packed strings
added a StringToLocal UTF-8 version to the VM --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40184
This commit is contained in:
parent
e4ff973dbf
commit
4d89283924
@ -481,22 +481,19 @@ int BaseContext::LocalToString(cell_t local_addr, char **addr)
|
||||
return SP_ERROR_NONE;
|
||||
}
|
||||
|
||||
int BaseContext::PushString(cell_t *local_addr, cell_t **phys_addr, const char *string)
|
||||
int BaseContext::PushString(cell_t *local_addr, char **phys_addr, const char *string)
|
||||
{
|
||||
cell_t *ph_addr;
|
||||
char *ph_addr;
|
||||
int err;
|
||||
unsigned int i, numcells = strlen(string);
|
||||
unsigned int len, numcells = ((len=strlen(string)) + sizeof(cell_t)) / sizeof(cell_t);
|
||||
|
||||
if ((err = HeapAlloc(numcells+1, local_addr, &ph_addr)) != SP_ERROR_NONE)
|
||||
if ((err = HeapAlloc(numcells, local_addr, (cell_t **)&ph_addr)) != SP_ERROR_NONE)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
|
||||
for (i=0; i<numcells; i++)
|
||||
{
|
||||
ph_addr[i] = (cell_t)string[i];
|
||||
}
|
||||
ph_addr[numcells] = '\0';
|
||||
memcpy(ph_addr, string, len);
|
||||
ph_addr[len] = '\0';
|
||||
|
||||
if ((err = PushCell(*local_addr)) != SP_ERROR_NONE)
|
||||
{
|
||||
@ -514,8 +511,8 @@ int BaseContext::PushString(cell_t *local_addr, cell_t **phys_addr, const char *
|
||||
|
||||
int BaseContext::StringToLocal(cell_t local_addr, size_t chars, const char *source)
|
||||
{
|
||||
cell_t *dest;
|
||||
int i, len;
|
||||
char *dest;
|
||||
int len;
|
||||
|
||||
if (((local_addr >= ctx->hp) && (local_addr < ctx->sp)) || (local_addr < 0) || ((ucell_t)local_addr >= ctx->mem_size))
|
||||
{
|
||||
@ -523,19 +520,97 @@ int BaseContext::StringToLocal(cell_t local_addr, size_t chars, const char *sour
|
||||
}
|
||||
|
||||
len = strlen(source);
|
||||
dest = (cell_t *)(ctx->memory + local_addr);
|
||||
dest = (char *)(ctx->memory + local_addr);
|
||||
|
||||
if ((size_t)len >= chars)
|
||||
{
|
||||
len = chars - 1;
|
||||
}
|
||||
|
||||
for (i=0; i<len; i++)
|
||||
if (len <= 0)
|
||||
{
|
||||
dest[i] = (cell_t)source[i];
|
||||
return SP_ERROR_NONE;
|
||||
}
|
||||
|
||||
memcpy(dest, source, len);
|
||||
dest[len] = '\0';
|
||||
|
||||
return SP_ERROR_NONE;
|
||||
}
|
||||
|
||||
inline int __CheckValidChar(char *c)
|
||||
{
|
||||
int count;
|
||||
int bytecount = 0;
|
||||
|
||||
for(count=1; (*c & 0xC0) == 0x80; count++)
|
||||
{
|
||||
c--;
|
||||
}
|
||||
|
||||
switch (*c & 0xF0)
|
||||
{
|
||||
case 0xC0:
|
||||
case 0xD0:
|
||||
{
|
||||
bytecount = 2;
|
||||
break;
|
||||
}
|
||||
case 0xE0:
|
||||
{
|
||||
bytecount = 3;
|
||||
break;
|
||||
}
|
||||
case 0xF0:
|
||||
{
|
||||
bytecount = 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (bytecount != count)
|
||||
{
|
||||
return count;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int BaseContext::StringToLocalUTF8(cell_t local_addr, size_t maxbytes, const char *source, size_t *wrtnbytes)
|
||||
{
|
||||
char *dest;
|
||||
int len;
|
||||
bool needtocheck = false;
|
||||
|
||||
if (((local_addr >= ctx->hp) && (local_addr < ctx->sp)) || (local_addr < 0) || ((ucell_t)local_addr >= ctx->mem_size))
|
||||
{
|
||||
return SP_ERROR_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
len = strlen(source);
|
||||
dest = (char *)(ctx->memory + local_addr);
|
||||
|
||||
if ((size_t)len >= maxbytes)
|
||||
{
|
||||
len = maxbytes - 1;
|
||||
needtocheck = true;
|
||||
}
|
||||
if (len <= 0)
|
||||
{
|
||||
return SP_ERROR_NONE;
|
||||
}
|
||||
|
||||
memcpy(dest, source, len);
|
||||
if ((dest[len] & 1<<7) && needtocheck)
|
||||
{
|
||||
len -= __CheckValidChar(dest+len-1);
|
||||
}
|
||||
dest[len] = '\0';
|
||||
|
||||
if (wrtnbytes)
|
||||
{
|
||||
*wrtnbytes = len;
|
||||
}
|
||||
|
||||
return SP_ERROR_NONE;
|
||||
}
|
||||
|
||||
|
@ -33,9 +33,10 @@ namespace SourcePawn
|
||||
virtual int LocalToPhysAddr(cell_t local_addr, cell_t **phys_addr);
|
||||
virtual int LocalToString(cell_t local_addr, char **addr);
|
||||
virtual int StringToLocal(cell_t local_addr, size_t chars, const char *source);
|
||||
virtual int StringToLocalUTF8(cell_t local_addr, size_t maxbytes, const char *source, size_t *wrtnbytes);
|
||||
virtual int PushCell(cell_t value);
|
||||
virtual int PushCellArray(cell_t *local_addr, cell_t **phys_addr, cell_t array[], unsigned int numcells);
|
||||
virtual int PushString(cell_t *local_addr, cell_t **phys_addr, const char *string);
|
||||
virtual int PushString(cell_t *local_addr, char **phys_addr, const char *string);
|
||||
virtual int PushCellsFromArray(cell_t array[], unsigned int numcells);
|
||||
virtual int BindNatives(sp_nativeinfo_t *natives, unsigned int num, int overwrite);
|
||||
virtual int BindNative(sp_nativeinfo_t *native);
|
||||
|
@ -204,10 +204,8 @@ namespace SourcePawn
|
||||
*/
|
||||
virtual int LocalToPhysAddr(cell_t local_addr, cell_t **phys_addr) =0;
|
||||
|
||||
/**:TODO: FIX ALL PACKED STUFF COMMENTS!
|
||||
/**
|
||||
* Converts a local address to a physical string.
|
||||
* Note that SourcePawn does not support packed strings, as such this function is
|
||||
* 'cell to char' only.
|
||||
*
|
||||
* @param local_addr Local address in plugin.
|
||||
* @param addr Destination output pointer.
|
||||
@ -216,7 +214,6 @@ namespace SourcePawn
|
||||
|
||||
/**
|
||||
* Converts a physical string to a local address.
|
||||
* Note that SourcePawn does not support packed strings.
|
||||
*
|
||||
* @param local_addr Local address in plugin.
|
||||
* @param chars Number of chars to write, including NULL terminator.
|
||||
@ -224,6 +221,18 @@ namespace SourcePawn
|
||||
*/
|
||||
virtual int StringToLocal(cell_t local_addr, size_t chars, const char *source) =0;
|
||||
|
||||
/**
|
||||
* Converts a physical UTF-8 string to a local address.
|
||||
* This function is the same as the ANSI version, except it will copy the maximum number of characters possible
|
||||
* without accidentally chopping a multi-byte character.
|
||||
*
|
||||
* @param local_addr Local address in plugin.
|
||||
* @param maxbytes Number of bytes to write, including NULL terminator.
|
||||
* @param source Source string to copy.
|
||||
* @param wrtnbytes Optionally filled with the number of written bytes.
|
||||
*/
|
||||
virtual int StringToLocalUTF8(cell_t local_addr, size_t maxbytes, const char *source, size_t *wrtnbytes) =0;
|
||||
|
||||
/**
|
||||
* Pushes a cell onto the stack. Increases the parameter count by one.
|
||||
*
|
||||
@ -253,7 +262,7 @@ namespace SourcePawn
|
||||
* @param phys_addr Optionally filled with physical address of new array.
|
||||
* @param string Source string to push.
|
||||
*/
|
||||
virtual int PushString(cell_t *local_addr, cell_t **phys_addr, const char *string) =0;
|
||||
virtual int PushString(cell_t *local_addr, char **phys_addr, const char *string) =0;
|
||||
|
||||
/**
|
||||
* Individually pushes each cell of an array of cells onto the stack. Increases the
|
||||
|
Loading…
Reference in New Issue
Block a user