update for HEAD-2003091401
[reactos.git] / ntoskrnl / rtl / unicode.c
index a9ec745..2637f1f 100644 (file)
@@ -4,26 +4,29 @@
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/rtl/unicode.c
  * PURPOSE:         String functions
- * PROGRAMMER:      Jason Filby (jasonfilby@yahoo.com)
+ * PROGRAMMERS:     Jason Filby (jasonfilby@yahoo.com)
+ *                  Vizzini (vizzini@plasmic.com)
  * UPDATE HISTORY:
  *                  Created 10/08/98
  */
 
 #include <ddk/ntddk.h>
-//#include <internal/nls.h>
 #include <ctype.h>
 #include <ntos/minmax.h>
 #include <internal/pool.h>
+#include <internal/nls.h>
 
 #define NDEBUG
 #include <internal/debug.h>
 
+
 /* GLOBALS *******************************************************************/
 
 #define TAG_USTR  TAG('U', 'S', 'T', 'R')
 #define TAG_ASTR  TAG('A', 'S', 'T', 'R')
 #define TAG_OSTR  TAG('O', 'S', 'T', 'R')
 
+
 /* FUNCTIONS *****************************************************************/
 
 WCHAR
@@ -48,6 +51,9 @@ RtlAnsiCharToUnicodeChar(IN CHAR AnsiChar)
 }
 
 
+/*
+ * @implemented
+ */
 ULONG
 STDCALL
 RtlAnsiStringToUnicodeSize(IN PANSI_STRING AnsiString)
@@ -62,6 +68,9 @@ RtlAnsiStringToUnicodeSize(IN PANSI_STRING AnsiString)
 }
 
 
+/*
+ * @implemented
+ */
 NTSTATUS
 STDCALL
 RtlAnsiStringToUnicodeString(IN OUT PUNICODE_STRING DestinationString,
@@ -120,6 +129,9 @@ RtlAnsiStringToUnicodeString(IN OUT PUNICODE_STRING DestinationString,
 }
 
 
+/*
+ * @implemented
+ */
 NTSTATUS
 STDCALL
 RtlAppendAsciizToString(IN OUT PSTRING Destination,
@@ -148,6 +160,9 @@ RtlAppendAsciizToString(IN OUT PSTRING Destination,
 }
 
 
+/*
+ * @implemented
+ */
 NTSTATUS
 STDCALL
 RtlAppendStringToString(IN OUT PSTRING Destination,
@@ -174,40 +189,33 @@ RtlAppendStringToString(IN OUT PSTRING Destination,
 }
 
 
+/*
+ * @implemented
+ */
 NTSTATUS
 STDCALL
 RtlAppendUnicodeStringToString(IN OUT PUNICODE_STRING Destination,
                               IN PUNICODE_STRING Source)
 {
-       PWCHAR Src, Dest;
-       ULONG i;
 
        if ((Source->Length + Destination->Length) >= Destination->MaximumLength)
                return STATUS_BUFFER_TOO_SMALL;
 
-       Src  = Source->Buffer;
-       Dest = Destination->Buffer + (Destination->Length / sizeof (WCHAR));
-       for (i = 0; i < (Source->Length / sizeof(WCHAR)); i++)
-       {
-               *Dest = *Src;
-               Dest++;
-               Src++;
-       }
-       *Dest = 0;
-
+       memcpy((PVOID)Destination->Buffer + Destination->Length, Source->Buffer, Source->Length);
        Destination->Length += Source->Length;
+       Destination->Buffer[Destination->Length / sizeof(WCHAR)] = 0;
 
        return STATUS_SUCCESS;
 }
 
 
+/*
+ * @implemented
+ */
 NTSTATUS STDCALL
 RtlAppendUnicodeToString(IN OUT PUNICODE_STRING Destination,
                         IN PWSTR Source)
 {
-  PWCHAR Src;
-  PWCHAR Dest;
-  ULONG  i;
   ULONG  slen;
 
   slen = wcslen(Source) * sizeof(WCHAR);
@@ -215,23 +223,16 @@ RtlAppendUnicodeToString(IN OUT PUNICODE_STRING Destination,
   if (Destination->Length + slen >= Destination->MaximumLength)
     return(STATUS_BUFFER_TOO_SMALL);
 
-  Src = Source;
-  Dest = Destination->Buffer + (Destination->Length / sizeof(WCHAR));
-
-  for (i = 0; i < (slen / sizeof(WCHAR)); i++)
-    {
-      *Dest = *Src;
-      Dest++;
-      Src++;
-    }
-  *Dest = 0;
-
+  memcpy((PVOID)Destination->Buffer + Destination->Length, Source, slen + sizeof(WCHAR));
   Destination->Length += slen;
 
   return(STATUS_SUCCESS);
 }
 
 
+/*
+ * @implemented
+ */
 NTSTATUS
 STDCALL
 RtlCharToInteger(IN PCSZ String,
@@ -272,6 +273,9 @@ RtlCharToInteger(IN PCSZ String,
 }
 
 
+/*
+ * @implemented
+ */
 LONG
 STDCALL
 RtlCompareString(IN PSTRING String1,
@@ -318,6 +322,9 @@ RtlCompareString(IN PSTRING String1,
 }
 
 
+/*
+ * @implemented
+ */
 LONG
 STDCALL
 RtlCompareUnicodeString(IN PUNICODE_STRING String1,
@@ -364,13 +371,15 @@ RtlCompareUnicodeString(IN PUNICODE_STRING String1,
 }
 
 
+/*
+ * @implemented
+ */
 VOID
 STDCALL
 RtlCopyString(IN OUT PSTRING DestinationString,
              IN PSTRING SourceString)
 {
-       ULONG copylen, i;
-       PCHAR Src, Dest;
+       ULONG copylen;
 
        if(SourceString == NULL)
        {
@@ -380,28 +389,22 @@ RtlCopyString(IN OUT PSTRING DestinationString,
 
        copylen = min (DestinationString->MaximumLength - sizeof(CHAR),
                       SourceString->Length);
-       Src = SourceString->Buffer;
-       Dest = DestinationString->Buffer;
-
-       for (i = 0; i < copylen; i++)
-       {
-               *Dest = *Src;
-               Dest++;
-               Src++;
-       }
-       *Dest = 0;
 
+       memcpy(DestinationString->Buffer, SourceString->Buffer, copylen);
+       DestinationString->Buffer[copylen] = 0;
        DestinationString->Length = copylen;
 }
 
 
+/*
+ * @implemented
+ */
 VOID
 STDCALL
 RtlCopyUnicodeString(IN OUT PUNICODE_STRING DestinationString,
                     IN PUNICODE_STRING SourceString)
 {
-       ULONG copylen, i;
-       PWCHAR Src, Dest;
+       ULONG copylen;
 
        if(SourceString==NULL)
        {
@@ -411,21 +414,15 @@ RtlCopyUnicodeString(IN OUT PUNICODE_STRING DestinationString,
 
        copylen = min(DestinationString->MaximumLength - sizeof(WCHAR),
                      SourceString->Length);
-       Src = SourceString->Buffer;
-       Dest = DestinationString->Buffer;
-
-       for (i = 0; i < (copylen / sizeof (WCHAR)); i++)
-       {
-               *Dest = *Src;
-               Dest++;
-               Src++;
-       }
-       *Dest = 0;
-
+       memcpy(DestinationString->Buffer, SourceString->Buffer, copylen);
+       DestinationString->Buffer[copylen / sizeof(WCHAR)] = 0;
        DestinationString->Length = copylen;
 }
 
 
+/*
+ * @implemented
+ */
 BOOLEAN
 STDCALL
 RtlCreateUnicodeString(IN OUT PUNICODE_STRING Destination,
@@ -471,15 +468,17 @@ RtlCreateUnicodeStringFromAsciiz(IN OUT PUNICODE_STRING Destination,
 }
 
 
-NTSTATUS
-STDCALL
+/*
+ * @implemented
+ */
+NTSTATUS STDCALL
 RtlDowncaseUnicodeString(IN OUT PUNICODE_STRING DestinationString,
                         IN PUNICODE_STRING SourceString,
                         IN BOOLEAN AllocateDestinationString)
 {
   ULONG i;
   PWCHAR Src, Dest;
-  
+
   if (AllocateDestinationString == TRUE)
     {
       DestinationString->MaximumLength = SourceString->Length + sizeof(WCHAR);
@@ -496,7 +495,7 @@ RtlDowncaseUnicodeString(IN OUT PUNICODE_STRING DestinationString,
        return STATUS_BUFFER_TOO_SMALL;
     }
   DestinationString->Length = SourceString->Length;
-  
+
   Src = SourceString->Buffer;
   Dest = DestinationString->Buffer;
   for (i=0; i < SourceString->Length / sizeof(WCHAR); i++)
@@ -511,19 +510,21 @@ RtlDowncaseUnicodeString(IN OUT PUNICODE_STRING DestinationString,
        }
       else
        {
-         /* FIXME: characters above 'Z' */
-         *Dest = *Src;
+         *Dest = RtlDowncaseUnicodeChar(*Src);
        }
-      
+
       Dest++;
       Src++;
     }
   *Dest = 0;
-  
+
   return STATUS_SUCCESS;
 }
 
 
+/*
+ * @implemented
+ */
 BOOLEAN
 STDCALL
 RtlEqualString(IN PSTRING String1,
@@ -567,6 +568,9 @@ RtlEqualString(IN PSTRING String1,
 }
 
 
+/*
+ * @implemented
+ */
 BOOLEAN
 STDCALL
 RtlEqualUnicodeString(IN PUNICODE_STRING String1,
@@ -609,6 +613,9 @@ RtlEqualUnicodeString(IN PUNICODE_STRING String1,
 }
 
 
+/*
+ * @implemented
+ */
 VOID
 STDCALL
 RtlFreeAnsiString(IN PANSI_STRING AnsiString)
@@ -624,6 +631,9 @@ RtlFreeAnsiString(IN PANSI_STRING AnsiString)
 }
 
 
+/*
+ * @implemented
+ */
 VOID
 STDCALL
 RtlFreeOemString(IN POEM_STRING OemString)
@@ -639,6 +649,9 @@ RtlFreeOemString(IN POEM_STRING OemString)
 }
 
 
+/*
+ * @implemented
+ */
 VOID
 STDCALL
 RtlFreeUnicodeString(IN PUNICODE_STRING UnicodeString)
@@ -654,6 +667,9 @@ RtlFreeUnicodeString(IN PUNICODE_STRING UnicodeString)
 }
 
 
+/*
+ * @implemented
+ */
 VOID
 STDCALL
 RtlInitAnsiString(IN OUT PANSI_STRING DestinationString,
@@ -676,6 +692,9 @@ RtlInitAnsiString(IN OUT PANSI_STRING DestinationString,
 }
 
 
+/*
+ * @implemented
+ */
 VOID
 STDCALL
 RtlInitString(IN OUT PSTRING DestinationString,
@@ -698,6 +717,9 @@ RtlInitString(IN OUT PSTRING DestinationString,
 }
 
 
+/*
+ * @implemented
+ */
 VOID
 STDCALL
 RtlInitUnicodeString(IN OUT PUNICODE_STRING DestinationString,
@@ -724,6 +746,9 @@ RtlInitUnicodeString(IN OUT PUNICODE_STRING DestinationString,
 }
 
 
+/*
+ * @implemented
+ */
 NTSTATUS
 STDCALL
 RtlIntegerToChar(IN ULONG Value,
@@ -770,6 +795,9 @@ RtlIntegerToChar(IN ULONG Value,
 }
 
 
+/*
+ * @implemented
+ */
 NTSTATUS
 STDCALL
 RtlIntegerToUnicodeString(IN ULONG Value,
@@ -799,6 +827,9 @@ RtlIntegerToUnicodeString(IN ULONG Value,
 }
 
 
+/*
+ * @implemented
+ */
 NTSTATUS
 STDCALL
 RtlOemStringToCountedUnicodeString(IN OUT PUNICODE_STRING DestinationString,
@@ -855,6 +886,9 @@ RtlOemStringToCountedUnicodeString(IN OUT PUNICODE_STRING DestinationString,
 }
 
 
+/*
+ * @implemented
+ */
 ULONG
 STDCALL
 RtlOemStringToUnicodeSize(IN POEM_STRING OemString)
@@ -869,6 +903,9 @@ RtlOemStringToUnicodeSize(IN POEM_STRING OemString)
 }
 
 
+/*
+ * @implemented
+ */
 NTSTATUS
 STDCALL
 RtlOemStringToUnicodeString(IN OUT PUNICODE_STRING DestinationString,
@@ -927,6 +964,9 @@ RtlOemStringToUnicodeString(IN OUT PUNICODE_STRING DestinationString,
 }
 
 
+/*
+ * @implemented
+ */
 BOOLEAN
 STDCALL
 RtlPrefixString(IN PANSI_STRING String1,
@@ -968,6 +1008,9 @@ RtlPrefixString(IN PANSI_STRING String1,
 }
 
 
+/*
+ * @implemented
+ */
 BOOLEAN
 STDCALL
 RtlPrefixUnicodeString(IN PUNICODE_STRING String1,
@@ -1010,6 +1053,9 @@ RtlPrefixUnicodeString(IN PUNICODE_STRING String1,
 }
 
 
+/*
+ * @implemented
+ */
 ULONG
 STDCALL
 RtlUnicodeStringToAnsiSize(IN PUNICODE_STRING UnicodeString)
@@ -1024,6 +1070,9 @@ RtlUnicodeStringToAnsiSize(IN PUNICODE_STRING UnicodeString)
 }
 
 
+/*
+ * @implemented
+ */
 NTSTATUS
 STDCALL
 RtlUnicodeStringToAnsiString(IN OUT PANSI_STRING DestinationString,
@@ -1077,6 +1126,9 @@ RtlUnicodeStringToAnsiString(IN OUT PANSI_STRING DestinationString,
 }
 
 
+/*
+ * @implemented
+ */
 NTSTATUS
 STDCALL
 RtlUnicodeStringToCountedOemString(IN OUT POEM_STRING DestinationString,
@@ -1140,96 +1192,89 @@ RtlUnicodeStringToCountedOemString(IN OUT POEM_STRING DestinationString,
 }
 
 
+/*
+ * @implemented
+ */
 NTSTATUS
 STDCALL
-RtlUnicodeStringToInteger(IN PUNICODE_STRING String,
+RtlUnicodeStringToInteger(IN PUNICODE_STRING InString,
                          IN ULONG Base,
                          OUT PULONG Value)
 {
-       PWCHAR Str;
-       ULONG lenmin = 0;
-       ULONG i;
-       ULONG Val;
-       BOOLEAN addneg = FALSE;
+  BOOLEAN Negative = 0;
+  PWCHAR String = InString->Buffer;
+  ULONG MaxLen = InString->Length / sizeof(WCHAR);
 
-    *Value = 0;
-       Str = String->Buffer;
+  *Value = 0;
 
-       for (i = 0; i < String->Length / sizeof(WCHAR); i++)
-       {
-               if (*Str == L'b')
-               {
-                       Base = 2;
-                       lenmin++;
-               }
-               else if (*Str == L'o')
-               {
-                       Base = 8;
-                       lenmin++;
-               }
-               else if (*Str == L'd')
-               {
-                       Base = 10;
-                       lenmin++;
-               }
-               else if (*Str == L'x')
-               {
-                       Base = 16;
-                       lenmin++;
-               }
-               else if (*Str == L'+')
-               {
-                       lenmin++;
-               }
-               else if (*Str == L'-')
-               {
-                       addneg = TRUE;
-                       lenmin++;
-               }
-               else if ((*Str > L'1') && (Base == 2))
-               {
-                       return STATUS_INVALID_PARAMETER;
-               }
-               else if (((*Str > L'7') || (*Str < L'0')) && (Base == 8))
-               {
-                       return STATUS_INVALID_PARAMETER;
-               }
-               else if (((*Str > L'9') || (*Str < L'0')) && (Base == 10))
-               {
-                       return STATUS_INVALID_PARAMETER;
-               }
-               else if ((((*Str > L'9') || (*Str < L'0')) ||
-                         ((towupper (*Str) > L'F') ||
-                          (towupper (*Str) < L'A'))) && (Base == 16))
-               {
-                       return STATUS_INVALID_PARAMETER;
-               }
-               else
-                       Str++;
-       }
+  if(*String == L'-')
+    {
+      Negative++;
+      String++;
+    }
+  else if(*String == L'+')
+    {
+      Negative = 0;
+      String++;
+    }
 
-       Str = String->Buffer + lenmin;
+  if(!Base)
+    {
+      if(*String == L'b')
+        {
+          Base = 2;
+          String++;
+        }
+      else if(*String == L'o')
+        {
+          Base = 8;
+          String++;
+        }
+      else if(*String == L'x')
+        {
+          Base = 16;
+          String++;
+        }
+      else
+        Base = 10;
+    }
 
-       if (Base == 0)
-               Base = 10;
+  while(*String && MaxLen)
+    {
+      short c = *String;;
+      String++;
+      MaxLen--;
 
-       while (iswxdigit (*Str) &&
-              (Val = iswdigit (*Str) ? *Str - L'0' : (iswlower (*Str)
-               ? toupper (*Str) : *Str) - L'A' + 10) < Base)
-       {
-               *Value = *Value * Base + Val;
-               Str++;
-       }
+      if(c >= 'a' && c <= 'f')
+        c -= 'a' - 'A';
 
-       if (addneg == TRUE)
-               *Value *= -1;
+      /* validate chars for bases <= 10 */
+      if( Base <= 10  && (c < '0' || c > '9') )
+        return STATUS_INVALID_PARAMETER;
 
-       return STATUS_SUCCESS;
+      /* validate chars for base 16 */
+      else if( (c < '0' || c > '9') && (c < 'A' || c > 'F') )
+        return STATUS_INVALID_PARAMETER;
+
+      /* perhaps someday we'll validate additional bases */
+
+      if(c >= 'A' && c <= 'F')
+        *Value = *Value * Base + c - 'A' + 10;
+      else
+        *Value = *Value * Base + c - '0';
+    }
+
+  if(Negative)
+    *Value *= -1;
+
+  return STATUS_SUCCESS;
 }
 
 
-ULONG
-STDCALL
+/*
+ * @implemented
+ */
+ULONG STDCALL
 RtlUnicodeStringToOemSize(IN PUNICODE_STRING UnicodeString)
 {
   ULONG Size;
@@ -1241,6 +1286,9 @@ RtlUnicodeStringToOemSize(IN PUNICODE_STRING UnicodeString)
 }
 
 
+/*
+ * @implemented
+ */
 NTSTATUS
 STDCALL
 RtlUnicodeStringToOemString(IN OUT POEM_STRING DestinationString,
@@ -1294,30 +1342,17 @@ RtlUnicodeStringToOemString(IN OUT POEM_STRING DestinationString,
 }
 
 
-WCHAR
-STDCALL
-RtlUpcaseUnicodeChar(IN WCHAR Source)
-{
-  if (Source < L'a')
-    return(Source);
-
-  if (Source <= L'z')
-    return(Source - (L'a' - L'A'));
-
-  /* FIXME: characters above 'z' */
-
-  return(Source);
-}
-
-
+/*
+ * @implemented
+ */
 NTSTATUS STDCALL
 RtlUpcaseUnicodeString(IN OUT PUNICODE_STRING DestinationString,
-                      IN PUNICODE_STRING SourceString,
+                      IN PCUNICODE_STRING SourceString,
                       IN BOOLEAN AllocateDestinationString)
 {
   ULONG i;
   PWCHAR Src, Dest;
-  
+
   if (AllocateDestinationString == TRUE)
     {
       DestinationString->MaximumLength = SourceString->Length + sizeof(WCHAR);
@@ -1334,7 +1369,7 @@ RtlUpcaseUnicodeString(IN OUT PUNICODE_STRING DestinationString,
        return(STATUS_BUFFER_TOO_SMALL);
     }
   DestinationString->Length = SourceString->Length;
-  
+
   Src = SourceString->Buffer;
   Dest = DestinationString->Buffer;
   for (i=0; i < SourceString->Length / sizeof(WCHAR); i++)
@@ -1344,13 +1379,15 @@ RtlUpcaseUnicodeString(IN OUT PUNICODE_STRING DestinationString,
       Src++;
     }
   *Dest = 0;
-  
+
   return(STATUS_SUCCESS);
 }
 
 
-NTSTATUS
-STDCALL
+/*
+ * @implemented
+ */
+NTSTATUS STDCALL
 RtlUpcaseUnicodeStringToAnsiString(IN OUT PANSI_STRING DestinationString,
                                   IN PUNICODE_STRING SourceString,
                                   IN BOOLEAN AllocateDestinationString)
@@ -1358,9 +1395,11 @@ RtlUpcaseUnicodeStringToAnsiString(IN OUT PANSI_STRING DestinationString,
   NTSTATUS Status;
   ULONG Length;
   
-  if (NlsMbCodePageTag == TRUE){
-    Length = RtlUnicodeStringToAnsiSize(SourceString); Length--;
-  }
+  if (NlsMbCodePageTag == TRUE)
+    {
+      Length = RtlUnicodeStringToAnsiSize(SourceString);
+      Length--;
+    }
   else
     Length = SourceString->Length / sizeof(WCHAR);
   
@@ -1402,8 +1441,10 @@ RtlUpcaseUnicodeStringToAnsiString(IN OUT PANSI_STRING DestinationString,
 }
 
 
-NTSTATUS
-STDCALL
+/*
+ * @implemented
+ */
+NTSTATUS STDCALL
 RtlUpcaseUnicodeStringToCountedOemString(IN OUT POEM_STRING DestinationString,
                                         IN PUNICODE_STRING SourceString,
                                         IN BOOLEAN AllocateDestinationString)
@@ -1464,8 +1505,10 @@ RtlUpcaseUnicodeStringToCountedOemString(IN OUT POEM_STRING DestinationString,
 }
 
 
-NTSTATUS
-STDCALL
+/*
+ * @implemented
+ */
+NTSTATUS STDCALL
 RtlUpcaseUnicodeStringToOemString(IN OUT POEM_STRING DestinationString,
                                  IN PUNICODE_STRING SourceString,
                                  IN BOOLEAN AllocateDestinationString)
@@ -1517,44 +1560,10 @@ RtlUpcaseUnicodeStringToOemString(IN OUT POEM_STRING DestinationString,
 }
 
 
-CHAR
-STDCALL
-RtlUpperChar(IN CHAR Source)
-{
-  WCHAR Unicode;
-  CHAR Destination;
-
-       if (NlsMbCodePageTag == FALSE)
-       {
-               /* single-byte code page */
-               /* ansi->unicode */
-               Unicode = (WCHAR)Source;
-#if 0
-               Unicode = NlsAnsiToUnicodeData[Source];
-#endif
-
-               /* upcase conversion */
-               Unicode = RtlUpcaseUnicodeChar (Unicode);
-
-               /* unicode -> ansi */
-               Destination = (CHAR)Unicode;
-#if 0
-               Destination = NlsUnicodeToAnsiData[Unicode];
-#endif
-       }
-       else
-       {
-               /* single-byte code page */
-               /* FIXME: implement the multi-byte stuff!! */
-               Destination = Source;
-       }
-
-  return(Destination);
-}
-
-
-VOID
-STDCALL
+/*
+ * @implemented
+ */
+VOID STDCALL
 RtlUpperString(PSTRING DestinationString,
               PSTRING SourceString)
 {
@@ -1580,32 +1589,40 @@ RtlUpperString(PSTRING DestinationString,
 }
 
 
-ULONG
-STDCALL
+/*
+ * @implemented
+ */
+ULONG STDCALL
 RtlxAnsiStringToUnicodeSize(IN PANSI_STRING AnsiString)
 {
   return RtlAnsiStringToUnicodeSize(AnsiString);
 }
 
 
-ULONG
-STDCALL
+/*
+ * @implemented
+ */
+ULONG STDCALL
 RtlxOemStringToUnicodeSize(IN POEM_STRING OemString)
 {
   return RtlOemStringToUnicodeSize((PANSI_STRING)OemString);
 }
 
 
-ULONG
-STDCALL
+/*
+ * @implemented
+ */
+ULONG STDCALL
 RtlxUnicodeStringToAnsiSize(IN PUNICODE_STRING UnicodeString)
 {
   return RtlUnicodeStringToAnsiSize(UnicodeString);
 }
 
 
-ULONG
-STDCALL
+/*
+ * @implemented
+ */
+ULONG STDCALL
 RtlxUnicodeStringToOemSize(IN PUNICODE_STRING UnicodeString)
 {
   return RtlUnicodeStringToOemSize(UnicodeString);