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

📄 sqlapi.cpp

📁 通用的数据库中间库
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	return s2.Compare(s1) == 0;
}
bool operator!=(const SAString &s1, const SAString &s2)
{
	return s1.Compare(s2) != 0;
}
bool operator!=(const SAString &s1, const SAChar *s2)
{
	return s1.Compare(s2) != 0;
}
bool operator!=(const SAChar *s1, const SAString &s2)
{
	return s2.Compare(s1) != 0;
}
bool operator<(const SAString &s1, const SAString &s2)
{
	return s1.Compare(s2) < 0;
}
bool operator<(const SAString &s1, const SAChar *s2)
{
	return s1.Compare(s2) < 0;
}
bool operator<(const SAChar *s1, const SAString &s2)
{
	return s2.Compare(s1) > 0;
}
bool operator>(const SAString &s1, const SAString &s2)
{
	return s1.Compare(s2) > 0;
}
bool operator>(const SAString &s1, const SAChar *s2)
{
	return s1.Compare(s2) > 0;
}
bool operator>(const SAChar *s1, const SAString &s2)
{
	return s2.Compare(s1) < 0;
}
bool operator<=(const SAString &s1, const SAString &s2)
{
	return s1.Compare(s2) <= 0;
}
bool operator<=(const SAString &s1, const SAChar *s2)
{
	return s1.Compare(s2) <= 0;
}
bool operator<=(const SAChar *s1, const SAString &s2)
{
	return s2.Compare(s1) >= 0;
}
bool operator>=(const SAString &s1, const SAString &s2)
{
	return s1.Compare(s2) >= 0;
}
bool operator>=(const SAString &s1, const SAChar *s2)
{
	return s1.Compare(s2) >= 0;
}
bool operator>=(const SAChar *s1, const SAString &s2)
{
	return s2.Compare(s1) <= 0;
}

//////////////////////////////////////////////////////////////////////////////
// Finding

int SAString::Find(SAChar ch) const
{
	return Find(ch, 0);
}

int SAString::Find(SAChar ch, int nStart) const
{
	int nLength = GetData()->nDataLength;
	if (nStart >= nLength)
		return -1;

	// find first single character
	const SAChar *lpsz = sa_strchr(m_pchData + nStart, ch);

	// return -1 if not found and index otherwise
	return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData);
}

int SAString::FindOneOf(const SAChar *lpszCharSet) const
{
	assert(lpszCharSet);
	const SAChar *lpsz = sa_strpbrk(m_pchData, lpszCharSet);
	return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData);
}

int SAString::ReverseFind(SAChar ch) const
{
	// find last single character
	const SAChar *lpsz = sa_strrchr(m_pchData, ch);

	// return -1 if not found, distance from beginning otherwise
	return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData);
}

// find a sub-string (like strstr)
int SAString::Find(const SAChar *lpszSub) const
{
	return Find(lpszSub, 0);
}

int SAString::Find(const SAChar *lpszSub, int nStart) const
{
	assert(lpszSub);

	int nLength = GetData()->nDataLength;
	if (nStart > nLength)
		return -1;

	// find first matching substring
	const SAChar *lpsz = sa_strstr(m_pchData + nStart, lpszSub);

	// return -1 for not found, distance from beginning otherwise
	return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData);
}

// Special constructor and buffer access routines to manipulate binary data

// constructor for binary data (no converion to SAChar)
SAString::SAString(const void *pBuffer, int nLengthInBytes)
{
#ifdef SA_UNICODE

	Init();
	if (nLengthInBytes != 0)
	{
		assert(pBuffer);
		int nBinaryDataLengthDiff = nLengthInBytes % sizeof(SAChar);
		// allocate at least so many characters that all binary data can be stored (round up if necessary)
		int nLengthInChars = nLengthInBytes / sizeof(SAChar) + (nBinaryDataLengthDiff? 1 : 0);
		AllocBuffer(nLengthInChars);
		// if nLengthInBytes is not a multiply of sizeof(SAChar)
		// we have to save the difference
		GetData()->nBinaryDataLengthDiff = nBinaryDataLengthDiff;
		memcpy(m_pchData, pBuffer, nLengthInBytes);
	}

#else	// !SA_UNICODE

	// byte == character in non-Unicode build
	Init();
	if (nLengthInBytes != 0)
	{
		assert(pBuffer);
		AllocBuffer(nLengthInBytes);
		memcpy(m_pchData, pBuffer, nLengthInBytes);
	}

#endif	// !SA_UNICODE
}

// get binary data length (in bytes)
int SAString::GetBinaryLength() const
{
#ifdef SA_UNICODE

	return GetLength()*sizeof(SAChar) - GetData()->nBinaryDataLengthDiff;

#else	// !SA_UNICODE

	// byte == character in non-Unicode build
	return GetLength();

#endif	// !SA_UNICODE
}

// return pointer to const binary data buffer
SAString::operator const void *() const
{
	return (const void *)m_pchData;
}

// get pointer to modifiable binary data buffer at least as long as nMinBufLengthInBytes
void *SAString::GetBinaryBuffer(int nMinBufLengthInBytes)
{
#ifdef SA_UNICODE

	// convert bytes count to characters count (round up if necessasry)
	int nMinBufLengthInChars = nMinBufLengthInBytes / sizeof(SAChar) + (nMinBufLengthInBytes % sizeof(SAChar)? 1 : 0);
	return GetBuffer(nMinBufLengthInChars);

#else	// !SA_UNICODE

	// byte == character in non-Unicode build
	return GetBuffer(nMinBufLengthInBytes);

#endif	// !SA_UNICODE
}

// release buffer, setting length to nNewLength (or to first nul if -1)
void SAString::ReleaseBinaryBuffer(int nNewLengthInBytes)
{
#ifdef SA_UNICODE

	int nBinaryDataLengthDiff = nNewLengthInBytes % sizeof(SAChar);
	// release at least so many characters that all binary data can be stored (round up if necessary)
	int nNewLengthInChars = nNewLengthInBytes / sizeof(SAChar) + (nBinaryDataLengthDiff? 1 : 0);
	ReleaseBuffer(nNewLengthInChars);
	// if nNewLengthInBytes is not a multiply of sizeof(SAChar)
	// we have to save the difference
	GetData()->nBinaryDataLengthDiff = nBinaryDataLengthDiff;

#else	// !SA_UNICODE

	// byte == character in non-Unicode build
	ReleaseBuffer(nNewLengthInBytes);

#endif	// !SA_UNICODE
}

// Special conversion functions (multi byte <-> unicode)
#ifdef SA_UNICODE

static void ConvertToMultiByteChars(SAStringData *pData)
{
	if(pData->pConvertedData)	// already converted and cached
		return;

	// calculate multi-byte length
	int mbLen = SAWideCharToMultiByte(
		NULL, pData->data(), pData->nDataLength);

	// alocate space for conversion
	pData->pConvertedData = (SAStringConvertedData *)
		new unsigned char[sizeof(SAStringConvertedData) + (mbLen+1)*sizeof(char)];
	pData->pConvertedData->nDataLength = mbLen;
	pData->pConvertedData->data()[mbLen] = '\0';

	// now actually convert
	SAWideCharToMultiByte(pData->pConvertedData->data(), pData->data(), pData->nDataLength);
}

const char *SAString::GetMultiByteChars() const
{
	ConvertToMultiByteChars(GetData());
	return GetData()->pConvertedData->data();
}

int SAString::GetMultiByteCharsLength() const
{
	ConvertToMultiByteChars(GetData());
	return GetData()->pConvertedData->nDataLength;
}

#else	// !SA_UNICODE

static void ConvertToWideChars(SAStringData *pData)
{
	if(pData->pConvertedData)	// already converted and cached
		return;

	// alocate space for conversion
	pData->pConvertedData = (SAStringConvertedData *)
		new unsigned char[sizeof(SAStringConvertedData) + (pData->nDataLength+1)*sizeof(wchar_t)];

	int wLen = SAMultiByteToWideChar(pData->pConvertedData->data(), pData->data(), pData->nDataLength);
	pData->pConvertedData->nDataLength = wLen;
	pData->pConvertedData->data()[wLen] = '\0';
}

const wchar_t *SAString::GetWideChars() const
{
	ConvertToWideChars(GetData());
	return GetData()->pConvertedData->data();
}

int SAString::GetWideCharsLength() const
{
	ConvertToWideChars(GetData());
	return GetData()->pConvertedData->nDataLength;
}

#endif	// !SA_UNICODE

//////////////////////////////////////////////////////////////////////
// SADateTime Class
//////////////////////////////////////////////////////////////////////

/*static */
int SADateTime::m_saMonthDays[13] =
	{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};

// thanks to Microsoft for AFX_STATIC BOOL AFXAPI _AfxOleDateFromTm
/*static */
bool SADateTime::DateFromTm(unsigned short wYear, unsigned short wMonth, unsigned short wDay,
	unsigned short wHour, unsigned short wMinute, unsigned short wSecond,
	unsigned long nNanoSecond,
	double &dtDest)
{
	wYear += (unsigned short)1900;
	// Validate year and month (ignore day of week and milliseconds)
	if (wYear > 9999 || wMonth < 1 || wMonth > 12)
		return false;

	//  Check for leap year and set the number of days in the month
	bool bLeapYear = ((wYear & 3) == 0) &&
		((wYear % 100) != 0 || (wYear % 400) == 0);

	int nDaysInMonth =
		m_saMonthDays[wMonth] - m_saMonthDays[wMonth-1] +
		((bLeapYear && wDay == 29 && wMonth == 2) ? 1 : 0);

	// Finish validating the date
	if (wDay < 1 || wDay > nDaysInMonth ||
		wHour > 23 || wMinute > 59 ||
		wSecond > 59)
	{
		return false;
	}

	// Cache the date in days and time in fractional days
	long nDate;
	double dblTime;

	//It is a valid date; make Jan 1, 1AD be 1
	nDate = wYear*365L + wYear/4 - wYear/100 + wYear/400 +
		m_saMonthDays[wMonth-1] + wDay;

	//  If leap year and it's before March, subtract 1:
	if (wMonth <= 2 && bLeapYear)
		--nDate;

	//  Offset so that 12/30/1899 is 0
	nDate -= 693959L;

	dblTime = (((long)wHour * 3600L) +  // hrs in seconds
		((long)wMinute * 60L) +  // mins in seconds
		((long)wSecond)) / 86400.;
	// add nanoseconds
	double dNanoSec = (double)nNanoSecond/(24.0*60.0*60.0*1e9);
	dblTime += dNanoSec;

	dtDest = (double) nDate + ((nDate >= 0) ? dblTime : -dblTime);

	return true;
}

// AFX_STATIC BOOL AFXAPI _AfxTmFromOleDate(DATE dtSrc, struct tm& tmDest)
/*static */
bool SADateTime::TmFromDate(
	double dtSrc,
	struct tm &tmDest, unsigned long &nNanoSecond)
{
	long MIN_DATE		=	(-657434L);  // about year 100
	long MAX_DATE		=	2958465L;    // about year 9999
//	double HALF_SECOND	=	(1.0/172800.0);

	// The legal range does not actually span year 0 to 9999.
	if (dtSrc > MAX_DATE || dtSrc < MIN_DATE) // about year 100 to about 9999
		return false;

	long nDaysAbsolute;     // Number of days since 1/1/0
	long nSecsInDay;        // Time in seconds since midnight
	long nMinutesInDay;     // Minutes in day

	long n400Years;         // Number of 400 year increments since 1/1/0
	long n400Century;       // Century within 400 year block (0,1,2 or 3)
	long n4Years;           // Number of 4 year increments since 1/1/0
	long n4Day;             // Day within 4 year block
							//  (0 is 1/1/yr1, 1460 is 12/31/yr4)
	long n4Yr;              // Year within 4 year block (0,1,2 or 3)
	bool bLeap4 = true;     // TRUE if 4 year block includes leap year

	double dblDate = dtSrc; // tempory serial date

	// MS Original Code:Round to the second
	// MS Original Code:dblDate += ((dtSrc > 0.0) ? HALF_SECOND : -HALF_SECOND);
	// SQLAPI++ Code:No rounding, we will maintain nanoseconds

	nDaysAbsolute = (long)dblDate + 693959L; // Add days from 1/1/0 to 12/30/1899

	dblDate = fabs(dblDate);
	double dblTime = dblDate - floor(dblDate);
	nSecsInDay = (long)(dblTime * 86400.);

	// Calculate the day of week (sun=1, mon=2...)
	//   -1 because 1/1/0 is Sat.  +1 because we want 1-based
	tmDest.tm_wday = (int)((nDaysAbsolute - 1) % 7L) + 1;

	// Leap years every 4 yrs except centuries not multiples of 400.
	n400Years = (long)(nDaysAbsolute / 146097L);

	// Set nDaysAbsolute to day within 400-year block
	nDaysAbsolute %= 146097L;

	// -1 because first century has extra day
	n400Century = (long)((nDaysAbsolute - 1) / 36524L);

	// Non-leap century
	if (n400Century != 0)
	{
		// Set nDaysAbsolute to day within century
		nDaysAbsolute = (nDaysAbsolute - 1) % 36524L;

		// +1 because 1st 4 year increment has 1460 days
		n4Years = (long)((nDaysAbsolute + 1) / 1461L);

		if (n4Years != 0)
			n4Day = (long)((nDaysAbsolute + 1) % 1461L);
		else
		{
			bLeap4 = false;
			n4Day = (long)nDaysAbsolute;
		}
	}
	else
	{
		// Leap century - not special case!
		n4Years = (long)(nDaysAbsolute / 1461L);
		n4Day = (long)(nDaysAbsolute % 1461L);
	}

	if (bLeap4)
	{
		// -1 because first year has 366 days
		n4Yr = (n4Day - 1) / 365;

		if (n4Yr != 0)
			n4Day = (n4Day - 1) % 365;
	}
	else
	{
		n4Yr = n4Day / 365;
		n4Day %= 365;
	}

	// n4Day is now 0-based day of year. Save 1-based day of year, year number
	tmDest.tm_yday = (int)n4Day + 1;
	tmDest.tm_year = n400Years * 400 + n400Century * 100 + n4Years * 4 + n4Yr;

	// Handle leap year: before, on, and after Feb. 29.
	if (n4Yr == 0 && bLeap4)
	{
		// Leap Year
		if (n4Day == 59)
		{
			/* Feb. 29 */
			tmDest.tm_mon = 2;
			tmDest.tm_mday = 29;

			goto DoTime;
		}

		// Pretend it's not a leap year for month/day comp.
		if (n4Day >= 60)
			--n4Day;
	}

	// Make n4DaY a 1-based day of non-leap year and compute
	//  month/day for everything but Feb. 29.
	++n4Day;

	// Month number always >= n/32, so save some loop time */
	for (tmDest.tm_mon = (n4Day >> 5) + 1;
		n4Day > m_saMonthDays[tmDest.tm_mon]; tmDest.tm_mon++);

	tmDest.tm_mday = (int)(n4Day - m_saMonthDays[tmDest.tm_mon-1]);

DoTime:
	if (nSecsInDay == 0)
		tmDest.tm_hour = tmDest.tm_min = tmDest.tm_sec = 0;
	else
	{
		tmDest.tm_sec = (int)nSecsInDay % 60L;
		nMinutesInDay = nSecsInDay / 60L;
		tmDest.tm_min = (int)nMinutesInDay % 60;
		tmDest.tm_hour = (int)nMinutesInDay / 60;
	}
	double dNanoSecs = dblTime - ((double)nSecsInDay/86400.0);
	assert(dNanoSecs >= 0);
	dNanoSecs *= 24.0 * 60.0 * 60.0 * 1e9;
	assert(dNanoSecs < 1e9);
	nNanoSecond = (unsigned long)dNanoSecs;
	assert(nNanoSecond <= 999999999);

	tmDest.tm_year -= 1900;  // year is based on 1900
	tmDest.tm_mon -= 1;      // month of year is 0-based
	tmDest.tm_wday -= 1;     // day of week is 0-based
	tmDest.tm_yday -= 1;     // day of year is 0-based
	return true;
}

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

void SADateTime::Init_Tm()
{
	memset(&m_tm, 0, sizeof(m_tm));
	m_nFraction = 0;
}

SADateTime::SADateTime()
{
	Init_Tm();
}

SADateTime::SADateTime(const SADateTime &other)
{
	m_tm = other.m_tm;
	m_nFraction = other.m_nFraction;
}

SADateTime::SADateTime(const struct tm &tmValue)
{
	m_tm = tmValue;
	m_nFraction = 0;
}

SADateTime::operator struct tm &()
{
	return m_tm;
}

SADateTime::operator struct tm() const
{
	return m_tm;
}

SADateTime::SADateTime(double dt)
{
	if(!TmFromDate(dt, m_tm, m_nFraction))
		Init_Tm();
}

SADateTime::operator double() const
{
	double dt;
	if(DateFromTm(
		(unsigned short)m_tm.tm_year, (unsigned short)(m_tm.tm_mon + 1), (unsigned short)m_tm.tm_mday,
		(unsigned short)m_tm.tm_hour, (unsigned short)m_tm.tm_min, (unsigned short)m_tm.tm_sec,
		m_nFraction,
		dt))
		return dt;

	return (double)0;
}

SADateTime::SADateTime(int nYear, int nMonth, int nDay, int nHour, int nMinute, int nSecond)
{
	m_tm.tm_year = nYear - 1900;

⌨️ 快捷键说明

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