Source code

Revision control

Copy as Markdown

Other Tools

/* -*- 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