- Use Rtl macros instead of manually handling the cases.
[reactos.git] / reactos / lib / rtl / unicode.c
index de854aa..7f30600 100644 (file)
@@ -20,7 +20,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #define __NTDRIVER__
-#include "rtl.h"
+#include <rtl.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -66,7 +66,7 @@ RtlAnsiCharToUnicodeChar (IN CHAR AnsiChar)
  */
 ULONG
 STDCALL
-RtlAnsiStringToUnicodeSize(IN PANSI_STRING AnsiString)
+RtlxAnsiStringToUnicodeSize(IN PCANSI_STRING AnsiString)
 {
    ULONG Size;
 
@@ -125,7 +125,7 @@ NTSTATUS
 STDCALL
 RtlAppendUnicodeStringToString(
    IN OUT PUNICODE_STRING Destination,
-   IN PUNICODE_STRING Source)
+   IN PCUNICODE_STRING Source)
 {
 
    if ((Source->Length + Destination->Length) > Destination->MaximumLength)
@@ -237,47 +237,28 @@ RtlCharToInteger(
 LONG
 STDCALL
 RtlCompareString(
-   IN PSTRING String1,
-   IN PSTRING String2,
+   IN PSTRING s1,
+   IN PSTRING s2,
    IN BOOLEAN CaseInsensitive)
 {
-   ULONG len1, len2;
-   PCHAR s1, s2;
-   CHAR  c1, c2;
+   unsigned int len;
+   LONG ret = 0;
+   LPCSTR p1, p2;
 
-   if (String1 && String2)
-   {
-      len1 = String1->Length;
-      len2 = String2->Length;
-      s1 = String1->Buffer;
-      s2 = String2->Buffer;
+   len = min(s1->Length, s2->Length);
+   p1 = s1->Buffer;
+   p2 = s2->Buffer;
 
-      if (s1 && s2)
-      {
-         if (CaseInsensitive)
-         {
-            for(;;)
-            {
-               c1 = len1-- ? RtlUpperChar (*s1++) : 0;
-               c2 = len2-- ? RtlUpperChar (*s2++) : 0;
-               if (!c1 || !c2 || c1 != c2)
-                  return c1 - c2;
-            }
-         }
-         else
-         {
-            for(;;)
-            {
-               c1 = len1-- ? *s1++ : 0;
-               c2 = len2-- ? *s2++ : 0;
-               if (!c1 || !c2 || c1 != c2)
-                  return c1 - c2;
-            }
-         }
-      }
+   if (CaseInsensitive)
+   {
+     while (!ret && len--) ret = RtlUpperChar(*p1++) - RtlUpperChar(*p2++);
    }
-
-   return 0;
+   else
+   {
+     while (!ret && len--) ret = *p1++ - *p2++;
+   }
+   if (!ret) ret = s1->Length - s2->Length;
+   return ret;
 }
 
 
@@ -290,40 +271,12 @@ RtlCompareString(
 BOOLEAN
 STDCALL
 RtlEqualString(
-   IN PSTRING String1,
-   IN PSTRING String2,
+   IN PSTRING s1,
+   IN PSTRING s2,
    IN BOOLEAN CaseInsensitive)
 {
-   ULONG i;
-   CHAR c1, c2;
-   PCHAR p1, p2;
-
-   if (String1->Length != String2->Length)
-      return FALSE;
-
-   p1 = String1->Buffer;
-   p2 = String2->Buffer;
-   for (i = 0; i < String1->Length; i++)
-   {
-      if (CaseInsensitive == TRUE)
-      {
-         c1 = RtlUpperChar (*p1);
-         c2 = RtlUpperChar (*p2);
-      }
-      else
-      {
-         c1 = *p1;
-         c2 = *p2;
-      }
-
-      if (c1 != c2)
-         return FALSE;
-
-      p1++;
-      p2++;
-   }
-
-   return TRUE;
+   if (s1->Length != s2->Length) return FALSE;
+   return !RtlCompareString(s1, s2, CaseInsensitive );
 }
 
 
@@ -336,41 +289,12 @@ RtlEqualString(
 BOOLEAN
 STDCALL
 RtlEqualUnicodeString(
-   IN CONST UNICODE_STRING *String1,
-   IN CONST UNICODE_STRING *String2,
+   IN CONST UNICODE_STRING *s1,
+   IN CONST UNICODE_STRING *s2,
    IN BOOLEAN  CaseInsensitive)
 {
-   ULONG i;
-   WCHAR wc1, wc2;
-   PWCHAR pw1, pw2;
-
-   if (String1->Length != String2->Length)
-      return FALSE;
-
-   pw1 = String1->Buffer;
-   pw2 = String2->Buffer;
-
-   for (i = 0; i < String1->Length / sizeof(WCHAR); i++)
-   {
-      if (CaseInsensitive == TRUE)
-      {
-         wc1 = RtlUpcaseUnicodeChar (*pw1);
-         wc2 = RtlUpcaseUnicodeChar (*pw2);
-      }
-      else
-      {
-         wc1 = *pw1;
-         wc2 = *pw2;
-      }
-
-      if (wc1 != wc2)
-         return FALSE;
-
-      pw1++;
-      pw2++;
-   }
-
-   return TRUE;
+   if (s1->Length != s2->Length) return FALSE;
+   return !RtlCompareUnicodeString((PUNICODE_STRING)s1, (PUNICODE_STRING)s2, CaseInsensitive );
 }
 
 
@@ -800,8 +724,8 @@ RtlPrefixString(
 BOOLEAN
 STDCALL
 RtlPrefixUnicodeString(
-   PUNICODE_STRING String1,
-   PUNICODE_STRING String2,
+   PCUNICODE_STRING String1,
+   PCUNICODE_STRING String2,
    BOOLEAN  CaseInsensitive)
 {
    PWCHAR pc1;
@@ -868,7 +792,7 @@ RtlPrefixUnicodeString(
 NTSTATUS
 STDCALL
 RtlUnicodeStringToInteger(
-    PUNICODE_STRING str, /* [I] Unicode string to be converted */
+    PCUNICODE_STRING str, /* [I] Unicode string to be converted */
     ULONG base,                /* [I] Number base for conversion (allowed 0, 2, 8, 10 or 16) */
     PULONG value)              /* [O] Destination for the converted value */
 {
@@ -876,44 +800,49 @@ RtlUnicodeStringToInteger(
     USHORT CharsRemaining = str->Length / sizeof(WCHAR);
     WCHAR wchCurrent;
     int digit;
+    ULONG newbase = 0;
     ULONG RunningTotal = 0;
     char bMinus = 0;
 
-    while (CharsRemaining >= 1 && *lpwstr <= ' ') {
+    while (CharsRemaining >= 1 && *lpwstr <= L' ') {
        lpwstr++;
        CharsRemaining--;
     } /* while */
 
     if (CharsRemaining >= 1) {
-       if (*lpwstr == '+') {
+       if (*lpwstr == L'+') {
            lpwstr++;
            CharsRemaining--;
-       } else if (*lpwstr == '-') {
+       } else if (*lpwstr == L'-') {
            bMinus = 1;
            lpwstr++;
            CharsRemaining--;
        } /* if */
     } /* if */
 
-    if (base == 0) {
-       base = 10;
-       if (CharsRemaining >= 2 && lpwstr[0] == '0') {
-           if (lpwstr[1] == 'b') {
-               lpwstr += 2;
-               CharsRemaining -= 2;
-               base = 2;
-           } else if (lpwstr[1] == 'o') {
-               lpwstr += 2;
-               CharsRemaining -= 2;
-               base = 8;
-           } else if (lpwstr[1] == 'x') {
-               lpwstr += 2;
-               CharsRemaining -= 2;
-               base = 16;
-           } /* if */
+    if (CharsRemaining >= 2 && lpwstr[0] == L'0') {
+        if (lpwstr[1] == L'b' || lpwstr[1] == L'B') {
+           lpwstr += 2;
+           CharsRemaining -= 2;
+           newbase = 2;
+       } else if (lpwstr[1] == L'o' || lpwstr[1] == L'O') {
+           lpwstr += 2;
+           CharsRemaining -= 2;
+           newbase = 8;
+        } else if (lpwstr[1] == L'x' || lpwstr[1] == L'X') {
+           lpwstr += 2;
+           CharsRemaining -= 2;
+           newbase = 16;
        } /* if */
-    } else if (base != 2 && base != 8 && base != 10 && base != 16) {
+    }
+    if (base == 0 && newbase == 0) {
+        base = 10;
+    } else if (base == 0 && newbase != 0) {
+        base = newbase;
+    } else if ((newbase != 0 && base != newbase) ||
+               (base != 2 && base != 8 && base != 10 && base != 16)) {
        return STATUS_INVALID_PARAMETER;
+
     } /* if */
 
     if (value == NULL) {
@@ -922,12 +851,12 @@ RtlUnicodeStringToInteger(
 
     while (CharsRemaining >= 1) {
        wchCurrent = *lpwstr;
-       if (wchCurrent >= '0' && wchCurrent <= '9') {
-           digit = wchCurrent - '0';
-       } else if (wchCurrent >= 'A' && wchCurrent <= 'Z') {
-           digit = wchCurrent - 'A' + 10;
-       } else if (wchCurrent >= 'a' && wchCurrent <= 'z') {
-           digit = wchCurrent - 'a' + 10;
+       if (wchCurrent >= L'0' && wchCurrent <= L'9') {
+           digit = wchCurrent - L'0';
+       } else if (wchCurrent >= L'A' && wchCurrent <= L'Z') {
+           digit = wchCurrent - L'A' + 10;
+       } else if (wchCurrent >= L'a' && wchCurrent <= L'z') {
+           digit = wchCurrent - L'a' + 10;
        } else {
            digit = -1;
        } /* if */
@@ -954,8 +883,8 @@ RtlUnicodeStringToInteger(
  */
 ULONG
 STDCALL
-RtlUnicodeStringToOemSize(
-   IN PUNICODE_STRING UnicodeString)
+RtlxUnicodeStringToOemSize(
+   IN PCUNICODE_STRING UnicodeString)
 {
    ULONG Size;
 
@@ -978,19 +907,13 @@ NTSTATUS
 STDCALL
 RtlUnicodeStringToAnsiString(
    IN OUT PANSI_STRING AnsiDest,
-   IN PUNICODE_STRING UniSource,
+   IN PCUNICODE_STRING UniSource,
    IN BOOLEAN AllocateDestinationString)
 {
    NTSTATUS Status = STATUS_SUCCESS;
    ULONG Length; /* including nullterm */
 
-   if (NlsMbCodePageTag == TRUE)
-   {
-      Length = RtlUnicodeStringToAnsiSize(UniSource);
-   }
-   else
-      Length = (UniSource->Length / sizeof(WCHAR)) + sizeof(CHAR);
-
+   Length = RtlUnicodeStringToAnsiSize(UniSource);
    AnsiDest->Length = Length - sizeof(CHAR);
 
    if (AllocateDestinationString)
@@ -1039,17 +962,13 @@ NTSTATUS
 STDCALL
 RtlOemStringToUnicodeString(
    IN OUT PUNICODE_STRING UniDest,
-   IN POEM_STRING OemSource,
+   IN PCOEM_STRING OemSource,
    IN BOOLEAN AllocateDestinationString)
 {
    NTSTATUS Status;
    ULONG Length; /* including nullterm */
 
-   if (NlsMbOemCodePageTag == TRUE)
-      Length = RtlOemStringToUnicodeSize(OemSource);
-   else
-      Length = (OemSource->Length * sizeof(WCHAR)) + sizeof(WCHAR);
-
+   Length = RtlOemStringToUnicodeSize(OemSource);
    if (Length > 0xffff)
       return STATUS_INVALID_PARAMETER_2;
 
@@ -1100,17 +1019,13 @@ NTSTATUS
 STDCALL
 RtlUnicodeStringToOemString(
    IN OUT POEM_STRING OemDest,
-   IN PUNICODE_STRING UniSource,
+   IN PCUNICODE_STRING UniSource,
    IN BOOLEAN  AllocateDestinationString)
 {
    NTSTATUS Status = STATUS_SUCCESS;
    ULONG Length; //including nullterm
 
-   if (NlsMbOemCodePageTag == TRUE)
-      Length = RtlUnicodeStringToAnsiSize (UniSource);
-   else
-      Length = (UniSource->Length / sizeof(WCHAR)) + sizeof(CHAR);
-
+   Length = RtlUnicodeStringToAnsiSize(UniSource);
    if (Length > 0x0000FFFF)
       return STATUS_INVALID_PARAMETER_2;
 
@@ -1223,17 +1138,13 @@ NTSTATUS
 STDCALL
 RtlOemStringToCountedUnicodeString(
    IN OUT PUNICODE_STRING UniDest,
-   IN POEM_STRING OemSource,
+   IN PCOEM_STRING OemSource,
    IN BOOLEAN AllocateDestinationString)
 {
    NTSTATUS Status;
    ULONG Length; /* excluding nullterm */
 
-   if (NlsMbCodePageTag == TRUE)
-      Length = RtlOemStringToUnicodeSize(OemSource) - sizeof(WCHAR);
-   else
-      Length = OemSource->Length * sizeof(WCHAR);
-
+   Length = RtlOemStringToCountedUnicodeSize(OemSource);
    if (Length > 65535)
       return STATUS_INVALID_PARAMETER_2;
 
@@ -1569,11 +1480,7 @@ RtlUnicodeStringToCountedOemString(
    NTSTATUS Status;
    ULONG Length; //excluding nullterm
 
-   if (NlsMbOemCodePageTag == TRUE)
-      Length = RtlUnicodeStringToAnsiSize(UniSource) - sizeof(CHAR);
-   else
-      Length = (UniSource->Length / sizeof(WCHAR));
-
+   Length = RtlUnicodeStringToCountedOemSize(UniSource);
    if (Length > 0x0000FFFF)
       return STATUS_INVALID_PARAMETER_2;
 
@@ -1719,11 +1626,7 @@ RtlUpcaseUnicodeStringToAnsiString(
    NTSTATUS Status;
    ULONG Length; /* including nullterm */
 
-   if (NlsMbCodePageTag == TRUE)
-      Length = RtlUnicodeStringToAnsiSize(UniSource);
-   else
-      Length = (UniSource->Length / sizeof(WCHAR)) + sizeof(CHAR);
-
+   Length = RtlUnicodeStringToAnsiSize(UniSource);
    if (Length > 0x0000FFFF)
       return STATUS_INVALID_PARAMETER_2;
 
@@ -1778,17 +1681,13 @@ NTSTATUS
 STDCALL
 RtlUpcaseUnicodeStringToCountedOemString(
    IN OUT POEM_STRING OemDest,
-   IN PUNICODE_STRING UniSource,
+   IN PCUNICODE_STRING UniSource,
    IN BOOLEAN AllocateDestinationString)
 {
    NTSTATUS Status;
    ULONG Length; /* excluding nullterm */
 
-   if (NlsMbCodePageTag == TRUE)
-      Length = RtlUnicodeStringToAnsiSize(UniSource) - sizeof(CHAR);
-   else
-      Length = UniSource->Length / sizeof(WCHAR);
-
+   Length = RtlUnicodeStringToCountedOemSize(UniSource);
    if (Length > 0x0000FFFF)
       return(STATUS_INVALID_PARAMETER_2);
 
@@ -1839,18 +1738,14 @@ NTSTATUS
 STDCALL
 RtlUpcaseUnicodeStringToOemString (
    IN OUT POEM_STRING OemDest,
-   IN PUNICODE_STRING UniSource,
+   IN PCUNICODE_STRING UniSource,
    IN BOOLEAN  AllocateDestinationString
 )
 {
    NTSTATUS Status;
    ULONG Length; /* including nullterm */
 
-   if (NlsMbOemCodePageTag == TRUE)
-      Length = RtlUnicodeStringToAnsiSize(UniSource);
-   else
-      Length = (UniSource->Length / sizeof(WCHAR)) + sizeof(CHAR);
-
+   Length = RtlUnicodeStringToAnsiSize(UniSource);
    if (Length > 0x0000FFFF)
       return STATUS_INVALID_PARAMETER_2;
 
@@ -1901,7 +1796,7 @@ RtlUpcaseUnicodeStringToOemString (
  */
 ULONG
 STDCALL
-RtlOemStringToUnicodeSize(IN POEM_STRING OemString)
+RtlxOemStringToUnicodeSize(IN PCOEM_STRING OemString)
 {
    ULONG Size;
 
@@ -1964,8 +1859,8 @@ RtlStringFromGUID (IN REFGUID Guid,
  */
 ULONG
 STDCALL
-RtlUnicodeStringToAnsiSize(
-   IN PUNICODE_STRING UnicodeString)
+RtlxUnicodeStringToAnsiSize(
+   IN PCUNICODE_STRING UnicodeString)
 {
    ULONG Size;
 
@@ -1978,58 +1873,38 @@ RtlUnicodeStringToAnsiSize(
 }
 
 
-
-
 /*
  * @implemented
  */
 LONG
 STDCALL
 RtlCompareUnicodeString(
-   IN PUNICODE_STRING String1,
-   IN PUNICODE_STRING String2,
+   IN PCUNICODE_STRING s1,
+   IN PCUNICODE_STRING s2,
    IN BOOLEAN  CaseInsensitive)
 {
-   ULONG len1, len2;
-   PWCHAR s1, s2;
-   WCHAR  c1, c2;
+   unsigned int len;
+   LONG ret = 0;
+   LPCWSTR p1, p2;
 
-   if (String1 && String2)
-   {
-      len1 = String1->Length / sizeof(WCHAR);
-      len2 = String2->Length / sizeof(WCHAR);
-      s1 = String1->Buffer;
-      s2 = String2->Buffer;
+   len = min(s1->Length, s2->Length) / sizeof(WCHAR);
+   p1 = s1->Buffer;
+   p2 = s2->Buffer;
 
-      if (s1 && s2)
-      {
-         if (CaseInsensitive)
-         {
-            while (1)
-            {
-               c1 = len1-- ? RtlUpcaseUnicodeChar (*s1++) : 0;
-               c2 = len2-- ? RtlUpcaseUnicodeChar (*s2++) : 0;
-               if (!c1 || !c2 || c1 != c2)
-                  return c1 - c2;
-            }
-         }
-         else
-         {
-            while (1)
-            {
-               c1 = len1-- ? *s1++ : 0;
-               c2 = len2-- ? *s2++ : 0;
-               if (!c1 || !c2 || c1 != c2)
-                  return c1 - c2;
-            }
-         }
-      }
+   if (CaseInsensitive)
+   {
+     while (!ret && len--) ret = RtlUpcaseUnicodeChar(*p1++) - RtlUpcaseUnicodeChar(*p2++);
    }
-
-   return 0;
+   else
+   {
+     while (!ret && len--) ret = *p1++ - *p2++;
+   }
+   if (!ret) ret = s1->Length - s2->Length;
+   return ret;
 }
 
 
+
 /*
  * @implemented
  */
@@ -2067,7 +1942,7 @@ VOID
 STDCALL
 RtlCopyUnicodeString(
    IN OUT PUNICODE_STRING DestinationString,
-   IN PUNICODE_STRING SourceString)
+   IN PCUNICODE_STRING SourceString)
 {
    ULONG copylen;
 
@@ -2149,7 +2024,7 @@ RtlCreateUnicodeStringFromAsciiz(
 NTSTATUS STDCALL
 RtlDowncaseUnicodeString(
    IN OUT PUNICODE_STRING UniDest,
-   IN PUNICODE_STRING UniSource,
+   IN PCUNICODE_STRING UniSource,
    IN BOOLEAN AllocateDestinationString)
 {
    ULONG i;
@@ -2239,11 +2114,7 @@ RtlAnsiStringToUnicodeString(
    NTSTATUS Status;
    ULONG Length; //including nullterm
 
-   if (NlsMbCodePageTag == TRUE)
-      Length = RtlAnsiStringToUnicodeSize(AnsiSource);
-   else
-      Length = (AnsiSource->Length * sizeof(WCHAR)) + sizeof(WCHAR);
-
+   Length = RtlAnsiStringToUnicodeSize(AnsiSource);
    if (Length > 0xffff)
       return STATUS_INVALID_PARAMETER_2;
 
@@ -2347,64 +2218,26 @@ RtlUpperString(PSTRING DestinationString,
    DestinationString->Length = SourceString->Length;
 }
 
-
-/*
- * @implemented
- */
-ULONG STDCALL
-RtlxAnsiStringToUnicodeSize(IN PANSI_STRING AnsiString)
-{
-   return RtlAnsiStringToUnicodeSize(AnsiString);
-}
-
-
-/*
- * @implemented
- */
-ULONG STDCALL
-RtlxOemStringToUnicodeSize(IN POEM_STRING OemString)
-{
-   return RtlOemStringToUnicodeSize(OemString);
-}
-
-
-
-/*
- * @implemented
- */
-ULONG STDCALL
-RtlxUnicodeStringToAnsiSize(IN PUNICODE_STRING UnicodeString)
-{
-   return RtlUnicodeStringToAnsiSize(UnicodeString);
-}
-
-
-/*
- * @implemented
- */
-ULONG STDCALL
-RtlxUnicodeStringToOemSize(IN PUNICODE_STRING UnicodeString)
-{
-   return RtlUnicodeStringToOemSize(UnicodeString);
-}
-
 /*
  * @implemented
  *
  * NOTES
  *  See RtlpDuplicateUnicodeString
  */
-NTSTATUS STDCALL
+NTSTATUS
+STDCALL
 RtlDuplicateUnicodeString(
-   INT AddNull,
-   IN PUNICODE_STRING SourceString,
-   PUNICODE_STRING DestinationString)
+   IN ULONG Flags,
+   IN PCUNICODE_STRING SourceString,
+   OUT PUNICODE_STRING DestinationString)
 {
    if (SourceString == NULL || DestinationString == NULL)
       return STATUS_INVALID_PARAMETER;
 
 
-   if (SourceString->Length == 0 && AddNull != 3)
+   if ((SourceString->Length == 0) && 
+       (Flags != (RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE | 
+                  RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING)))
    {
       DestinationString->Length = 0;
       DestinationString->MaximumLength = 0;
@@ -2414,7 +2247,7 @@ RtlDuplicateUnicodeString(
    {
       UINT DestMaxLength = SourceString->Length;
 
-      if (AddNull)
+      if (Flags & RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE)
          DestMaxLength += sizeof(UNICODE_NULL);
 
       DestinationString->Buffer = RtlpAllocateStringMemory(DestMaxLength, TAG_USTR);
@@ -2425,7 +2258,7 @@ RtlDuplicateUnicodeString(
       DestinationString->Length = SourceString->Length;
       DestinationString->MaximumLength = DestMaxLength;
 
-      if (AddNull)
+      if (Flags & RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE)
          DestinationString->Buffer[DestinationString->Length / sizeof(WCHAR)] = 0;
    }