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

📄 sqlapi.cpp

📁 通用的数据库中间库
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	int nLen = SafeStrlen(lpsz);
	if (nLen != 0)
	{
		AllocBuffer(nLen);
		memcpy(m_pchData, lpsz, nLen*sizeof(SAChar));
	}
}

/////////////////////////////////////////////////////////////////////////////
// Special conversion constructors

#ifdef SA_UNICODE

SAString::SAString(const char *lpsz)
{
	Init();
	int nSrcLen = lpsz != NULL ? strlen(lpsz) : 0;
	if (nSrcLen != 0)
	{
		AllocBuffer(nSrcLen);
		ReleaseBuffer(SAMultiByteToWideChar(m_pchData, lpsz, nSrcLen));
	}
}

SAString::SAString(const char *lpch, int nLength)
{
	Init();
	if (nLength != 0)
	{
		AllocBuffer(nLength);
		ReleaseBuffer(SAMultiByteToWideChar(m_pchData, lpch, nLength));
	}
}

#else	// !SA_UNICODE

SAString::SAString(const wchar_t *lpsz)
{
	Init();
	int nSrcLen = lpsz != NULL ? wcslen(lpsz) : 0;
	if (nSrcLen != 0)
	{
		AllocBuffer(nSrcLen*2);
		ReleaseBuffer(SAWideCharToMultiByte(m_pchData, lpsz, nSrcLen));
	}
}

SAString::SAString(const wchar_t *lpch, int nLength)
{
	Init();
	if (nLength != 0)
	{
		AllocBuffer(nLength*2);
		ReleaseBuffer(SAWideCharToMultiByte(m_pchData, lpch, nLength));
	}
}

#endif //!SA_UNICODE

SAString::SAString(const SAChar *lpch, int nLength)
{
	Init();
	if (nLength != 0)
	{
		assert(lpch);
		AllocBuffer(nLength);
		memcpy(m_pchData, lpch, nLength*sizeof(SAChar));
	}
}

SAString::SAString(const unsigned char *psz)
{
	Init();
	*this = (const char*)psz;
}

//////////////////////////////////////////////////////////////////////////////
// More sophisticated construction

SAString::SAString(SAChar ch, int nLength)
{
	Init();
	if (nLength >= 1)
	{
		AllocBuffer(nLength);
#ifdef SA_UNICODE
		for (int i = 0; i < nLength; ++i)
			m_pchData[i] = ch;
#else
		memset(m_pchData, ch, nLength);
#endif
	}
}

SAString::~SAString()
{
	if (GetData() != _saDataNil)
	{
		//  free any attached data
		if (--GetData()->nRefs <= 0)
			FreeData(GetData());
	}
}

void SAString::Empty()
{
	if (GetData()->nDataLength == 0)
		return;

	if (GetData()->nRefs >= 0)
		Release();
	else
		*this =	_saPchNil;

	assert(GetData()->nDataLength == 0);
	assert(GetData()->nRefs < 0 || GetData()->nAllocLength == 0);
}

bool SAString::IsEmpty() const
{
	return GetData()->nDataLength == 0;
}

int SAString::GetLength() const
{
	return GetData()->nDataLength;
}

SAString::operator const SAChar *() const
{
	return m_pchData;
}

//////////////////////////////////////////////////////////////////////////////
// Assignment operators
//  All assign a new value to the string
//      (a) first see if the buffer is big enough
//      (b) if enough room, copy on top of old buffer, set size and type
//      (c) otherwise free old string data, and create a new one
//
//  All routines return the new string (but as a 'const SAString&' so that
//      assigning it again will cause a copy, eg: s1 = s2 = "hi there".
//

#ifdef SA_UNICODE

void SAString::AssignBinaryCopy(int nSrcLenInBytes, const void *pSrcData)
{
	int nBinaryDataLengthDiff = nSrcLenInBytes % sizeof(SAChar);
	// allocate at least so many characters that all binary data could be stored (round up if necessary)
	int nSrcLenInChars = nSrcLenInBytes / sizeof(SAChar) + (nBinaryDataLengthDiff? 1 : 0);

	AllocBeforeWrite(nSrcLenInChars);
	memcpy(m_pchData, pSrcData, nSrcLenInBytes);
	GetData()->nDataLength = nSrcLenInChars;
	m_pchData[nSrcLenInChars] = '\0';

	// if nSrcLenInBytes is not a multiply of sizeof(SAChar)
	// we have to save the difference
	GetData()->nBinaryDataLengthDiff = nBinaryDataLengthDiff;
}

#endif	// SA_UNICODE

void SAString::AssignCopy(int nSrcLen, const SAChar *lpszSrcData)
{
	AllocBeforeWrite(nSrcLen);
	memcpy(m_pchData, lpszSrcData, nSrcLen*sizeof(SAChar));
	GetData()->nDataLength = nSrcLen;
	m_pchData[nSrcLen] = '\0';
}

const SAString &SAString::operator=(const SAString &stringSrc)
{
	if (m_pchData != stringSrc.m_pchData)
	{
		if ((GetData()->nRefs < 0 && GetData() != _saDataNil) ||
			stringSrc.GetData()->nRefs < 0)
		{
			// actual copy necessary since one of the strings is locked
#ifdef SA_UNICODE

			// Under Unicode we should be aware that stringSrc
			// can be binary string with length not being multiply of sizeof(SAChar),
			// so we should copy bytes, not characters
			AssignBinaryCopy(stringSrc.GetBinaryLength(), (const void*)stringSrc);

#else	// !SA_UNICODE

			AssignCopy(stringSrc.GetData()->nDataLength, stringSrc.m_pchData);

#endif	// !SA_UNICODE
		}
		else
		{
			// can just copy references around
			Release();
			assert(stringSrc.GetData() != _saDataNil);
			m_pchData = stringSrc.m_pchData;
			++GetData()->nRefs;
		}
	}
	return *this;
}

const SAString &SAString::operator =(const SAChar *lpsz)
{
	AssignCopy(SafeStrlen(lpsz), lpsz);
	return *this;
}

/////////////////////////////////////////////////////////////////////////////
// Special conversion assignment

#ifdef SA_UNICODE

const SAString &SAString::operator=(const char *lpsz)
{
	int nSrcLen = lpsz? strlen(lpsz) : 0;
	AllocBeforeWrite(nSrcLen);
	ReleaseBuffer(SAMultiByteToWideChar(m_pchData, lpsz, nSrcLen));
	return *this;
}

#else //!SA_UNICODE

const SAString &SAString::operator=(const wchar_t *lpsz)
{
	int nSrcLen = lpsz? wcslen(lpsz) : 0;
	AllocBeforeWrite(nSrcLen*2);
	ReleaseBuffer(SAWideCharToMultiByte(m_pchData, lpsz, nSrcLen));
	return *this;
}

#endif  //!SA_UNICODE

const SAString &SAString::operator=(SAChar ch)
{
	AssignCopy(1, &ch);
	return *this;
}

#ifdef SA_UNICODE

const SAString &SAString::operator=(char ch)
{
	*this = (SAChar)ch;
	return *this;
}

#endif

const SAString &SAString::operator=(const unsigned char *psz)
{
	*this = (const char *)psz;
	return *this;
}

//////////////////////////////////////////////////////////////////////////////
// concatenation

// NOTE: "operator+" is done as friend functions for simplicity
//      There are three variants:
//          SAString + SAString
// and for ? = SAChar, const SAChar*
//          SAString + ?
//          ? + CString

#ifdef SA_UNICODE

void SAString::ConcatBinaryCopy(int nSrc1LenInBytes, const void *pSrc1Data,
	int nSrc2LenInBytes, const void *pSrc2Data)
{
	// -- master concatenation routine (binary)
	// Concatenate two sources
	// -- assume that 'this' is a new SAString object

	int nNewLenInBytes = nSrc1LenInBytes + nSrc2LenInBytes;
	if (nNewLenInBytes != 0)
	{
		int nBinaryDataLengthDiff = nNewLenInBytes % sizeof(SAChar);
		// allocate at least so many characters that all binary data could be stored (round up if necessary)
		int nNewLenInChars = nNewLenInBytes / sizeof(SAChar) + (nBinaryDataLengthDiff? 1 : 0);

		AllocBuffer(nNewLenInChars);
		// if nNewLengthInBytes is not a multiply of sizeof(SAChar)
		// we have to save the difference
		GetData()->nBinaryDataLengthDiff = nBinaryDataLengthDiff;
		memcpy((unsigned char*)m_pchData, pSrc1Data, nSrc1LenInBytes);
		memcpy((unsigned char*)m_pchData+nSrc1LenInBytes, pSrc2Data, nSrc2LenInBytes);
	}
}

#endif	// SA_UNICODE

void SAString::ConcatCopy(int nSrc1Len, const SAChar *lpszSrc1Data,
	int nSrc2Len, const SAChar *lpszSrc2Data)
{
	// -- master concatenation routine
	// Concatenate two sources
	// -- assume that 'this' is a new SAString object

	int nNewLen = nSrc1Len + nSrc2Len;
	if (nNewLen != 0)
	{
		AllocBuffer(nNewLen);
		memcpy(m_pchData, lpszSrc1Data, nSrc1Len*sizeof(SAChar));
		memcpy(m_pchData+nSrc1Len, lpszSrc2Data, nSrc2Len*sizeof(SAChar));
	}
}

SAString operator+(const SAString &string1, const SAString &string2)
{
#ifdef SA_UNICODE

	// Under Unicode we should be aware that *this or string (or both)
	// can be binary string with length not being multiply of sizeof(SAChar),
	// so we should concatinate bytes, not characters
	SAString s;
	s.ConcatBinaryCopy(string1.GetBinaryLength(), (const void*)string1,
		string2.GetBinaryLength(), (const void*)string2);
	return s;

#else	// !SA_UNICODE

	SAString s;
	s.ConcatCopy(string1.GetData()->nDataLength, string1.m_pchData,
		string2.GetData()->nDataLength, string2.m_pchData);
	return s;

#endif	// !SA_UNICODE
}

SAString operator+(const SAString &string, const SAChar *lpsz)
{
	SAString s;
	s.ConcatCopy(string.GetData()->nDataLength, string.m_pchData,
		SAString::SafeStrlen(lpsz), lpsz);
	return s;
}

SAString operator+(const SAChar *lpsz, const SAString &string)
{
	SAString s;
	s.ConcatCopy(SAString::SafeStrlen(lpsz), lpsz, string.GetData()->nDataLength,
		string.m_pchData);
	return s;
}

SAString operator+(const SAString &string1, SAChar ch)
{
	SAString s;
	s.ConcatCopy(string1.GetData()->nDataLength, string1.m_pchData, 1, &ch);
	return s;
}

SAString operator+(SAChar ch, const SAString &string)
{
	SAString s;
	s.ConcatCopy(1, &ch, string.GetData()->nDataLength, string.m_pchData);
	return s;
}

#ifdef SA_UNICODE
SAString operator+(const SAString &string, char ch)
{
	return string + (SAChar)ch;
}

SAString operator+(char ch, const SAString &string)
{
	return (SAChar)ch + string;
}
#endif

/////////////////////////////////////////////////////////////////////////////
// SAString formatting

#define FORCE_ANSI      0x10000
#define FORCE_UNICODE   0x20000
#define FORCE_INT64     0x40000

void SAString::FormatV(const SAChar *lpszFormat, va_list argList)
{
	assert(lpszFormat);

	va_list argListSave = argList;

	// make a guess at the maximum length of the resulting string
	int nMaxLen = 0;
	for (const SAChar *lpsz = lpszFormat; *lpsz != '\0'; lpsz = sa_csinc(lpsz))
	{
		// handle '%' character, but watch out for '%%'
		if (*lpsz != '%' || *(lpsz = sa_csinc(lpsz)) == '%')
		{
			nMaxLen += sa_clen(lpsz);
			continue;
		}

		int nItemLen = 0;

		// handle '%' character with format
		int nWidth = 0;
		for (; *lpsz != '\0'; lpsz = sa_csinc(lpsz))
		{
			// check for valid flags
			if (*lpsz == '#')
				nMaxLen += 2;   // for '0x'
			else if (*lpsz == '*')
				nWidth = va_arg(argList, int);
			else if (*lpsz == '-' || *lpsz == '+' || *lpsz == '0' ||
				*lpsz == ' ')
				;
			else // hit non-flag character
				break;
		}
		// get width and skip it
		if (nWidth == 0)
		{
			// width indicated by
			nWidth = sa_toi(lpsz);
			for (; *lpsz != '\0' && sa_isdigit(*lpsz); lpsz = sa_csinc(lpsz))
				;
		}
		assert(nWidth >= 0);

		int nPrecision = 0;
		if (*lpsz == '.')
		{
			// skip past '.' separator (width.precision)
			lpsz = sa_csinc(lpsz);

			// get precision and skip it
			if (*lpsz == '*')
			{
				nPrecision = va_arg(argList, int);
				lpsz = sa_csinc(lpsz);
			}
			else
			{
				nPrecision = sa_toi(lpsz);
				for (; *lpsz != '\0' && sa_isdigit(*lpsz); lpsz = sa_csinc(lpsz))
					;
			}
			assert(nPrecision >= 0);
		}

		// should be on type modifier or specifier
		int nModifier = 0;
		if (sa_strncmp(lpsz, _SA("I64"), 3) == 0)
		{
			lpsz += 3;
			nModifier = FORCE_INT64;
#if !defined(_X86_) && !defined(_ALPHA_)
			// __int64 is only available on X86 and ALPHA platforms
			assert(false);
#endif
		}
		else
		{
			switch (*lpsz)
			{
			// modifiers that affect size
			case 'h':
				nModifier = FORCE_ANSI;
				lpsz = sa_csinc(lpsz);
				break;
			case 'l':
				nModifier = FORCE_UNICODE;
				lpsz = sa_csinc(lpsz);
				break;

			// modifiers that do not affect size
			case 'F':
			case 'N':
			case 'L':
				lpsz = sa_csinc(lpsz);
				break;
			}
		}

		// now should be on specifier
		switch (*lpsz | nModifier)
		{
		// single characters
		case 'c':
		case 'C':
			nItemLen = 2;
			// int is OK
			// need a cast here since va_arg only
			// takes fully promoted types
			(void)va_arg(argList, int/*SAChar*/);
			break;
		case 'c'|FORCE_ANSI:
		case 'C'|FORCE_ANSI:
			nItemLen = 2;
			// int is OK
			// need a cast here since va_arg only
			// takes fully promoted types
			(void)va_arg(argList, int/*char*/);
			break;
		case 'c'|FORCE_UNICODE:
		case 'C'|FORCE_UNICODE:
			nItemLen = 2;
			// int is OK
			// need a cast here since va_arg only
			// takes fully promoted types
			(void)va_arg(argList, int/*wchar_t*/);
			break;

		// strings
		case 's':
			{
				const SAChar *pstrNextArg = va_arg(argList, const SAChar*);
				if (pstrNextArg == NULL)
				   nItemLen = 6;  // "(null)"
				else
				{
				   nItemLen = sa_strlen(pstrNextArg);
				   nItemLen = sa_max(1, nItemLen);
				}
			}
			break;

		case 'S':
			{
#ifndef SA_UNICODE
				wchar_t *pstrNextArg = va_arg(argList, wchar_t*);
				if (pstrNextArg == NULL)
				   nItemLen = 6;  // "(null)"
				else
				{
				   nItemLen = wcslen(pstrNextArg);
				   nItemLen = sa_max(1, nItemLen);
				}
#else
				const char *pstrNextArg = va_arg(argList, const char*);
				if (pstrNextArg == NULL)
				   nItemLen = 6; // "(null)"
				else
				{
				   nItemLen = strlen(pstrNextArg);
				   nItemLen = sa_max(1, nItemLen);
				}
#endif
			}

⌨️ 快捷键说明

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