reactos/sdk/lib/dnslib/string.c

258 lines
7.2 KiB
C

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