Estoy depurando un código opensource en un sistema Solaris de 64 bits, usando GCC, que convierte caracteres de 2 bytes ( wchar_t
) a caracteres de 4 bytes ( wchar_t
). Porque Solaris como algunos otros Unixes definen wchar_t como 4byte, no 2byte como en Windows.
Ahora he arreglado el problema, mediante la disposición de la aritmética de punteros en dos líneas, pero no estoy seguro de lo que estaba mal en el código original. ¿Alguna pista?
Código original
int StringCopy2to4bytes(const unsigned short* src, int src_size,
unsigned int* dst, int dst_size)
{
int cp_size = 0;
const unsigned short *src_end = NULL;
const unsigned int *dst_end = NULL;
unsigned int c1, c2;
src_end = src + src_size;
dst_end = dst + dst_size;
while (src < src_end)
{
c1 = *src++;
if ((c1 >= UNI_SUR_HIGH_START) && (c1 <= UNI_SUR_HIGH_END))
{
if (src < src_end)
{
c2 = *src;
if ((c2 >= UNI_SUR_LOW_START) && (c2 <= UNI_SUR_LOW_END))
{
c1 = ((c1 - UNI_SUR_HIGH_START) << UNI_SHIFT) +
(c1 - UNI_SUR_LOW_START ) + UNI_BASE;
++src;
}
}
else
return -1;
}
if (dst >= dst_end) return -2;
*dst++ = c1;
cp_size++;
}
return cp_size;
}
Código fijo
int StringCopy2to4bytes(const unsigned short* src, int src_size,
unsigned int* dst, int dst_size)
{
int cp_size = 0;
const unsigned short *src_end = NULL;
const unsigned int *dst_end = NULL;
unsigned int c1, c2;
src_end = src + src_size;
dst_end = dst + dst_size;
while (src < src_end)
{
c1 = *src; //FIX
++src;
if ((c1 >= UNI_SUR_HIGH_START) && (c1 <= UNI_SUR_HIGH_END))
{
if (src < src_end)
{
c2 = *src;
if ((c2 >= UNI_SUR_LOW_START) && (c2 <= UNI_SUR_LOW_END))
{
c1 = ((c1 - UNI_SUR_HIGH_START) << UNI_SHIFT) +
(c1 - UNI_SUR_LOW_START ) + UNI_BASE;
++src;
}
}
else
return -1;
}
if (dst >= dst_end) return -2;
*dst = c1; //FIX
++dst;
cp_size++;
}
return cp_size;
}
Editar : para que conste, el código no es mío, sólo lo estoy usando, y resulta que lo estoy depurando, no es que haga una gran diferencia, pero el código fuente es bastante grande, así que estoy tratando de arreglarlo con pinzas como sea, no refactorizarlo todo, de todos modos los errores son errores, y necesito arreglarlo y enviar un correo al autor sobre lo que estaba mal.
Las constantes son:
/* unicode constants */
#define UNI_SHIFT ((int) 10 )
#define UNI_BASE ((unsigned int) 0x0010000UL)
#define UNI_MASK ((unsigned int) 0x3FFUL)
#define UNI_REPLACEMENT_CHAR ((unsigned int) 0x0000FFFD)
#define UNI_MAX_BMP ((unsigned int) 0x0000FFFF)
#define UNI_MAX_UTF16 ((unsigned int) 0x0010FFFF)
#define UNI_MAX_UTF32 ((unsigned int) 0x7FFFFFFF)
#define UNI_MAX_LEGAL_UTF32 ((unsigned int) 0x0010FFFF)
#define UNI_SUR_HIGH_START ((unsigned int) 0xD800)
#define UNI_SUR_HIGH_END ((unsigned int) 0xDBFF)
#define UNI_SUR_LOW_START ((unsigned int) 0xDC00)
#define UNI_SUR_LOW_END ((unsigned int) 0xDFFF)