/* --------------------------------------------------------------------- */
ConversionResult ConvertUTF16toUTF8(const WCHAR** sourceStart, const WCHAR* sourceEnd,
- BYTE** targetStart, BYTE* targetEnd, ConversionFlags flags)
+ BYTE** targetStart, BYTE* te, ConversionFlags flags)
{
- BYTE* target;
+ size_t pos = 0;
+ size_t end = 0;
const WCHAR* source;
- BOOL computeLength;
- ConversionResult result;
- computeLength = (!targetEnd) ? TRUE : FALSE;
+ const BOOL computeLength = (!te) ? TRUE : FALSE;
+ ConversionResult result = conversionOK;
+
+ if (targetStart && te)
+ {
+ const size_t s = (size_t)*targetStart;
+ const size_t e = (size_t)te;
+ if (s > e)
+ return sourceIllegal;
+ end = e - s;
+ }
+
source = *sourceStart;
- target = *targetStart;
- result = conversionOK;
while (source < sourceEnd)
{
ch = UNI_REPLACEMENT_CHAR;
}
- target += bytesToWrite;
+ pos += bytesToWrite;
- if ((target > targetEnd) && (!computeLength))
+ if ((pos > end) && (!computeLength))
{
source = oldSource; /* Back up source pointer! */
- target -= bytesToWrite;
+ pos -= bytesToWrite;
result = targetExhausted;
break;
}
{
/* note: everything falls through. */
case 4:
- *--target = (BYTE)((ch | byteMark) & byteMask);
+ (*targetStart)[--pos] = (BYTE)((ch | byteMark) & byteMask);
ch >>= 6;
case 3:
- *--target = (BYTE)((ch | byteMark) & byteMask);
+ (*targetStart)[--pos] = (BYTE)((ch | byteMark) & byteMask);
ch >>= 6;
case 2:
- *--target = (BYTE)((ch | byteMark) & byteMask);
+ (*targetStart)[--pos] = (BYTE)((ch | byteMark) & byteMask);
ch >>= 6;
case 1:
- *--target = (BYTE)(ch | firstByteMark[bytesToWrite]);
+ (*targetStart)[--pos] = (BYTE)(ch | firstByteMark[bytesToWrite]);
}
}
else
{
/* note: everything falls through. */
case 4:
- --target;
+ --pos;
case 3:
- --target;
+ --pos;
case 2:
- --target;
+ --pos;
case 1:
- --target;
+ --pos;
}
}
- target += bytesToWrite;
+ pos += bytesToWrite;
}
*sourceStart = source;
- *targetStart = target;
+ if (targetStart && *targetStart)
+ *targetStart = &(*targetStart)[pos];
+ else if (targetStart)
+ *targetStart = (BYTE*)pos;
return result;
}
ConversionResult ConvertUTF8toUTF16(const BYTE** sourceStart, const BYTE* sourceEnd,
WCHAR** targetStart, WCHAR* targetEnd, ConversionFlags flags)
{
- WCHAR* target;
+ size_t target = 0;
+ size_t end = 0;
const BYTE* source;
BOOL computeLength;
ConversionResult result;
computeLength = (!targetEnd) ? TRUE : FALSE;
result = conversionOK;
source = *sourceStart;
- target = *targetStart;
+
+ if (targetStart && targetEnd)
+ {
+ const size_t s = (size_t)*targetStart;
+ const size_t e = (size_t)targetEnd;
+ if (s > e)
+ return sourceIllegal;
+
+ end = ((size_t)(targetEnd)) - ((size_t)(*targetStart));
+ }
while (source < sourceEnd)
{
ch -= offsetsFromUTF8[extraBytesToRead];
- if ((target >= targetEnd) && (!computeLength))
+ if ((target >= end) && (!computeLength))
{
source -= (extraBytesToRead + 1); /* Back up source pointer! */
result = targetExhausted;
else
{
if (!computeLength)
- {
- Data_Write_UINT16(target, UNI_REPLACEMENT_CHAR);
- target++;
- }
- else
- target++;
+ Data_Write_UINT16(&(*targetStart)[target], UNI_REPLACEMENT_CHAR);
+ target++;
}
}
else
{
if (!computeLength)
- {
- Data_Write_UINT16(target, ch); /* normal case */
- target++;
- }
- else
- target++;
+ Data_Write_UINT16(&(*targetStart)[target], ch); /* normal case */
+ target++;
}
}
else if (ch > UNI_MAX_UTF16)
else
{
if (!computeLength)
- {
- Data_Write_UINT16(target, UNI_REPLACEMENT_CHAR);
- target++;
- }
- else
- target++;
+ Data_Write_UINT16(&(*targetStart)[target], UNI_REPLACEMENT_CHAR);
+ target++;
}
}
else
{
/* target is a character in range 0xFFFF - 0x10FFFF. */
- if ((target + 1 >= targetEnd) && (!computeLength))
+ if ((target + 1 >= end) && (!computeLength))
{
source -= (extraBytesToRead + 1); /* Back up source pointer! */
result = targetExhausted;
{
WCHAR wchar;
wchar = (ch >> halfShift) + UNI_SUR_HIGH_START;
- Data_Write_UINT16(target, wchar);
- target++;
+ Data_Write_UINT16(&(*targetStart)[target++], wchar);
wchar = (ch & halfMask) + UNI_SUR_LOW_START;
- Data_Write_UINT16(target, wchar);
- target++;
+ Data_Write_UINT16(&(*targetStart)[target++], wchar);
}
else
{
}
*sourceStart = source;
- *targetStart = target;
+ if (targetStart && (*targetStart))
+ *targetStart = &(*targetStart)[target];
+ else if (targetStart)
+ *targetStart = (WCHAR*)(target * sizeof(WCHAR));
return result;
}