⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mystr.cpp

📁 内存管理程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*=========================================================
*	File name	       :	MyStr.cpp
*	Description	:	字符串处理,支持多线程
*
*	Modify  	:	
*=========================================================*
#include "mystr.h"
#include "stdlib.h"
#include "stdio.h"
#include "stdarg.h"
#include "string.h"


*/
/*********************************************************************
* Proc:		cstr_abort_application
* Purpose:	简单的错误处理,有对话框提示
*********************************************************************/
//static char buf[65535];

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "pthread.h"
#include "mystr.h"
#include "memmgr.h"
#include "ctype.h"

void cstr_abort_application(int fatal_type)
{
	// Display message and abort
	char msg[64];
	sprintf (msg, "CStr fatal %d", fatal_type);
	abort();
}

// Define specific type of ASSERT
#ifdef _DEBUG
#define CSTR_ASSERT(x)  { if ((x) == 0)  cstr_abort_application (1111); }
#else
#define CSTR_ASSERT(x)  { }
#endif

/*********************************************************************
* Proc:		CStr::destructor
*********************************************************************/
CStr::~CStr()
{
	// MyMemFree associated text block and descriptor
	MyMemFree (data.m_Text);
}

/*********************************************************************
* Proc:		CStr::NewFromString
* Purpose:	Core code for 'copy char* constructor' and '= operator'.
*			Assumes our 'data' field is garbage on entry.
*********************************************************************/

void CStr::NewFromString(const char* s, int slen, int prealloc)
{
	// Determine actual size of buffer that needs to be allocated
	if (slen > prealloc)
		prealloc = slen;
	// Empty string?
	if (slen == 0  &&  prealloc == 0) {
		return;
	}
	// Round up to MyMemAlloc() granularity
	// Get memory for string
	char* target = (char*) MyMemAlloc (prealloc+1);
	ThrowIfNull(target);

	// Copy the string bytes, including the null
	memcpy (target, s, slen+1);
	target[ slen ] = 0;//set NULL terminated

	if( data.m_Text != NULL )MyMemFree(data.m_Text);
	// Locate MyMemFree descriptor, fill it in
	data.m_Text = target;
	data.m_Length = slen;
	data.m_Alloc = prealloc;
}


/*********************************************************************
* Proc:		CStr::CStr (UINT prealloc)
* Purpose:	Instantiates an empty string, but with the specified
*			number of bytes in the preallocated buffer.
* In:		prealloc - number of bytes to reserve
*********************************************************************/

CStr::CStr(int prealloc)//default value is 32
{  
	m_wordfindpos =0;
	if( prealloc <= 0 )prealloc=DEFAULT_CSTR_LENGTH;

	// Get memory for string
	char* target = (char*) MyMemAlloc (prealloc+1);
	if (target == NULL)
		return ;
	ThrowIfNull(target);
	target[0] = 0;
	// Locate MyMemFree descriptor, fill it in
	data.m_Text = target;
	data.m_Length = 0;
	data.m_Alloc = prealloc;
}


/*********************************************************************
* Proc:		CStr::CStr(const char*)
* Purpose:	Construct an instance that exactly copies the specified
*			string.  An optional second parameter specifies the buffer
*			size (will be ignored if it is less than what's needed)
*********************************************************************/

CStr::CStr(const char* s, int prealloc /*= 32*/)
{
       int slen = 0;
       m_wordfindpos =0;
       data.m_Text = NULL;
       data.m_Alloc = 0;
       data.m_Length = 0;
	if( prealloc <= 0 )prealloc=DEFAULT_CSTR_LENGTH;

	// No need to check for limit in CSTR_LARGE_STRINGS, because
	// NewFromString will blow up because of the buffer size
	slen = strlen(s);
	NewFromString(s, slen, prealloc);
}


/*********************************************************************
* Proc:		CStr::copy constructor
*********************************************************************/

CStr::CStr(const CStr& source)
{
	// Determine actual size of buffer that needs to be allocated
	int slen = source.GetLength();
	int prealloc = DEFAULT_CSTR_LENGTH;
	data.m_Length = 0;
	data.m_Alloc = 0;
	data.m_Text = NULL;
       m_wordfindpos =0;	
	// Empty string?
	if( slen > prealloc  )
	{
		prealloc = slen;
	}
	// Round up to MyMemAlloc() granularity
	// Get memory for string
	char* target = (char*) MyMemAlloc (prealloc+1);
	ThrowIfNull(target);
	// Locate MyMemFree descriptor, fill it in
	data.m_Text = target;
	data.m_Length = slen;
	data.m_Alloc = prealloc;
	// Copy the string bytes, including the null
	memcpy (target, source.GetString(), slen+1);
	target[ slen ] = 0;//set NULL terminated

}

CStr::CStr( const CStr * source )
{
	// Determine actual size of buffer that needs to be allocated
	int slen = source->GetLength();
	int prealloc;
	data.m_Length = 0;
	data.m_Alloc = 0;
	data.m_Text = NULL;
       m_wordfindpos =0;	
	// Empty string?
	if( slen == 0  )
	{
		prealloc = DEFAULT_CSTR_LENGTH;
	}
	// Round up to MyMemAlloc() granularity
	// Get memory for string
	char* target = (char*) MyMemAlloc (prealloc+1);
	ThrowIfNull(target);
	// Locate MyMemFree descriptor, fill it in
	data.m_Text = target;
	data.m_Length = slen;
	data.m_Alloc = prealloc;
	// Copy the string bytes, including the null
	memcpy (target, source->GetString(), slen+1);
	target[ slen ] = 0;//set NULL terminated

}


/*********************************************************************
* Proc:		CStr::operator = CStr
* Purpose:	Copies a string into another string, destroying the
*			previous content.
*********************************************************************/

const CStr& CStr::operator=(const CStr& source)
{
	// Determine actual size of buffer that needs to be allocated
	int slen = source.GetLength();
       m_wordfindpos =0;	
	// Empty string?
	if( slen == 0  )
	{
		return *this;
	}

	char* target;
	if( data.m_Alloc < slen )
	{
		MyMemFree( data.m_Text );
		// Round up to MyMemAlloc() granularity
		// Get memory for string
		target = (char*) MyMemAlloc (slen+1);
		ThrowIfNull(target);
		data.m_Text = target;
		data.m_Alloc = slen;
	}
	else
	{
		target = data.m_Text;
	}
	// Locate MyMemFree descriptor, fill it in
	data.m_Length = slen;
	// Copy the string bytes, including the null
	memcpy (target, source.GetString(), slen+1);
	target[ slen ] = 0;//set NULL terminated

	return *this;
}


/*********************************************************************
* Proc:		CStr::Buffer
* Purpose:	Helper.  Makes sure that our internal buffer has
*			the specified number of bytes available, and that
*			we can overwrite it (i.e. m_Usage is 1).  If this
*			isn't so, prepares a copy of our internal data.
*********************************************************************/

void CStr::Buffer (int newlength)
{
	// Reallocate. First handle case where we cannot just
	//   touch the buffer.  We don't need to test for m_Null
	//   here because it's m_Usage field is always >1

	// Buffer already big enough?
	if (data.m_Alloc >= newlength)
		return;

	int prevLength = data.m_Length;
	if (newlength < prevLength)
		newlength = prevLength;
	NewFromString( data.m_Text, prevLength, newlength);
}

/*********************************************************************
* Proc:		CStr::operator = const char
* Purpose:	Copies a char into our internal buffer, if it is big
*			enough and is used only by us; otherwise, MyMemFrees the
*			current instance and allocates a new one.
*********************************************************************/


const CStr& CStr::operator=(const char ch)
{
       m_wordfindpos =0;
	// Check for zero length string.
	char s[2];
	s[0] = ch;
	s[1] = '\0';
	// Check for zero length string.
	int slen = 1;
	// Can we handle this without reallocations?  NOTE: we do
	//   not use Buffer() here because if the string needs to
	//   be expanded, the old one will be copied, and we don't
	//   care about it anyway.
	if ( data.m_Alloc > slen) 
	{
		// Yes, copy bytes and get out
		memcpy (data.m_Text, s, slen+1);
		data.m_Length = (int) slen;
		return *this;
	}

	// No. MyMemFree old string, allocate new one.
	NewFromString(s, (int) slen, 1);
	return *this;
}


/*********************************************************************
* Proc:		CStr::operator = const char*
* Purpose:	Copies a string into our internal buffer, if it is big
*			enough and is used only by us; otherwise, MyMemFrees the
*			current instance and allocates a new one.
*********************************************************************/

const CStr& CStr::operator=(const char* s)
{
    m_wordfindpos =0;
	// Check for zero length string.
	int slen = strlen(s);
	if (slen == 0) 
	{
		if ( data.m_Text != 0 )
			data.m_Text[0] = 0;;
		data.m_Length = 0;
		return *this;
	}
	// Can we handle this without reallocations?  NOTE: we do
	//   not use Buffer() here because if the string needs to
	//   be expanded, the old one will be copied, and we don't
	//   care about it anyway.
	if ( data.m_Alloc > slen) 
	{
		// Yes, copy bytes and get out
		memcpy (data.m_Text, s, slen+1);
		data.m_Length = (int) slen;
		return *this;
	}
	// No. MyMemFree old string, allocate new one.
	NewFromString(s, (int) slen, 0);
	return *this;
}


/*********************************************************************
* Proc:		CStr::Empty
* Purpose:	Sets the string to NULL.  However, the allocated buffer
*			is not released.
*********************************************************************/

void CStr::Empty()
{
       m_wordfindpos =0;
       if( data.m_Text != NULL )data.m_Text[0] = 0;
	data.m_Length = 0;
}

/*********************************************************************
* Proc:		CStr::AddChar
* Purpose:	Appends a single character to the end of the string
*********************************************************************/
void CStr::AddChar(char ch)
{
	// Get a copy if m_Usage>1, expand buffer if necessary
	UINT cur_len = data.m_Length;
	Buffer (int(cur_len + 1));
	// And append the character (no need for CStrCritical because of Buffer)
	data.m_Text[cur_len] = ch;
	data.m_Text[cur_len+1] = 0;
	data.m_Length = int(cur_len+1);
}


/*********************************************************************
* Proc:		CStr::AddInt
* Purpose:	Appends a decimal signed integer, possibly with - sign
*********************************************************************/

void CStr::AddInt(int value)
{
	char buf[32];
	sprintf( buf, "%d", value );
	AddString (buf);
}

/*********************************************************************
* Proc:		CStr::AddDouble
* Purpose:	Appends a signed double value, uses specified # of digits
*********************************************************************/

void CStr::AddDouble(double value, UINT after_dot)
{
	if (after_dot > 48)
		after_dot = 48;
	char fmt[16];
	sprintf (fmt, "%%.%df", (int) after_dot);
	char buf[256];
	sprintf (buf, fmt, value);
	AddString (buf);
}


/*********************************************************************
* Proc:		CStr::CoreAddChars
* Purpose:	Core code for AddChars() and operators +=; assumes
*			howmany is bigger than 0
*********************************************************************/

void CStr::CoreAddChars(const char* s, int howmany)
{
	if(howmany <= 0)
       {
		return;
       }
	assert(howmany>=0&&howmany<1024*1024);
	// Prepare big enough buffer
	Buffer (int(data.m_Length + howmany));
	// And copy the bytes
	char* dest = data.m_Text + data.m_Length;
	memcpy (dest, s, howmany);
	dest[howmany] = 0;
	data.m_Length = int(data.m_Length + howmany);
}


/*********************************************************************
* Proc:		CStr::operator += (both from const char* and from CStr)
* Purpose:	Append a string to what we already contain.
*********************************************************************/

void CStr::operator += (const CStr& obj)
{
	if (obj.data.m_Length != 0)
		CoreAddChars (obj.data.m_Text, obj.data.m_Length);
}

void CStr::operator += (const char* s)
{
	UINT slen = strlen(s);
	if (slen != 0) {
		CoreAddChars (s, (int) slen);
	}
}


/*********************************************************************
* Proc:		CStr::AddChars
* Purpose:	Catenates a number of characters to our internal data.
*********************************************************************/

void CStr::AddChars(const char* s, int startat, int howmany)
{
	if (howmany != 0) {
		CoreAddChars (s+startat, howmany);
	}
}


/*********************************************************************
* Proc:		CStr::AddStringAtLeft

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -