diff options
Diffstat (limited to '')
-rw-r--r-- | comm/mailnews/db/mork/morkCellObject.cpp | 453 |
1 files changed, 453 insertions, 0 deletions
diff --git a/comm/mailnews/db/mork/morkCellObject.cpp b/comm/mailnews/db/mork/morkCellObject.cpp new file mode 100644 index 0000000000..7ad8402348 --- /dev/null +++ b/comm/mailnews/db/mork/morkCellObject.cpp @@ -0,0 +1,453 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef _MDB_ +# include "mdb.h" +#endif + +#ifndef _MORK_ +# include "mork.h" +#endif + +#ifndef _MORKNODE_ +# include "morkNode.h" +#endif + +#ifndef _MORKOBJECT_ +# include "morkObject.h" +#endif + +#ifndef _MORKENV_ +# include "morkEnv.h" +#endif + +#ifndef _MORKCELLOBJECT_ +# include "morkCellObject.h" +#endif + +#ifndef _MORKROWOBJECT_ +# include "morkRowObject.h" +#endif + +#ifndef _MORKROW_ +# include "morkRow.h" +#endif + +#ifndef _MORKCELL_ +# include "morkCell.h" +#endif + +#ifndef _MORKSTORE_ +# include "morkStore.h" +#endif + +// 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 + +// ````` ````` ````` ````` ````` +// { ===== begin morkNode interface ===== + +/*public virtual*/ void morkCellObject::CloseMorkNode( + morkEnv* ev) // CloseCellObject() only if open +{ + if (this->IsOpenNode()) { + this->MarkClosing(); + this->CloseCellObject(ev); + this->MarkShut(); + } +} + +/*public virtual*/ +morkCellObject::~morkCellObject() // assert CloseCellObject() executed earlier +{ + CloseMorkNode(mMorkEnv); + MORK_ASSERT(mCellObject_Row == 0); +} + +/*public non-poly*/ +morkCellObject::morkCellObject(morkEnv* ev, const morkUsage& inUsage, + nsIMdbHeap* ioHeap, morkRow* ioRow, + morkCell* ioCell, mork_column inCol, + mork_pos inPos) + : morkObject(ev, inUsage, ioHeap, morkColor_kNone, (morkHandle*)0), + mCellObject_RowObject(0), + mCellObject_Row(0), + mCellObject_Cell(0), + mCellObject_Col(inCol), + mCellObject_RowSeed(0), + mCellObject_Pos((mork_u2)inPos) { + if (ev->Good()) { + if (ioRow && ioCell) { + if (ioRow->IsRow()) { + morkStore* store = ioRow->GetRowSpaceStore(ev); + if (store) { + morkRowObject* rowObj = ioRow->AcquireRowObject(ev, store); + if (rowObj) { + mCellObject_Row = ioRow; + mCellObject_Cell = ioCell; + mCellObject_RowSeed = ioRow->mRow_Seed; + + // morkRowObject::SlotStrongRowObject(rowObj, ev, + // &mCellObject_RowObject); + + mCellObject_RowObject = rowObj; // assume control of strong ref + } + if (ev->Good()) mNode_Derived = morkDerived_kCellObject; + } + } else + ioRow->NonRowTypeError(ev); + } else + ev->NilPointerError(); + } +} + +NS_IMPL_ISUPPORTS_INHERITED(morkCellObject, morkObject, nsIMdbCell) + +/*public non-poly*/ void morkCellObject::CloseCellObject( + morkEnv* ev) // called by CloseMorkNode(); +{ + if (this->IsNode()) { + NS_RELEASE(mCellObject_RowObject); + mCellObject_Row = 0; + mCellObject_Cell = 0; + mCellObject_RowSeed = 0; + this->CloseObject(ev); + this->MarkShut(); + } else + this->NonNodeError(ev); +} + +// } ===== end morkNode methods ===== +// ````` ````` ````` ````` ````` + +mork_bool morkCellObject::ResyncWithRow(morkEnv* ev) { + morkRow* row = mCellObject_Row; + mork_pos pos = 0; + morkCell* cell = row->GetCell(ev, mCellObject_Col, &pos); + if (cell) { + mCellObject_Pos = (mork_u2)pos; + mCellObject_Cell = cell; + mCellObject_RowSeed = row->mRow_Seed; + } else { + mCellObject_Cell = 0; + this->MissingRowColumnError(ev); + } + return ev->Good(); +} + +morkAtom* morkCellObject::GetCellAtom(morkEnv* ev) const { + morkCell* cell = mCellObject_Cell; + if (cell) + return cell->GetAtom(); + else + this->NilCellError(ev); + + return (morkAtom*)0; +} + +/*static*/ void morkCellObject::WrongRowObjectRowError(morkEnv* ev) { + ev->NewError("mCellObject_Row != mCellObject_RowObject->mRowObject_Row"); +} + +/*static*/ void morkCellObject::NilRowError(morkEnv* ev) { + ev->NewError("nil mCellObject_Row"); +} + +/*static*/ void morkCellObject::NilRowObjectError(morkEnv* ev) { + ev->NewError("nil mCellObject_RowObject"); +} + +/*static*/ void morkCellObject::NilCellError(morkEnv* ev) { + ev->NewError("nil mCellObject_Cell"); +} + +/*static*/ void morkCellObject::NonCellObjectTypeError(morkEnv* ev) { + ev->NewError("non morkCellObject"); +} + +/*static*/ void morkCellObject::MissingRowColumnError(morkEnv* ev) { + ev->NewError("mCellObject_Col not in mCellObject_Row"); +} + +nsIMdbCell* morkCellObject::AcquireCellHandle(morkEnv* ev) { + nsIMdbCell* outCell = this; + NS_ADDREF(outCell); + return outCell; +} + +morkEnv* morkCellObject::CanUseCell(nsIMdbEnv* mev, mork_bool inMutable, + nsresult* outErr, morkCell** outCell) { + morkEnv* outEnv = 0; + morkCell* cell = 0; + morkEnv* ev = morkEnv::FromMdbEnv(mev); + if (ev) { + if (IsCellObject()) { + if (IsMutable() || !inMutable) { + morkRowObject* rowObj = mCellObject_RowObject; + if (rowObj) { + morkRow* row = mCellObject_Row; + if (row) { + if (rowObj->mRowObject_Row == row) { + mork_u2 oldSeed = mCellObject_RowSeed; + if (row->mRow_Seed == oldSeed || ResyncWithRow(ev)) { + cell = mCellObject_Cell; + if (cell) { + outEnv = ev; + } else + NilCellError(ev); + } + } else + WrongRowObjectRowError(ev); + } else + NilRowError(ev); + } else + NilRowObjectError(ev); + } else + NonMutableNodeError(ev); + } else + NonCellObjectTypeError(ev); + } + *outErr = ev->AsErr(); + MORK_ASSERT(outEnv); + *outCell = cell; + + return outEnv; +} + +// { ----- begin attribute methods ----- +NS_IMETHODIMP morkCellObject::SetBlob(nsIMdbEnv* /* mev */, + nsIMdbBlob* /* ioBlob */) { + NS_ASSERTION(false, "not implemented"); + return NS_ERROR_NOT_IMPLEMENTED; +} // reads inBlob slots + +// when inBlob is in the same suite, this might be fastest cell-to-cell + +NS_IMETHODIMP +morkCellObject::ClearBlob( // make empty (so content has zero length) + nsIMdbEnv* /* mev */) { + NS_ASSERTION(false, "not implemented"); + return NS_ERROR_NOT_IMPLEMENTED; + // remember row->MaybeDirtySpaceStoreAndRow(); +} +// clearing a yarn is like SetYarn() with empty yarn instance content + +NS_IMETHODIMP morkCellObject::GetBlobFill(nsIMdbEnv* mev, mdb_fill* outFill) +// Same value that would be put into mYarn_Fill, if one called GetYarn() +// with a yarn instance that had mYarn_Buf==nil and mYarn_Size==0. +{ + NS_ASSERTION(false, "not implemented"); + return NS_ERROR_NOT_IMPLEMENTED; +} // size of blob + +NS_IMETHODIMP morkCellObject::SetYarn(nsIMdbEnv* mev, const mdbYarn* inYarn) { + nsresult outErr = NS_OK; + morkCell* cell = 0; + morkEnv* ev = + this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue, &outErr, &cell); + if (ev) { + morkRow* row = mCellObject_Row; + if (row) { + morkStore* store = row->GetRowSpaceStore(ev); + if (store) { + cell->SetYarn(ev, inYarn, store); + if (row->IsRowClean() && store->mStore_CanDirty) + row->MaybeDirtySpaceStoreAndRow(); + } + } else + ev->NilPointerError(); + + outErr = ev->AsErr(); + } + + return outErr; +} // reads from yarn slots +// make this text object contain content from the yarn's buffer + +NS_IMETHODIMP morkCellObject::GetYarn(nsIMdbEnv* mev, mdbYarn* outYarn) { + nsresult outErr = NS_OK; + morkCell* cell = 0; + morkEnv* ev = + this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue, &outErr, &cell); + if (ev) { + morkAtom* atom = cell->GetAtom(); + morkAtom::GetYarn(atom, outYarn); + outErr = ev->AsErr(); + } + + return outErr; +} // writes some yarn slots +// copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form + +NS_IMETHODIMP morkCellObject::AliasYarn(nsIMdbEnv* mev, mdbYarn* outYarn) { + nsresult outErr = NS_OK; + morkCell* cell = 0; + morkEnv* ev = + this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue, &outErr, &cell); + if (ev) { + morkAtom* atom = cell->GetAtom(); + morkAtom::AliasYarn(atom, outYarn); + outErr = ev->AsErr(); + } + + return outErr; +} // writes ALL yarn slots + +// } ----- end attribute methods ----- + +// } ===== end nsIMdbBlob methods ===== + +// { ===== begin nsIMdbCell methods ===== + +// { ----- begin attribute methods ----- +NS_IMETHODIMP morkCellObject::SetColumn(nsIMdbEnv* mev, mdb_column inColumn) { + NS_ASSERTION(false, "not implemented"); + return NS_ERROR_NOT_IMPLEMENTED; + // remember row->MaybeDirtySpaceStoreAndRow(); +} + +NS_IMETHODIMP morkCellObject::GetColumn(nsIMdbEnv* mev, mdb_column* outColumn) { + nsresult outErr = NS_OK; + mdb_column col = 0; + morkCell* cell = 0; + morkEnv* ev = + this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue, &outErr, &cell); + if (ev) { + col = mCellObject_Col; + outErr = ev->AsErr(); + } + if (outColumn) *outColumn = col; + return outErr; +} + +NS_IMETHODIMP +morkCellObject::GetCellInfo( // all cell metainfo except actual content + nsIMdbEnv* mev, + mdb_column* outColumn, // the column in the containing row + mdb_fill* outBlobFill, // the size of text content in bytes + mdbOid* outChildOid, // oid of possible row or table child + mdb_bool* outIsRowChild) // nonzero if child, and a row child +// Checking all cell metainfo is a good way to avoid forcing a large cell +// in to memory when you don't actually want to use the content. +{ + NS_ASSERTION(false, "not implemented"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP morkCellObject::GetRow( + nsIMdbEnv* mev, // parent row for this cell + nsIMdbRow** acqRow) { + nsresult outErr = NS_OK; + nsIMdbRow* outRow = 0; + morkCell* cell = 0; + morkEnv* ev = + this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue, &outErr, &cell); + if (ev) { + outRow = mCellObject_RowObject->AcquireRowHandle(ev); + + outErr = ev->AsErr(); + } + if (acqRow) *acqRow = outRow; + return outErr; +} + +NS_IMETHODIMP morkCellObject::GetPort(nsIMdbEnv* mev, // port containing cell + nsIMdbPort** acqPort) { + nsresult outErr = NS_OK; + nsIMdbPort* outPort = 0; + morkCell* cell = 0; + morkEnv* ev = + this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue, &outErr, &cell); + if (ev) { + if (mCellObject_Row) { + morkStore* store = mCellObject_Row->GetRowSpaceStore(ev); + if (store) outPort = store->AcquireStoreHandle(ev); + } else + ev->NilPointerError(); + + outErr = ev->AsErr(); + } + if (acqPort) *acqPort = outPort; + return outErr; +} +// } ----- end attribute methods ----- + +// { ----- begin children methods ----- +NS_IMETHODIMP +morkCellObject::HasAnyChild( // does cell have a child instead of text? + nsIMdbEnv* mev, + mdbOid* outOid, // out id of row or table (or unbound if no child) + mdb_bool* outIsRow) // nonzero if child is a row (rather than a table) +{ + nsresult outErr = NS_OK; + mdb_bool isRow = morkBool_kFalse; + outOid->mOid_Scope = 0; + outOid->mOid_Id = morkId_kMinusOne; + morkCell* cell = 0; + morkEnv* ev = + this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue, &outErr, &cell); + if (ev) { + morkAtom* atom = GetCellAtom(ev); + if (atom) { + isRow = atom->IsRowOid(); + if (isRow || atom->IsTableOid()) + *outOid = ((morkOidAtom*)atom)->mOidAtom_Oid; + } + + outErr = ev->AsErr(); + } + if (outIsRow) *outIsRow = isRow; + + return outErr; +} + +NS_IMETHODIMP +morkCellObject::GetAnyChild( // access table of specific attribute + nsIMdbEnv* mev, // context + nsIMdbRow** acqRow, // child row (or null) + nsIMdbTable** acqTable) // child table (or null) +{ + NS_ASSERTION(false, "not implemented"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +morkCellObject::SetChildRow( // access table of specific attribute + nsIMdbEnv* mev, // context + nsIMdbRow* ioRow) { + NS_ASSERTION(false, "not implemented"); + return NS_ERROR_NOT_IMPLEMENTED; +} // inRow must be bound inside this same db port + +NS_IMETHODIMP morkCellObject::GetChildRow( // access row of specific attribute + nsIMdbEnv* mev, // context + nsIMdbRow** acqRow) // acquire child row (or nil if no child) +{ + NS_ASSERTION(false, "not implemented"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +morkCellObject::SetChildTable( // access table of specific attribute + nsIMdbEnv* mev, // context + nsIMdbTable* inTable) // table must be bound inside this same db port +{ + NS_ASSERTION(false, "not implemented"); + return NS_ERROR_NOT_IMPLEMENTED; + // remember row->MaybeDirtySpaceStoreAndRow(); +} + +NS_IMETHODIMP +morkCellObject::GetChildTable( // access table of specific attribute + nsIMdbEnv* mev, // context + nsIMdbTable** acqTable) // acquire child tabdle (or nil if no chil) +{ + NS_ASSERTION(false, "not implemented"); + return NS_ERROR_NOT_IMPLEMENTED; +} +// } ----- end children methods ----- + +// } ===== end nsIMdbCell methods ===== + +// 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 |