summaryrefslogtreecommitdiffstats
path: root/comm/mailnews/db/mork/morkCellObject.h
blob: 1ef8718ab22afc7c29899d45542bf3290aeb5677 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/* -*- 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 _MORKCELLOBJECT_
#define _MORKCELLOBJECT_ 1

#ifndef _MORK_
#  include "mork.h"
#endif

#ifndef _MORKNODE_
#  include "morkNode.h"
#endif

#ifndef _MORKOBJECT_
#  include "morkObject.h"
#endif

// 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789

#define morkDerived_kCellObject /*i*/ 0x634F /* ascii 'cO' */

class morkCellObject : public morkObject,
                       public nsIMdbCell {  // blob attribute in column scope

  // public: // slots inherited from morkObject (meant to inform only)
  // nsIMdbHeap*     mNode_Heap;
  // mork_able    mNode_Mutable; // can this node be modified?
  // mork_load    mNode_Load;    // is this node clean or dirty?
  // mork_base    mNode_Base;    // must equal morkBase_kNode
  // mork_derived mNode_Derived; // depends on specific node subclass
  // mork_access  mNode_Access;  // kOpen, kClosing, kShut, or kDead
  // mork_usage   mNode_Usage;   // kHeap, kStack, kMember, kGlobal, kNone
  // mork_uses    mNode_Uses;    // refcount for strong refs
  // mork_refs    mNode_Refs;    // refcount for strong refs + weak refs

  // mork_color   mBead_Color;   // ID for this bead
  // morkHandle*  mObject_Handle;  // weak ref to handle for this object

 public:  // state is public because the entire Mork system is private
  NS_DECL_ISUPPORTS_INHERITED

  morkRowObject* mCellObject_RowObject;  // strong ref to row's object
  morkRow* mCellObject_Row;              // cell's row if still in row object
  morkCell* mCellObject_Cell;            // cell in row if rowseed matches
  mork_column mCellObject_Col;           // col of cell last living in pos
  mork_u2 mCellObject_RowSeed;           // copy of row's seed
  mork_u2 mCellObject_Pos;               // position of cell in row

  // { ===== begin morkNode interface =====
 public:  // morkNode virtual methods
  virtual void CloseMorkNode(
      morkEnv* ev) override;  // CloseCellObject() only if open

 public:  // morkCellObject construction & destruction
  morkCellObject(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap,
                 morkRow* ioRow, morkCell* ioCell, mork_column inCol,
                 mork_pos inPos);
  void CloseCellObject(morkEnv* ev);  // called by CloseMorkNode();

  NS_IMETHOD SetBlob(nsIMdbEnv* ev,
                     nsIMdbBlob* ioBlob) override;  // reads inBlob slots
  // when inBlob is in the same suite, this might be fastest cell-to-cell

  NS_IMETHOD ClearBlob(  // make empty (so content has zero length)
      nsIMdbEnv* ev) override;
  // clearing a yarn is like SetYarn() with empty yarn instance content

  NS_IMETHOD GetBlobFill(nsIMdbEnv* ev,
                         mdb_fill* outFill) override;  // size of blob
  // 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_IMETHOD SetYarn(nsIMdbEnv* ev,
                     const mdbYarn* inYarn) override;  // reads from yarn slots
  // make this text object contain content from the yarn's buffer

  NS_IMETHOD GetYarn(nsIMdbEnv* ev,
                     mdbYarn* outYarn) override;  // writes some yarn slots
  // copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form

  NS_IMETHOD AliasYarn(nsIMdbEnv* ev,
                       mdbYarn* outYarn) override;  // writes ALL yarn slots
  NS_IMETHOD SetColumn(nsIMdbEnv* ev, mdb_column inColumn) override;
  NS_IMETHOD GetColumn(nsIMdbEnv* ev, mdb_column* outColumn) override;

  NS_IMETHOD GetCellInfo(  // all cell metainfo except actual content
      nsIMdbEnv* ev,
      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) override;  // 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_IMETHOD GetRow(nsIMdbEnv* ev,  // parent row for this cell
                    nsIMdbRow** acqRow) override;
  NS_IMETHOD GetPort(nsIMdbEnv* ev,  // port containing cell
                     nsIMdbPort** acqPort) override;
  // } ----- end attribute methods -----

  // { ----- begin children methods -----
  NS_IMETHOD HasAnyChild(  // does cell have a child instead of text?
      nsIMdbEnv* ev,
      mdbOid* outOid,  // out id of row or table (or unbound if no child)
      mdb_bool* outIsRow)
      override;  // nonzero if child is a row (rather than a table)

  NS_IMETHOD GetAnyChild(                // access table of specific attribute
      nsIMdbEnv* ev,                     // context
      nsIMdbRow** acqRow,                // child row (or null)
      nsIMdbTable** acqTable) override;  // child table (or null)

  NS_IMETHOD SetChildRow(  // access table of specific attribute
      nsIMdbEnv* ev,       // context
      nsIMdbRow* ioRow)
      override;  // inRow must be bound inside this same db port

  NS_IMETHOD GetChildRow(            // access row of specific attribute
      nsIMdbEnv* ev,                 // context
      nsIMdbRow** acqRow) override;  // acquire child row (or nil if no child)

  NS_IMETHOD SetChildTable(  // access table of specific attribute
      nsIMdbEnv* ev,         // context
      nsIMdbTable* inTable)
      override;  // table must be bound inside this same db port

  NS_IMETHOD GetChildTable(  // access table of specific attribute
      nsIMdbEnv* ev,         // context
      nsIMdbTable** acqTable)
      override;  // acquire child table (or nil if no child)

  // } ----- end children methods -----

  // } ===== end nsIMdbCell methods =====
 private:                     // copying is not allowed
  virtual ~morkCellObject();  // assert that CloseCellObject() executed earlier
  morkCellObject(const morkCellObject& other);
  morkCellObject& operator=(const morkCellObject& other);

 public:  // dynamic type identification
  mork_bool IsCellObject() const {
    return IsNode() && mNode_Derived == morkDerived_kCellObject;
  }
  // } ===== end morkNode methods =====

 public:  // other cell node methods
  morkEnv* CanUseCell(nsIMdbEnv* mev, mork_bool inMutable, nsresult* outErr,
                      morkCell** outCell);

  mork_bool ResyncWithRow(morkEnv* ev);  // return ev->Good()
  morkAtom* GetCellAtom(morkEnv* ev) const;

  static void MissingRowColumnError(morkEnv* ev);
  static void NilRowError(morkEnv* ev);
  static void NilCellError(morkEnv* ev);
  static void NilRowObjectError(morkEnv* ev);
  static void WrongRowObjectRowError(morkEnv* ev);
  static void NonCellObjectTypeError(morkEnv* ev);

  nsIMdbCell* AcquireCellHandle(morkEnv* ev);

 public:  // typesafe refcounting inlines calling inherited morkNode methods
  static void SlotWeakCellObject(morkCellObject* me, morkEnv* ev,
                                 morkCellObject** ioSlot) {
    morkNode::SlotWeakNode((morkNode*)me, ev, (morkNode**)ioSlot);
  }

  static void SlotStrongCellObject(morkCellObject* me, morkEnv* ev,
                                   morkCellObject** ioSlot) {
    morkNode::SlotStrongNode((morkNode*)me, ev, (morkNode**)ioSlot);
  }
};

// 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789

#endif /* _MORKCELLOBJECT_ */