summaryrefslogtreecommitdiffstats
path: root/comm/mailnews/db/mork/morkCellObject.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'comm/mailnews/db/mork/morkCellObject.cpp')
-rw-r--r--comm/mailnews/db/mork/morkCellObject.cpp453
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