1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 #ifndef _MDB_
7 # include "mdb.h"
8 #endif
9
10 #ifndef _MORK_
11 # include "mork.h"
12 #endif
13
14 #ifndef _MORKNODE_
15 # include "morkNode.h"
16 #endif
17
18 #ifndef _MORKOBJECT_
19 # include "morkObject.h"
20 #endif
21
22 #ifndef _MORKENV_
23 # include "morkEnv.h"
24 #endif
25
26 #ifndef _MORKCELLOBJECT_
27 # include "morkCellObject.h"
28 #endif
29
30 #ifndef _MORKROWOBJECT_
31 # include "morkRowObject.h"
32 #endif
33
34 #ifndef _MORKROW_
35 # include "morkRow.h"
36 #endif
37
38 #ifndef _MORKCELL_
39 # include "morkCell.h"
40 #endif
41
42 #ifndef _MORKSTORE_
43 # include "morkStore.h"
44 #endif
45
46 // 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
47
48 // ````` ````` ````` ````` `````
49 // { ===== begin morkNode interface =====
50
CloseMorkNode(morkEnv * ev)51 /*public virtual*/ void morkCellObject::CloseMorkNode(
52 morkEnv* ev) // CloseCellObject() only if open
53 {
54 if (this->IsOpenNode()) {
55 this->MarkClosing();
56 this->CloseCellObject(ev);
57 this->MarkShut();
58 }
59 }
60
61 /*public virtual*/
~morkCellObject()62 morkCellObject::~morkCellObject() // assert CloseCellObject() executed earlier
63 {
64 CloseMorkNode(mMorkEnv);
65 MORK_ASSERT(mCellObject_Row == 0);
66 }
67
68 /*public non-poly*/
morkCellObject(morkEnv * ev,const morkUsage & inUsage,nsIMdbHeap * ioHeap,morkRow * ioRow,morkCell * ioCell,mork_column inCol,mork_pos inPos)69 morkCellObject::morkCellObject(morkEnv* ev, const morkUsage& inUsage,
70 nsIMdbHeap* ioHeap, morkRow* ioRow,
71 morkCell* ioCell, mork_column inCol,
72 mork_pos inPos)
73 : morkObject(ev, inUsage, ioHeap, morkColor_kNone, (morkHandle*)0),
74 mCellObject_RowObject(0),
75 mCellObject_Row(0),
76 mCellObject_Cell(0),
77 mCellObject_Col(inCol),
78 mCellObject_RowSeed(0),
79 mCellObject_Pos((mork_u2)inPos) {
80 if (ev->Good()) {
81 if (ioRow && ioCell) {
82 if (ioRow->IsRow()) {
83 morkStore* store = ioRow->GetRowSpaceStore(ev);
84 if (store) {
85 morkRowObject* rowObj = ioRow->AcquireRowObject(ev, store);
86 if (rowObj) {
87 mCellObject_Row = ioRow;
88 mCellObject_Cell = ioCell;
89 mCellObject_RowSeed = ioRow->mRow_Seed;
90
91 // morkRowObject::SlotStrongRowObject(rowObj, ev,
92 // &mCellObject_RowObject);
93
94 mCellObject_RowObject = rowObj; // assume control of strong ref
95 }
96 if (ev->Good()) mNode_Derived = morkDerived_kCellObject;
97 }
98 } else
99 ioRow->NonRowTypeError(ev);
100 } else
101 ev->NilPointerError();
102 }
103 }
104
NS_IMPL_ISUPPORTS_INHERITED(morkCellObject,morkObject,nsIMdbCell)105 NS_IMPL_ISUPPORTS_INHERITED(morkCellObject, morkObject, nsIMdbCell)
106
107 /*public non-poly*/ void morkCellObject::CloseCellObject(
108 morkEnv* ev) // called by CloseMorkNode();
109 {
110 if (this->IsNode()) {
111 NS_RELEASE(mCellObject_RowObject);
112 mCellObject_Row = 0;
113 mCellObject_Cell = 0;
114 mCellObject_RowSeed = 0;
115 this->CloseObject(ev);
116 this->MarkShut();
117 } else
118 this->NonNodeError(ev);
119 }
120
121 // } ===== end morkNode methods =====
122 // ````` ````` ````` ````` `````
123
ResyncWithRow(morkEnv * ev)124 mork_bool morkCellObject::ResyncWithRow(morkEnv* ev) {
125 morkRow* row = mCellObject_Row;
126 mork_pos pos = 0;
127 morkCell* cell = row->GetCell(ev, mCellObject_Col, &pos);
128 if (cell) {
129 mCellObject_Pos = (mork_u2)pos;
130 mCellObject_Cell = cell;
131 mCellObject_RowSeed = row->mRow_Seed;
132 } else {
133 mCellObject_Cell = 0;
134 this->MissingRowColumnError(ev);
135 }
136 return ev->Good();
137 }
138
GetCellAtom(morkEnv * ev) const139 morkAtom* morkCellObject::GetCellAtom(morkEnv* ev) const {
140 morkCell* cell = mCellObject_Cell;
141 if (cell)
142 return cell->GetAtom();
143 else
144 this->NilCellError(ev);
145
146 return (morkAtom*)0;
147 }
148
WrongRowObjectRowError(morkEnv * ev)149 /*static*/ void morkCellObject::WrongRowObjectRowError(morkEnv* ev) {
150 ev->NewError("mCellObject_Row != mCellObject_RowObject->mRowObject_Row");
151 }
152
NilRowError(morkEnv * ev)153 /*static*/ void morkCellObject::NilRowError(morkEnv* ev) {
154 ev->NewError("nil mCellObject_Row");
155 }
156
NilRowObjectError(morkEnv * ev)157 /*static*/ void morkCellObject::NilRowObjectError(morkEnv* ev) {
158 ev->NewError("nil mCellObject_RowObject");
159 }
160
NilCellError(morkEnv * ev)161 /*static*/ void morkCellObject::NilCellError(morkEnv* ev) {
162 ev->NewError("nil mCellObject_Cell");
163 }
164
NonCellObjectTypeError(morkEnv * ev)165 /*static*/ void morkCellObject::NonCellObjectTypeError(morkEnv* ev) {
166 ev->NewError("non morkCellObject");
167 }
168
MissingRowColumnError(morkEnv * ev)169 /*static*/ void morkCellObject::MissingRowColumnError(morkEnv* ev) {
170 ev->NewError("mCellObject_Col not in mCellObject_Row");
171 }
172
AcquireCellHandle(morkEnv * ev)173 nsIMdbCell* morkCellObject::AcquireCellHandle(morkEnv* ev) {
174 nsIMdbCell* outCell = this;
175 NS_ADDREF(outCell);
176 return outCell;
177 }
178
CanUseCell(nsIMdbEnv * mev,mork_bool inMutable,nsresult * outErr,morkCell ** outCell)179 morkEnv* morkCellObject::CanUseCell(nsIMdbEnv* mev, mork_bool inMutable,
180 nsresult* outErr, morkCell** outCell) {
181 morkEnv* outEnv = 0;
182 morkCell* cell = 0;
183 morkEnv* ev = morkEnv::FromMdbEnv(mev);
184 if (ev) {
185 if (IsCellObject()) {
186 if (IsMutable() || !inMutable) {
187 morkRowObject* rowObj = mCellObject_RowObject;
188 if (rowObj) {
189 morkRow* row = mCellObject_Row;
190 if (row) {
191 if (rowObj->mRowObject_Row == row) {
192 mork_u2 oldSeed = mCellObject_RowSeed;
193 if (row->mRow_Seed == oldSeed || ResyncWithRow(ev)) {
194 cell = mCellObject_Cell;
195 if (cell) {
196 outEnv = ev;
197 } else
198 NilCellError(ev);
199 }
200 } else
201 WrongRowObjectRowError(ev);
202 } else
203 NilRowError(ev);
204 } else
205 NilRowObjectError(ev);
206 } else
207 NonMutableNodeError(ev);
208 } else
209 NonCellObjectTypeError(ev);
210 }
211 *outErr = ev->AsErr();
212 MORK_ASSERT(outEnv);
213 *outCell = cell;
214
215 return outEnv;
216 }
217
218 // { ----- begin attribute methods -----
SetBlob(nsIMdbEnv *,nsIMdbBlob *)219 NS_IMETHODIMP morkCellObject::SetBlob(nsIMdbEnv* /* mev */,
220 nsIMdbBlob* /* ioBlob */) {
221 NS_ASSERTION(false, "not implemented");
222 return NS_ERROR_NOT_IMPLEMENTED;
223 } // reads inBlob slots
224
225 // when inBlob is in the same suite, this might be fastest cell-to-cell
226
227 NS_IMETHODIMP
ClearBlob(nsIMdbEnv *)228 morkCellObject::ClearBlob( // make empty (so content has zero length)
229 nsIMdbEnv* /* mev */) {
230 NS_ASSERTION(false, "not implemented");
231 return NS_ERROR_NOT_IMPLEMENTED;
232 // remember row->MaybeDirtySpaceStoreAndRow();
233 }
234 // clearing a yarn is like SetYarn() with empty yarn instance content
235
GetBlobFill(nsIMdbEnv * mev,mdb_fill * outFill)236 NS_IMETHODIMP morkCellObject::GetBlobFill(nsIMdbEnv* mev, mdb_fill* outFill)
237 // Same value that would be put into mYarn_Fill, if one called GetYarn()
238 // with a yarn instance that had mYarn_Buf==nil and mYarn_Size==0.
239 {
240 NS_ASSERTION(false, "not implemented");
241 return NS_ERROR_NOT_IMPLEMENTED;
242 } // size of blob
243
SetYarn(nsIMdbEnv * mev,const mdbYarn * inYarn)244 NS_IMETHODIMP morkCellObject::SetYarn(nsIMdbEnv* mev, const mdbYarn* inYarn) {
245 nsresult outErr = NS_OK;
246 morkCell* cell = 0;
247 morkEnv* ev =
248 this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue, &outErr, &cell);
249 if (ev) {
250 morkRow* row = mCellObject_Row;
251 if (row) {
252 morkStore* store = row->GetRowSpaceStore(ev);
253 if (store) {
254 cell->SetYarn(ev, inYarn, store);
255 if (row->IsRowClean() && store->mStore_CanDirty)
256 row->MaybeDirtySpaceStoreAndRow();
257 }
258 } else
259 ev->NilPointerError();
260
261 outErr = ev->AsErr();
262 }
263
264 return outErr;
265 } // reads from yarn slots
266 // make this text object contain content from the yarn's buffer
267
GetYarn(nsIMdbEnv * mev,mdbYarn * outYarn)268 NS_IMETHODIMP morkCellObject::GetYarn(nsIMdbEnv* mev, mdbYarn* outYarn) {
269 nsresult outErr = NS_OK;
270 morkCell* cell = 0;
271 morkEnv* ev =
272 this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue, &outErr, &cell);
273 if (ev) {
274 morkAtom* atom = cell->GetAtom();
275 morkAtom::GetYarn(atom, outYarn);
276 outErr = ev->AsErr();
277 }
278
279 return outErr;
280 } // writes some yarn slots
281 // copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form
282
AliasYarn(nsIMdbEnv * mev,mdbYarn * outYarn)283 NS_IMETHODIMP morkCellObject::AliasYarn(nsIMdbEnv* mev, mdbYarn* outYarn) {
284 nsresult outErr = NS_OK;
285 morkCell* cell = 0;
286 morkEnv* ev =
287 this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue, &outErr, &cell);
288 if (ev) {
289 morkAtom* atom = cell->GetAtom();
290 morkAtom::AliasYarn(atom, outYarn);
291 outErr = ev->AsErr();
292 }
293
294 return outErr;
295 } // writes ALL yarn slots
296
297 // } ----- end attribute methods -----
298
299 // } ===== end nsIMdbBlob methods =====
300
301 // { ===== begin nsIMdbCell methods =====
302
303 // { ----- begin attribute methods -----
SetColumn(nsIMdbEnv * mev,mdb_column inColumn)304 NS_IMETHODIMP morkCellObject::SetColumn(nsIMdbEnv* mev, mdb_column inColumn) {
305 NS_ASSERTION(false, "not implemented");
306 return NS_ERROR_NOT_IMPLEMENTED;
307 // remember row->MaybeDirtySpaceStoreAndRow();
308 }
309
GetColumn(nsIMdbEnv * mev,mdb_column * outColumn)310 NS_IMETHODIMP morkCellObject::GetColumn(nsIMdbEnv* mev, mdb_column* outColumn) {
311 nsresult outErr = NS_OK;
312 mdb_column col = 0;
313 morkCell* cell = 0;
314 morkEnv* ev =
315 this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue, &outErr, &cell);
316 if (ev) {
317 col = mCellObject_Col;
318 outErr = ev->AsErr();
319 }
320 if (outColumn) *outColumn = col;
321 return outErr;
322 }
323
324 NS_IMETHODIMP
GetCellInfo(nsIMdbEnv * mev,mdb_column * outColumn,mdb_fill * outBlobFill,mdbOid * outChildOid,mdb_bool * outIsRowChild)325 morkCellObject::GetCellInfo( // all cell metainfo except actual content
326 nsIMdbEnv* mev,
327 mdb_column* outColumn, // the column in the containing row
328 mdb_fill* outBlobFill, // the size of text content in bytes
329 mdbOid* outChildOid, // oid of possible row or table child
330 mdb_bool* outIsRowChild) // nonzero if child, and a row child
331 // Checking all cell metainfo is a good way to avoid forcing a large cell
332 // in to memory when you don't actually want to use the content.
333 {
334 NS_ASSERTION(false, "not implemented");
335 return NS_ERROR_NOT_IMPLEMENTED;
336 }
337
GetRow(nsIMdbEnv * mev,nsIMdbRow ** acqRow)338 NS_IMETHODIMP morkCellObject::GetRow(
339 nsIMdbEnv* mev, // parent row for this cell
340 nsIMdbRow** acqRow) {
341 nsresult outErr = NS_OK;
342 nsIMdbRow* outRow = 0;
343 morkCell* cell = 0;
344 morkEnv* ev =
345 this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue, &outErr, &cell);
346 if (ev) {
347 outRow = mCellObject_RowObject->AcquireRowHandle(ev);
348
349 outErr = ev->AsErr();
350 }
351 if (acqRow) *acqRow = outRow;
352 return outErr;
353 }
354
GetPort(nsIMdbEnv * mev,nsIMdbPort ** acqPort)355 NS_IMETHODIMP morkCellObject::GetPort(nsIMdbEnv* mev, // port containing cell
356 nsIMdbPort** acqPort) {
357 nsresult outErr = NS_OK;
358 nsIMdbPort* outPort = 0;
359 morkCell* cell = 0;
360 morkEnv* ev =
361 this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue, &outErr, &cell);
362 if (ev) {
363 if (mCellObject_Row) {
364 morkStore* store = mCellObject_Row->GetRowSpaceStore(ev);
365 if (store) outPort = store->AcquireStoreHandle(ev);
366 } else
367 ev->NilPointerError();
368
369 outErr = ev->AsErr();
370 }
371 if (acqPort) *acqPort = outPort;
372 return outErr;
373 }
374 // } ----- end attribute methods -----
375
376 // { ----- begin children methods -----
377 NS_IMETHODIMP
HasAnyChild(nsIMdbEnv * mev,mdbOid * outOid,mdb_bool * outIsRow)378 morkCellObject::HasAnyChild( // does cell have a child instead of text?
379 nsIMdbEnv* mev,
380 mdbOid* outOid, // out id of row or table (or unbound if no child)
381 mdb_bool* outIsRow) // nonzero if child is a row (rather than a table)
382 {
383 nsresult outErr = NS_OK;
384 mdb_bool isRow = morkBool_kFalse;
385 outOid->mOid_Scope = 0;
386 outOid->mOid_Id = morkId_kMinusOne;
387 morkCell* cell = 0;
388 morkEnv* ev =
389 this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue, &outErr, &cell);
390 if (ev) {
391 morkAtom* atom = GetCellAtom(ev);
392 if (atom) {
393 isRow = atom->IsRowOid();
394 if (isRow || atom->IsTableOid())
395 *outOid = ((morkOidAtom*)atom)->mOidAtom_Oid;
396 }
397
398 outErr = ev->AsErr();
399 }
400 if (outIsRow) *outIsRow = isRow;
401
402 return outErr;
403 }
404
405 NS_IMETHODIMP
GetAnyChild(nsIMdbEnv * mev,nsIMdbRow ** acqRow,nsIMdbTable ** acqTable)406 morkCellObject::GetAnyChild( // access table of specific attribute
407 nsIMdbEnv* mev, // context
408 nsIMdbRow** acqRow, // child row (or null)
409 nsIMdbTable** acqTable) // child table (or null)
410 {
411 NS_ASSERTION(false, "not implemented");
412 return NS_ERROR_NOT_IMPLEMENTED;
413 }
414
415 NS_IMETHODIMP
SetChildRow(nsIMdbEnv * mev,nsIMdbRow * ioRow)416 morkCellObject::SetChildRow( // access table of specific attribute
417 nsIMdbEnv* mev, // context
418 nsIMdbRow* ioRow) {
419 NS_ASSERTION(false, "not implemented");
420 return NS_ERROR_NOT_IMPLEMENTED;
421 } // inRow must be bound inside this same db port
422
GetChildRow(nsIMdbEnv * mev,nsIMdbRow ** acqRow)423 NS_IMETHODIMP morkCellObject::GetChildRow( // access row of specific attribute
424 nsIMdbEnv* mev, // context
425 nsIMdbRow** acqRow) // acquire child row (or nil if no child)
426 {
427 NS_ASSERTION(false, "not implemented");
428 return NS_ERROR_NOT_IMPLEMENTED;
429 }
430
431 NS_IMETHODIMP
SetChildTable(nsIMdbEnv * mev,nsIMdbTable * inTable)432 morkCellObject::SetChildTable( // access table of specific attribute
433 nsIMdbEnv* mev, // context
434 nsIMdbTable* inTable) // table must be bound inside this same db port
435 {
436 NS_ASSERTION(false, "not implemented");
437 return NS_ERROR_NOT_IMPLEMENTED;
438 // remember row->MaybeDirtySpaceStoreAndRow();
439 }
440
441 NS_IMETHODIMP
GetChildTable(nsIMdbEnv * mev,nsIMdbTable ** acqTable)442 morkCellObject::GetChildTable( // access table of specific attribute
443 nsIMdbEnv* mev, // context
444 nsIMdbTable** acqTable) // acquire child tabdle (or nil if no chil)
445 {
446 NS_ASSERTION(false, "not implemented");
447 return NS_ERROR_NOT_IMPLEMENTED;
448 }
449 // } ----- end children methods -----
450
451 // } ===== end nsIMdbCell methods =====
452
453 // 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
454