Click here to Skip to main content
15,896,606 members
Articles / Web Development / HTML

Catch All Bugs with BugTrap!

Rate me:
Please Sign up or sign in to vote.
4.34/5 (84 votes)
31 Jan 2009MIT5 min read 1.9M   9.1K   293  
A tool that can catch unhandled errors and exceptions, and deliver error reports to remote support servers
/*
 * This is a part of the BugTrap package.
 * Copyright (c) 2005-2007 IntelleSoft.
 * All rights reserved.
 *
 * Description: String (memory) stream class.
 * Author: Maksim Pyatkovskiy.
 *
 * This source code is only intended as a supplement to the
 * BugTrap package reference and related electronic documentation
 * provided with the product. See these sources for detailed
 * information regarding the BugTrap package.
 */

#include "StdAfx.h"
#include "StrStream.h"
#include "StrHolder.h"
#include "BugTrapUtils.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

void CStrStream::InitBuffer(void)
{
	m_pszData = NULL;
	m_nSize = m_nLength = 0;
}

/**
 * @param nSize - initial buffer size.
 */
void CStrStream::InitBuffer(int nSize)
{
	if (nSize)
	{
		m_nLength = 0;
		m_pszData = new TCHAR[nSize];
		if (m_pszData)
		{
			*m_pszData = _T('\0');
			m_nSize = nSize;
		}
		else
		{
			m_nSize = 0;
			RaiseException(STATUS_NO_MEMORY, 0, 0, NULL);
		}
	}
	else
		InitBuffer();
}

/**
 * @param nSize - requested buffer size.
 * @param bAdaptiveGrowth - true for adaptive growth.
 */
void CStrStream::EnsureSize(int nSize, bool bAdaptiveGrowth)
{
	if (m_nSize < nSize)
	{
		if (bAdaptiveGrowth)
			nSize *= 2;
		PTSTR pszData = new TCHAR[nSize];
		if (! pszData)
			RaiseException(STATUS_NO_MEMORY, 0, 0, NULL);
		if (m_pszData)
		{
			_tcscpy_s(pszData, nSize, m_pszData);
			delete[] m_pszData;
		}
		m_pszData = pszData;
		m_nSize = nSize;
	}
}


/**
 * @param pszStrData - data source.
 * @param nLength - string length.
 */
void CStrStream::InitData(PCTSTR pszStrData, int nLength)
{
	if (pszStrData && *pszStrData)
	{
		int nSize = nLength + 1;
		InitBuffer(nSize);
		_tcsncpy_s(m_pszData, nSize, pszStrData, nLength);
		m_nLength = nLength;
	}
	else
		InitBuffer();
}

/**
 * @param pszStrData - data source.
 * @param nLength - string length.
 */
void CStrStream::CopyData(PCTSTR pszStrData, int nLength)
{
	if (m_pszData != pszStrData)
	{
		if (pszStrData && *pszStrData)
		{
			int nSize = nLength + 1;
			EnsureSize(nSize, false);
			_tcsncpy_s(m_pszData, nSize, pszStrData, nLength);
			m_nLength = nLength;
		}
		else
			Reset();
	}
}

/**
 * @param pszStrData - data source.
 * @param nLength - string length.
 */
void CStrStream::AppendData(PCTSTR pszStrData, int nLength)
{
	if (pszStrData && *pszStrData)
	{
		int nNewLength = m_nLength + nLength;
		EnsureSize(nNewLength + 1, true);
		_tcsncpy_s(m_pszData + m_nLength, nLength + 1, pszStrData, nLength);
		m_nLength = nNewLength;
	}
}

#ifdef _UNICODE

/**
 * @param pszStrData - data source.
 */
void CStrStream::InitData(PCSTR pszStrData)
{
	if (pszStrData && *pszStrData)
	{
		int nSize = MultiByteToWideChar(CP_ACP, 0, pszStrData, -1, NULL, 0);
		_ASSERTE(nSize > 0);
		InitBuffer(nSize);
		MultiByteToWideChar(CP_ACP, 0, pszStrData, -1, m_pszData, nSize);
		m_nLength = nSize - 1;
	}
	else
		InitBuffer();
}

/**
 * @param pszStrData - data source.
 */
void CStrStream::CopyData(PCSTR pszStrData)
{
	if (pszStrData && *pszStrData)
	{
		int nSize = MultiByteToWideChar(CP_ACP, 0, pszStrData, -1, NULL, 0);
		_ASSERTE(nSize > 0);
		EnsureSize(nSize, false);
		MultiByteToWideChar(CP_ACP, 0, pszStrData, -1, m_pszData, nSize);
		m_nLength = nSize - 1;
	}
	else
		Reset();
}

/**
 * @param pszStrData - data source.
 */
void CStrStream::AppendData(PCSTR pszStrData)
{
	if (pszStrData && *pszStrData)
	{
		int nSize = MultiByteToWideChar(CP_ACP, 0, pszStrData, -1, NULL, 0);
		_ASSERTE(nSize > 0);
		int nNewSize = m_nLength + nSize;
		EnsureSize(nNewSize, true);
		MultiByteToWideChar(CP_ACP, 0, pszStrData, -1, m_pszData + m_nLength, nSize);
		m_nLength = nNewSize - 1;
	}
}

#else

/**
 * @param pszStrData - data source.
 */
void CStrStream::InitData(PCWSTR pszStrData)
{
	if (pszStrData && *pszStrData)
	{
		int nSize = WideCharToMultiByte(CP_ACP, 0, pszStrData, -1, NULL, 0, NULL, NULL);
		_ASSERTE(nSize > 0);
		InitBuffer(nSize);
		WideCharToMultiByte(CP_ACP, 0, pszStrData, -1, m_pszData, nSize, NULL, NULL);
		m_nLength = nSize - 1;
	}
	else
		InitBuffer();
}

/**
 * @param pszStrData - data source.
 */
void CStrStream::CopyData(PCWSTR pszStrData)
{
	if (pszStrData && *pszStrData)
	{
		int nSize = WideCharToMultiByte(CP_ACP, 0, pszStrData, -1, NULL, 0, NULL, NULL);
		_ASSERTE(nSize > 0);
		EnsureSize(nSize, false);
		WideCharToMultiByte(CP_ACP, 0, pszStrData, -1, m_pszData, nSize, NULL, NULL);
		m_nLength = nSize - 1;
	}
	else
		Reset();
}

/**
 * @param pszStrData - data source.
 */
void CStrStream::AppendData(PCWSTR pszStrData)
{
	if (pszStrData && *pszStrData)
	{
		int nSize = WideCharToMultiByte(CP_ACP, 0, pszStrData, -1, NULL, 0, NULL, NULL);
		_ASSERTE(nSize > 0);
		int nNewSize = m_nLength + nSize;
		EnsureSize(nNewSize, true);
		WideCharToMultiByte(CP_ACP, 0, pszStrData, -1, m_pszData + m_nLength, nSize, NULL, NULL);
		m_nLength = nNewSize - 1;
	}
}

#endif

/**
 * @return object string buffer.
 * @note The caller is responsible to free returned string buffer.
 */
PTSTR CStrStream::Detach(void)
{
	PTSTR pszData = m_pszData;
	InitBuffer();
	return pszData;
}

void CStrStream::Reset(void)
{
	if (m_pszData)
	{
		*m_pszData = _T('\0');
		m_nLength = 0;
	}
}

void CStrStream::Free(void)
{
	if (m_pszData)
	{
		delete[] m_pszData;
		InitBuffer();
	}
}

/**
 * @param nPosition - start position.
 * @param nLength - length of the extracted string.
 */
void CStrStream::ValidateIndex(int nPosition, int& nLength) const
{
	_ASSERTE(nPosition >= 0 && nPosition <= m_nLength);
	if (nPosition < 0 || nPosition > m_nLength)
		RaiseException(STATUS_ARRAY_BOUNDS_EXCEEDED, 0, 0, NULL);
	int nMaxLength = m_nLength - nPosition;
	if (nLength < 0)
		nLength = nMaxLength;
	else
	{
		_ASSERTE(nLength <= nMaxLength);
		if (nLength > nMaxLength)
			RaiseException(STATUS_ARRAY_BOUNDS_EXCEEDED, 0, 0, NULL);
	}
}

/**
 * @param rStrHolder - string buffer that receives the data.
 * @param nPosition - start position.
 * @param nLength - length of the extracted string.
 */
void CStrStream::Substring(CStrHolder& rStrHolder, int nPosition, int nLength) const
{
	ValidateIndex(nPosition, nLength);
	int nEndPosition = nPosition + nLength;
	TCHAR chData = m_pszData[nEndPosition];
	m_pszData[nEndPosition] = _T('\0');
	rStrHolder = m_pszData + nPosition;
	m_pszData[nEndPosition] = chData;
}

/**
 * @param pszSubstring - inserted string buffer.
 * @param nPosition - start position.
 * @param nLength - length of the inserted string.
 */
void CStrStream::Insert(PCTSTR pszSubstring, int nPosition, int nLength)
{
	ValidateIndex(nPosition);
	int nNewLength = m_nLength + nLength;
	EnsureSize(nNewLength + 1, true);
	int nNextPosition = nPosition + nLength;
	int nNextLength = m_nLength - nPosition;
	MoveMemory(m_pszData + nNextPosition, m_pszData + nPosition, (nNextLength + 1) * sizeof(TCHAR));
	MoveMemory(m_pszData + nPosition, pszSubstring, nLength * sizeof(TCHAR));
	m_nLength = nNewLength;
}

/**
 * @param nPosition - start position.
 * @param nLength - length of the extracted string.
 */
void CStrStream::Delete(int nPosition, int nLength)
{
	ValidateIndex(nPosition, nLength);
	int nNewLength = m_nLength - nLength;
	MoveMemory(m_pszData + nPosition, m_pszData + nLength, (nNewLength + 1) * sizeof(TCHAR));
	m_nLength = nNewLength;
}

void CStrStream::Trim(void)
{
	TrimSpaces(m_pszData);
	m_nLength = _tcslen(m_pszData);
}

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 MIT License


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