/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS DNS Shared Library * FILE: lib/dnslib/string.c * PURPOSE: functions for string manipulation and conversion. */ /* INCLUDES ******************************************************************/ #include "precomp.h" /* DATA **********************************************************************/ /* FUNCTIONS *****************************************************************/ ULONG WINAPI Dns_StringCopy(OUT PVOID Destination, IN OUT PULONG DestinationSize, IN PVOID String, IN ULONG StringSize OPTIONAL, IN DWORD InputType, IN DWORD OutputType) { ULONG DestSize; ULONG OutputSize = 0; /* Check if the caller already gave us the string size */ if (!StringSize) { /* He didn't, get the input type */ if (InputType == UnicodeString) { /* Unicode string, calculate the size */ StringSize = (ULONG)wcslen((LPWSTR)String); } else { /* ANSI or UTF-8 sting, get the size */ StringSize = (ULONG)strlen((LPSTR)String); } } /* Check if we have a limit on the desination size */ if (DestinationSize) { /* Make sure that we can respect it */ DestSize = Dns_GetBufferLengthForStringCopy(String, StringSize, InputType, OutputType); if (*DestinationSize < DestSize) { /* Fail due to missing buffer space */ SetLastError(ERROR_MORE_DATA); /* Return how much data we actually need */ *DestinationSize = DestSize; return 0; } else if (!DestSize) { /* Fail due to invalid data */ SetLastError(ERROR_INVALID_DATA); return 0; } /* Return how much data we actually need */ *DestinationSize = DestSize; } /* Now check if this is a Unicode String as input */ if (InputType == UnicodeString) { /* Check if the output is ANSI */ if (OutputType == AnsiString) { /* Convert and return the final desination size */ OutputSize = WideCharToMultiByte(CP_ACP, 0, String, StringSize, Destination, -1, NULL, NULL) + 1; } else if (OutputType == UnicodeString) { /* Copy the string */ StringSize = StringSize * sizeof(WCHAR); RtlMoveMemory(Destination, String, StringSize); /* Return output length */ OutputSize = StringSize + 2; } else if (OutputType == Utf8String) { /* FIXME */ OutputSize = 0; } } else if (InputType == AnsiString) { /* It's ANSI, is the output ansi too? */ if (OutputType == AnsiString) { /* Copy the string */ RtlMoveMemory(Destination, String, StringSize); /* Return output length */ OutputSize = StringSize + 1; } else if (OutputType == UnicodeString) { /* Convert to Unicode and return size */ OutputSize = MultiByteToWideChar(CP_ACP, 0, String, StringSize, Destination, -1) * sizeof(WCHAR) + 2; } else if (OutputType == Utf8String) { /* FIXME */ OutputSize = 0; } } else if (InputType == Utf8String) { /* FIXME */ OutputSize = 0; } /* Return the output size */ return OutputSize; } LPWSTR WINAPI Dns_CreateStringCopy_W(IN LPWSTR Name) { SIZE_T StringLength; LPWSTR NameCopy; /* Make sure that we have a name */ if (!Name) { /* Fail */ SetLastError(ERROR_INVALID_PARAMETER); return NULL; } /* Find out the size of the string */ StringLength = (wcslen(Name) + 1) * sizeof(WCHAR); /* Allocate space for the copy */ NameCopy = Dns_AllocZero(StringLength); if (NameCopy) { /* Copy it */ RtlCopyMemory(NameCopy, Name, StringLength); } else { /* Fail */ SetLastError(ERROR_NOT_ENOUGH_MEMORY); } /* Return the copy */ return NameCopy; } ULONG WINAPI Dns_GetBufferLengthForStringCopy(IN PVOID String, IN ULONG Size OPTIONAL, IN DWORD InputType, IN DWORD OutputType) { ULONG OutputSize = 0; /* Check what kind of string this is */ if (InputType == UnicodeString) { /* Check if we have a size */ if (!Size) { /* Get it ourselves */ Size = (ULONG)wcslen(String); } /* Check the output type */ if (OutputType == UnicodeString) { /* Convert the size to bytes */ OutputSize = (Size + 1) * sizeof(WCHAR); } else if (OutputType == Utf8String) { /* FIXME */ OutputSize = 0; } else { /* Find out how much it will be in ANSI bytes */ OutputSize = WideCharToMultiByte(CP_ACP, 0, String, Size, NULL, 0, NULL, NULL) + 1; } } else if (InputType == AnsiString) { /* Check if we have a size */ if (!Size) { /* Get it ourselves */ Size = (ULONG)strlen(String); } /* Check the output type */ if (OutputType == AnsiString) { /* Just add a byte for the null char */ OutputSize = Size + 1; } else if (OutputType == UnicodeString) { /* Calculate the bytes for a Unicode string */ OutputSize = (MultiByteToWideChar(CP_ACP, 0, String, Size, NULL, 0) + 1) * sizeof(WCHAR); } else if (OutputType == Utf8String) { /* FIXME */ OutputSize = 0; } } else if (InputType == Utf8String) { /* FIXME */ OutputSize = 0; } /* Return the size required */ return OutputSize; }