[ros-diffs] [fireball] 33868: - Update RtlIsTextUnicode (fixes some ntdll rtlstr winetests).

fireball at svn.reactos.org fireball at svn.reactos.org
Fri Jun 6 23:33:44 CEST 2008


Author: fireball
Date: Fri Jun  6 16:33:43 2008
New Revision: 33868

URL: http://svn.reactos.org/svn/reactos?rev=33868&view=rev
Log:
- Update RtlIsTextUnicode (fixes some ntdll rtlstr winetests).

Modified:
    trunk/reactos/include/ndk/rtlfuncs.h
    trunk/reactos/lib/rtl/unicode.c

Modified: trunk/reactos/include/ndk/rtlfuncs.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/rtlfuncs.h?rev=33868&r1=33867&r2=33868&view=diff
==============================================================================
--- trunk/reactos/include/ndk/rtlfuncs.h [iso-8859-1] (original)
+++ trunk/reactos/include/ndk/rtlfuncs.h [iso-8859-1] Fri Jun  6 16:33:43 2008
@@ -1690,12 +1690,12 @@
 );
 
 NTSYSAPI
-ULONG
+BOOLEAN
 NTAPI
 RtlIsTextUnicode(
-    PVOID Buffer,
-    ULONG Length,
-    ULONG *Flags
+    LPCVOID Buffer,
+    INT Length,
+    INT *Flags
 );
 
 NTSYSAPI

Modified: trunk/reactos/lib/rtl/unicode.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/unicode.c?rev=33868&r1=33867&r2=33868&view=diff
==============================================================================
--- trunk/reactos/lib/rtl/unicode.c [iso-8859-1] (original)
+++ trunk/reactos/lib/rtl/unicode.c [iso-8859-1] Fri Jun  6 16:33:43 2008
@@ -1055,57 +1055,84 @@
  * RETURNS
  *  The length of the string if all tests were passed, 0 otherwise.
  */
-ULONG NTAPI
-RtlIsTextUnicode (PVOID Buffer,
-                  ULONG Length,
-                  ULONG *Flags)
-{
-   PWSTR s = Buffer;
-   ULONG in_flags = (ULONG)-1;
-   ULONG out_flags = 0;
-
-   if (Length == 0)
-      goto done;
-
-   if (Flags != 0)
-      in_flags = *Flags;
-
-   /*
-    * Apply various tests to the text string. According to the
-    * docs, each test "passed" sets the corresponding flag in
-    * the output flags. But some of the tests are mutually
-    * exclusive, so I don't see how you could pass all tests ...
-    */
-
-   /* Check for an odd length ... pass if even. */
-   if (!(Length & 1))
-      out_flags |= IS_TEXT_UNICODE_ODD_LENGTH;
-
-   /* Check for the BOM (byte order mark). */
-   if (*s == 0xFEFF)
-      out_flags |= IS_TEXT_UNICODE_SIGNATURE;
-
-#if 0
-   /* Check for the reverse BOM (byte order mark). */
-   if (*s == 0xFFFE)
-      out_flags |= IS_TEXT_UNICODE_REVERSE_SIGNATURE;
-#endif
-
-   /* FIXME: Add more tests */
-
-   /*
-    * Check whether the string passed all of the tests.
-    */
-   in_flags &= ITU_IMPLEMENTED_TESTS;
-   if ((out_flags & in_flags) != in_flags)
-      Length = 0;
-
-done:
-   if (Flags != 0)
-      *Flags = out_flags;
-
-   return Length;
-}
+BOOLEAN
+NTAPI
+RtlIsTextUnicode( LPCVOID buf, INT len, INT *pf )
+{
+    const WCHAR *s = buf;
+    int i;
+    unsigned int flags = ~0U, out_flags = 0;
+    
+    if (len < sizeof(WCHAR))
+    {
+        /* FIXME: MSDN documents IS_TEXT_UNICODE_BUFFER_TOO_SMALL but there is no such thing... */
+        if (pf) *pf = 0;
+        return FALSE;
+    }
+    if (pf)
+        flags = *pf;
+    /*
+     * Apply various tests to the text string. According to the
+     * docs, each test "passed" sets the corresponding flag in
+     * the output flags. But some of the tests are mutually
+     * exclusive, so I don't see how you could pass all tests ...
+     */
+    
+    /* Check for an odd length ... pass if even. */
+    if (len & 1) out_flags |= IS_TEXT_UNICODE_ODD_LENGTH;
+    
+    if (((char *)buf)[len - 1] == 0)
+        len--;  /* Windows seems to do something like that to avoid e.g. false IS_TEXT_UNICODE_NULL_BYTES  */
+    
+    len /= sizeof(WCHAR);
+    /* Windows only checks the first 256 characters */
+    if (len > 256) len = 256;
+    
+    /* Check for the special byte order unicode marks. */
+    if (*s == 0xFEFF) out_flags |= IS_TEXT_UNICODE_SIGNATURE;
+    if (*s == 0xFFFE) out_flags |= IS_TEXT_UNICODE_REVERSE_SIGNATURE;
+    
+    /* apply some statistical analysis */
+    if (flags & IS_TEXT_UNICODE_STATISTICS)
+    {
+        int stats = 0;
+        /* FIXME: checks only for ASCII characters in the unicode stream */
+        for (i = 0; i < len; i++)
+        {
+            if (s[i] <= 255) stats++;
+        }
+        if (stats > len / 2)
+            out_flags |= IS_TEXT_UNICODE_STATISTICS;
+    }
+    
+    /* Check for unicode NULL chars */
+    if (flags & IS_TEXT_UNICODE_NULL_BYTES)
+    {
+        for (i = 0; i < len; i++)
+        {
+            if (!(s[i] & 0xff) || !(s[i] >> 8))
+            {
+                out_flags |= IS_TEXT_UNICODE_NULL_BYTES;
+                break;
+            }
+        }
+    }
+    
+    if (pf)
+    {
+        out_flags &= *pf;
+        *pf = out_flags;
+    }
+    /* check for flags that indicate it's definitely not valid Unicode */
+    if (out_flags & (IS_TEXT_UNICODE_REVERSE_MASK | IS_TEXT_UNICODE_NOT_UNICODE_MASK)) return FALSE;
+    /* now check for invalid ASCII, and assume Unicode if so */
+    if (out_flags & IS_TEXT_UNICODE_NOT_ASCII_MASK) return TRUE;
+    /* now check for Unicode flags */
+    if (out_flags & IS_TEXT_UNICODE_UNICODE_MASK) return TRUE;
+    /* no flags set */
+    return FALSE;
+}
+
 
 /*
  * @implemented



More information about the Ros-diffs mailing list