#include "wchar.h"
#include "windows.h"
#include <mbctype.h>
  #include "UAString.h"
  //#include "PointsAndVectors.h"
//#include "Color.h"
  
/************************************************************************/
/* Constructors / Destructor                                            */
/************************************************************************/
  #define CONSTRUCTOR_ALL \
	uStringLength = 0; \
	uStringBufferSize = 0; \
	uString = NULL; \
	aStringLength = 0; \
	aString = NULL; \
	codepage = CP_ACP; \
	
  CUAString::CUAString()
{
	CONSTRUCTOR_ALL;
}
  CUAString::CUAString( const CUAString& _in)
{
	CONSTRUCTOR_ALL;
	*this = _in;
}
  CUAString::CUAString( const wchar_t* _in)
{
	CONSTRUCTOR_ALL;
	*this = _in;
}
  CUAString::CUAString( const char* _in)
{
	CONSTRUCTOR_ALL;
	*this = _in;
}
  CUAString::CUAString( const double _in)
{
	CONSTRUCTOR_ALL;
	*this = _in;
}
  CUAString::~CUAString()
{
	Clear();
}
  
/************************************************************************/
/*                                                                      */
/* Operators                                                            */
/*                                                                      */
/************************************************************************/
  /************************************************************************/
/* = Operators                                                          */
/************************************************************************/
const CUAString& CUAString::operator=( const CUAString& _in)
{
	if ( _in.uStringLength)
	{
		AllocateString( _in.uStringLength);
		AppendString( _in.uString, _in.uStringLength);
	}
  	codepage = _in.Codepage;
	
	return *this;
}
  const CUAString& CUAString::operator=( const wchar_t* _in)
{
	if ( _in) 
	{
		int inLength = wcslen( _in);
		if ( inLength)
		{
			AllocateString( inLength + 1);
			AppendString( _in, inLength);
		}
		else
		{
			DeAllocateString();
		}
	}
  	return *this;
}
  const CUAString& CUAString::operator=( const char* _in)
{
	if ( _in) 
	{
		int inLength = strlen( _in);
		
		int cp = codepage;
		if ( !codepage)
		{
			cp = CP_ACP;
		}
		
		int convertedInLength = MultiByteToWideChar( cp, 0, _in, inLength, NULL, 0);
		if ( convertedInLength)
		{
			AllocateString( convertedInLength + 1);
			uStringLength = MultiByteToWideChar( cp, 0, _in, inLength, uString, uStringBufferSize);
			uString[ uStringLength] = 0;
		}
		else
		{
			DeAllocateString();
		}
		
	}
	
	return *this;
}
  const CUAString& CUAString::operator=( const double _in)
{
	DeAllocateString();
	AppendDouble( _in);
	return *this;
}
  /************************************************************************/
/* += Operators                                                         */
/************************************************************************/
  const CUAString& CUAString::operator+=( const CUAString& _in)
{
	AppendString( _in.uString, _in.uStringLength);
	return *this;
}
  const CUAString& CUAString::operator+=( const wchar_t* _in)
{
	int inLength = wcslen( _in);
	AppendString( _in, inLength);
	return *this;
}
  const CUAString& CUAString::operator+=( const char* _in)
{
	CUAString tempString( _in);
	*this += tempString;
	return *this;
}
  const CUAString& CUAString::operator+=( const double _in)
{
	AppendDouble( _in);
	return *this;
}
  /************************************************************************/
/* + Operators                                                          */
/************************************************************************/
#define OPERATOR_PLUS( type1, type2) \
	CUAString operator+( const type1 string1, const type2 string2) \
	{ \
		CUAString ret = string1; \
		ret += string2; \
		return ret; \
	} \
  OPERATOR_PLUS( CUAString&, CUAString&);
OPERATOR_PLUS( CUAString&, wchar_t*);
OPERATOR_PLUS( wchar_t*, CUAString&);
OPERATOR_PLUS( CUAString&, char*);
OPERATOR_PLUS( char*, CUAString&);
OPERATOR_PLUS( CUAString&, double);
OPERATOR_PLUS( double, CUAString&);
  /************************************************************************/
/*  Comaprison operators                                                */
/************************************************************************/
  bool CUAString::operator==( const CUAString& _in)
{
	return !wcscmp( uString, _in.uString);
}
  bool CUAString::operator==( const wchar_t* _in)
{
	return !wcscmp( uString, _in);
}
  bool CUAString::operator!=( const CUAString& _in)
{
	return wcscmp( uString, _in.uString);
}
  bool CUAString::operator!=( const wchar_t* _in)
{
	return wcscmp( uString, _in);
}
  /************************************************************************/
/* Search functions                                                     */
/*                                                                      */
/* If the find functions returns something>Length then no occurences    */
/* were found.                                                          */
/************************************************************************/
  unsigned int CUAString::FindFirstOf( unsigned int startPos, wchar_t* filter)
{
	if ( startPos < uStringLength)
	{
		wchar_t* res = wcspbrk( uString + startPos, filter);
		if ( res){
			return res - uString;
		}
	}
	return uStringLength;
}
  unsigned int CUAString::FindFirstNotOf( unsigned int startPos, wchar_t* filter)
{
	size_t res = uStringLength;
	if ( startPos < uStringLength)
	{
		res = wcsspn( uString + startPos, filter) + startPos;
	}
	return res;
}
  CUAString CUAString::SubString( unsigned int startPos, int length)
{
	CUAString ret;
  	if ( startPos < uStringLength) 
	{
		int minLength = min( length, uStringLength - startPos);
		if ( length < 0)
		{
			minLength = uStringLength - startPos;
		}
		ret.AppendString( uString + startPos, minLength);
	}
  	return ret;
}
  /************************************************************************/
/* Public Functions                                                     */
/************************************************************************/
  bool CUAString::Empty()
{
	if ( uStringLength)
	{
		return true;
	}
	else
	{
		return false;
	}
}
  void CUAString::MakeLower()
{
	wcslwr( uString);
}
  void CUAString::MakeUpper()
{
	wcsupr( uString);
}
  int CUAString::Codepage()
{
	return codepage;
}
  bool CUAString::Codepage( int _codepage)
{
	codepage = CP_ACP;
  	int oldCodepage = _getmbcp();
  	if ( 0 == _setmbcp( _codepage))
	{
		codepage = _codepage;
	} 
  	_setmbcp( oldCodepage);
  	if ( codepage)
	{
		return true;
	}
	else
	{
		return false;
	}
}
  /************************************************************************/
/* Conversion functions (AsFoo)                                         */
/************************************************************************/
  double CUAString::AsDouble( bool extract)
{
	unsigned int endPos, startPos;
	double number = 0;
	
	endPos = 0;
	startPos = FindFirstOf( endPos, L"+-1234567890.");
	endPos = FindFirstNotOf( startPos + 1, L"+-1234567890.");
  	if ( startPos < uStringLength)
	{
		number = wcstod( SubString( startPos, endPos - startPos).AsUnicode(), NULL);
  		if ( extract)
		{
			*this = SubString( endPos);
		}
	}
	
	return number;
}
  
long CUAString::AsLong( bool extract)
{
	unsigned int endPos, startPos;
	long number = 0;
	
	endPos = 0;
	startPos = FindFirstOf( endPos, L"+-1234567890");
	endPos = FindFirstNotOf( startPos + 1, L"+-1234567890");
	
	if ( startPos < uStringLength)
	{
		number = wcstol( SubString( startPos, endPos - startPos).AsUnicode(), NULL, 10);
		if ( extract)
		{
			*this = SubString( endPos);
		}
	}
	
	return number;
}
  CUAString CUAString::AsToken( wchar_t startChar, wchar_t endChar, bool extract)
{
	CUAString ret;
	wchar_t startBuf[] = L"[";
	startBuf[0] = startChar;
	wchar_t endBuf[] = L"]";
	endBuf[0] = endChar;
	unsigned int endPos, startPos;
	
	endPos = 0;
	startPos = FindFirstOf( endPos, startBuf) + 1;
	endPos = FindFirstOf( startPos, endBuf);
	
	ret = SubString( startPos, endPos - startPos);
	if ( extract)
	{
		*this = SubString( endPos + 1);
	}
  	return ret;
}
  const wchar_t* CUAString::AsUnicode()
{
	return uString;
}
  const char*	 CUAString::AsAscii( int _codepage)
{
  	int cp = codepage;
  	if ( _codepage)
	{
		cp = _codepage;
	}
  	if ( !aString)
	{
  		int convertedLength = WideCharToMultiByte( cp, 0, uString, uStringLength, aString, 0, NULL, NULL);
		if ( convertedLength)
		{
			aStringLength = convertedLength;
			if ( aString) delete[] aString;
			aString = new char[aStringLength + 1];
			WideCharToMultiByte( cp, 0, uString, uStringLength, aString, aStringLength, NULL, NULL);
			aString[ aStringLength] = 0;
			
		}
		
	}
  	if ( aString)
	{
		return aString;
	}
  	return "";
}
  /************************************************************************/
/* Protected Functions                                                  */
/************************************************************************/
  void CUAString::Clear()
{
	DeAllocateString();
	codepage = CP_ACP;
}
  void CUAString::DeAllocateString()
{
	uStringLength = 0;
	uStringBufferSize = 0;
	if ( uString) delete[] uString;
	uString = NULL;
	
	aStringLength = 0;
	if ( aString) delete[] aString;
	aString = NULL;
}
  
void CUAString::AllocateString( unsigned int _size)
{
	DeAllocateString();
	if ( _size > 0)
	{
		uStringBufferSize = _size;
		uString = new wchar_t[ uStringBufferSize];
		uString[0] = 0;
	}
}
  void CUAString::ReAllocateString( unsigned int _size)
{
  	if ( _size > 0)
	{
		wchar_t* tempStr = new wchar_t[ _size];
		int minLength = min( uStringLength + 1, _size);
		if ( uString)
		{
			memcpy( tempStr, uString, minLength * sizeof(wchar_t));
		}
		tempStr[minLength - 1] = 0;
  		DeAllocateString();
  		uString = tempStr;
		uStringLength = minLength - 1;
		uStringBufferSize = _size;
	}
	else
	{
		DeAllocateString();
	}
}
  void CUAString::AppendString( const wchar_t* _str, unsigned int _length)
{
	if ( uStringBufferSize < uStringLength + _length + 1) 
	{
		ReAllocateString( uStringLength + _length + 1);
	}
  	memcpy( uString + uStringLength, _str, _length * sizeof(wchar_t));
	uStringLength = uStringLength + _length;
	uString[ uStringLength] = 0;
}
  void CUAString::AppendDouble( double num) {
	
	int dec, sign;
	CUAString tempString;
	char* buffer = _fcvt( num, 5, &dec, &sign );
  	int bufLength = strlen( buffer) - 1;
	while ( (bufLength > 0) && (buffer[bufLength] == '0'))
	{
		buffer[bufLength] = 0;
		bufLength--;
	}
  
	if ( buffer[0] != '0')
	{
		if ( sign) tempString += L"-";
		
		if ( dec <= 0) 
		{
			tempString += L"0.";
			while ( dec < 0) 
			{
				tempString += L"0";
				dec++;
			}
		} 
		else 
			if ( bufLength > dec) 
			{
				char temp = buffer[dec];
				buffer[dec] = 0;
				tempString += buffer;
				buffer[dec] = temp;
				buffer += dec;
				tempString += L".";
			}
	}
  	tempString += buffer;
  	*this += tempString;
}
   |