* 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
}
+/*
+ * @implemented
+ */
ULONG
STDCALL
RtlAnsiStringToUnicodeSize(IN PANSI_STRING AnsiString)
}
+/*
+ * @implemented
+ */
NTSTATUS
STDCALL
RtlAnsiStringToUnicodeString(IN OUT PUNICODE_STRING DestinationString,
}
+/*
+ * @implemented
+ */
NTSTATUS
STDCALL
RtlAppendAsciizToString(IN OUT PSTRING Destination,
}
+/*
+ * @implemented
+ */
NTSTATUS
STDCALL
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);
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,
}
+/*
+ * @implemented
+ */
LONG
STDCALL
RtlCompareString(IN PSTRING String1,
}
+/*
+ * @implemented
+ */
LONG
STDCALL
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)
{
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)
{
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,
}
-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);
return STATUS_BUFFER_TOO_SMALL;
}
DestinationString->Length = SourceString->Length;
-
+
Src = SourceString->Buffer;
Dest = DestinationString->Buffer;
for (i=0; i < SourceString->Length / sizeof(WCHAR); i++)
}
else
{
- /* FIXME: characters above 'Z' */
- *Dest = *Src;
+ *Dest = RtlDowncaseUnicodeChar(*Src);
}
-
+
Dest++;
Src++;
}
*Dest = 0;
-
+
return STATUS_SUCCESS;
}
+/*
+ * @implemented
+ */
BOOLEAN
STDCALL
RtlEqualString(IN PSTRING String1,
}
+/*
+ * @implemented
+ */
BOOLEAN
STDCALL
RtlEqualUnicodeString(IN PUNICODE_STRING String1,
}
+/*
+ * @implemented
+ */
VOID
STDCALL
RtlFreeAnsiString(IN PANSI_STRING AnsiString)
}
+/*
+ * @implemented
+ */
VOID
STDCALL
RtlFreeOemString(IN POEM_STRING OemString)
}
+/*
+ * @implemented
+ */
VOID
STDCALL
RtlFreeUnicodeString(IN PUNICODE_STRING UnicodeString)
}
+/*
+ * @implemented
+ */
VOID
STDCALL
RtlInitAnsiString(IN OUT PANSI_STRING DestinationString,
}
+/*
+ * @implemented
+ */
VOID
STDCALL
RtlInitString(IN OUT PSTRING DestinationString,
}
+/*
+ * @implemented
+ */
VOID
STDCALL
RtlInitUnicodeString(IN OUT PUNICODE_STRING DestinationString,
}
+/*
+ * @implemented
+ */
NTSTATUS
STDCALL
RtlIntegerToChar(IN ULONG Value,
}
+/*
+ * @implemented
+ */
NTSTATUS
STDCALL
RtlIntegerToUnicodeString(IN ULONG Value,
}
+/*
+ * @implemented
+ */
NTSTATUS
STDCALL
RtlOemStringToCountedUnicodeString(IN OUT PUNICODE_STRING DestinationString,
}
+/*
+ * @implemented
+ */
ULONG
STDCALL
RtlOemStringToUnicodeSize(IN POEM_STRING OemString)
}
+/*
+ * @implemented
+ */
NTSTATUS
STDCALL
RtlOemStringToUnicodeString(IN OUT PUNICODE_STRING DestinationString,
}
+/*
+ * @implemented
+ */
BOOLEAN
STDCALL
RtlPrefixString(IN PANSI_STRING String1,
}
+/*
+ * @implemented
+ */
BOOLEAN
STDCALL
RtlPrefixUnicodeString(IN PUNICODE_STRING String1,
}
+/*
+ * @implemented
+ */
ULONG
STDCALL
RtlUnicodeStringToAnsiSize(IN PUNICODE_STRING UnicodeString)
}
+/*
+ * @implemented
+ */
NTSTATUS
STDCALL
RtlUnicodeStringToAnsiString(IN OUT PANSI_STRING DestinationString,
}
+/*
+ * @implemented
+ */
NTSTATUS
STDCALL
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;
}
+/*
+ * @implemented
+ */
NTSTATUS
STDCALL
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);
return(STATUS_BUFFER_TOO_SMALL);
}
DestinationString->Length = SourceString->Length;
-
+
Src = SourceString->Buffer;
Dest = DestinationString->Buffer;
for (i=0; i < SourceString->Length / sizeof(WCHAR); i++)
Src++;
}
*Dest = 0;
-
+
return(STATUS_SUCCESS);
}
-NTSTATUS
-STDCALL
+/*
+ * @implemented
+ */
+NTSTATUS STDCALL
RtlUpcaseUnicodeStringToAnsiString(IN OUT PANSI_STRING DestinationString,
IN PUNICODE_STRING SourceString,
IN BOOLEAN AllocateDestinationString)
NTSTATUS Status;
ULONG Length;
- if (NlsMbCodePageTag == TRUE){
- Length = RtlUnicodeStringToAnsiSize(SourceString); Length--;
- }
+ if (NlsMbCodePageTag == TRUE)
+ {
+ Length = RtlUnicodeStringToAnsiSize(SourceString);
+ Length--;
+ }
else
Length = SourceString->Length / sizeof(WCHAR);
}
-NTSTATUS
-STDCALL
+/*
+ * @implemented
+ */
+NTSTATUS STDCALL
RtlUpcaseUnicodeStringToCountedOemString(IN OUT POEM_STRING DestinationString,
IN PUNICODE_STRING SourceString,
IN BOOLEAN AllocateDestinationString)
}
-NTSTATUS
-STDCALL
+/*
+ * @implemented
+ */
+NTSTATUS STDCALL
RtlUpcaseUnicodeStringToOemString(IN OUT POEM_STRING DestinationString,
IN PUNICODE_STRING SourceString,
IN BOOLEAN AllocateDestinationString)
}
-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)
{
}
-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);