/*---------------------------------------------------------------------------------------------- Load the data from the given file into an empty window. ----------------------------------------------------------------------------------------------*/ void WpDa::LoadIntoEmpty(StrAnsi staFileName, WpChildWnd * pwcw) { Assert(staFileName != ""); int ctss; CheckHr(get_VecSize(1, kflidStText_Paragraphs, &ctss)); Assert(ctss <= 1); Vector<StrUni> vstu; ReadTextFromFile(staFileName, vstu); HVO * prghvoPara = NewObj HVO[vstu.Size()]; for (int istu = 0; istu < vstu.Size(); istu++) prghvoPara[istu] = istu + 2; CacheVecProp(1, kflidStText_Paragraphs, prghvoPara, vstu.Size()); ITsStrFactoryPtr qtsf; qtsf.CreateInstance(CLSID_TsStrFactory); int enc = 100; // replace by the right number when we figure out what it is for (istu = 0; istu < vstu.Size(); istu++) { StrUni stuPara = vstu[istu]; ITsStringPtr qtss; CheckHr(qtsf->MakeStringRgch(stuPara.Chars(), stuPara.Length(), enc, &qtss)); CacheStringProp(istu + 2, kflidStTxtPara_Contents, qtss); } ITsPropsBldrPtr qtpb; qtpb.CreateInstance(CLSID_TsPropsBldr); StrUni stuNormal = L"Normal"; CheckHr(qtpb->SetStrPropValue(kspNamedStyle, stuNormal.Bstr())); delete[] prghvoPara; pwcw->ChangeNumberOfStrings(vstu.Size()); }
/*---------------------------------------------------------------------------------------------- Initialize the data from the given file, or create a new empty string. ----------------------------------------------------------------------------------------------*/ void WpDa::InitNew(StrAnsi staFileName) { if (staFileName == "") { InitNewEmpty(); return; } Vector<StrUni> vstu; ReadTextFromFile(staFileName, vstu); HVO * prghvoPara = NewObj HVO[vstu.Size()]; for (int istu = 0; istu < vstu.Size(); istu++) prghvoPara[istu] = istu + 2; CacheVecProp(1, kflidStText_Paragraphs, prghvoPara, vstu.Size()); ITsStrFactoryPtr qtsf; qtsf.CreateInstance(CLSID_TsStrFactory); int enc = 100; // replace by the right number when we figure out what it is for (istu = 0; istu < vstu.Size(); istu++) { StrUni stuPara = vstu[istu]; ITsStringPtr qtss; CheckHr(qtsf->MakeStringRgch(stuPara.Chars(), stuPara.Length(), enc, &qtss)); CacheStringProp(istu + 2, kflidStTxtPara_Contents, qtss); } ITsPropsBldrPtr qtpb; qtpb.CreateInstance(CLSID_TsPropsBldr); StrUni stuNormal = L"Normal"; CheckHr(qtpb->SetStrPropValue(kspNamedStyle,stuNormal.Bstr())); delete[] prghvoPara; }
/*---------------------------------------------------------------------------------------------- Initialize an empty document. It has a document object (always ID 1!) and one paragraph containing (implicitly) an empty string. Style is set to Normal Review SharonC(JohnT): what encoding should the empty string have?? ----------------------------------------------------------------------------------------------*/ void WpDa::InitNewEmpty() { HVO hvoPara = 2; CacheVecProp(1, kflidStText_Paragraphs, &hvoPara, 1); ITsStrFactoryPtr qtsf; qtsf.CreateInstance(CLSID_TsStrFactory); ITsStringPtr qtss; int enc = 100; CheckHr(qtsf->MakeStringRgch(L"", 0, enc, &qtss)); CacheStringProp(hvoPara, kflidStTxtPara_Contents, qtss); ITsPropsBldrPtr qtpb; qtpb.CreateInstance(CLSID_TsPropsBldr); StrUni stuNormal = L"Normal"; CheckHr(qtpb->SetStrPropValue(kspNamedStyle, stuNormal.Bstr())); }
/*---------------------------------------------------------------------------------------------- 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()); } }