[RTL]
[reactos.git] / reactos / sdk / lib / rtl / unicode.c
index 41c9a99..a6185b9 100644 (file)
@@ -24,15 +24,19 @@ extern BOOLEAN NlsMbOemCodePageTag;
 extern PUSHORT NlsLeadByteInfo;
 extern USHORT NlsOemDefaultChar;
 extern USHORT NlsUnicodeDefaultChar;
+extern PUSHORT NlsOemLeadByteInfo;
+extern PWCHAR NlsOemToUnicodeTable;
+extern PCHAR NlsUnicodeToOemTable;
+extern PUSHORT NlsUnicodeToMbOemTable;
 
 
 /* FUNCTIONS *****************************************************************/
 
 NTSTATUS
 NTAPI
-RtlMultiAppendUnicodeStringBuffer(IN PVOID Unknown,
-                                  IN ULONG Unknown2,
-                                  IN PVOID Unknown3)
+RtlMultiAppendUnicodeStringBuffer(OUT PRTL_UNICODE_STRING_BUFFER StringBuffer,
+                                  IN ULONG NumberOfAddends,
+                                  IN PCUNICODE_STRING Addends)
 {
     UNIMPLEMENTED;
     return STATUS_NOT_IMPLEMENTED;
@@ -503,14 +507,48 @@ RtlpDidUnicodeToOemWork(IN PCUNICODE_STRING UnicodeString,
 }
 
 /*
-* @unimplemented
+* @implemented
 */
 BOOLEAN
 NTAPI
 RtlIsValidOemCharacter(IN PWCHAR Char)
 {
-    UNIMPLEMENTED;
-    return FALSE;
+    WCHAR UnicodeChar;
+    WCHAR OemChar;
+
+    /* If multi-byte code page present */
+    if (NlsMbOemCodePageTag)
+    {
+        USHORT Offset = 0;
+
+        OemChar = NlsUnicodeToMbOemTable[*Char];
+
+        /* If character has Lead Byte */
+        if (NlsOemLeadByteInfo[HIBYTE(OemChar)])
+            Offset = NlsOemLeadByteInfo[HIBYTE(OemChar)];
+
+        /* Receive Unicode character from the table */
+        UnicodeChar = RtlpUpcaseUnicodeChar(NlsOemToUnicodeTable[LOBYTE(OemChar) + Offset]);
+
+        /* Receive OEM character from the table */
+        OemChar = NlsUnicodeToMbOemTable[UnicodeChar];
+    }
+    else
+    {
+        /* Receive Unicode character from the table */
+        UnicodeChar = RtlpUpcaseUnicodeChar(NlsOemToUnicodeTable[(UCHAR)NlsUnicodeToOemTable[*Char]]);
+
+        /* Receive OEM character from the table */
+        OemChar = NlsUnicodeToOemTable[UnicodeChar];
+    }
+
+    /* Not valid character, failed */
+    if (OemChar == NlsOemDefaultChar)
+        return FALSE;
+
+    *Char = UnicodeChar;
+
+    return TRUE;
 }
 
 /*
@@ -704,11 +742,11 @@ NTSTATUS NTAPI RtlIntegerToChar(
     }
     else if (len == length)
     {
-        memcpy(str, pos, len);
+        RtlCopyMemory(str, pos, len);
     }
     else
     {
-        memcpy(str, pos, len + 1);
+        RtlCopyMemory(str, pos, len + 1);
     }
 
     return STATUS_SUCCESS;
@@ -905,8 +943,8 @@ RtlPrefixUnicodeString(
         {
             while (NumChars--)
             {
-                if (RtlUpcaseUnicodeChar(*pc1++) !=
-                    RtlUpcaseUnicodeChar(*pc2++))
+                if (RtlpUpcaseUnicodeChar(*pc1++) !=
+                    RtlpUpcaseUnicodeChar(*pc2++))
                     return FALSE;
             }
         }
@@ -1295,6 +1333,16 @@ RtlIsTextUnicode(CONST VOID* buf, INT len, INT* pf)
 
         last_lo_byte = lo_byte;
         last_hi_byte = hi_byte;
+
+        switch (s[i])
+        {
+            case 0xFFFE: /* Reverse BOM */
+            case UNICODE_NULL:
+            case 0x0A0D: /* ASCII CRLF (packed into one word) */
+            case 0xFFFF: /* Unicode 0xFFFF */
+                out_flags |= IS_TEXT_UNICODE_ILLEGAL_CHARS;
+                break;
+        }
     }
 
     if (NlsMbCodePageTag)
@@ -1318,9 +1366,27 @@ RtlIsTextUnicode(CONST VOID* buf, INT len, INT* pf)
                 weight = 2;
             else
                 weight = 1;
+
+            if (flags & IS_TEXT_UNICODE_DBCS_LEADBYTE)
+                out_flags |= IS_TEXT_UNICODE_DBCS_LEADBYTE;
         }
     }
 
+    if (lo_byte_diff < 127 && !hi_byte_diff)
+    {
+        out_flags |= IS_TEXT_UNICODE_ASCII16;
+    }
+
+    if (hi_byte_diff && !lo_byte_diff)
+    {
+        out_flags |= IS_TEXT_UNICODE_REVERSE_ASCII16;
+    }
+
+    if ((weight * lo_byte_diff) < hi_byte_diff)
+    {
+        out_flags |= IS_TEXT_UNICODE_REVERSE_STATISTICS;
+    }
+
     /* apply some statistical analysis */
     if ((flags & IS_TEXT_UNICODE_STATISTICS) &&
         ((weight * hi_byte_diff) < lo_byte_diff))
@@ -1363,16 +1429,6 @@ RtlIsTextUnicode(CONST VOID* buf, INT len, INT* pf)
                 break;
             }
         }
-
-        if (hi_byte_diff && !lo_byte_diff)
-        {
-            out_flags |= IS_TEXT_UNICODE_REVERSE_ASCII16;
-        }
-
-        if ((weight * lo_byte_diff) < hi_byte_diff)
-        {
-            out_flags |= IS_TEXT_UNICODE_REVERSE_STATISTICS;
-        }
     }
 
     if (pf)
@@ -1868,7 +1924,7 @@ RtlUpcaseUnicodeString(
 
     for (i = 0; i < j; i++)
     {
-        UniDest->Buffer[i] = RtlUpcaseUnicodeChar(UniSource->Buffer[i]);
+        UniDest->Buffer[i] = RtlpUpcaseUnicodeChar(UniSource->Buffer[i]);
     }
 
     UniDest->Length = UniSource->Length;
@@ -2140,7 +2196,7 @@ RtlCompareUnicodeString(
 
     if (CaseInsensitive)
     {
-        while (!ret && len--) ret = RtlUpcaseUnicodeChar(*p1++) - RtlUpcaseUnicodeChar(*p2++);
+        while (!ret && len--) ret = RtlpUpcaseUnicodeChar(*p1++) - RtlpUpcaseUnicodeChar(*p2++);
     }
     else
     {
@@ -2320,7 +2376,7 @@ RtlDowncaseUnicodeString(
         }
         else
         {
-            UniDest->Buffer[i] = RtlDowncaseUnicodeChar(UniSource->Buffer[i]);
+            UniDest->Buffer[i] = RtlpDowncaseUnicodeChar(UniSource->Buffer[i]);
         }
     }
 
@@ -2530,13 +2586,13 @@ RtlpIsCharInUnicodeString(
     USHORT i;
 
     if (CaseInSensitive)
-        Char = RtlUpcaseUnicodeChar(Char);
+        Char = RtlpUpcaseUnicodeChar(Char);
 
     for (i = 0; i < MatchString->Length / sizeof(WCHAR); i++)
     {
         WCHAR OtherChar = MatchString->Buffer[i];
         if (CaseInSensitive)
-            OtherChar = RtlUpcaseUnicodeChar(OtherChar);
+            OtherChar = RtlpUpcaseUnicodeChar(OtherChar);
 
         if (Char == OtherChar)
             return TRUE;