Author: ion
Date: Tue Jun 27 08:09:03 2006
New Revision: 22653
URL:
http://svn.reactos.org/svn/reactos?rev=22653&view=rev
Log:
- Fix all the failures in the RTLSTR Wine test by merging our old rtl string routines with
Wine's. We now pass all 2300 something tests.
Modified:
trunk/reactos/lib/rtl/nls.c
trunk/reactos/lib/rtl/unicode.c
Modified: trunk/reactos/lib/rtl/nls.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/nls.c?rev=22653&am…
==============================================================================
--- trunk/reactos/lib/rtl/nls.c (original)
+++ trunk/reactos/lib/rtl/nls.c Tue Jun 27 08:09:03 2006
@@ -564,19 +564,19 @@
{
USHORT Offset;
- if (Source < L'a')
+ if (Source < 'a')
return Source;
- if (Source <= L'z')
- return (Source - (L'a' - L'A'));
-
- Offset = ((USHORT)Source >> 8);
+ if (Source <= 'z')
+ return (Source - ('a' - 'A'));
+
+ Offset = ((USHORT)Source >> 8) & 0xFF;
Offset = NlsUnicodeUpcaseTable[Offset];
- Offset += (((USHORT)Source & 0x00F0) >> 4);
+ Offset += ((USHORT)Source >> 4) & 0xF;
Offset = NlsUnicodeUpcaseTable[Offset];
- Offset += ((USHORT)Source & 0x000F);
+ Offset += ((USHORT)Source & 0xF);
Offset = NlsUnicodeUpcaseTable[Offset];
return Source + (SHORT)Offset;
@@ -727,24 +727,42 @@
WCHAR Unicode;
CHAR Destination;
- if (NlsMbCodePageTag == FALSE)
- {
- /* single-byte code page */
-
- /* ansi->unicode */
- Unicode = NlsAnsiToUnicodeTable[(UCHAR)Source];
-
- /* upcase conversion */
- Unicode = RtlUpcaseUnicodeChar (Unicode);
-
- /* unicode -> ansi */
- Destination = NlsUnicodeToAnsiTable[(USHORT)Unicode];
- }
- else
- {
- /* multi-byte code page */
- /* FIXME */
- Destination = Source;
+ /* Check for simple ANSI case */
+ if (Source <= 'z')
+ {
+ /* Check for simple downcase a-z case */
+ if (Source >= 'a')
+ {
+ /* Just XOR with the difference */
+ return Source ^ ('a' - 'A');
+ }
+ else
+ {
+ /* Otherwise return the same char, it's already upcase */
+ return Source;
+ }
+ }
+ else
+ {
+ if (NlsMbCodePageTag == FALSE)
+ {
+ /* single-byte code page */
+
+ /* ansi->unicode */
+ Unicode = NlsAnsiToUnicodeTable[(UCHAR)Source];
+
+ /* upcase conversion */
+ Unicode = RtlUpcaseUnicodeChar (Unicode);
+
+ /* unicode -> ansi */
+ Destination = NlsUnicodeToAnsiTable[(USHORT)Unicode];
+ }
+ else
+ {
+ /* multi-byte code page */
+ /* FIXME */
+ Destination = Source;
+ }
}
return Destination;
Modified: trunk/reactos/lib/rtl/unicode.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/unicode.c?rev=2265…
==============================================================================
--- trunk/reactos/lib/rtl/unicode.c (original)
+++ trunk/reactos/lib/rtl/unicode.c Tue Jun 27 08:09:03 2006
@@ -510,54 +510,48 @@
* Str is nullterminated when length allowes it.
* When str fits exactly in length characters the nullterm is ommitted.
*/
-NTSTATUS
-NTAPI
-RtlIntegerToChar(
- IN ULONG Value,
- IN ULONG Base,
- IN ULONG Length,
- IN OUT PCHAR String)
-{
- ULONG Radix;
- CHAR temp[33];
- ULONG v = Value;
- ULONG i;
- PCHAR tp;
- PCHAR sp;
-
- Radix = Base;
- if (Radix == 0)
- Radix = 10;
-
- if ((Radix != 2) && (Radix != 8) &&
- (Radix != 10) && (Radix != 16))
- {
- return STATUS_INVALID_PARAMETER;
- }
-
- tp = temp;
- while (v || tp == temp)
- {
- i = v % Radix;
- v = v / Radix;
- if (i < 10)
- *tp = i + '0';
- else
- *tp = i + 'a' - 10;
- tp++;
- }
-
- if ((ULONG)((ULONG_PTR)tp - (ULONG_PTR)temp) >= Length)
- {
- return STATUS_BUFFER_TOO_SMALL;
- }
-
- sp = String;
- while (tp > temp)
- *sp++ = *--tp;
- *sp = 0;
-
- return STATUS_SUCCESS;
+NTSTATUS NTAPI RtlIntegerToChar(
+ ULONG value, /* [I] Value to be converted */
+ ULONG base, /* [I] Number base for conversion (allowed 0, 2, 8, 10 or 16) */
+ ULONG length, /* [I] Length of the str buffer in bytes */
+ PCHAR str) /* [O] Destination for the converted value */
+{
+ CHAR buffer[33];
+ PCHAR pos;
+ CHAR digit;
+ ULONG len;
+
+ if (base == 0) {
+ base = 10;
+ } else if (base != 2 && base != 8 && base != 10 && base !=
16) {
+ return STATUS_INVALID_PARAMETER;
+ } /* if */
+
+ pos = &buffer[32];
+ *pos = '\0';
+
+ do {
+ pos--;
+ digit = value % base;
+ value = value / base;
+ if (digit < 10) {
+ *pos = '0' + digit;
+ } else {
+ *pos = 'A' + digit - 10;
+ } /* if */
+ } while (value != 0L);
+
+ len = &buffer[32] - pos;
+ if (len > length) {
+ return STATUS_BUFFER_OVERFLOW;
+ } else if (str == NULL) {
+ return STATUS_ACCESS_VIOLATION;
+ } else if (len == length) {
+ memcpy(str, pos, len);
+ } else {
+ memcpy(str, pos, len + 1);
+ } /* if */
+ return STATUS_SUCCESS;
}
/*
@@ -765,87 +759,57 @@
}
return FALSE;
}
-
-/**************************************************************************
- * RtlUnicodeStringToInteger (NTDLL.@)
- * @implemented
- * Converts an unicode string into its integer equivalent.
- *
- * RETURNS
- * Success: STATUS_SUCCESS. value contains the converted number
- * Failure: STATUS_INVALID_PARAMETER, if base is not 0, 2, 8, 10 or 16.
- * STATUS_ACCESS_VIOLATION, if value is NULL.
- *
- * NOTES
- * For base 0 it uses 10 as base and the string should be in the format
- * "{whitespace} [+|-] [0[x|o|b]] {digits}".
- * For other bases the string should be in the format
- * "{whitespace} [+|-] {digits}".
- * No check is made for value overflow, only the lower 32 bits are assigned.
- * If str is NULL it crashes, as the native function does.
- *
- * Note that regardless of success or failure status, we should leave the
- * partial value in Value. An error is never returned based on the chars
- * in the string.
- *
- * DIFFERENCES
- * This function does not read garbage on string length 0 as the native
- * version does.
- */
-NTSTATUS
-NTAPI
-RtlUnicodeStringToInteger(
- PCUNICODE_STRING str, /* [I] Unicode string to be converted */
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+RtlUnicodeStringToInteger(const UNICODE_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 */
+ ULONG *value) /* [O] Destination for the converted value */
{
LPWSTR lpwstr = str->Buffer;
USHORT CharsRemaining = str->Length / sizeof(WCHAR);
WCHAR wchCurrent;
int digit;
- ULONG newbase = 0;
ULONG RunningTotal = 0;
char bMinus = 0;
- while (CharsRemaining >= 1 && *lpwstr <= L' ') {
+ while (CharsRemaining >= 1 && *lpwstr <= ' ') {
lpwstr++;
CharsRemaining--;
} /* while */
if (CharsRemaining >= 1) {
- if (*lpwstr == L'+') {
+ if (*lpwstr == '+') {
lpwstr++;
CharsRemaining--;
- } else if (*lpwstr == L'-') {
+ } else if (*lpwstr == '-') {
bMinus = 1;
lpwstr++;
CharsRemaining--;
} /* if */
} /* 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 (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 */
- }
- 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)) {
+ } else if (base != 2 && base != 8 && base != 10 && base !=
16) {
return STATUS_INVALID_PARAMETER;
-
} /* if */
if (value == NULL) {
@@ -854,16 +818,16 @@
while (CharsRemaining >= 1) {
wchCurrent = *lpwstr;
- 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;
+ 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;
} else {
digit = -1;
} /* if */
- if (digit < 0 || digit >= (int)base) {
+ if (digit < 0 || digit >= base) {
*value = bMinus ? -RunningTotal : RunningTotal;
return STATUS_SUCCESS;
} /* if */
@@ -1267,7 +1231,7 @@
/* Convert string: {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}
* to memory: DWORD... WORD WORD BYTES............
*/
- while (i < 37)
+ while (i <= 37)
{
switch (i)
{
@@ -1774,36 +1738,28 @@
RtlStringFromGUID (IN REFGUID Guid,
OUT PUNICODE_STRING GuidString)
{
- static CONST PWCHAR Hex = L"0123456789ABCDEF";
- WCHAR Buffer[40];
- PWCHAR BufferPtr;
- ULONG i;
-
- if (Guid == NULL)
- {
- return STATUS_INVALID_PARAMETER;
- }
-
- swprintf (Buffer,
- L"{%08lX-%04X-%04X-%02X%02X-",
+ /* Setup the string */
+ GuidString->Length = 38 * sizeof(WCHAR);
+ GuidString->MaximumLength = GuidString->Length + sizeof(UNICODE_NULL);
+ GuidString->Buffer = RtlpAllocateStringMemory(GuidString->MaximumLength,
+ TAG_USTR);
+ if (!GuidString->Buffer) return STATUS_NO_MEMORY;
+
+ /* Now format the GUID */
+ swprintf(GuidString->Buffer,
+ L"{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
Guid->Data1,
Guid->Data2,
Guid->Data3,
Guid->Data4[0],
- Guid->Data4[1]);
- BufferPtr = Buffer + 25;
-
- /* 6 hex bytes */
- for (i = 2; i < 8; i++)
- {
- *BufferPtr++ = Hex[Guid->Data4[i] >> 4];
- *BufferPtr++ = Hex[Guid->Data4[i] & 0xf];
- }
-
- *BufferPtr++ = L'}';
- *BufferPtr++ = L'\0';
-
- return RtlCreateUnicodeString (GuidString, Buffer);
+ Guid->Data4[1],
+ Guid->Data4[2],
+ Guid->Data4[3],
+ Guid->Data4[4],
+ Guid->Data4[5],
+ Guid->Data4[6],
+ Guid->Data4[7]);
+ return STATUS_SUCCESS;
}
/*
@@ -2119,7 +2075,7 @@
PCHAR Src, Dest;
Length = min(SourceString->Length,
- DestinationString->MaximumLength - 1);
+ DestinationString->MaximumLength);
Src = SourceString->Buffer;
Dest = DestinationString->Buffer;
@@ -2146,8 +2102,12 @@
{
PAGED_CODE_RTL();
- if (SourceString == NULL || DestinationString == NULL)
- return STATUS_INVALID_PARAMETER;
+ if (SourceString == NULL || DestinationString == NULL ||
+ SourceString->Length > SourceString->MaximumLength ||
+ (SourceString->Length == 0 && SourceString->MaximumLength > 0
&& SourceString->Buffer == NULL) ||
+ Flags == RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING || Flags >= 4 ||
Flags < 0) {
+ return STATUS_INVALID_PARAMETER;
+ }
if ((SourceString->Length == 0) &&