--- /dev/null
+/*
+ * 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;
+}
+