Sync to Wine-20050725:
Alexandre Julliard <julliard(a)winehq.org>
- Faster implementation of wcstombs that handles overlapping buffers
properly (based on a patch by Dmitry Timoshkov).
Modified: trunk/reactos/tools/unicode/wctomb.c
_____
Modified: trunk/reactos/tools/unicode/wctomb.c
--- trunk/reactos/tools/unicode/wctomb.c 2005-08-05 21:53:20 UTC
(rev 17089)
+++ trunk/reactos/tools/unicode/wctomb.c 2005-08-05 22:24:53 UTC
(rev 17090)
@@ -142,45 +142,52 @@
ret = -1;
}
- if (dst <= (const char *)src && dst + 16 > (const char *)src)
+ while (srclen >= 16)
{
- /* overlapping buffers, do it char by char */
- while (srclen--)
- {
- *dst++ = uni2cp_low[uni2cp_high[*src >> 8] + (*src &
0xff)];
- src++;
- }
- return ret;
+ dst[0] = uni2cp_low[uni2cp_high[src[0] >> 8] + (src[0] &
0xff)];
+ dst[1] = uni2cp_low[uni2cp_high[src[1] >> 8] + (src[1] &
0xff)];
+ dst[2] = uni2cp_low[uni2cp_high[src[2] >> 8] + (src[2] &
0xff)];
+ dst[3] = uni2cp_low[uni2cp_high[src[3] >> 8] + (src[3] &
0xff)];
+ dst[4] = uni2cp_low[uni2cp_high[src[4] >> 8] + (src[4] &
0xff)];
+ dst[5] = uni2cp_low[uni2cp_high[src[5] >> 8] + (src[5] &
0xff)];
+ dst[6] = uni2cp_low[uni2cp_high[src[6] >> 8] + (src[6] &
0xff)];
+ dst[7] = uni2cp_low[uni2cp_high[src[7] >> 8] + (src[7] &
0xff)];
+ dst[8] = uni2cp_low[uni2cp_high[src[8] >> 8] + (src[8] &
0xff)];
+ dst[9] = uni2cp_low[uni2cp_high[src[9] >> 8] + (src[9] &
0xff)];
+ dst[10] = uni2cp_low[uni2cp_high[src[10] >> 8] + (src[10] &
0xff)];
+ dst[11] = uni2cp_low[uni2cp_high[src[11] >> 8] + (src[11] &
0xff)];
+ dst[12] = uni2cp_low[uni2cp_high[src[12] >> 8] + (src[12] &
0xff)];
+ dst[13] = uni2cp_low[uni2cp_high[src[13] >> 8] + (src[13] &
0xff)];
+ dst[14] = uni2cp_low[uni2cp_high[src[14] >> 8] + (src[14] &
0xff)];
+ dst[15] = uni2cp_low[uni2cp_high[src[15] >> 8] + (src[15] &
0xff)];
+ src += 16;
+ dst += 16;
+ srclen -= 16;
}
- for (;;)
+ /* now handle remaining characters */
+ src += srclen;
+ dst += srclen;
+ switch(srclen)
{
- switch(srclen)
- {
- default:
- case 16: dst[15] = uni2cp_low[uni2cp_high[src[15] >> 8] +
(src[15] & 0xff)];
- case 15: dst[14] = uni2cp_low[uni2cp_high[src[14] >> 8] +
(src[14] & 0xff)];
- case 14: dst[13] = uni2cp_low[uni2cp_high[src[13] >> 8] +
(src[13] & 0xff)];
- case 13: dst[12] = uni2cp_low[uni2cp_high[src[12] >> 8] +
(src[12] & 0xff)];
- case 12: dst[11] = uni2cp_low[uni2cp_high[src[11] >> 8] +
(src[11] & 0xff)];
- case 11: dst[10] = uni2cp_low[uni2cp_high[src[10] >> 8] +
(src[10] & 0xff)];
- case 10: dst[9] = uni2cp_low[uni2cp_high[src[9] >> 8] +
(src[9] & 0xff)];
- case 9: dst[8] = uni2cp_low[uni2cp_high[src[8] >> 8] +
(src[8] & 0xff)];
- case 8: dst[7] = uni2cp_low[uni2cp_high[src[7] >> 8] +
(src[7] & 0xff)];
- case 7: dst[6] = uni2cp_low[uni2cp_high[src[6] >> 8] +
(src[6] & 0xff)];
- case 6: dst[5] = uni2cp_low[uni2cp_high[src[5] >> 8] +
(src[5] & 0xff)];
- case 5: dst[4] = uni2cp_low[uni2cp_high[src[4] >> 8] +
(src[4] & 0xff)];
- case 4: dst[3] = uni2cp_low[uni2cp_high[src[3] >> 8] +
(src[3] & 0xff)];
- case 3: dst[2] = uni2cp_low[uni2cp_high[src[2] >> 8] +
(src[2] & 0xff)];
- case 2: dst[1] = uni2cp_low[uni2cp_high[src[1] >> 8] +
(src[1] & 0xff)];
- case 1: dst[0] = uni2cp_low[uni2cp_high[src[0] >> 8] +
(src[0] & 0xff)];
- case 0: break;
- }
- if (srclen < 16) return ret;
- dst += 16;
- src += 16;
- srclen -= 16;
+ case 15: dst[-15] = uni2cp_low[uni2cp_high[src[-15] >> 8] +
(src[-15] & 0xff)];
+ case 14: dst[-14] = uni2cp_low[uni2cp_high[src[-14] >> 8] +
(src[-14] & 0xff)];
+ case 13: dst[-13] = uni2cp_low[uni2cp_high[src[-13] >> 8] +
(src[-13] & 0xff)];
+ case 12: dst[-12] = uni2cp_low[uni2cp_high[src[-12] >> 8] +
(src[-12] & 0xff)];
+ case 11: dst[-11] = uni2cp_low[uni2cp_high[src[-11] >> 8] +
(src[-11] & 0xff)];
+ case 10: dst[-10] = uni2cp_low[uni2cp_high[src[-10] >> 8] +
(src[-10] & 0xff)];
+ case 9: dst[-9] = uni2cp_low[uni2cp_high[src[-9] >> 8] +
(src[-9] & 0xff)];
+ case 8: dst[-8] = uni2cp_low[uni2cp_high[src[-8] >> 8] +
(src[-8] & 0xff)];
+ case 7: dst[-7] = uni2cp_low[uni2cp_high[src[-7] >> 8] +
(src[-7] & 0xff)];
+ case 6: dst[-6] = uni2cp_low[uni2cp_high[src[-6] >> 8] +
(src[-6] & 0xff)];
+ case 5: dst[-5] = uni2cp_low[uni2cp_high[src[-5] >> 8] +
(src[-5] & 0xff)];
+ case 4: dst[-4] = uni2cp_low[uni2cp_high[src[-4] >> 8] +
(src[-4] & 0xff)];
+ case 3: dst[-3] = uni2cp_low[uni2cp_high[src[-3] >> 8] +
(src[-3] & 0xff)];
+ case 2: dst[-2] = uni2cp_low[uni2cp_high[src[-2] >> 8] +
(src[-2] & 0xff)];
+ case 1: dst[-1] = uni2cp_low[uni2cp_high[src[-1] >> 8] +
(src[-1] & 0xff)];
+ case 0: break;
}
+ return ret;
}
/* slow version of wcstombs_sbcs that handles the various flags */