#include #include #include #include "hdr/MString.h" ///////////////////////////////////////////////////////////////////////////////////////// // CMBaseString CNilMStringData CMBaseString::m_nil; CMStringData* CMBaseString::Allocate( int nChars, int nCharSize ) { CMStringData* pData; nChars++; // nil char size_t nDataBytes = nCharSize * nChars; size_t nTotalSize = nDataBytes + sizeof(CMStringData); pData = static_cast(malloc(nTotalSize)); if (pData == NULL) return NULL; pData->nRefs = 1; pData->nAllocLength = nChars - 1; pData->nDataLength = 0; return pData; } void CMBaseString::Free(CMStringData* pData) { free(pData); } CMStringData* CMBaseString::Realloc(CMStringData* pData, int nChars, int nCharSize) { CMStringData* pNewData; nChars++; // nil char ULONG nDataBytes = nCharSize * nChars; ULONG nTotalSize = nDataBytes + sizeof(CMStringData); pNewData = static_cast(realloc(pData, nTotalSize)); if (pNewData == NULL) return NULL; pNewData->nAllocLength = nChars - 1; return pNewData; } CMStringData* CMBaseString::GetNilString() { m_nil.AddRef(); return &m_nil; } ///////////////////////////////////////////////////////////////////////////////////////// // CMStringData void* CMStringData::data() { return (this + 1); } void CMStringData::AddRef() { InterlockedIncrement(&nRefs); } bool CMStringData::IsLocked() const { return nRefs < 0; } bool CMStringData::IsShared() const { return (nRefs > 1); } void CMStringData::Lock() { nRefs--; // Locked buffers can't be shared, so no interlocked operation necessary if ( nRefs == 0 ) nRefs = -1; } void CMStringData::Release() { if (InterlockedDecrement(&nRefs) <= 0) CMBaseString::Free(this); } void CMStringData::Unlock() { if (IsLocked()) { nRefs++; // Locked buffers can't be shared, so no interlocked operation necessary if (nRefs == 0) nRefs = 1; } } CNilMStringData::CNilMStringData() { nRefs = 2; // Never gets freed nDataLength = 0; nAllocLength = 0; achNil[0] = 0; achNil[1] = 0; } ///////////////////////////////////////////////////////////////////////////////////////// // ChTraitsCRT #if _MSC_VER < 1400 static HINSTANCE hCrt = NULL; typedef int ( __cdecl *_vscprintf_func )( LPCSTR pszFormat, va_list args ); static _vscprintf_func _vscprintf_ptr = NULL; typedef int ( __cdecl *_vscwprintf_func )( LPCWSTR pszFormat, va_list args ); static _vscwprintf_func _vscwprintf_ptr = NULL; typedef int ( __cdecl *_vsnprintf_func )( char*, size_t, const char*, va_list ); static _vsnprintf_func _vsnprintf_ptr = NULL; typedef int ( __cdecl *_vsnwprintf_func )( wchar_t *, size_t, const wchar_t *, va_list ); static _vsnwprintf_func _vsnwprintf_ptr = NULL; typedef int ( __cdecl *vswprintf_func )( wchar_t *, size_t, const wchar_t *, va_list ); static vswprintf_func vswprintf_ptr = NULL; typedef int ( __cdecl *vsprintf_func )( char*, size_t, const char*, va_list ); static vsprintf_func vsprintf_ptr = NULL; static void checkCrt( void ) { if ( hCrt == NULL ) { hCrt = GetModuleHandleA( "msvcrt.dll" ); _vscprintf_ptr = (_vscprintf_func)GetProcAddress( hCrt, "_vscprintf" ); _vscwprintf_ptr = (_vscwprintf_func)GetProcAddress( hCrt, "_vscwprintf" ); _vsnprintf_ptr = (_vsnprintf_func)GetProcAddress( hCrt, "_vsnprintf" ); _vsnwprintf_ptr = (_vsnwprintf_func)GetProcAddress( hCrt, "_vsnwprintf" ); vswprintf_ptr = (vswprintf_func)GetProcAddress( hCrt, "vswprintf" ); vsprintf_ptr = (vsprintf_func)GetProcAddress( hCrt, "vsprintf" ); } } #endif int __stdcall ChTraitsCRT::GetFormattedLength( LPCWSTR pszFormat, va_list args ) { #if _MSC_VER < 1400 checkCrt(); if ( _vscwprintf_ptr != NULL ) return _vscwprintf_ptr( pszFormat, args ); WCHAR buf[ 4000 ]; return vswprintf_ptr( buf, SIZEOF(buf), pszFormat, args ); #else return _vscwprintf( pszFormat, args ); #endif } int __stdcall ChTraitsCRT::Format( LPWSTR pszBuffer, size_t nLength, LPCWSTR pszFormat, va_list args) { #if _MSC_VER < 1400 checkCrt(); if ( _vsnwprintf_ptr != NULL ) return _vsnwprintf_ptr( pszBuffer, nLength, pszFormat, args ); return vswprintf_ptr( pszBuffer, nLength, pszFormat, args ); #else return _vsnwprintf( pszBuffer, nLength, pszFormat, args ); #endif } ///////////////////////////////////////////////////////////////////////////////////////// // ChTraitsCRT int __stdcall ChTraitsCRT::GetFormattedLength( LPCSTR pszFormat, va_list args ) { #if _MSC_VER < 1400 checkCrt(); if ( _vscprintf_ptr != NULL ) return _vscprintf_ptr( pszFormat, args ); char buf[4000]; return vsprintf_ptr( buf, sizeof(buf), pszFormat, args ); #else return _vscprintf( pszFormat, args ); #endif } int __stdcall ChTraitsCRT::Format( LPSTR pszBuffer, size_t nlength, LPCSTR pszFormat, va_list args ) { #if _MSC_VER < 1400 checkCrt(); return _vsnprintf( pszBuffer, nlength, pszFormat, args ); #else return vsprintf_s( pszBuffer, nlength, pszFormat, args ); #endif }