diff options
Diffstat (limited to 'db/mork/src/morkCellObject.cpp')
-rw-r--r-- | db/mork/src/morkCellObject.cpp | 530 |
1 files changed, 530 insertions, 0 deletions
diff --git a/db/mork/src/morkCellObject.cpp b/db/mork/src/morkCellObject.cpp new file mode 100644 index 000000000..5310df07d --- /dev/null +++ b/db/mork/src/morkCellObject.cpp @@ -0,0 +1,530 @@ +/* -*- 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 + +//3456789_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(); + atom->GetYarn(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 ===== + + +//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 |