Click here to Skip to main content
15,895,667 members
Articles / Web Development / HTML

A Comprehensive CE Class Library to Replace ATL and MFC

Rate me:
Please Sign up or sign in to vote.
4.48/5 (14 votes)
4 Oct 2000CPOL 282.3K   998   70  
A collection of classes for CE that do not use ATL or MFC, plus an FTP client, database viewer, and sample application that solves beam deflection equations.
#include "stdafx.h"

#include "CeString.h"


// For an empty string, m_pchData will point here
// (note: avoids special case of checking for NULL m_pchData)
// empty string data (and locked)
int          CeStringRep::s_rgNullData[] = { 0, 0, 0 };
CeStringRep* CeStringRep::s_cerepNullRep = (CeStringRep*) s_rgNullData;
LPCTSTR      CeStringRep::s_lpszCeEmpty = (LPCTSTR)(((BYTE*)&s_rgNullData)+sizeof(CeStringRep));


///////////////////////////////////////////////////////////////////////////////
// Windows CE specific conversion
wchar_t* wce_AsciiToWide( wchar_t* ws, const char* s )
{
	wchar_t* pszSave = ws;
    while (*ws++ = (wchar_t) *s++)
		;

	return (pszSave);
}

#ifdef _WIN32_WCE
const CeString& CeString::operator= (const char *lps)
{
	Release();
	int nLen = strlen(lps);
	CeStringRep* pRep = CeStringRep::AllocBuf(nLen);
	m_pStr = pRep->GetString();
	wce_AsciiToWide(m_pStr, lps);
	return *this;
}
#endif

const CeString& CeString::operator= (const CeString& strSrc)
{
	if (strSrc.m_pStr != m_pStr)
	{
		Release();	// checks for null
		m_pStr = strSrc.m_pStr;

		if (0 != GetRep()->GetLength())
			GetRep()->AddRef();
	}
	return *this;
}

const CeString& CeString::operator= (LPCTSTR lpsz)
{
	Assign(lpsz);
	return *this;
}

void CeString::Append(LPCTSTR lpsz, int nChars/*=-1*/)
{
	if (-1 == nChars)
		nChars = lstrlen(lpsz);

	// concatenating an empty string is a no-op!
	if (nChars == 0)
		return;

	if (0 == Length())
		Assign(lpsz, nChars);
	else
	{
		// allocate and concatinate strings
		CeStringRep* pRep = CeStringRep::AllocBuf(Length() + nChars);
		memcpy(pRep->GetString(), m_pStr, GetRep()->GetLength() * sizeof TCHAR);
		memcpy(pRep->GetString() + GetRep()->GetLength(), lpsz, nChars * sizeof TCHAR);

		// free reference to old string
		Release();

		// assign
		m_pStr = pRep->GetString();
	}
}

const CeString& CeString::operator+ (const CeString& T)
{
	Append(T);
	return *this;
}

const CeString& CeString::operator+ (LPCTSTR str)
{
	Append(str);
	return *this;
}

void CeString::Set(char ch, int nChars)
{
	// get rid of old
	Release();

	CeStringRep* pRep = CeStringRep::AllocBuf(nChars);
	m_pStr = pRep->GetString();

	for (int ii = 0; ii < nChars; ii++)
		m_pStr[ii] = ch;
}

void CeString::Set(char ch)
{
	CopyOnWrite();
	_tcsset (m_pStr, ch);
}

#ifdef UNICODE
# ifndef _ltot
#  define _ltot _ltow
#  define _itot _itow
#  define _ultot _ultow
# endif
#else
# ifndef _ltot
#  define _ltot _ltoa
#  define _itot _itoa
#  define _ultot _ultoa
# endif
#endif

void CeString::SetShort(short s, int b/*=10*/)
{
	// maximum of 33 characters according to doco
	TCHAR szBuf[33];
	Assign( _itot(s, szBuf, b) );
}

void CeString::SetLong(long l, int b/*=10*/)
{
	// maximum of 33 characters according to doco
	TCHAR szBuf[33];
	Assign( _ltot(l, szBuf, b) );
}

void CeString::SetULong(unsigned long ul, int b/*=10*/)
{
	// maximum of 33 characters according to doco
	TCHAR szBuf[33];
	Assign( _ultot(ul, szBuf, b) );
}

void CeString::SetDouble(double dValue, int nPrecision)
{
	TCHAR szOut[33];
	TCHAR* pszBuf = szOut;

	int nDecimal;
	int nSign;
	
	char* pszResult = _fcvt( dValue, nPrecision, &nDecimal, &nSign );

	if (nSign)
		*pszBuf++ = _T('-');
	
	if (nDecimal <= 0)
	{
		*pszBuf++ = _T('0');
		*pszBuf++ = _T('.');
		for (int ii = nDecimal; ii < 0; ii++)
			*pszBuf++ = _T('0');
	}
	else
	{
		for (int ii = 0; ii < nDecimal; ii++)
			*pszBuf++ = *pszResult++;

		*pszBuf++ = _T('.');
	}

	// append the remaining characters
	while (*pszResult)
		*pszBuf++ = *pszResult++;
			
	*pszBuf++ = 0;

	Assign(szOut, pszBuf - szOut - 1);
}


void CeString::Truncate(int nLen)
{
	// check for noop
	if (GetRep()->GetLength() >= nLen || nLen < 0)
		return;

	// copy to the new
	CeStringRep* pRep = CeStringRep::AllocBuf(nLen);
	memcpy(pRep->GetString(), m_pStr, Length() * sizeof TCHAR);

	// Get rid of the old
	Release();

	// assign new
	m_pStr = pRep->GetString();
}

void CeString::Trim()
{
	RTrim();
	LTrim();
}

void CeString::LTrim()
{
	if (*m_pStr == 0 || ! _istspace(*m_pStr))
		// noop
		return;

	int nLen = GetRep()->GetLength();
	for (int ii = 0; ii < nLen && _istspace(m_pStr[ii]) ; ii++)
		;

	if (ii != nLen)
	{
		// all white space, set empty and release
		Release();
	}
	else
	{
		// create a new string from the old
		CeStringRep* pRep = CeStringRep::AllocBuf(nLen - ii);
		memcpy(pRep->GetString(), m_pStr + ii, sizeof(TCHAR) * (nLen - ii + 1));

		// free/release reference
		Release();

		// assign new reference
		m_pStr = pRep->GetString();
	}
}

void CeString::RTrim()
{
	if (*m_pStr == 0 || ! _istspace(m_pStr[Length()-1]))
		// noop
		return;

	for (int ii = GetRep()->GetLength()-1; ii >= 0 && _istspace(m_pStr[ii]) ; ii--)
		;

	if (ii < 0)
	{
		// all white space, set empty and release
		Release();
	}
	else
	{
		// create a new string from the old
		CeStringRep* pRep = CeStringRep::AllocBuf(ii);
		memcpy(pRep->GetString(), m_pStr, sizeof(TCHAR) * (ii + 1));

		// free/release reference
		Release();

		// assign new reference
		m_pStr = pRep->GetString();
	}
}

// Utility functions
// Use this function to retrieve the system error message string
// for a system error ID, e.g. Win32, COM or ActiveX error ID.

void CeString::FormatMessage(DWORD dwSystemErrorID)
{
	LPVOID lpMsgBuf;

	DWORD dwSize = ::FormatMessage(
		FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
		NULL,
		dwSystemErrorID,
		MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT), // Default language
		(LPTSTR)&lpMsgBuf,
		0,
		NULL
	);

	if (0 != dwSize)
	{
		Assign((LPCTSTR)lpMsgBuf, dwSize);

		// Free the buffer.
		LocalFree(lpMsgBuf);
	}
	else
	{
		Format(_T("Error %d occured"), dwSystemErrorID);
	}
}


LPTSTR CeString::GetBuffer(int nMinLen)
{
	ASSERT(nMinLen >= 0);
	if (0 == nMinLen)
		return NULL;

	if (nMinLen > Length())
	{
		// remove duplicate if any
		CopyOnWrite();

		// allocate a new copy and get the window text
		CeStringRep* pRep = CeStringRep::AllocBuf(nMinLen);
		return m_pStr = pRep->GetString();
	}
	else
		return m_pStr;
}

LPTSTR CeString::GetBufferSetLength(int nLen)
{
	ASSERT(nLen >= 0);

	if (Length() == nLen && nLen > 0)
		return m_pStr;

	// get rid of any duplicates
	Release();

	if (0 == nLen)
		// zero length buffer
		return m_pStr;

	// allocate a new copy and get the window text
	CeStringRep* pRep = CeStringRep::AllocBuf(nLen);
	return m_pStr = pRep->GetString();	
}

void CeString::ReleaseBuffer()
{
	int nLen = _tcslen(m_pStr);

	if (nLen <= 0)
	{
		Release();
	}
	else if (nLen != Length())
	{
		// allocate a new copy and get the window text
		CeStringRep* pRep = CeStringRep::AllocBuf(nLen);
		memcpy(pRep->GetString(), m_pStr, nLen * sizeof TCHAR);

		Release();
		m_pStr = pRep->GetString();
	}
}

void CeString::Format(LPCTSTR szFormat, ...)
{
	TCHAR sz[1024];

	va_list va;
	va_start(va, szFormat);
	int nOut = wvsprintf(sz, szFormat, va);
	va_end(va);

	Assign(sz, nOut);
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions