/*
 *	Rtl string functions
 *
 *	Copyright 1996-1998 Marcus Meissner
 */

#include "config.h"

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "wine/winestring.h"
#include "crtdll.h"
#include "heap.h"
#include "winnls.h"
#include "debugtools.h"
#include "ntdll_misc.h"
#include "ntddk.h"

#include "casemap.h"

DEFAULT_DEBUG_CHANNEL(ntdll)

/*	STRING FUNCTIONS	*/

/**************************************************************************
 *		NTDLL.towupper
 */
WCHAR CDECL NTDLL_towupper(WCHAR code)
{
    const WCHAR * ptr = uprtable[HIBYTE(code)];
    return ptr ? ptr[LOBYTE(code)] : code;
}

/**************************************************************************
 *		NTDLL.towlower
 */
WCHAR CDECL NTDLL_towlower(WCHAR code)
{
    const WCHAR * ptr = lwrtable[HIBYTE(code)];
    return ptr ? ptr[LOBYTE(code)] : code;
}

/**************************************************************************
 *	RtlInitString
 */
VOID WINAPI RtlInitString(PSTRING target,LPCSTR source)
{
	TRACE("%p %p(%s)\n", target, source, debugstr_a(source));

	target->Buffer = (LPSTR)source;
	if (source)
	{
	  target->Length = lstrlenA(source);
	  target->MaximumLength = target->Length+1;
	}
	else
	{
	  target->Length = target->MaximumLength = 0;
	}
}



/*	ANSI FUNCTIONS	*/

/**************************************************************************
 *	RtlInitAnsiString
 */
VOID WINAPI RtlInitAnsiString(
	PANSI_STRING target,
	LPCSTR source)
{
	TRACE("%p %p(%s)\n", target, source, debugstr_a(source));

	target->Buffer = (LPSTR)source;
	if (source)
	{
	  target->Length = lstrlenA(source);
	  target->MaximumLength = target->Length+1;
	}
	else
	{
	  target->Length = target->MaximumLength = 0;
	}
}

/**************************************************************************
 *	RtlFreeAnsiString
 */
VOID WINAPI RtlFreeAnsiString(
	PANSI_STRING AnsiString)
{
	TRACE("%p\n", AnsiString);
	dump_AnsiString(AnsiString, TRUE);

	if( AnsiString->Buffer )
	  HeapFree( GetProcessHeap(),0,AnsiString->Buffer );
}



/*	UNICODE FUNCTIONS	*/

/**************************************************************************
 *	RtlInitUnicodeString			[NTDLL.403]
 */
VOID WINAPI RtlInitUnicodeString(
	PUNICODE_STRING target,
	LPCWSTR source)
{
	TRACE("%p %p(%s)\n", target, source, debugstr_w(source));
	
	target->Buffer = (LPWSTR)source;
	if (source)
	{
	  target->Length = lstrlenW(source)*2;
	  target->MaximumLength = target->Length + 2;
	}
	else
	{
	  target->Length = target->MaximumLength = 0;
	}
}

/**************************************************************************
 *	RtlFreeUnicodeString			[NTDLL.377]
 */
VOID WINAPI RtlFreeUnicodeString(
	PUNICODE_STRING UnicodeString)
{
	TRACE("%p\n", UnicodeString);
	dump_UnicodeString(UnicodeString, TRUE);

	if (UnicodeString->Buffer)
	  HeapFree(GetProcessHeap(),0,UnicodeString->Buffer);
}

/*
	 COMPARE FUNCTIONS
*/

/**************************************************************************
 *	RtlEqualUnicodeString
 */
BOOLEAN WINAPI RtlEqualUnicodeString(
	IN PUNICODE_STRING s1,
	IN PUNICODE_STRING s2,
        IN BOOLEAN CaseInsensitive) 
{
	BOOLEAN ret;
	TRACE("(%p,%p,%x)\n",s1,s2,CaseInsensitive);
	dump_UnicodeString(s1, TRUE);
	dump_UnicodeString(s2, TRUE);

	if(!s1 || !s2 || !s1->Buffer || !s2->Buffer) return FALSE;
	if (s1->Length != s2->Length) return FALSE;

	if (CaseInsensitive)
	  ret = !CRTDLL__wcsnicmp(s1->Buffer,s2->Buffer,s1->Length/sizeof(WCHAR));
	else	
	  ret = !CRTDLL_wcsncmp(s1->Buffer,s2->Buffer,s1->Length/sizeof(WCHAR));
	return ret;
}

/******************************************************************************
 *	RtlCompareUnicodeString
 */
LONG WINAPI RtlCompareUnicodeString(
	PUNICODE_STRING s1,
	PUNICODE_STRING s2,
	BOOLEAN CaseInsensitive) 
{
	LONG ret;

	TRACE("(%p,%p,%x)\n",s1,s2,CaseInsensitive);
	dump_UnicodeString(s1, TRUE);
	dump_UnicodeString(s2, TRUE);

	if(!s1 || !s2 || !s1->Buffer || !s2->Buffer) return FALSE;
	
	if (s1->Length != s2->Length) return (s1->Length - s2->Length);

	if (CaseInsensitive)
	  ret = CRTDLL__wcsnicmp(s1->Buffer,s2->Buffer,s1->Length/sizeof(WCHAR));
	else	
	  ret = CRTDLL_wcsncmp(s1->Buffer,s2->Buffer,s1->Length/sizeof(WCHAR));
	return ret;
}

/*
	COPY BETWEEN ANSI_STRING or UNICODE_STRING
	there is no parameter checking, it just crashes
*/

/**************************************************************************
 *	RtlAnsiStringToUnicodeString
 *
 * NOTES:
 *  writes terminating 0
 */
NTSTATUS
WINAPI RtlAnsiStringToUnicodeString(
	PUNICODE_STRING uni,
	PANSI_STRING ansi,
	BOOLEAN doalloc)
{
	int len = ansi->Length * sizeof(WCHAR);

	TRACE("%p %p %u\n",uni, ansi, doalloc);
	dump_AnsiString(ansi, TRUE);
	dump_UnicodeString(uni, FALSE);

	if (len>0xfffe) return STATUS_INVALID_PARAMETER_2;
	uni->Length = len;
	if (doalloc) 
	{
	  uni->MaximumLength = len + sizeof(WCHAR);
	  uni->Buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,uni->MaximumLength);
	  if (!uni->Buffer) return STATUS_NO_MEMORY;
	}
	else if (len+sizeof(WCHAR) > uni->MaximumLength)
	{
	  return STATUS_BUFFER_OVERFLOW;
	}
	lstrcpynAtoW(uni->Buffer,ansi->Buffer,ansi->Length+1);
	return STATUS_SUCCESS;
}

/**************************************************************************
 *	RtlUpcaseUnicodeString
 *
 * NOTES:
 *  destination string is never 0-terminated because dest can be equal to src
 *  and src might be not 0-terminated
 *  dest.Length only set when success
 */
DWORD WINAPI RtlUpcaseUnicodeString(
	PUNICODE_STRING dest,
	PUNICODE_STRING src,
	BOOLEAN doalloc)
{
	int i, len = src->Length;

	TRACE("(%p,%p,%x)\n",dest, src, doalloc);
	dump_UnicodeString(dest, FALSE);
	dump_UnicodeString(src, TRUE);

	if (doalloc)
	{
	  dest->Buffer = (LPWSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
	  if (!dest->Buffer) return STATUS_NO_MEMORY;
	  dest->MaximumLength = len; 
	}
	else if (len > dest->MaximumLength)
	{
	  return STATUS_BUFFER_OVERFLOW;
	}

	for (i=0; i < len/sizeof(WCHAR); i++)
	{
	  dest->Buffer[i] = NTDLL_towupper(src->Buffer[i]);
	}
	dest->Length = len;
	return STATUS_SUCCESS;
}

/**************************************************************************
 *	RtlOemStringToUnicodeString
 *
 * NOTES
 *  writes terminating 0
 *  buffer must be bigger than (ansi->Length+1)*2
 *  if astr.Length > 0x7ffe it returns STATUS_INVALID_PARAMETER_2
 *
 * FIXME
 *  OEM to unicode
 */
NTSTATUS
WINAPI RtlOemStringToUnicodeString(
	PUNICODE_STRING uni,
	PSTRING ansi,
	BOOLEAN doalloc)
{
	int len = ansi->Length * sizeof(WCHAR);

	if (len > 0xfffe) return STATUS_INVALID_PARAMETER_2;

	uni->Length = len;
	if (doalloc) 
	{
	  uni->Buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, len + sizeof(WCHAR));
	  if (!uni->Buffer) return STATUS_NO_MEMORY;
	  uni->MaximumLength = len + sizeof(WCHAR);
	}
	else if (len+1 > uni->MaximumLength )
	{
	  return STATUS_BUFFER_OVERFLOW;
	}
	lstrcpynAtoW(uni->Buffer,ansi->Buffer,ansi->Length+1);
	return STATUS_SUCCESS;
}

/**************************************************************************
 *	RtlUnicodeStringToOemString
 *
 * NOTES
 *   allocates uni->Length+1
 *   writes terminating 0
 */
NTSTATUS
WINAPI RtlUnicodeStringToOemString(
	PANSI_STRING oem,
	PUNICODE_STRING uni,
	BOOLEAN doalloc)
{
	int len = uni->Length/sizeof(WCHAR);

	TRACE("%p %s %i\n", oem, debugstr_us(uni), doalloc);

	oem->Length = len;
	if (doalloc)
	{
	  oem->Buffer = (LPSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len+1);
	  if (! oem->Buffer) return STATUS_NO_MEMORY;
	  oem->MaximumLength = len + 1;
	}
	else if (oem->MaximumLength <= len)
	{
	  return STATUS_BUFFER_OVERFLOW;
	}
	lstrcpynWtoA(oem->Buffer, uni->Buffer, len+1);
	return STATUS_SUCCESS;
}

/**************************************************************************
 *	RtlUpcaseUnicodeStringToOemString
 *
 * NOTES
 *  writes terminating 0
 */
NTSTATUS
WINAPI RtlUpcaseUnicodeStringToOemString(
	PANSI_STRING oem,
	PUNICODE_STRING uni,
	BOOLEAN doalloc)
{
	int i, len = uni->Length/sizeof(WCHAR);

	TRACE("%p %s %i\n", oem, debugstr_us(uni), doalloc);

	oem->Length = len;
	if (doalloc)
	{
	  oem->Buffer = (LPSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len+1);
	  if (! oem->Buffer) return STATUS_NO_MEMORY;
	  oem->MaximumLength = len + 1;
	}
	else if (oem->MaximumLength <= len)
	{
	  return STATUS_BUFFER_OVERFLOW;
	}

	for (i=0; i < len; i++)
	{
	  oem->Buffer[i] = NTDLL_towupper((char)(uni->Buffer[i]));
	}
	oem->Buffer[i] = 0;
	return STATUS_SUCCESS;
}

/**************************************************************************
 *	RtlUnicodeStringToAnsiString
 *
 * NOTES
 *  writes terminating 0
 *  copys a part if the buffer is to small
 */
NTSTATUS
WINAPI RtlUnicodeStringToAnsiString(
	PANSI_STRING ansi,
	PUNICODE_STRING uni,
	BOOLEAN doalloc)
{
	int len = uni->Length/sizeof(WCHAR);
	NTSTATUS ret = STATUS_SUCCESS;

	TRACE("%p %s %i\n", ansi, debugstr_us(uni), doalloc);

	ansi->Length = len;
	if (doalloc)
	{
	  ansi->Buffer = (LPSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len+1);
	  if (! ansi->Buffer) return STATUS_NO_MEMORY;
	  ansi->MaximumLength = len + 1;
	}
	else if (ansi->MaximumLength <= len)
	{
	  ansi->Length = ansi->MaximumLength - 1;
	  ret = STATUS_BUFFER_OVERFLOW;
	}
	lstrcpynWtoA(ansi->Buffer, uni->Buffer, ansi->Length+1);
	return ret;
}

/*
	COPY BETWEEN ANSI/UNICODE_STRING AND MULTIBYTE STRINGS
*/
/**************************************************************************
 *	RtlMultiByteToUnicodeN
 *
 * NOTES
 *  dest can be equal to src
 *  if unistr is to small a part is copyed
 *
 * FIXME
 *  multibyte support
 */
NTSTATUS
WINAPI RtlMultiByteToUnicodeN(
	LPWSTR unistr,
	DWORD unilen,
	LPDWORD reslen,
	LPSTR oemstr,
	DWORD oemlen)
{
	UINT len;
	int i;

	TRACE("%p %lu, %p, %s, %lu\n", oemstr, oemlen, reslen, debugstr_w(unistr), unilen);

	len = (unilen/sizeof(WCHAR) < oemlen) ? unilen/sizeof(WCHAR) : oemlen;

	for (i = len-1; i>=0; i--)
	  unistr[i] = (WCHAR)oemstr[i];

	if (reslen) *reslen = len * 2;
	return 0;
}

/**************************************************************************
 *	RtlOemToUnicodeN
 */
NTSTATUS
WINAPI RtlOemToUnicodeN(
	LPWSTR unistr,
	DWORD unilen,
	LPDWORD reslen,
	LPSTR oemstr,
	DWORD oemlen)
{
	UINT len;
	int i;

	TRACE("%p %lu, %p, %s, %lu\n", oemstr, oemlen, reslen, debugstr_w(unistr), unilen);

	len = (unilen/sizeof(WCHAR) < oemlen) ? unilen/sizeof(WCHAR) : oemlen;

	for (i = len-1; i>=0; i--)
	  unistr[i] = (WCHAR)oemstr[i];

	if (reslen) *reslen = len * 2;
	return 0;
}


/**************************************************************************
 *	RtlUnicodeToOemN
 */
NTSTATUS
WINAPI RtlUnicodeToOemN(
	LPSTR oemstr,
	DWORD oemlen,
	LPDWORD reslen,
	LPWSTR unistr,
	DWORD unilen)
{
	UINT len;
	int i;

	TRACE("%p %lu, %p, %s, %lu\n", oemstr, oemlen, reslen, debugstr_w(unistr), unilen);

	len = (oemlen < unilen/sizeof(WCHAR)) ? unilen/sizeof(WCHAR) : oemlen;

	for (i = len-1; i>=0; i--)
	  oemstr[i] = (CHAR)unistr[i];

	if (reslen) *reslen = len * 2;
	return 0;
}

/**************************************************************************
 *	RtlUpcaseUnicodeToOemN
 */
NTSTATUS
WINAPI RtlUpcaseUnicodeToOemN(
	LPSTR oemstr,
	DWORD oemlen,
	LPDWORD reslen,
	LPWSTR unistr,
	DWORD unilen)
{
	UINT len;
	int i;

	TRACE("%p %lu, %p, %s, %lu\n", oemstr, oemlen, reslen, debugstr_w(unistr), unilen);

	len = (oemlen < unilen/sizeof(WCHAR)) ? unilen/sizeof(WCHAR) : oemlen;

	for (i = len-1; i>=0; i--)
	  oemstr[i] = toupper((CHAR)unistr[i]);

	if (reslen) *reslen = len * 2;
	return 0;
}

/**************************************************************************
 *	RtlUnicodeToMultiByteN
 */
NTSTATUS WINAPI RtlUnicodeToMultiByteN(
	PCHAR  MbString,
	ULONG  MbSize,
	PULONG ResultSize,
	PWCHAR UnicodeString,
	ULONG  UnicodeSize)
{
        int Size = 0, i;

	TRACE("(%p,%lu,%p,%p(%s),%lu)\n",
	MbString, MbSize, ResultSize, UnicodeString, debugstr_w(UnicodeString), UnicodeSize);

	Size = (UnicodeSize > (MbSize*sizeof(WCHAR))) ? MbSize: UnicodeSize/sizeof(WCHAR);

	if (ResultSize != NULL) *ResultSize = Size;

	for(i = 0; i < Size; i++)
	{
	  *(MbString++) = *(UnicodeString++);
        }
	return STATUS_SUCCESS;      
}

/*
	STRING SIZE

	Rtlx* supports multibyte
*/

/**************************************************************************
 *	RtlxOemStringToUnicodeSize
 */
UINT WINAPI RtlxOemStringToUnicodeSize(PSTRING str)
{
	return str->Length*2+2;
}

/**************************************************************************
 *	RtlxAnsiStringToUnicodeSize
 */
UINT WINAPI RtlxAnsiStringToUnicodeSize(PANSI_STRING str)
{
	return str->Length*2+2;
}

/**************************************************************************
 *	RtlxUnicodeStringToOemSize
 *
 */
UINT WINAPI RtlxUnicodeStringToOemSize(PUNICODE_STRING str)
{
	return str->Length+1;
}

/*
	MISC
*/

/**************************************************************************
 *	RtlIsTextUnicode
 *
 *	Apply various feeble heuristics to guess whether
 *	the text buffer contains Unicode.
 *	FIXME: should implement more tests.
 */
DWORD WINAPI RtlIsTextUnicode(
	LPVOID buf,
	DWORD len,
	DWORD *pf)
{
	LPWSTR s = buf;
	DWORD flags = -1, out_flags = 0;

	if (!len)
		goto out;
	if (pf)
		flags = *pf;
	/*
	 * Apply various tests to the text string. According to the
	 * docs, each test "passed" sets the corresponding flag in
	 * the output flags. But some of the tests are mutually
	 * exclusive, so I don't see how you could pass all tests ...
	 */

	/* Check for an odd length ... pass if even. */
	if (!(len & 1))
		out_flags |= IS_TEXT_UNICODE_ODD_LENGTH;

	/* Check for the special unicode marker byte. */
	if (*s == 0xFEFF)
		out_flags |= IS_TEXT_UNICODE_SIGNATURE;

	/*
	 * Check whether the string passed all of the tests.
	 */
	flags &= ITU_IMPLEMENTED_TESTS;
	if ((out_flags & flags) != flags)
		len = 0;
out:
	if (pf)
		*pf = out_flags;
	return len;
}

/**************************************************************************
 *	RtlPrefixUnicodeString
 */
NTSTATUS WINAPI RtlPrefixUnicodeString(
	PUNICODE_STRING a,
	PUNICODE_STRING b,
	DWORD x)
{
	TRACE("(%s,%s,%lx)\n",debugstr_us(a),debugstr_us(b),x);
	return STATUS_SUCCESS;
}

