summaryrefslogtreecommitdiffstats
path: root/comm/mailnews/db/mork/morkRowObject.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'comm/mailnews/db/mork/morkRowObject.cpp')
-rw-r--r--comm/mailnews/db/mork/morkRowObject.cpp530
1 files changed, 530 insertions, 0 deletions
diff --git a/comm/mailnews/db/mork/morkRowObject.cpp b/comm/mailnews/db/mork/morkRowObject.cpp
new file mode 100644
index 0000000000..39844172b8
--- /dev/null
+++ b/comm/mailnews/db/mork/morkRowObject.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 _MORKROWOBJECT_
+# include "morkRowObject.h"
+#endif
+
+#ifndef _MORKENV_
+# include "morkEnv.h"
+#endif
+
+#ifndef _MORKSTORE_
+# include "morkStore.h"
+#endif
+
+#ifndef _MORKROWCELLCURSOR_
+# include "morkRowCellCursor.h"
+#endif
+
+#ifndef _MORKCELLOBJECT_
+# include "morkCellObject.h"
+#endif
+
+#ifndef _MORKROW_
+# include "morkRow.h"
+#endif
+
+// 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
+
+// ````` ````` ````` ````` `````
+// { ===== begin morkNode interface =====
+
+/*public virtual*/ void morkRowObject::CloseMorkNode(
+ morkEnv* ev) // CloseRowObject() only if open
+{
+ if (this->IsOpenNode()) {
+ this->MarkClosing();
+ this->CloseRowObject(ev);
+ this->MarkShut();
+ }
+}
+
+/*public virtual*/
+morkRowObject::~morkRowObject() // assert CloseRowObject() executed earlier
+{
+ CloseMorkNode(mMorkEnv);
+ MORK_ASSERT(this->IsShutNode());
+}
+
+/*public non-poly*/
+morkRowObject::morkRowObject(morkEnv* ev, const morkUsage& inUsage,
+ nsIMdbHeap* ioHeap, morkRow* ioRow,
+ morkStore* ioStore)
+ : morkObject(ev, inUsage, ioHeap, morkColor_kNone, (morkHandle*)0),
+ mRowObject_Row(0),
+ mRowObject_Store(0) {
+ if (ev->Good()) {
+ if (ioRow && ioStore) {
+ mRowObject_Row = ioRow;
+ mRowObject_Store =
+ ioStore; // morkRowObjects don't ref-cnt the owning store.
+
+ if (ev->Good()) mNode_Derived = morkDerived_kRowObject;
+ } else
+ ev->NilPointerError();
+ }
+}
+
+NS_IMPL_ISUPPORTS_INHERITED(morkRowObject, morkObject, nsIMdbRow)
+// { ===== begin nsIMdbCollection methods =====
+
+// { ----- begin attribute methods -----
+NS_IMETHODIMP
+morkRowObject::GetSeed(nsIMdbEnv* mev, mdb_seed* outSeed) {
+ nsresult outErr = NS_OK;
+ morkEnv* ev = morkEnv::FromMdbEnv(mev);
+ if (ev) {
+ *outSeed = (mdb_seed)mRowObject_Row->mRow_Seed;
+ outErr = ev->AsErr();
+ }
+ return outErr;
+}
+NS_IMETHODIMP
+morkRowObject::GetCount(nsIMdbEnv* mev, mdb_count* outCount) {
+ nsresult outErr = NS_OK;
+ morkEnv* ev = morkEnv::FromMdbEnv(mev);
+ if (ev) {
+ *outCount = (mdb_count)mRowObject_Row->mRow_Length;
+ outErr = ev->AsErr();
+ }
+ return outErr;
+}
+
+NS_IMETHODIMP
+morkRowObject::GetPort(nsIMdbEnv* mev, nsIMdbPort** acqPort) {
+ nsresult outErr = NS_OK;
+ nsIMdbPort* outPort = 0;
+ morkEnv* ev = morkEnv::FromMdbEnv(mev);
+ if (ev) {
+ morkRowSpace* rowSpace = mRowObject_Row->mRow_Space;
+ if (rowSpace && rowSpace->mSpace_Store) {
+ morkStore* store = mRowObject_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 cursor methods -----
+NS_IMETHODIMP
+morkRowObject::GetCursor( // make a cursor starting iter at inMemberPos
+ nsIMdbEnv* mev, // context
+ mdb_pos inMemberPos, // zero-based ordinal pos of member in collection
+ nsIMdbCursor** acqCursor) {
+ return this->GetRowCellCursor(mev, inMemberPos,
+ (nsIMdbRowCellCursor**)acqCursor);
+}
+// } ----- end cursor methods -----
+
+// { ----- begin ID methods -----
+NS_IMETHODIMP
+morkRowObject::GetOid(nsIMdbEnv* mev, mdbOid* outOid) {
+ *outOid = mRowObject_Row->mRow_Oid;
+ morkEnv* ev = morkEnv::FromMdbEnv(mev);
+ return (ev) ? ev->AsErr() : NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+morkRowObject::BecomeContent(nsIMdbEnv* mev, const mdbOid* inOid) {
+ NS_ASSERTION(false, "not implemented");
+ return NS_ERROR_NOT_IMPLEMENTED;
+ // remember row->MaybeDirtySpaceStoreAndRow();
+}
+// } ----- end ID methods -----
+
+// { ----- begin activity dropping methods -----
+NS_IMETHODIMP
+morkRowObject::DropActivity( // tell collection usage no longer expected
+ nsIMdbEnv* mev) {
+ NS_ASSERTION(false, "not implemented");
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+// } ----- end activity dropping methods -----
+
+// } ===== end nsIMdbCollection methods =====
+
+// { ===== begin nsIMdbRow methods =====
+
+// { ----- begin cursor methods -----
+NS_IMETHODIMP
+morkRowObject::GetRowCellCursor( // make a cursor starting iteration at
+ // inCellPos
+ nsIMdbEnv* mev, // context
+ mdb_pos inPos, // zero-based ordinal position of cell in row
+ nsIMdbRowCellCursor** acqCursor) {
+ nsresult outErr = NS_OK;
+ morkEnv* ev = morkEnv::FromMdbEnv(mev);
+ nsIMdbRowCellCursor* outCursor = 0;
+ if (ev) {
+ morkRowCellCursor* cursor = mRowObject_Row->NewRowCellCursor(ev, inPos);
+ if (cursor) {
+ if (ev->Good()) {
+ cursor->mCursor_Seed = (mork_seed)inPos;
+ outCursor = cursor;
+ NS_ADDREF(cursor);
+ }
+ }
+ outErr = ev->AsErr();
+ }
+ if (acqCursor) *acqCursor = outCursor;
+ return outErr;
+}
+// } ----- end cursor methods -----
+
+// { ----- begin column methods -----
+NS_IMETHODIMP
+morkRowObject::AddColumn( // make sure a particular column is inside row
+ nsIMdbEnv* mev, // context
+ mdb_column inColumn, // column to add
+ const mdbYarn* inYarn) {
+ nsresult outErr = NS_ERROR_FAILURE;
+ morkEnv* ev = morkEnv::FromMdbEnv(mev);
+ if (ev) {
+ if (mRowObject_Store && mRowObject_Row)
+ mRowObject_Row->AddColumn(ev, inColumn, inYarn, mRowObject_Store);
+
+ outErr = ev->AsErr();
+ }
+ return outErr;
+}
+
+NS_IMETHODIMP
+morkRowObject::CutColumn( // make sure a column is absent from the row
+ nsIMdbEnv* mev, // context
+ mdb_column inColumn) {
+ nsresult outErr = NS_ERROR_FAILURE;
+ morkEnv* ev = morkEnv::FromMdbEnv(mev);
+ if (ev) {
+ mRowObject_Row->CutColumn(ev, inColumn);
+ outErr = ev->AsErr();
+ }
+ return outErr;
+}
+
+NS_IMETHODIMP
+morkRowObject::CutAllColumns( // remove all columns from the row
+ nsIMdbEnv* mev) {
+ nsresult outErr = NS_OK;
+ morkEnv* ev = morkEnv::FromMdbEnv(mev);
+ if (ev) {
+ mRowObject_Row->CutAllColumns(ev);
+ outErr = ev->AsErr();
+ }
+ return outErr;
+}
+// } ----- end column methods -----
+
+// { ----- begin cell methods -----
+NS_IMETHODIMP
+morkRowObject::NewCell( // get cell for specified column, or add new one
+ nsIMdbEnv* mev, // context
+ mdb_column inColumn, // column to add
+ nsIMdbCell** acqCell) {
+ nsresult outErr = NS_OK;
+ morkEnv* ev = morkEnv::FromMdbEnv(mev);
+ if (ev) {
+ GetCell(mev, inColumn, acqCell);
+ if (!*acqCell) {
+ if (mRowObject_Store) {
+ mdbYarn yarn; // to pass empty yarn into morkRowObject::AddColumn()
+ yarn.mYarn_Buf = 0;
+ yarn.mYarn_Fill = 0;
+ yarn.mYarn_Size = 0;
+ yarn.mYarn_More = 0;
+ yarn.mYarn_Form = 0;
+ yarn.mYarn_Grow = 0;
+ AddColumn(ev, inColumn, &yarn);
+ GetCell(mev, inColumn, acqCell);
+ }
+ }
+
+ outErr = ev->AsErr();
+ }
+ return outErr;
+}
+
+NS_IMETHODIMP
+morkRowObject::AddCell( // copy a cell from another row to this row
+ nsIMdbEnv* mev, // context
+ const nsIMdbCell* inCell) {
+ nsresult outErr = NS_OK;
+ morkEnv* ev = morkEnv::FromMdbEnv(mev);
+ if (ev) {
+ morkCell* cell = 0;
+ morkCellObject* cellObj = (morkCellObject*)inCell;
+ if (cellObj->CanUseCell(mev, morkBool_kFalse, &outErr, &cell)) {
+ morkRow* cellRow = cellObj->mCellObject_Row;
+ if (cellRow) {
+ if (mRowObject_Row != cellRow) {
+ morkStore* store = mRowObject_Row->GetRowSpaceStore(ev);
+ morkStore* cellStore = cellRow->GetRowSpaceStore(ev);
+ if (store && cellStore) {
+ mork_column col = cell->GetColumn();
+ morkAtom* atom = cell->mCell_Atom;
+ mdbYarn yarn;
+ morkAtom::AliasYarn(atom, &yarn); // works even when atom is nil
+
+ if (store != cellStore) col = store->CopyToken(ev, col, cellStore);
+ if (ev->Good()) AddColumn(ev, col, &yarn);
+ } else
+ ev->NilPointerError();
+ }
+ } else
+ ev->NilPointerError();
+ }
+
+ outErr = ev->AsErr();
+ }
+ return outErr;
+}
+
+NS_IMETHODIMP
+morkRowObject::GetCell( // find a cell in this row
+ nsIMdbEnv* mev, // context
+ mdb_column inColumn, // column to find
+ nsIMdbCell** acqCell) {
+ nsresult outErr = NS_OK;
+ nsIMdbCell* outCell = 0;
+ morkEnv* ev = morkEnv::FromMdbEnv(mev);
+
+ if (ev) {
+ if (inColumn) {
+ mork_pos pos = 0;
+ morkCell* cell = mRowObject_Row->GetCell(ev, inColumn, &pos);
+ if (cell) {
+ outCell = mRowObject_Row->AcquireCellHandle(ev, cell, inColumn, pos);
+ }
+ } else
+ mRowObject_Row->ZeroColumnError(ev);
+
+ outErr = ev->AsErr();
+ }
+ if (acqCell) *acqCell = outCell;
+ return outErr;
+}
+
+NS_IMETHODIMP
+morkRowObject::EmptyAllCells( // make all cells in row empty of content
+ nsIMdbEnv* mev) {
+ nsresult outErr = NS_OK;
+ morkEnv* ev = morkEnv::FromMdbEnv(mev);
+ if (ev) {
+ EmptyAllCells(ev);
+ outErr = ev->AsErr();
+ }
+ return outErr;
+}
+// } ----- end cell methods -----
+
+// { ----- begin row methods -----
+NS_IMETHODIMP
+morkRowObject::AddRow( // add all cells in another row to this one
+ nsIMdbEnv* mev, // context
+ nsIMdbRow* ioSourceRow) {
+ nsresult outErr = NS_OK;
+ morkEnv* ev = morkEnv::FromMdbEnv(mev);
+ if (ev) {
+ morkRow* unsafeSource = (morkRow*)ioSourceRow; // unsafe cast
+ // if ( unsafeSource->CanUseRow(mev, morkBool_kFalse, &outErr, &source) )
+ { mRowObject_Row->AddRow(ev, unsafeSource); }
+ outErr = ev->AsErr();
+ }
+ return outErr;
+}
+
+NS_IMETHODIMP
+morkRowObject::SetRow( // make exact duplicate of another row
+ nsIMdbEnv* mev, // context
+ nsIMdbRow* ioSourceRow) {
+ nsresult outErr = NS_OK;
+ morkEnv* ev = morkEnv::FromMdbEnv(mev);
+ if (ev) {
+ morkRowObject* sourceObject = (morkRowObject*)ioSourceRow; // unsafe cast
+ morkRow* unsafeSource = sourceObject->mRowObject_Row;
+ // if ( unsafeSource->CanUseRow(mev, morkBool_kFalse, &outErr, &source) )
+ { mRowObject_Row->SetRow(ev, unsafeSource); }
+ outErr = ev->AsErr();
+ }
+ return outErr;
+}
+// } ----- end row methods -----
+
+// { ----- begin blob methods -----
+NS_IMETHODIMP
+morkRowObject::SetCellYarn( // synonym for AddColumn()
+ nsIMdbEnv* mev, // context
+ mdb_column inColumn, // column to add
+ const mdbYarn* inYarn) {
+ nsresult outErr = NS_OK;
+ morkEnv* ev = morkEnv::FromMdbEnv(mev);
+ if (ev) {
+ if (mRowObject_Store) AddColumn(ev, inColumn, inYarn);
+
+ outErr = ev->AsErr();
+ }
+ return outErr;
+}
+NS_IMETHODIMP
+morkRowObject::GetCellYarn(nsIMdbEnv* mev, // context
+ mdb_column inColumn, // column to read
+ mdbYarn* outYarn) // writes some yarn slots
+// copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form
+{
+ nsresult outErr = NS_OK;
+ morkEnv* ev = morkEnv::FromMdbEnv(mev);
+ if (ev) {
+ if (mRowObject_Store && mRowObject_Row) {
+ morkAtom* atom = mRowObject_Row->GetColumnAtom(ev, inColumn);
+ morkAtom::GetYarn(atom, outYarn);
+ }
+
+ outErr = ev->AsErr();
+ }
+ return outErr;
+}
+
+NS_IMETHODIMP
+morkRowObject::AliasCellYarn(nsIMdbEnv* mev, // context
+ mdb_column inColumn, // column to alias
+ mdbYarn* outYarn) // writes ALL yarn slots
+{
+ nsresult outErr = NS_OK;
+ morkEnv* ev = morkEnv::FromMdbEnv(mev);
+ if (ev) {
+ if (mRowObject_Store && mRowObject_Row) {
+ morkAtom* atom = mRowObject_Row->GetColumnAtom(ev, inColumn);
+ morkAtom::AliasYarn(atom, outYarn);
+ // note nil atom works and sets yarn correctly
+ }
+ outErr = ev->AsErr();
+ }
+ return outErr;
+}
+
+NS_IMETHODIMP
+morkRowObject::NextCellYarn(
+ nsIMdbEnv* mev, // iterative version of GetCellYarn()
+ mdb_column* ioColumn, // next column to read
+ mdbYarn* outYarn) // writes some yarn slots
+// copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form
+//
+// The ioColumn argument is an inout parameter which initially contains the
+// last column accessed and returns the next column corresponding to the
+// content read into the yarn. Callers should start with a zero column
+// value to say 'no previous column', which causes the first column to be
+// read. Then the value returned in ioColumn is perfect for the next call
+// to NextCellYarn(), since it will then be the previous column accessed.
+// Callers need only examine the column token returned to see which cell
+// in the row is being read into the yarn. When no more columns remain,
+// and the iteration has ended, ioColumn will return a zero token again.
+// So iterating over cells starts and ends with a zero column token.
+{
+ nsresult outErr = NS_OK;
+ morkEnv* ev = morkEnv::FromMdbEnv(mev);
+ if (ev) {
+ if (mRowObject_Store && mRowObject_Row)
+ mRowObject_Row->NextColumn(ev, ioColumn, outYarn);
+
+ outErr = ev->AsErr();
+ }
+ return outErr;
+}
+
+NS_IMETHODIMP
+morkRowObject::SeekCellYarn( // resembles nsIMdbRowCellCursor::SeekCell()
+ nsIMdbEnv* mev, // context
+ mdb_pos inPos, // position of cell in row sequence
+ mdb_column* outColumn, // column for this particular cell
+ mdbYarn* outYarn) // writes some yarn slots
+// copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form
+// Callers can pass nil for outYarn to indicate no interest in content, so
+// only the outColumn value is returned. NOTE to subclasses: you must be
+// able to ignore outYarn when the pointer is nil; please do not crash.
+
+{
+ nsresult outErr = NS_OK;
+ morkEnv* ev = morkEnv::FromMdbEnv(mev);
+ if (ev) {
+ if (mRowObject_Store && mRowObject_Row)
+ mRowObject_Row->SeekColumn(ev, inPos, outColumn, outYarn);
+
+ outErr = ev->AsErr();
+ }
+ return outErr;
+}
+
+// } ----- end blob methods -----
+
+// } ===== end nsIMdbRow methods =====
+
+/*public non-poly*/ void morkRowObject::CloseRowObject(
+ morkEnv* ev) // called by CloseMorkNode();
+{
+ if (this->IsNode()) {
+ morkRow* row = mRowObject_Row;
+ mRowObject_Row = 0;
+ this->CloseObject(ev);
+ this->MarkShut();
+
+ if (row) {
+ MORK_ASSERT(row->mRow_Object == this);
+ if (row->mRow_Object == this) {
+ row->mRow_Object = 0; // just nil this slot -- cut ref down below
+
+ mRowObject_Store = 0; // morkRowObjects don't ref-cnt the owning store.
+
+ this->CutWeakRef(
+ ev->AsMdbEnv()); // do last, because it might self destroy
+ }
+ }
+ } else
+ this->NonNodeError(ev);
+}
+
+// } ===== end morkNode methods =====
+// ````` ````` ````` ````` `````
+
+/*static*/ void morkRowObject::NonRowObjectTypeError(morkEnv* ev) {
+ ev->NewError("non morkRowObject");
+}
+
+/*static*/ void morkRowObject::NilRowError(morkEnv* ev) {
+ ev->NewError("nil mRowObject_Row");
+}
+
+/*static*/ void morkRowObject::NilStoreError(morkEnv* ev) {
+ ev->NewError("nil mRowObject_Store");
+}
+
+/*static*/ void morkRowObject::RowObjectRowNotSelfError(morkEnv* ev) {
+ ev->NewError("mRowObject_Row->mRow_Object != self");
+}
+
+nsIMdbRow* morkRowObject::AcquireRowHandle(morkEnv* ev) // mObject_Handle
+{
+ AddRef();
+ return this;
+}
+
+// 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789