void c4_FormatS::Set(int index_, const c4_Bytes &buf_) { int m = buf_.Size(); if (--m >= 0) { d4_assert(buf_.Contents()[m] == 0); if (m == 0) { SetOne(index_, c4_Bytes()); // don't store data for empty strings return ; } } SetOne(index_, buf_); }
inline const MonomLex& MonomLex::operator=(const MonomLex& anotherMonom) { if (this == &anotherMonom) { return *this; } if (!anotherMonom.ListHead) { SetOne(); } else { TotalDegree = anotherMonom.TotalDegree; VarsListNode *iteratorAnother = anotherMonom.ListHead, **iterator = &ListHead; while (*iterator && iteratorAnother) { (*iterator)->Value = iteratorAnother->Value; iterator = &((*iterator)->Next); iteratorAnother = iteratorAnother->Next; } if (*iterator) { VarsListNode *nodeToDelete = (*iterator)->Next; *iterator = 0; while (nodeToDelete) { iteratorAnother = nodeToDelete; nodeToDelete = nodeToDelete->Next; delete iteratorAnother; } } else while (iteratorAnother) { *iterator = new VarsListNode(); (*iterator)->Value = iteratorAnother->Value; iterator = &((*iterator)->Next); iteratorAnother = iteratorAnother->Next; } } return *this; }
inline void MonomLex::SetQuotientOf(const MonomLex& monomA, const MonomLex& monomB) { SetOne(); VarsListNode **iterator = &ListHead, *iteratorA = monomA.ListHead, *iteratorB = monomB.ListHead; while (iteratorA && iteratorB) { if (iteratorA->Value == iteratorB->Value) { iteratorA = iteratorA->Next; iteratorB = iteratorB->Next; } else { ++TotalDegree; *iterator = new VarsListNode(); (*iterator)->Value = iteratorA->Value; iterator = &((*iterator)->Next); if (iteratorA->Value < iteratorB->Value) { iteratorA = iteratorA->Next; } } } while (iteratorA) { ++TotalDegree; *iterator = new VarsListNode(); (*iterator)->Value = iteratorA->Value; iterator = &((*iterator)->Next); iteratorA = iteratorA->Next; } }
inline MonomLex::~MonomLex() { SetOne(); }
void c4_FormatB::Commit(c4_SaveContext &ar_) { int rows = _memos.GetSize(); d4_assert(rows > 0); bool full = _recalc || ar_.Serializing(); if (!full) for (int i = 0; i < rows; ++i) { c4_Column *col = (c4_Column*)_memos.GetAt(i); if (col != 0) { full = true; break; } } d4_assert(_recalc || _sizeCol.RowCount() == rows); if (full) { _memoCol.SetBuffer(0); _sizeCol.SetBuffer(0); _sizeCol.SetAccessWidth(0); _sizeCol.SetRowCount(rows); int skip = 0; c4_Column *saved = ar_.SetWalkBuffer(&_memoCol); for (int r = 0; r < rows; ++r) { ++skip; t4_i32 start; c4_Column *col; int len = ItemLenOffCol(r, start, col); bool oldMemo = col != &_data; bool newMemo = ShouldBeMemo(len); if (!oldMemo && newMemo) { col = GetNthMemoCol(r, true); d4_assert(col != &_data); //? start = 0; } c4_Bytes temp; if (newMemo) { // it now is a memo, inlined data will be empty ar_.StoreValue(skip - 1); skip = 0; ar_.CommitColumn(*col); } else if (!oldMemo) { // it was no memo, done if it hasn't become one _sizeCol.SetInt(r, len); continue; } else { // it was a memo, but it no longer is d4_assert(start == 0); if (len > 0) { _sizeCol.SetInt(r, len); col->FetchBytes(start, len, temp, true); delete (c4_Column*)_memos.GetAt(r); // 28-11-2001: fix mem leak _memos.SetAt(r, 0); // 02-11-2001: fix for use after commit } } SetOne(r, temp, true); // bypass current memo pointer } ar_.SetWalkBuffer(saved); } ar_.CommitColumn(_data); if (_data.ColSize() > 0) { _sizeCol.FixSize(true); ar_.CommitColumn(_sizeCol); //_sizeCol.FixSize(false); } ar_.CommitColumn(_memoCol); // need a way to find out when the data has been committed (on 2nd pass) // both _sizeCol and _memoCol will be clean again when it has // but be careful because dirty flag is only useful if size is nonzero if (_recalc && !ar_.Serializing()) _recalc = _sizeCol.ColSize() > 0 && _sizeCol.IsDirty() || _memoCol.ColSize() > 0 && _memoCol.IsDirty(); }
void c4_FormatB::Set(int index_, const c4_Bytes &buf_) { SetOne(index_, buf_); }
void c4_FormatB::OldDefine(char type_, c4_Persist &pers_) { int rows = Owner().NumRows(); c4_ColOfInts sizes(_data.Persist()); if (type_ == 'M') { InitOffsets(sizes); c4_ColOfInts szVec(_data.Persist()); pers_.FetchOldLocation(szVec); szVec.SetRowCount(rows); c4_ColOfInts posVec(_data.Persist()); pers_.FetchOldLocation(posVec); posVec.SetRowCount(rows); for (int r = 0; r < rows; ++r) { t4_i32 sz = szVec.GetInt(r); if (sz > 0) { c4_Column *mc = d4_new c4_Column(_data.Persist()); d4_assert(mc != 0); _memos.SetAt(r, mc); mc->SetLocation(posVec.GetInt(r), sz); } } } else { pers_.FetchOldLocation(_data); if (type_ == 'B') { pers_.FetchOldLocation(sizes); #if !q4_OLD_IS_ALWAYS_V2 // WARNING - HUGE HACK AHEAD - THIS IS NOT 100% FULLPROOF! // // The above is correct for MK versions 2.0 and up, but *NOT* // for MK 1.8.6 datafiles, which store sizes first (OUCH!!!). // This means that there is not a 100% safe way to auto-convert // both 1.8.6 and 2.0 files - since there is no way to detect // unambiguously which version a datafile is. All we can do, // is to carefully check both vectors, and *hope* that only one // of them is valid as sizes vector. This problem applies to // the 'B' (bytes) property type only, and only pre 2.0 files. // // To build a version which *always* converts assuming 1.8.6, // add flag "-Dq4_OLD_IS_PRE_V2" to the compiler command line. // Conversely, "-Dq4_OLD_IS_ALWAYS_V2" forces 2.0 conversion. if (rows > 0) { t4_i32 s1 = sizes.ColSize(); t4_i32 s2 = _data.ColSize(); #if !q4_OLD_IS_PRE_V2 // if the size vector is clearly impossible, swap vectors bool fix = c4_ColOfInts::CalcAccessWidth(rows, s1) < 0; // if the other vector might be valid as well, check further if (!fix && c4_ColOfInts::CalcAccessWidth(rows, s2) >= 0) { sizes.SetRowCount(rows); t4_i32 total = 0; for (int i = 0; i < rows; ++i) { t4_i32 w = sizes.GetInt(i); if (w < 0 || total > s2) { total = - 1; break; } total += w; } // if the sizes don't add up, swap vectors fix = total != s2; } if (fix) #endif { t4_i32 p1 = sizes.Position(); t4_i32 p2 = _data.Position(); _data.SetLocation(p1, s1); sizes.SetLocation(p2, s2); } } #endif InitOffsets(sizes); } else { d4_assert(type_ == 'S'); sizes.SetRowCount(rows); t4_i32 pos = 0; t4_i32 lastEnd = 0; int k = 0; c4_ColIter iter(_data, 0, _data.ColSize()); while (iter.Next()) { const t4_byte *p = iter.BufLoad(); for (int j = 0; j < iter.BufLen(); ++j) if (!p[j]) { sizes.SetInt(k++, pos + j + 1-lastEnd); lastEnd = pos + j + 1; } pos += iter.BufLen(); } d4_assert(pos == _data.ColSize()); if (lastEnd < pos) { // last entry had no zero byte _data.InsertData(pos++, 1, true); sizes.SetInt(k, pos - lastEnd); } InitOffsets(sizes); // get rid of entries with just a null byte for (int r = 0; r < rows; ++r) if (c4_FormatB::ItemSize(r) == 1) SetOne(r, c4_Bytes()); } } }