vector<string> SearchDatabase(const string& key, int col, int ret) { if (ret < -1 || col < -1) return vector<string>(); LoadDatabase(); vector<string> whole; int len = data.size(); for (pivot = 0; pivot < len; ++pivot) { vector<string> rec = ParseRecord(data[pivot]); if (ret >= 0) whole.push_back(rec[ret]); if (col >= 0 && key == rec[col]) { if (ret < 0) return rec; return vector<string>(1, rec[ret]); } } if (col == -1) return whole; return vector<string>(); }
// return CSV 中 record 个数,不包含 header。 // 如果解析失败,返回 -1 // CSV Record 不能超过 int 最大数 int CCsvParser::Parse(void (*RecordHandler)(std::vector<std::string>&, int)) { if ( !ParseRecord(header) ) { return -1; } int recordCount = 0; while( ParseRecord(recordCache) ) { recordCount++; RecordHandler(recordCache, recordCount); recordCache.clear(); } return recordCount; }
T ConfigFileReaderBase<T>::GetNextRecord() { std::string buffer; char buf[200]; fgets(buf, 200, m_pTheFile); buffer.append(buf); buffer.pop_back(); return ParseRecord(buffer); }
void OGRXPlaneNavReader::Read() { const char* pszLine = NULL; while( (pszLine = CPLReadLineL(fp)) != NULL ) { papszTokens = CSLTokenizeString(pszLine); nTokens = CSLCount(papszTokens); nLineNumber++; if (nTokens == 1 && strcmp(papszTokens[0], "99") == 0) { CSLDestroy(papszTokens); papszTokens = NULL; bEOF = true; return; } else if( nTokens == 0 || !assertMinCol(9) ) { CSLDestroy(papszTokens); papszTokens = NULL; continue; } const int nType = atoi(papszTokens[0]); if (!((nType >= NAVAID_NDB && nType <= NAVAID_IM) || nType == NAVAID_DME_COLOC || nType == NAVAID_DME_STANDALONE)) { CPLDebug("XPlane", "Line %d : bad feature code '%s'", nLineNumber, papszTokens[0]); CSLDestroy(papszTokens); papszTokens = NULL; continue; } ParseRecord(nType); CSLDestroy(papszTokens); papszTokens = NULL; if( poInterestLayer && !poInterestLayer->IsEmpty() ) return; } papszTokens = NULL; bEOF = true; }
void OGRXPlaneFixReader::Read() { const char* pszLine; while((pszLine = CPLReadLine(fp)) != NULL) { papszTokens = CSLTokenizeString(pszLine); nTokens = CSLCount(papszTokens); nLineNumber ++; if (nTokens == 1 && strcmp(papszTokens[0], "99") == 0) { CSLDestroy(papszTokens); papszTokens = NULL; bEOF = TRUE; return; } else if (nTokens == 0 || assertMinCol(3) == FALSE) { CSLDestroy(papszTokens); papszTokens = NULL; continue; } ParseRecord(); CSLDestroy(papszTokens); papszTokens = NULL; if (poInterestLayer && poInterestLayer->IsEmpty() == FALSE) return; } papszTokens = NULL; bEOF = TRUE; }
vector<string> CurrentInDatabase() { if (pivot < 0 || pivot >= (int)data.size()) return vector<string>(); return ParseRecord(data[pivot]); }
void ExhTestCPEngine::ExhTestProperties() { HRESULT hr; // REVIEW LarsH: how do we pass in the location of the UnicodeData.txt file as // a parameter? Env var? StrAnsi staDataFile = L"d:\\lars\\Unicode\\UnicodeData.txt"; FILE *pFileIn = fopen(staDataFile, "r"); if (!pFileIn) FailureFormat("Unable to open Unicode data file %s", staDataFile); CodePtData cpdCurrent, cpdNext; cpdNext.chCodeValue = -1; // uninitialized // TODO LarsH: We should test through 0x10FFFF, but currently there are // some problems with higher characters which have been postponed, // so in order to avoid a humungous error log we'll stick with the first page for now. // Raid #31 #define JUST_FIRST_PAGE #ifdef JUST_FIRST_PAGE for (int ch = 0; ch <= 0xFFFF; ch++) #else for (int ch = 0; ch <= 0x10FFFF; ch++) #endif { if (! (ch % 0x1000)) LogFormat("%x:\n", ch); // Read in the next record unless we've already got this data if (cpdNext.chCodeValue < ch) ParseRecord(pFileIn, &cpdNext); // This is NOT an "else"; it may happen in addition to the above. if (cpdNext.chCodeValue == ch) { // got the right record; copy it over cpdCurrent.chCodeValue = ch; strcpy(cpdCurrent.szCategory, cpdNext.szCategory); wcscpy(cpdCurrent.szwName, cpdNext.szwName); cpdCurrent.nNumericValue = cpdNext.nNumericValue; cpdCurrent.nCombiningClass = cpdNext.nCombiningClass; wcscpy(cpdCurrent.szwDecomposition, cpdNext.szwDecomposition); cpdCurrent.chUpper = cpdNext.chUpper; cpdCurrent.chLower = cpdNext.chLower; cpdCurrent.chTitle = cpdNext.chTitle; } // Treat special ranges specially: if (ch >= 0x3400 && ch <= 0x4db5 || ch >= 0x4e00 && ch <= 0x9fa5) { // CJK Ideographs (Extension A and other) // Most data is same as previous, so don't need to load; // but must set names algorithmically. swprintf(cpdCurrent.szwName, L"CJK UNIFIED IDEOGRAPH-%X", ch); } else if (ch >= 0xac00 && ch <= 0xd7a3) { // Hangul Syllables // Data for 0xAC00 is loaded, and applies to all others, except // name and decomp. HangulDecomposition(ch, cpdCurrent.szwDecomposition); HangulName(cpdCurrent.szwDecomposition, cpdCurrent.szwName); } else if (ch >= 0xd800 && // ch <= 0xdb7f || ch >= 0xdb80 && ch <= 0xdbff || // ch >= 0xdc00 && ch <= 0xdfff || ch >= 0xe000 ch <= 0xf8ff) { // Consecutive ranges: Non-Private Use High Surrogates, // Private Use High Surrogates, Low Surrogates, Private Use Area. // All of these are nameless (UnicodeData File Format v3.0.0) // TODO LarsH: change all this before closing Raid #24. cpdCurrent.szwName[0] = '\0'; } else if (ch == 0xfffe || ch == 0xffff || // explicitly "not Unicode chars" cpdNext.chCodeValue > ch || (cpdNext.chCodeValue < ch && feof(pFileIn))) { // Not assigned in the data file. cpdCurrent.chCodeValue = ch; cpdCurrent.szwName[0] = '\0'; strcpy(cpdCurrent.szCategory, "Cn"); cpdCurrent.nCombiningClass = 0; // Must distinguish between lack of a NumericValue and a zero NumericValue. cpdCurrent.nNumericValue = -1; cpdCurrent.szwDecomposition[0] = '\0'; // Zero is not an anycase equivalent of any character. cpdCurrent.chLower = cpdCurrent.chUpper = cpdCurrent.chTitle = ch; } // ** If looking for a character with a specific combination of properties, // ** you can test it here. This would be better done in SQL. // if (cpdCurrent.szCategory[0] != 'L' && cpdCurrent.chUpper > 0) // LogFormat("*** U+%x fulfills conditions\n"); // continue; // skip all the usual tests if desired // Make sure the property interface methods get the same data. LgGeneralCharCategory cc = ParseCC(cpdCurrent.szCategory); CheckCat(ch, cc); ComBool fLet, fPun, fNum, fSep, fSym, fMar, fOth, fAll; #define CheckBoolProp(prop, var, index, letter) \ { \ hr = m_qpropeng->get_##prop(ch, &var); \ WarnHr(hr); \ if (var != (cpdCurrent.szCategory[index] == letter)) \ FailureFormat("get_" #prop "(U+%x) gave wrong answer", ch); \ } CheckBoolProp(IsLetter, fLet, 0, 'L'); CheckBoolProp(IsPunctuation, fPun, 0, 'P'); CheckBoolProp(IsNumber, fNum, 0, 'N'); CheckBoolProp(IsSeparator, fSep, 0, 'Z'); CheckBoolProp(IsSymbol, fSym, 0, 'S'); CheckBoolProp(IsMark, fMar, 0, 'M'); CheckBoolProp(IsOther, fOth, 0, 'C'); // REVIEW LarsH: is int(ComBool) guaranteed to be 1 if true? I think so. int nCat; if ((nCat = fLet + fPun + fNum + fSep + fSym + fMar + fOth) != 1) FailureFormat("Codepoint U+%x is in %d categories instead of one.", ch, nCat); if (fLet) { ComBool fUpp, fLow, fTit, fMod, fOth; CheckBoolProp(IsUpper, fUpp, 1, 'u'); CheckBoolProp(IsLower, fLow, 1, 'l'); CheckBoolProp(IsTitle, fTit, 1, 't'); CheckBoolProp(IsModifier, fMod, 1, 'm'); CheckBoolProp(IsOtherLetter, fOth, 1, 'o'); if ((nCat = fUpp + fLow + fTit + fMod + fOth) != 1) FailureFormat("Letter U+%x is in %d subcategories instead of one.", ch, nCat); } else { // All should be false. CheckBoolProp(IsUpper, fAll, 0, 'L'); CheckBoolProp(IsLower, fAll, 0, 'L'); CheckBoolProp(IsTitle, fAll, 0, 'L'); CheckBoolProp(IsModifier, fAll, 0, 'L'); CheckBoolProp(IsOtherLetter, fAll, 0, 'L'); } if (fPun) { ComBool fOpe, fClo, fMed; CheckBoolProp(IsOpen, fOpe, 1, 's'); CheckBoolProp(IsClose, fOpe, 1, 'e'); CheckBoolProp(IsWordMedial, fOpe, 1, 'c'); // TODO LarsH: update this if definition in Language.idh changes, e.g. // if the above methods come to be true for Pd, Pi, Pf } else { CheckBoolProp(IsOpen, fAll, 0, 'P'); CheckBoolProp(IsClose, fAll, 0, 'P'); CheckBoolProp(IsWordMedial, fAll, 0, 'P'); } // IsControl should return true if category is Cc, false otherwise: CheckBoolProp(IsControl, fAll, 1, (cpdCurrent.szCategory[0] == 'C' ? 'c' : 0)); #undef CheckBoolProp #define IsLetter() (cpdCurrent.szCategory[0] == 'L') #define IsUpper() (cpdCurrent.szCategory[1] == 'u') #define IsLower() (cpdCurrent.szCategory[1] == 'l') #define IsTitle() (cpdCurrent.szCategory[1] == 't') // We must check IsLetter() etc. because the docs say, if it's not Lu/Ll/Tt, ToUpper() etc. // don't do case conversion, even if the Unicode database gives a conversion. int chUpper = -1, chLower = -1, chTitle = -1; // TODO LarsH: some of these should check different locales // if such data exists in SpecialCasing.txt hr = m_qpropeng->get_ToUpperCh(ch, &chUpper); if (FAILED(hr)) FailureFormat("get_ToUpperCh(0x%x) gave result %s", ch, AsciiHresult(hr)); int chUExp = (IsLetter() && (IsLower() || IsTitle()) && cpdCurrent.chUpper) ? cpdCurrent.chUpper : ch; if (chUpper != chUExp) { FailureFormat("get_ToUpperCh(0x%x {%s}) returned 0x%x instead of 0x%x", ch, cpdCurrent.szCategory, chUpper, chUExp); } hr = m_qpropeng->get_ToLowerCh(ch, &chLower); if (FAILED(hr)) FailureFormat("get_ToLowerCh(0x%x) gave result %s", ch, AsciiHresult(hr)); int chLExp = (IsLetter() && (IsUpper() || IsTitle()) && cpdCurrent.chLower) ? cpdCurrent.chLower : ch; if (chLower != chLExp) { FailureFormat("get_ToLowerCh(0x%x {%s}) returned 0x%x instead of 0x%x", ch, cpdCurrent.szCategory, chLower, chLExp); } hr = m_qpropeng->get_ToTitleCh(ch, &chTitle); if (FAILED(hr)) FailureFormat("get_ToTitleCh(0x%x) gave result %s", ch, AsciiHresult(hr)); #define FIXED_BUG_198 // just for now #ifdef FIXED_BUG_198 int chTExp = (IsLetter() && (IsUpper() || IsLower())) ? (cpdCurrent.chTitle ? cpdCurrent.chTitle : cpdCurrent.chUpper ? cpdCurrent.chUpper : ch) : ch; // ToTitleCh() returns the uppercase if there is no titlecase value defined if (chTitle != chTExp) { FailureFormat("get_ToTitleCh(0x%x {%s}) returned 0x%x instead of 0x%x", ch, cpdCurrent.szCategory, chTitle, chTExp); } #endif // FIXED_BUG_198 // TODO LarsH: test get_ToLower, etc. (BSTR functions) // These should take into account any special casing (SpecialCasing.txt), by testing // different locales (esp. Turkish) and contexts (FINAL/NON_FINAL, MODERN/NON_MODERN). wchar pwz[2]; pwz[0] = (wchar)ch; pwz[1] = '\0'; SmartBstr sbstrFrom(pwz), sbstrTo = L"fish"; // This one properly gives a warning if ch is half of a surrogate pair. if (ch >= 0xd800 && ch <= 0xdfff) // half a surrogate pair { IgnoreWarnings iw; hr = m_qpropeng->ToLower(sbstrFrom, &sbstrTo); TestFailZero(sbstrTo, "ToLower"); if (SUCCEEDED(hr)) FailureFormat("ToLower with 0x%x (half a surrogate pair) should have failed", ch); } else { hr = m_qpropeng->ToLower(sbstrFrom, &sbstrTo); TestFailZero(sbstrTo, "ToLower"); WarnHr(hr); // TODO LarsH: check that the return value from get_ToLower is correct // TODO LarsH: use smart bstrs where possible } // TODO LarsH: test get_ToLowerRgch, etc. (Rgch functions) // TODO LarsH: test IsUserDefinedClass(). Right now there is no way to define // classes, so this will always return false. ComBool fRet; hr = m_qpropeng->get_IsUserDefinedClass(ch, 'A', &fRet); WarnHr(hr); if (fRet) FailureFormat("Character U+%x is a member of class 'A'??", ch); // TODO LarsH: test SoundAlikeKey // REVIEW LarsH: is this bstr causing a memory leak on every iteration of ch? SmartBstr sbstr = L"foo"; // TODO LarsH: Remove this kludge once get_CharacterName(Hangul) is working. if (ch >= 0xac00 && ch <= 0xd7a3) goto skipHangul; hr = m_qpropeng->get_CharacterName(ch, &sbstr); TestFailZero(sbstr, "get_CharacterName"); if (FAILED(hr)) FailureFormat("get_CharacterName(U+%x) failed", ch); else if ( #ifndef FIXED_BUG_24 !(ch >= 0xd800 && ch <= 0xf8ff) && #endif wcscmp(cpdCurrent.szwName, sbstr)) { FailureFormat(L"get_CharacterName(U+%x) returned \"%s\" instead of \"%s\".", ch, sbstr, cpdCurrent.szwName); } // if (sbstr) // SysFreeString(sbstr); #ifdef FIXED_BUG_125 sbstr = L"foo"; hr = m_qpropeng->get_Decomposition(ch, &sbstr); TestFailZero(sbstr, "get_Decomposition"); if (FAILED(hr)) FailureFormat("get_Decomposition(U+%x) failed", ch); // REVIEW LarsH: Does wcscmp understand NULL sbstrs? Apparently... else if (sbstr ? wcscmp(cpdCurrent.szwDecomposition, sbstr) : cpdCurrent.szwDecomposition[0]) { FailureFormat("Got wrong decomposition for U+%x", ch); } // if (sbstr) // SysFreeString(bstr); #endif // FIXED_BUG_125 sbstr = NULL; // TODO LarsH: test DecompositionRgch // That will probably require a separate pass through the whole UnicodeData // file to build up a hash table or sthg... skipHangul: int nNumericValue; { IgnoreWarnings iw; hr = m_qpropeng->get_NumericValue(ch, &nNumericValue); } if (fNum && (cc == kccNd || cc == kccNl || cc == kccNo) && cpdCurrent.nNumericValue > -1) { if (FAILED(hr)) FailureFormat("get_NumericValue(U+%x) failed with hr=%s", ch, AsciiHresult(hr)); else if (nNumericValue != cpdCurrent.nNumericValue) { FailureFormat("get_NumericValue(U+%x) returned %d instead of %d", ch, nNumericValue, cpdCurrent.nNumericValue); } } else if (hr != E_UNEXPECTED) { FailureFormat("get_NumericValue(U+%x {%s}) gave result %s instead of E_UNEXPECTED", ch, cpdCurrent.szCategory, AsciiHresult(hr)); } #define FIXED_BUG_18 1 // Seems to be fixed now. #ifdef FIXED_BUG_18 int nCombClass; hr = m_qpropeng->get_CombiningClass(ch, &nCombClass); WarnHr(hr); if (nCombClass != cpdCurrent.nCombiningClass) { FailureFormat("get_CombiningClass(U+%x) gave %d instead of %d", ch, nCombClass, cpdCurrent.nCombiningClass); } #endif // TODO LarsH: test everything else // TODO LarsH: test get_Comment // TODO LarsH: test GetLineBreakProps if not obsolete // TODO LarsH: test GetLineBreakStatus if not obsolete } }