Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers...
[reactos.git] / sdk / lib / dnslib / string.c
diff --git a/sdk/lib/dnslib/string.c b/sdk/lib/dnslib/string.c
new file mode 100644 (file)
index 0000000..e5ec0cf
--- /dev/null
@@ -0,0 +1,257 @@
+/*
+ * 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;
+}
+