Author: cwittich
Date: Sun Jun 28 10:21:52 2015
New Revision: 68299
URL:
http://svn.reactos.org/svn/reactos?rev=68299&view=rev
Log:
[KERNEL32]
replace WideCharToUtf7 with wine version
Modified:
trunk/reactos/dll/win32/kernel32/winnls/string/nls.c
Modified: trunk/reactos/dll/win32/kernel32/winnls/string/nls.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/winnls/…
==============================================================================
--- trunk/reactos/dll/win32/kernel32/winnls/string/nls.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/winnls/string/nls.c [iso-8859-1] Sun Jun 28 10:21:52
2015
@@ -1476,160 +1476,127 @@
}
}
-static const char mustshift[] =
-{
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1
-};
-
-static const char base64[] =
-"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
-static INT WideCharToUtf7Size(LPCWSTR pszWide, INT cchWide)
-{
- WCHAR wch;
- INT c = 0;
- BOOL fShift = FALSE;
-
- while(cchWide > 0)
- {
- wch = *pszWide;
- if (wch < 0x80 && !mustshift[wch])
- {
- c++;
- cchWide--;
- pszWide++;
+static inline BOOL utf7_can_directly_encode(WCHAR codepoint)
+{
+ static const BOOL directly_encodable_table[] =
+ {
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, /* 0x00 - 0x0F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 - 0x1F */
+ 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, /* 0x20 - 0x2F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 0x30 - 0x3F */
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40 - 0x4F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x50 - 0x5F */
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60 - 0x6F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 /* 0x70 - 0x7A */
+ };
+
+ return codepoint <= 0x7A ? directly_encodable_table[codepoint] : FALSE;
+}
+
+static inline BOOL utf7_write_c(char *dst, int dstlen, int *index, char character)
+{
+ if (dstlen > 0)
+ {
+ if (*index >= dstlen)
+ return FALSE;
+
+ dst[*index] = character;
+ }
+
+ (*index)++;
+
+ return TRUE;
+}
+
+static INT WideCharToUtf7(const WCHAR *src, int srclen, char *dst, int dstlen)
+{
+ static const char base64_encoding_table[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+ const WCHAR *source_end = src + srclen;
+ int dest_index = 0;
+
+ while (src < source_end)
+ {
+ if (*src == '+')
+ {
+ if (!utf7_write_c(dst, dstlen, &dest_index, '+'))
+ {
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ return 0;
+ }
+ if (!utf7_write_c(dst, dstlen, &dest_index, '-'))
+ {
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ return 0;
+ }
+ src++;
+ }
+ else if (utf7_can_directly_encode(*src))
+ {
+ if (!utf7_write_c(dst, dstlen, &dest_index, *src))
+ {
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ return 0;
+ }
+ src++;
}
else
{
- if (wch == L'+')
- {
- c++;
- c++;
- cchWide--;
- pszWide++;
- continue;
- }
- if (!fShift)
- {
- c++;
- fShift = TRUE;
- }
- pszWide++;
- cchWide--;
- c += 3;
- if (cchWide > 0 && (*pszWide >= 0x80 || mustshift[*pszWide]))
- {
- pszWide++;
- cchWide--;
- c += 3;
- if (cchWide > 0 && (*pszWide >= 0x80 ||
mustshift[*pszWide]))
+ unsigned int offset = 0;
+ DWORD byte_pair = 0;
+
+ if (!utf7_write_c(dst, dstlen, &dest_index, '+'))
+ {
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ return 0;
+ }
+
+ while (src < source_end && !utf7_can_directly_encode(*src))
+ {
+ byte_pair = (byte_pair << 16) | *src;
+ offset += 16;
+ while (offset >= 6)
{
- pszWide++;
- cchWide--;
- c += 2;
+ if (!utf7_write_c(dst, dstlen, &dest_index,
base64_encoding_table[(byte_pair >> (offset - 6)) & 0x3F]))
+ {
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ return 0;
+ }
+ offset -= 6;
}
- }
- if (cchWide > 0 && *pszWide < 0x80 &&
!mustshift[*pszWide])
- {
- c++;
- fShift = FALSE;
- }
- }
- }
- if (fShift)
- c++;
-
- return c;
-}
-
-static INT WideCharToUtf7(LPCWSTR pszWide, INT cchWide, LPSTR pszUtf7, INT cchUtf7)
-{
- WCHAR wch;
- INT c, n;
- WCHAR wsz[3];
- BOOL fShift = FALSE;
-
- c = WideCharToUtf7Size(pszWide, cchWide);
- if (cchUtf7 == 0)
- return c;
-
- if (cchUtf7 < c)
- {
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- return 0;
- }
-
- while(cchWide > 0)
- {
- wch = *pszWide;
- if (wch < 0x80 && !mustshift[wch])
- {
- *pszUtf7++ = (CHAR) wch;
- cchWide--;
- pszWide++;
- }
- else
- {
- if (wch == L'+')
- {
- *pszUtf7++ = '+';
- *pszUtf7++ = '-';
- cchWide--;
- pszWide++;
- continue;
- }
- if (!fShift)
- {
- *pszUtf7++ = '+';
- fShift = TRUE;
- }
- wsz[0] = *pszWide++;
- cchWide--;
- n = 1;
- if (cchWide > 0 && (*pszWide >= 0x80 || mustshift[*pszWide]))
- {
- wsz[1] = *pszWide++;
- cchWide--;
- n++;
- if (cchWide > 0 && (*pszWide >= 0x80 ||
mustshift[*pszWide]))
+ src++;
+ }
+
+ if (offset)
+ {
+ /* Windows won't create a padded base64 character if there's no
room for the - sign
+ * as well ; this is probably a bug in Windows */
+ if (dstlen > 0 && dest_index + 1 >= dstlen)
{
- wsz[2] = *pszWide++;
- cchWide--;
- n++;
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ return 0;
}
- }
- *pszUtf7++ = base64[wsz[0] >> 10];
- *pszUtf7++ = base64[(wsz[0] >> 4) & 0x3F];
- *pszUtf7++ = base64[(wsz[0] << 2 | (n >= 2 ? wsz[1] >> 14 :
0)) & 0x3F];
- if (n >= 2)
- {
- *pszUtf7++ = base64[(wsz[1] >> 8) & 0x3F];
- *pszUtf7++ = base64[(wsz[1] >> 2) & 0x3F];
- *pszUtf7++ = base64[(wsz[1] << 4 | (n >= 3 ? wsz[2] >> 12
: 0)) & 0x3F];
- if (n >= 3)
+
+ byte_pair <<= (6 - offset);
+ if (!utf7_write_c(dst, dstlen, &dest_index,
base64_encoding_table[byte_pair & 0x3F]))
{
- *pszUtf7++ = base64[(wsz[2] >> 6) & 0x3F];
- *pszUtf7++ = base64[wsz[2] & 0x3F];
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ return 0;
}
}
- if (cchWide > 0 && *pszWide < 0x80 &&
!mustshift[*pszWide])
- {
- *pszUtf7++ = '-';
- fShift = FALSE;
- }
- }
- }
- if (fShift)
- *pszUtf7 = '-';
-
- return c;
+
+ /* Windows always explicitly terminates the base64 sequence
+ even though RFC 2152 (page 3, rule 2) does not require this */
+ if (!utf7_write_c(dst, dstlen, &dest_index, '-'))
+ {
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ return 0;
+ }
+ }
+ }
+
+ return dest_index;
}
DWORD