Beispiel #1
0
/*----------------------------------------------------------------------------------------------
	Calculate the transition times for switching between STD time and DST.
----------------------------------------------------------------------------------------------*/
bool TimeMapper::CalcTransitions(int dminBias, SYSTEMTIME & st, const int * prgyday,
	int * prgymin)
{
	AssertArray(prgyday, kmonPerYear);
	AssertArray(prgymin, kdayPerWeek);

	int zmon = st.wMonth - 1;
	int wday = st.wDayOfWeek;
	int week = st.wDay;
	int min = st.wHour * kminPerHour + st.wMinute;

	if ((uint)zmon >= 12 || (uint)wday >= kdayPerWeek || week < 1 || week > 5 ||
		(uint)min >= kminPerDay)
	{
		Assert(!"Bad time zone info");
		return false;
	}

	int ydayLast = prgyday[zmon] + week * kdayPerWeek - 1;
	if (ydayLast >= prgyday[zmon + 1])
		ydayLast = prgyday[zmon + 1] - 1;

	// Find the first day <= ydayLast that is the correct day of the week.
	for (int wdayT = 0; wdayT < kdayPerWeek; wdayT++)
	{
		int wdayLast = (ydayLast + wdayT) % kdayPerWeek;
		int yday = ydayLast - (wdayLast - wday) - (wdayLast < wday) * kdayPerWeek;
		Assert(yday <= ydayLast);
		Assert((yday + wdayT) % kdayPerWeek == wday);
		prgymin[wdayT] = yday * kminPerDay + min + dminBias;
	}

	return true;
}
Beispiel #2
0
	void Vector<T>::Replace(int ieMin, int ieLimDel, const T * prgeIns, int ceIns)
{
	AssertObj(this);
	Assert((uint)ieMin <= (uint)ieLimDel && (uint)ieLimDel <= (uint)m_ieLim);
	Debug( if (prgeIns) AssertArray(prgeIns, ceIns); )

	if ((uint)ieLimDel > (uint)m_ieLim)
Beispiel #3
0
/*----------------------------------------------------------------------------------------------
	Parameters:
		prgwch: 16-bit key string to find
		cchLim: Length of prgwch
		pcch:   Will contain the length of the matched word if there is one.
			This can be NULL if the length is not needed. If it is not
			NULL, it should be initialized to 0 before the call.
----------------------------------------------------------------------------------------------*/
bool CTrieLevel::FindWord(wchar * prgwch, int cchLim, const char * pszDelim, COLORREF * pcr,
	int * pcch, BOOL fCaseMatters)
{
	AssertArray(prgwch, cchLim);
	AssertPtr(pcr);
	AssertPtr(pszDelim);
	int ite;

	*pcr = m_cr;
	if (!cchLim || !FindElement(fCaseMatters ? *prgwch : towlower(*prgwch), &ite))
		return m_cr != (COLORREF)-1;
	if (pcch)
		(*pcch)++;
	return m_ppte[ite]->m_ptlSub->FindWord(prgwch + 1, cchLim - 1, pszDelim, pcr, pcch, fCaseMatters);
}
Beispiel #4
0
/*----------------------------------------------------------------------------------------------
	This unicode case mapping function converts cch wide (16-bit) characters in prgch to
	lower case.
----------------------------------------------------------------------------------------------*/
void ToLower(utf16 * prgch, int cch)
{
	AssertArray(prgch, cch);

	utf16 * pch;
	utf16 * pchLim = prgch + cch;

	for (pch = prgch; pch < pchLim; ++pch)
	{
		if (*pch < kchLimLower1)
		{
			if (*pch >= kchMinLower1)
				*pch = g_mpchchLower1[*pch - kchMinLower1];
		}
		else if (*pch < kchLimLower4)
		{
			if (*pch < kchMinLower3)
			{
				if (*pch < kchLimLower2)
				{
					if (*pch >= kchMinLower2)
						*pch = g_mpchchLower2[*pch - kchMinLower2];
				}
			}
			else if (*pch < kchLimLower3)
				*pch += kdchLower3;
			else if (*pch >= kchMinLower4)
				*pch = g_mpchchLower4[*pch - kchMinLower4];
		}
		else if (*pch < kchLimLower6)
		{
			if (*pch < kchLimLower5)
			{
				if (*pch >= kchMinLower5)
					*pch += kdchLower5;
			}
			else if (*pch >= kchMinLower6)
				*pch += kdchLower6;
		}
		else if (*pch < kchLimLower7)
		{
			if (*pch >= kchMinLower7)
				*pch += kdchLower7;
		}
	}
}
Beispiel #5
0
/*----------------------------------------------------------------------------------------------
	This unicode case mapping function converts cch wide (16-bit) characters in prgch to
	upper case.
----------------------------------------------------------------------------------------------*/
void ToUpper(utf16 * prgch, int cch)
{
	Assert(cch >= 0);
	AssertArray(prgch, cch);

	utf16 ch;
	utf16 *pch;
	utf16 *pchLim = prgch + cch;

	for (pch = prgch; pch < pchLim; ++pch)
	{
		ch = *pch;

		// Try the common case first.
		if (*pch < kchLimUpper1)
		{
			if (*pch >= kchMinUpper1)
				*pch = g_mpchchUpper1[*pch - kchMinUpper1];
		}
		else if (*pch < kchLimUpper4)
		{
			if (*pch < kchMinUpper3)
			{
				if (*pch < kchLimUpper2)
				{
					if (*pch >= kchMinUpper2)
						*pch = g_mpchchUpper2[*pch - kchMinUpper2];
				}
			}
			else if (*pch < kchLimUpper3)
				*pch = g_mpchchUpper3[*pch - kchMinUpper3];
			else if (*pch >= kchMinUpper4)
				*pch += kdchUpper4;
		}
		else if (*pch < kchMinUpper6)
		{
			if (*pch < kchLimUpper5)
			{
				if (*pch >= kchMinUpper5)
					*pch += kdchUpper5;
			}
		}
		else if (*pch < kchLimUpper6)
			*pch += kdchUpper6;
	}
}
Beispiel #6
0
TypeFunction::TypeFunction(Type *return_type, TypeCSU *csu_type, bool varargs,
                           const Vector<Type*> &argument_types)
  : Type(YK_Function),
    m_return_type(return_type), m_csu_type(csu_type), m_varargs(varargs),
    m_argument_types(argument_types.Data()),
    m_argument_count(argument_types.Size())
{
  Assert(m_return_type);
  AssertArray(m_argument_types, m_argument_count);

  if (m_varargs)
    m_hash++;
  m_hash = Hash32(m_hash, m_return_type->Hash());
  if (m_csu_type)
    m_hash = Hash32(m_hash, m_csu_type->Hash());
  for (size_t aind = 0; aind < m_argument_count; aind++)
    m_hash = Hash32(m_hash, m_argument_types[aind]->Hash());
}
Beispiel #7
0
/*----------------------------------------------------------------------------------------------
	Load data into the cache from the record set defined by hstmt, according to the specs
	in prgocs/cocs. Columns with m_icolID = 0 give properties of hvoBase.
	Load properties of at most crowMax objects; this may only be used if there is no vector
	property being loaded, since we could not be sure of having a complete record of the
	value of a vector without loading the next row. If crowMax is zero, load everything.
	Note: call from inside try/catch block; may throw exceptions.
	Note that prgocs[i] describes the column which ODBC indexes as [i+1].
----------------------------------------------------------------------------------------------*/
void VwRsOdbcDa::Load(SQLHSTMT hstmt, OdbcColSpec * prgocs, int cocs, HVO hvoBase,
	int crowMax)
{
	AssertArray(prgocs, cocs);
	Assert((uint)cocs <= (uint) 200); // limit because of size of rghvoBaseIds
	Assert(crowMax >= 0);

	ITsStrFactoryPtr qtsf;
	qtsf.CreateInstance(CLSID_TsStrFactory);
	ITsPropsFactoryPtr qtpf;
	qtpf.CreateInstance(CLSID_TsPropsFactory);

	// Block of variables for binary fields
	Vector<byte> vbData; // used to buffer data from binary fields
	const int kcbMaxData = 1000; // amount of binary data to read in one go
	byte rgbData[kcbMaxData];  // buffer for short binary data fields
	long cbData; // how many bytes in prgbData hold valid data
	byte * prgbData; // points to rgbData or vbData.Begin(), as appropriate

	// Similar block for Unicode text
	Vector<wchar> vchData;
	const int kcchMaxData = 1000;
	wchar rgchData[kcchMaxData];
	long cchData;
	wchar * prgchData;

	Vector<HVO> vhvo; // accumulate objects for sequence property
	int nrows = 0;

	if (crowMax == 0)
		crowMax = INT_MAX;


	HVO rghvoBaseIds[200];

	int icolVec = -1; // index of (one and only) column of type koctObjVec
	int hvoVecBase; // object that is base of vector property

	while (CheckSqlRc(SQLFetch(hstmt)) != SQL_NO_DATA)
	{
		// We have a record.
		for (int icol = 0; icol < cocs; icol++)
		{
			int nVal;
			HVO hvoVal;
			ITsStringPtr qtssVal;
			// TOxDO JohnT: fill this in...
			HVO hvoCurBase; // object whose property we will read.
			if (prgocs[icol].m_icolID == 0)
				hvoCurBase = hvoBase;
			else
			{
				// Must refer to a previous column; use <= because m_icolID is 1-based, so
				// if equal to i, it refers to the immediate previous column.
				Assert(prgocs[icol].m_icolID <= icol);
				hvoCurBase = rghvoBaseIds[prgocs[icol].m_icolID - 1];
			}
			switch (prgocs[icol].m_oct)
			{
			default:
				Assert(false);
				ThrowHr(WarnHr(E_UNEXPECTED));
			case koctInt:
				CheckSqlRc(SQLGetData(hstmt, (unsigned short)(icol + 1), SQL_C_SLONG, &nVal, 4, NULL));
				CacheIntProp(hvoCurBase, prgocs[icol].m_tag, nVal);
				break;
			case koctUnicode:
				ReadUnicode(hstmt, icol + 1, rgchData, kcchMaxData,
					vchData, prgchData, cchData);
				CacheUnicodeProp(hvoCurBase, prgocs[icol].m_tag, prgchData, cchData);
				break;
			case koctString:
			case koctMlsAlt:
			case koctMltAlt:
				// Next column must give format; both are for the same property
				ReadUnicode(hstmt, icol + 1, rgchData, kcchMaxData,
					vchData, prgchData, cchData);
				if (koctMltAlt != prgocs[icol].m_oct)
				{
					Assert(icol < cocs - 1 && prgocs[icol + 1].m_oct == koctFmt);
					Assert(prgocs[icol].m_tag == prgocs[icol + 1].m_tag);
					// Leave the data in prgchData and cchData, to be processed next iteration
					// when we read the format.
					break;
				}
				// A MS alt without a FMT column, use the specified writing system both for the string
				// formatting and to indicate the alternative.
				CheckHr(qtsf->MakeStringRgch(prgchData, cchData, prgocs[icol].m_ws, &qtssVal));
				CacheStringAlt(hvoCurBase, prgocs[icol].m_tag,
						prgocs[icol].m_ws, qtssVal);
				break;
			case koctFmt:
				// Previous column must be string or multistring; we have already checked same tag.
				Assert(icol > 0 &&
					(prgocs[icol - 1].m_oct == koctString || prgocs[icol - 1].m_oct == koctMlsAlt));
				ReadBinary(hstmt, icol + 1, rgbData, kcbMaxData,
					vbData, prgbData, cbData);
				int cbDataInt;
				cbDataInt = cbData;
				int cchDataInt;
				cchDataInt = cchData;
				if (cchDataInt == 0 && cbDataInt == 0)
					CheckHr(qtsf->MakeStringRgch(NULL, 0, prgocs[icol - 1].m_ws, &qtssVal));
				else
					CheckHr(qtsf->DeserializeStringRgch(prgchData, &cchDataInt, prgbData,
						&cbDataInt, &qtssVal));
				if (prgocs[icol - 1].m_oct == koctString)
				{
					CacheStringProp(hvoCurBase, prgocs[icol].m_tag, qtssVal);
				}
				else
				{
					CacheStringAlt(hvoCurBase, prgocs[icol].m_tag,
						prgocs[icol - 1].m_ws, qtssVal);
				}
				break;
			case koctObj:
			case koctBaseId:
				long nIndicator;
				CheckSqlRc(SQLGetData(hstmt, (unsigned short)(icol + 1), SQL_C_SLONG,
					&hvoVal, 4, &nIndicator));
				// Treat null as zero.
				if (nIndicator == SQL_NULL_DATA)
					hvoVal = 0;
				if (prgocs[icol].m_oct == koctObj)
					CacheObjProp(hvoCurBase, prgocs[icol].m_tag, hvoVal);
				rghvoBaseIds[icol] = hvoVal;
				break;
			case koctObjVec:
				CheckSqlRc(SQLGetData(hstmt, (unsigned short)(icol + 1), SQL_C_SLONG,
					&hvoVal, 4, NULL));
				rghvoBaseIds[icol] = hvoVal;
				// See if there has been a change in the base column, if so, record value and
				// start a new one.
				if (icolVec < 0)
				{
					// First iteration, ignore previous object
					icolVec = icol;
					hvoVecBase = hvoCurBase;
				}
				else
				{
					// Only one vector column allowed!
					Assert(icolVec == icol);
					if (hvoVecBase != hvoCurBase)
					{
						// Started a new vector! Record the old one
						CacheVecProp(hvoVecBase, prgocs[icolVec].m_tag, vhvo.Begin(),
							vhvo.Size());
						// clear the list out and note new base object
						vhvo.Clear();
						hvoVecBase = hvoCurBase;
					}
				}
				vhvo.Push(hvoVal);
				break;
			case koctTtp:
				ReadBinary(hstmt, icol + 1, rgbData, kcbMaxData,
					vbData, prgbData, cbData);
				if (cbData > 0) // otherwise field is null, cache nothing
				{
					cbDataInt = cbData;
					ITsTextPropsPtr qttp;
					qtpf->DeserializePropsRgb(prgbData, &cbDataInt, &qttp);
					CacheUnknown(hvoCurBase, prgocs[icol].m_tag, qttp);
				}
				break;
			}
		}

		// Stop if we have processed the requested number of rows.
		nrows++;
		if (nrows >= crowMax)
			break;
	}
	// If we are processing a vector, we need to fill in the last occurrence
	if (icolVec >= 0)
	{
		CacheVecProp(hvoVecBase, prgocs[icolVec].m_tag, vhvo.Begin(),
			vhvo.Size());
	}
}
Beispiel #8
0
/*----------------------------------------------------------------------------------------------
	Decode 1-6 bytes in the character string from UTF-8 format to Unicode (UCS-4).
	As a side-effect, cbOut is set to the number of UTF-8 bytes consumed.

	@param rgchUtf8 Pointer to a a character array containing UTF-8 data.
	@param cchUtf8 Number of characters in the array.
	@param cbOut Reference to an integer for holding the number of input (8-bit) characters
					consumed to produce the single output Unicode character.

	@return A single Unicode (UCS-4) character.  If an error occurs, return -1.
----------------------------------------------------------------------------------------------*/
long GrCharStream::DecodeUtf8(const utf8 * rgchUtf8, int cchUtf8, int * pcbOut)
{
	// check for valid input
	AssertArray(rgchUtf8, cchUtf8);
	if ((cchUtf8 == 0) || (rgchUtf8[0] == '\0'))
	{
		*pcbOut = (cchUtf8) ? 1 : 0;
		return 0;
	}
	//
	// decode the first byte of the UTF-8 sequence
	//
	long lnUnicode;
	int cbExtra;
	int chsUtf8 = *rgchUtf8++ & 0xFF;
	if (chsUtf8 >= kzUtf8Flag6)					// 0xFC
	{
		lnUnicode = chsUtf8 & kzUtf8Mask6;
		cbExtra = 5;
	}
	else if (chsUtf8 >= kzUtf8Flag5)			// 0xF8
	{
		lnUnicode = chsUtf8 & kzUtf8Mask5;
		cbExtra = 4;
	}
	else if (chsUtf8 >= kzUtf8Flag4)			// 0xF0
	{
		lnUnicode = chsUtf8 & kzUtf8Mask4;
		cbExtra = 3;
	}
	else if (chsUtf8 >= kzUtf8Flag3)			// 0xE0
	{
		lnUnicode = chsUtf8 & kzUtf8Mask3;
		cbExtra = 2;
	}
	else if (chsUtf8 >= kzUtf8Flag2)			// 0xC0
	{
		lnUnicode = chsUtf8 & kzUtf8Mask2;
		cbExtra = 1;
	}
	else										// 0x00
	{
		lnUnicode = chsUtf8;
		cbExtra = 0;
	}
	if (cbExtra >= cchUtf8)
	{
		return -1;
	}

	switch (cbExtra)
	{
	case 5:
		lnUnicode <<= kzUtf8ByteShift;
		chsUtf8 = *rgchUtf8++ & 0xFF;
		if ((chsUtf8 & ~kzByteMask) != 0x80)
			return -1;
		lnUnicode += chsUtf8 & kzByteMask;
		// fall through
	case 4:
		lnUnicode <<= kzUtf8ByteShift;
		chsUtf8 = *rgchUtf8++ & 0xFF;
		if ((chsUtf8 & ~kzByteMask) != 0x80)
			return -1;
		lnUnicode += chsUtf8 & kzByteMask;
		// fall through
	case 3:
		lnUnicode <<= kzUtf8ByteShift;
		chsUtf8 = *rgchUtf8++ & 0xFF;
		if ((chsUtf8 & ~kzByteMask) != 0x80)
			return -1;
		lnUnicode += chsUtf8 & kzByteMask;
		// fall through
	case 2:
		lnUnicode <<= kzUtf8ByteShift;
		chsUtf8 = *rgchUtf8++ & 0xFF;
		if ((chsUtf8 & ~kzByteMask) != 0x80)
			return -1;
		lnUnicode += chsUtf8 & kzByteMask;
		// fall through
	case 1:
		lnUnicode <<= kzUtf8ByteShift;
		chsUtf8 = *rgchUtf8++ & 0xFF;
		if ((chsUtf8 & ~kzByteMask) != 0x80)
			return -1;
		lnUnicode += chsUtf8 & kzByteMask;
		break;
	case 0:
		// already handled
		break;
	default:
		Assert(false);
	}
	if ((unsigned long)lnUnicode > kzUnicodeMax)
	{
		return -1;
	}
	*pcbOut = cbExtra + 1;
	return lnUnicode;
}
Beispiel #9
0
	static bool FParseSilTime(const XChar * prgch, int cch, XChar chDateSep, XChar chSep,
		XChar chTimeSep, const XChar ** ppchLim, bool fUtc, SilTime * pstim)
{
	// REVIEW SteveMc: Should we do range checking and report errors?
	AssertArray(prgch, cch);
	AssertPtrN(ppchLim);
	AssertPtr(pstim);

	SilTimeInfo sti;
	ClearItems(&sti, 1);

	const XChar * pch = prgch;
	const XChar * pchLim = prgch + cch;

	// Get the year.
	if (pch < pchLim && *pch == '-')
		pch++;
	while (pch < pchLim && '0' <= *pch && *pch <= '9')
		sti.year = sti.year * 10 + (*pch++ - '0');
	if (cch > 0 && *prgch == chDateSep)
		sti.year = -sti.year;

	if (pch < pchLim && *pch == chDateSep)
	{
		pch++;
		while (pch < pchLim && '0' <= *pch && *pch <= '9')
			sti.ymon = sti.ymon * 10 + (*pch++ - '0');
		if (pch < pchLim && *pch == chDateSep)
		{
			pch++;
			while (pch < pchLim && '0' <= *pch && *pch <= '9')
				sti.mday = sti.mday * 10 + (*pch++ - '0');
		}
	}

	if (pch < pchLim && *pch == chSep)
	{
		pch++;
		while (pch < pchLim && '0' <= *pch && *pch <= '9')
			sti.hour = sti.hour * 10 + (*pch++ - '0');
		if (pch < pchLim && *pch == chTimeSep)
		{
			pch++;
			while (pch < pchLim && '0' <= *pch && *pch <= '9')
				sti.min = sti.min * 10 + (*pch++ - '0');
			if (pch < pchLim && *pch == chTimeSep)
			{
				pch++;
				while (pch < pchLim && '0' <= *pch && *pch <= '9')
					sti.sec = sti.sec * 10 + (*pch++ - '0');
				if (pch < pchLim && *pch == '.')
				{
					pch++;
					if ('0' <= *pch && *pch <= '9')
					{
						sti.msec += (*pch++ - '0') * 100;
						if ('0' <= *pch && *pch <= '9')
						{
							sti.msec += (*pch++ - '0') * 10;
							if ('0' <= *pch && *pch <= '9')
								sti.msec += (*pch++ - '0');
						}
					}
				}
			}
		}
	}

	if (ppchLim)
		*ppchLim = pch;

	pstim->SetTimeInfo(sti, true);
	return true;
}
Beispiel #10
0
/*----------------------------------------------------------------------------------------------
	Get all the MONOlingual formatted string fields in the database.  The standard metadata
	cache does not provide the information we need, so we find all the class/field pairs whose
	values are String or BigString.

	@param podc Pointer to data base command object.
	@param vstuClass Reference to output class names (parallel to vstuField).
	@param vstuField Reference to output field names.
	@param rgnFlidsToIgnore array of flids that we don't want to put in output (defaults to
					empty)
	@param cFlidsToIgnore size of rgnFlidsToIgnore
----------------------------------------------------------------------------------------------*/
void DbStringCrawler::GetFieldsForTypes(IOleDbCommand * podc, const int * rgnTypes, int cTypes,
	Vector<StrUni> & vstuClass, Vector<StrUni> & vstuField,
		const int * rgflidToIgnore, const int cflidToIgnore)
{
	AssertPtr(podc);
	AssertArray(rgnTypes, cTypes);
	AssertArray(rgflidToIgnore, cflidToIgnore);
	if (!cTypes)
		return;
	StrUni stuCmd;
	ComBool fMoreRows;
	ComBool fIsNull;
	unsigned long cbSpaceTaken;
	Vector<wchar> vchFieldName;
	Vector<wchar> vchClassName;
	int cchFieldName;
	int cchClassName;
	StrUni stu;

	stuCmd.Assign(L"SELECT f.Name, c.Name FROM Field$ f"
		L" JOIN Class$ c ON c.id = f.Class WHERE f.Type IN (");
	for (int i = 0; i < cTypes; ++i)
	{
		if (i != 0)
			stuCmd.FormatAppend(L",%d", rgnTypes[i]);
		else
			stuCmd.FormatAppend(L"%d", rgnTypes[i]);
	}
	stuCmd.Append(L")");
	if (cflidToIgnore)
	{
		stuCmd.Append(L" AND NOT f.Id IN (");
		for (int i = 0; i < cflidToIgnore; ++i)
		{
			if (i != 0)
				stuCmd.FormatAppend(L",%d", rgflidToIgnore[i]);
			else
				stuCmd.FormatAppend(L"%d", rgflidToIgnore[i]);
		}
		stuCmd.Append(L")");
	}
	CheckHr(podc->ExecCommand(stuCmd.Bstr(), knSqlStmtSelectWithOneRowset));
	CheckHr(podc->GetRowset(0));
	CheckHr(podc->NextRow(&fMoreRows));
	vchFieldName.Resize(100);
	vchClassName.Resize(100);
	while (fMoreRows)
	{
		CheckHr(podc->GetColValue(1, reinterpret_cast<BYTE *>(vchFieldName.Begin()),
			vchFieldName.Size() * isizeof(wchar), &cbSpaceTaken, &fIsNull, 0));
		cchFieldName = cbSpaceTaken / isizeof(wchar);
		Assert(cbSpaceTaken == cchFieldName * sizeof(wchar));
		if (cchFieldName >= vchFieldName.Size())
		{
			vchFieldName.Resize(cchFieldName + 1);
			CheckHr(podc->GetColValue(1,
				reinterpret_cast<BYTE *>(vchFieldName.Begin()),
				vchFieldName.Size() * isizeof(wchar), &cbSpaceTaken, &fIsNull, 0));
			cchFieldName = cbSpaceTaken / isizeof(wchar);
			Assert(cchFieldName < vchFieldName.Size());
		}
		CheckHr(podc->GetColValue(2, reinterpret_cast<BYTE *>(vchClassName.Begin()),
			vchClassName.Size() * isizeof(wchar), &cbSpaceTaken, &fIsNull, 0));
		cchClassName = cbSpaceTaken / isizeof(wchar);
		Assert(cbSpaceTaken == cchClassName * sizeof(wchar));
		if (cchClassName >= vchClassName.Size())
		{
			vchClassName.Resize(cchClassName + 1);
			CheckHr(podc->GetColValue(2,
				reinterpret_cast<BYTE *>(vchClassName.Begin()),
				vchClassName.Size() * isizeof(wchar), &cbSpaceTaken, &fIsNull, 0));
			cchClassName = cbSpaceTaken / isizeof(wchar);
			Assert(cchClassName < vchClassName.Size());
		}
		stu.Assign(vchFieldName.Begin(), cchFieldName);
		vstuField.Push(stu);
		stu.Assign(vchClassName.Begin(), cchClassName);
		vstuClass.Push(stu);
		CheckHr(podc->NextRow(&fMoreRows));
	}
}
Beispiel #11
0
	void StrBase<XChar>::_Replace(int ichMin, int ichLim,
		const YChar * prgchIns, YChar chIns, int cchIns)
{
	AssertObj(this);
	Assert(cchIns >= 0);
	AssertArray(prgchIns, cchIns);

	// These are used ony when prgchIns is NULL.
	const int kcchMaxChar = 8;
	XChar rgchChar[kcchMaxChar];
	int cchChar;

	int cchCur = m_pbuf->Cch();
	Assert((unsigned int)ichMin <= (unsigned int)ichLim && (unsigned int)ichLim <= (unsigned int)cchCur);

	// Determine the number of characters we're inserting.
	int cchDst;

	if (cchIns)
	{
		if (prgchIns)
		{
			cchDst = ConvertText(prgchIns, cchIns, (XChar *)NULL, 0);
			if (!cchDst)
				ThrowHr(WarnHr(E_FAIL));
			Assert(cchCur + cchDst > cchCur);
		}
		else
		{
			cchChar = ConvertText(&chIns, 1, rgchChar, kcchMaxChar);
			if (!cchChar)
				ThrowHr(WarnHr(E_FAIL));
			Assert((unsigned int)cchChar <= (unsigned int)kcchMaxChar);
			cchDst = cchChar * cchIns;
			Assert(cchCur + cchDst > cchCur);
		}
	}
	else
		cchDst = 0;

	// Allocate the new buffer.
	StrBuffer * pbuf;
	int cchNew = cchCur + cchDst - ichLim + ichMin;

	if (cchNew == cchCur && !m_pbuf->m_crefMinusOne)
	{
		// The buffer size is staying the same and we own the characters.
		pbuf = m_pbuf;
	}
	else
	{
		// Allocate the new buffer.
		pbuf = StrBuffer::Create(cchNew);
	}

	// Copy and convert the text.
	if (ichMin > 0 && pbuf != m_pbuf)
		std::copy(m_pbuf->m_rgch, m_pbuf->m_rgch + ichMin, pbuf->m_rgch);
//		CopyItems(m_pbuf->m_rgch, pbuf->m_rgch, ichMin);
	if (cchDst > 0)
	{
		if (prgchIns)
			ConvertText(prgchIns, cchIns, pbuf->m_rgch + ichMin, cchDst);
		else
		{
			XChar * pch = pbuf->m_rgch + ichMin;
			if (cchChar == 1)
				std::fill_n(pch, cchIns, rgchChar[0]);
//				FillChars(pch, rgchChar[0], cchIns);
			else
			{
				int cchT;
				for (cchT = cchIns; --cchT >= 0; )
				{
					std::copy(rgchChar, rgchChar + cchChar, pch);
//					CopyItems(rgchChar, pch, cchChar);
					pch += cchChar;
				}
			}
		}
	}
	if (pbuf != m_pbuf)
	{
		if (ichLim < cchCur)
			std::copy(m_pbuf->m_rgch + ichLim, m_pbuf->m_rgch + cchCur, pbuf->m_rgch + ichMin + cchDst);
//			CopyItems(m_pbuf->m_rgch + ichLim, pbuf->m_rgch + ichMin + cchDst, cchCur - ichLim);
		// Set our buffer to the new one.
		_AttachBuf(pbuf);
	}

	AssertObj(this);
}
Beispiel #12
0
DEFINE_THIS_FILE


/***********************************************************************************************
	Functions
***********************************************************************************************/
// This includes a number of enum definitions for useful constants plus a function shared with
// the TESO dll code that doesn't use anything else in Generic.
#include "DecodeUtf8_i.c"

//:End Ignore

//:Associate with "XML and Unicode Utility Functions"
/*----------------------------------------------------------------------------------------------
	Return the number of bytes needed to store the 16-bit Unicode string as XML UTF-8.

	@param rgchwSrc Pointer to an array of wide (Unicode) characters.
	@param cchwSrc Number of wide characters in rgchwSrc.  This may be greater than the number
					of actual Unicode characters due to surrogate pairs.
	@param fXml Flag whether the output needs to have XML character code escapes for "<>&".
----------------------------------------------------------------------------------------------*/
int CountXmlUtf8FromUtf16(const wchar * rgchwSrc, int cchwSrc, bool fXml)
{
	AssertArray(rgchwSrc, cchwSrc);

	int cchChar;
	const wchar * pchw;
	const wchar * pchwLim = rgchwSrc + cchwSrc;

	int cchDst = 0;

	for (pchw = rgchwSrc; pchw < pchwLim; )
	{
		ulong luChar = *pchw++;
		if (kSurrogateHighFirst <= luChar && luChar <= kSurrogateHighLast && pchw < pchwLim)
		{
			ulong luChar2 = *pchw;
			if (kSurrogateLowFirst <= luChar2 && luChar2 <= kSurrogateLowLast)
			{
				luChar -= kSurrogateHighFirst;
				luChar <<= kSurrogateShift;
				luChar += luChar2 - kSurrogateLowFirst;
				luChar += kSurrogateBase;
				++pchw;
			}
		}
		if (luChar > kUnicodeMax)
		{
			luChar = kReplacementChar;
		}

		if (luChar < kUtf8Min2)
		{
			cchChar = 1;
			if (fXml)
			{
				switch (luChar)
				{
				case '<':
					cchChar = 4;
					break;
				case '>':
					cchChar = 4;
					break;
				case '&':
					cchChar = 5;
					break;
				case '"':
					cchChar = 6;
					break;
				}
			}
		}
		else if (luChar < kUtf8Min3)
		{
			cchChar = 2;
		}
		else if (luChar < kUtf8Min4)
		{
			cchChar = 3;
		}
		else if (luChar < kUtf8Min5)
		{
			cchChar = 4;
		}
		else if (luChar < kUtf8Min6)
		{
			cchChar = 5;
		}
		else
		{
			cchChar = 6;
		}

		cchDst += cchChar;
	}

	return cchDst;
}
Beispiel #13
0
/*----------------------------------------------------------------------------------------------
	Convert the 16-bit Unicode string to UTF-8, returning the length in bytes of the UTF-8
	string.  Care is taken not to overflow the output buffer.

	@param rgchDst Pointer to an output array of (8-bit) characters.
	@param cchMaxDst Maximum number of (8-bit) characters that can be stored in rgchDst.
	@param rgchwSrc Pointer to an input array of wide (Unicode) characters.
	@param cchwSrc Number of wide characters in rgchwSrc.  This may be greater than the number
					of actual Unicode characters due to surrogate pairs.
	@param fXml Flag whether the output needs to have XML character code escapes for "<>&"".

	@return Number of characters required for the output buffer. If cchMaxDst is less than or
					equal to the return value, all of the output was written.
----------------------------------------------------------------------------------------------*/
int ConvertUtf16ToXmlUtf8(char * rgchDst, int cchMaxDst, const wchar * rgchwSrc, int cchwSrc,
	bool fXml)
{
	AssertArray(rgchDst, cchMaxDst);
	AssertArray(rgchwSrc, cchwSrc);

	int cchChar;
	char rgchChar[8];
	const char * prgchChar;
	const wchar * pchw;
	const wchar * pchwLim = rgchwSrc + cchwSrc;

	// TODO SteveMc(ShonK): This needs a better name. When you decide on hungarian tags for
	// the constants above use the same tag here.
	byte bFirstMark = 0;

	int cchDst = 0;

	for (pchw = rgchwSrc; pchw < pchwLim; )
	{
		ulong luChar = *pchw++;
		if (kSurrogateHighFirst <= luChar && luChar <= kSurrogateHighLast && pchw < pchwLim)
		{
			ulong luChar2 = *pchw;
			if (kSurrogateLowFirst <= luChar2 && luChar2 <= kSurrogateLowLast)
			{
				luChar -= kSurrogateHighFirst;
				luChar <<= kSurrogateShift;
				luChar += luChar2 - kSurrogateLowFirst;
				luChar += kSurrogateBase;
				++pchw;
			}
		}
		if (luChar > kUnicodeMax)
		{
			luChar = kReplacementChar;
		}

		prgchChar = NULL;

		if (luChar < kUtf8Min2)
		{
			if (fXml)
			{
				switch (luChar)
				{
				case '<':
					prgchChar = "&lt;";
					cchChar = 4;
					break;
				case '>':
					prgchChar = "&gt;";
					cchChar = 4;
					break;
				case '&':
					prgchChar = "&amp;";
					cchChar = 5;
					break;
				case '"':
					prgchChar = "&quot;";
					cchChar = 6;
					break;
				default:
					bFirstMark = kUtf8Flag1;
					cchChar = 1;
					break;
				}
			}
			else
			{
				bFirstMark = kUtf8Flag1;
				cchChar = 1;
			}
		}
		else if (luChar < kUtf8Min3)
		{
			bFirstMark = kUtf8Flag2;
			cchChar = 2;
		}
		else if (luChar < kUtf8Min4)
		{
			bFirstMark = kUtf8Flag3;
			cchChar = 3;
		}
		else if (luChar < kUtf8Min5)
		{
			bFirstMark = kUtf8Flag4;
			cchChar = 4;
		}
		else if (luChar < kUtf8Min6)
		{
			bFirstMark = kUtf8Flag5;
			cchChar = 5;
		}
		else
		{
			bFirstMark = kUtf8Flag6;
			cchChar = 6;
		}

		if (!prgchChar)
		{
			prgchChar = rgchChar;

			char * pch = &rgchChar[cchChar];

			switch (cchChar)
			{
			case 6:
				*--pch = (char)((luChar & kByteMask) | kByteMark);
				luChar >>= kByteShift;
				// fall through
			case 5:
				*--pch = (char)((luChar & kByteMask) | kByteMark);
				luChar >>= kByteShift;
				// fall through
			case 4:
				*--pch = (char)((luChar & kByteMask) | kByteMark);
				luChar >>= kByteShift;
				// fall through
			case 3:
				*--pch = (char)((luChar & kByteMask) | kByteMark);
				luChar >>= kByteShift;
				// fall through
			case 2:
				*--pch = (char)((luChar & kByteMask) | kByteMark);
				luChar >>= kByteShift;
				// fall through
			case 1:
				*--pch = (char)(luChar | bFirstMark);
				break;
			default:
				Assert(false);		// can't happen!!
			}
		}

		if (cchDst < cchMaxDst)
		{
			CopyItems(prgchChar, rgchDst + cchDst, Min(cchChar, cchMaxDst - cchDst));
		}
		else
		{
			// REVIEW: should we somehow signal an error on overflowing the output buffer?
			ThrowHr(E_OUTOFMEMORY, StrUni(L"BUFFER OVERFLOW in ConvertUtf16ToXmlUtf8()").Chars());
		}
		cchDst += cchChar;
	}