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
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
|
/* -*- 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 _MORKBUILDER_
#define _MORKBUILDER_ 1
#ifndef _MORK_
#include "mork.h"
#endif
#ifndef _MORKPARSER_
#include "morkParser.h"
#endif
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
/*| kCellsVecSize: length of cell vector buffer inside morkBuilder
|*/
#define morkBuilder_kCellsVecSize 64
#define morkBuilder_kDefaultBytesPerParseSegment 512 /* plausible to big */
#define morkDerived_kBuilder /*i*/ 0x4275 /* ascii 'Bu' */
class morkBuilder /*d*/ : public morkParser {
// public: // slots inherited from morkParser (meant to inform only)
// nsIMdbHeap* mNode_Heap;
// 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_able mNode_Mutable; // can this node be modified?
// mork_load mNode_Load; // is this node clean or dirty?
// mork_uses mNode_Uses; // refcount for strong refs
// mork_refs mNode_Refs; // refcount for strong refs + weak refs
// nsIMdbHeap* mParser_Heap; // refcounted heap used for allocation
// morkStream* mParser_Stream; // refcounted input stream
// mork_u4 mParser_Tag; // must equal morkParser_kTag
// mork_count mParser_MoreGranularity; // constructor inBytesPerParseSegment
// mork_u4 mParser_State; // state where parser should resume
// after finding ends of group transactions, we can re-seek the start:
// mork_pos mParser_GroupContentStartPos; // start of this group
// mdbOid mParser_TableOid; // table oid if inside a table
// mdbOid mParser_RowOid; // row oid if inside a row
// mork_gid mParser_GroupId; // group ID if inside a group
// mork_bool mParser_InPort; // called OnNewPort but not OnPortEnd?
// mork_bool mParser_InDict; // called OnNewDict but not OnDictEnd?
// mork_bool mParser_InCell; // called OnNewCell but not OnCellEnd?
// mork_bool mParser_InMeta; // called OnNewMeta but not OnMetaEnd?
// morkMid mParser_Mid; // current alias being parsed
// note that mParser_Mid.mMid_Buf points at mParser_ScopeCoil below:
// blob coils allocated in mParser_Heap
// morkCoil mParser_ScopeCoil; // place to accumulate ID scope blobs
// morkCoil mParser_ValueCoil; // place to accumulate value blobs
// morkCoil mParser_ColumnCoil; // place to accumulate column blobs
// morkCoil mParser_StringCoil; // place to accumulate string blobs
// morkSpool mParser_ScopeSpool; // writes to mParser_ScopeCoil
// morkSpool mParser_ValueSpool; // writes to mParser_ValueCoil
// morkSpool mParser_ColumnSpool; // writes to mParser_ColumnCoil
// morkSpool mParser_StringSpool; // writes to mParser_StringCoil
// yarns allocated in mParser_Heap
// morkYarn mParser_MidYarn; // place to receive from MidToYarn()
// span showing current ongoing file position status:
// morkSpan mParser_PortSpan; // span of current db port file
// various spans denoting nested subspaces inside the file's port span:
// morkSpan mParser_GroupSpan; // span of current transaction group
// morkSpan mParser_DictSpan;
// morkSpan mParser_AliasSpan;
// morkSpan mParser_MetaDictSpan;
// morkSpan mParser_TableSpan;
// morkSpan mParser_MetaTableSpan;
// morkSpan mParser_RowSpan;
// morkSpan mParser_MetaRowSpan;
// morkSpan mParser_CellSpan;
// morkSpan mParser_ColumnSpan;
// morkSpan mParser_SlotSpan;
// ````` ````` ````` ````` ````` ````` ````` `````
protected: // protected morkBuilder members
// weak refs that do not prevent closure of referenced nodes:
morkStore* mBuilder_Store; // weak ref to builder's store
// strong refs that do indeed prevent closure of referenced nodes:
morkTable* mBuilder_Table; // current table being built (or nil)
morkRow* mBuilder_Row; // current row being built (or nil)
morkCell* mBuilder_Cell; // current cell within CellsVec (or nil)
morkRowSpace* mBuilder_RowSpace; // space for mBuilder_CellRowScope
morkAtomSpace* mBuilder_AtomSpace; // space for mBuilder_CellAtomScope
morkAtomSpace* mBuilder_OidAtomSpace; // ground atom space for oids
morkAtomSpace* mBuilder_ScopeAtomSpace; // ground atom space for scopes
// scoped object ids for current objects under construction:
mdbOid mBuilder_TableOid; // full oid for current table
mdbOid mBuilder_RowOid; // full oid for current row
// tokens that become set as the result of meta cells in port rows:
mork_cscode mBuilder_PortForm; // default port charset format
mork_scope mBuilder_PortRowScope; // port row scope
mork_scope mBuilder_PortAtomScope; // port atom scope
// tokens that become set as the result of meta cells in meta tables:
mork_cscode mBuilder_TableForm; // default table charset format
mork_scope mBuilder_TableRowScope; // table row scope
mork_scope mBuilder_TableAtomScope; // table atom scope
mork_kind mBuilder_TableKind; // table kind
mork_token mBuilder_TableStatus; // dummy: priority/unique/verbose
mork_priority mBuilder_TablePriority; // table priority
mork_bool mBuilder_TableIsUnique; // table uniqueness
mork_bool mBuilder_TableIsVerbose; // table verboseness
mork_u1 mBuilder_TablePadByte; // for u4 alignment
// tokens that become set as the result of meta cells in meta rows:
mork_cscode mBuilder_RowForm; // default row charset format
mork_scope mBuilder_RowRowScope; // row scope per row metainfo
mork_scope mBuilder_RowAtomScope; // row atom scope
// meta tokens currently in force, driven by meta info slots above:
mork_cscode mBuilder_CellForm; // cell charset format
mork_scope mBuilder_CellAtomScope; // cell atom scope
mork_cscode mBuilder_DictForm; // dict charset format
mork_scope mBuilder_DictAtomScope; // dict atom scope
mork_token* mBuilder_MetaTokenSlot; // pointer to some slot above
// If any of these 'cut' bools are true, it means a minus was seen in the
// Mork source text to indicate removal of content from some container.
// (Note there is no corresponding 'add' bool, since add is the default.)
// CutRow implies the current row should be cut from the table.
// CutCell implies the current column should be cut from the row.
mork_bool mBuilder_DoCutRow; // row with kCut change
mork_bool mBuilder_DoCutCell; // cell with kCut change
mork_u1 mBuilder_row_pad; // pad to u4 alignment
mork_u1 mBuilder_cell_pad; // pad to u4 alignment
morkCell mBuilder_CellsVec[ morkBuilder_kCellsVecSize + 1 ];
mork_fill mBuilder_CellsVecFill; // count used in CellsVec
// Note when mBuilder_CellsVecFill equals morkBuilder_kCellsVecSize, and
// another cell is added, this means all the cells in the vector above
// must be flushed to the current row being built to create more room.
protected: // protected inlines
mork_bool CellVectorIsFull() const
{ return ( mBuilder_CellsVecFill == morkBuilder_kCellsVecSize ); }
// { ===== begin morkNode interface =====
public: // morkNode virtual methods
virtual void CloseMorkNode(morkEnv* ev) override; // CloseBuilder() only if open
virtual ~morkBuilder(); // assert that CloseBuilder() executed earlier
public: // morkYarn construction & destruction
morkBuilder(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap,
morkStream* ioStream, // the readonly stream for input bytes
mdb_count inBytesPerParseSegment, // target for ParseMore()
nsIMdbHeap* ioSlotHeap, morkStore* ioStore
);
void CloseBuilder(morkEnv* ev); // called by CloseMorkNode();
private: // copying is not allowed
morkBuilder(const morkBuilder& other);
morkBuilder& operator=(const morkBuilder& other);
public: // dynamic type identification
mork_bool IsBuilder() const
{ return IsNode() && mNode_Derived == morkDerived_kBuilder; }
// } ===== end morkNode methods =====
public: // errors
static void NonBuilderTypeError(morkEnv* ev);
static void NilBuilderCellError(morkEnv* ev);
static void NilBuilderRowError(morkEnv* ev);
static void NilBuilderTableError(morkEnv* ev);
static void NonColumnSpaceScopeError(morkEnv* ev);
void LogGlitch(morkEnv* ev, const morkGlitch& inGlitch,
const char* inKind);
public: // other builder methods
morkCell* AddBuilderCell(morkEnv* ev,
const morkMid& inMid, mork_change inChange);
void FlushBuilderCells(morkEnv* ev);
// ````` ````` ````` ````` ````` ````` ````` `````
public: // in virtual morkParser methods, data flow subclass to parser
virtual void MidToYarn(morkEnv* ev,
const morkMid& inMid, // typically an alias to concat with strings
mdbYarn* outYarn) override;
// The parser might ask that some aliases be turned into yarns, so they
// can be concatenated into longer blobs under some circumstances. This
// is an alternative to using a long and complex callback for many parts
// for a single cell value.
// ````` ````` ````` ````` ````` ````` ````` `````
public: // out virtual morkParser methods, data flow parser to subclass
virtual void OnNewPort(morkEnv* ev, const morkPlace& inPlace) override;
virtual void OnPortGlitch(morkEnv* ev, const morkGlitch& inGlitch) override;
virtual void OnPortEnd(morkEnv* ev, const morkSpan& inSpan) override;
virtual void OnNewGroup(morkEnv* ev, const morkPlace& inPlace, mork_gid inGid) override;
virtual void OnGroupGlitch(morkEnv* ev, const morkGlitch& inGlitch) override;
virtual void OnGroupCommitEnd(morkEnv* ev, const morkSpan& inSpan) override;
virtual void OnGroupAbortEnd(morkEnv* ev, const morkSpan& inSpan) override;
virtual void OnNewPortRow(morkEnv* ev, const morkPlace& inPlace,
const morkMid& inMid, mork_change inChange) override;
virtual void OnPortRowGlitch(morkEnv* ev, const morkGlitch& inGlitch) override;
virtual void OnPortRowEnd(morkEnv* ev, const morkSpan& inSpan) override;
virtual void OnNewTable(morkEnv* ev, const morkPlace& inPlace,
const morkMid& inMid, mork_bool inCutAllRows) override;
virtual void OnTableGlitch(morkEnv* ev, const morkGlitch& inGlitch) override;
virtual void OnTableEnd(morkEnv* ev, const morkSpan& inSpan) override;
virtual void OnNewMeta(morkEnv* ev, const morkPlace& inPlace) override;
virtual void OnMetaGlitch(morkEnv* ev, const morkGlitch& inGlitch) override;
virtual void OnMetaEnd(morkEnv* ev, const morkSpan& inSpan) override;
virtual void OnMinusRow(morkEnv* ev) override;
virtual void OnNewRow(morkEnv* ev, const morkPlace& inPlace,
const morkMid& inMid, mork_bool inCutAllCols) override;
virtual void OnRowPos(morkEnv* ev, mork_pos inRowPos) override;
virtual void OnRowGlitch(morkEnv* ev, const morkGlitch& inGlitch) override;
virtual void OnRowEnd(morkEnv* ev, const morkSpan& inSpan) override;
virtual void OnNewDict(morkEnv* ev, const morkPlace& inPlace) override;
virtual void OnDictGlitch(morkEnv* ev, const morkGlitch& inGlitch) override;
virtual void OnDictEnd(morkEnv* ev, const morkSpan& inSpan) override;
virtual void OnAlias(morkEnv* ev, const morkSpan& inSpan,
const morkMid& inMid) override;
virtual void OnAliasGlitch(morkEnv* ev, const morkGlitch& inGlitch) override;
virtual void OnMinusCell(morkEnv* ev) override;
virtual void OnNewCell(morkEnv* ev, const morkPlace& inPlace,
const morkMid* inMid, const morkBuf* inBuf) override;
// Exactly one of inMid and inBuf is nil, and the other is non-nil.
// When hex ID syntax is used for a column, then inMid is not nil, and
// when a naked string names a column, then inBuf is not nil.
virtual void OnCellGlitch(morkEnv* ev, const morkGlitch& inGlitch) override;
virtual void OnCellForm(morkEnv* ev, mork_cscode inCharsetFormat) override;
virtual void OnCellEnd(morkEnv* ev, const morkSpan& inSpan) override;
virtual void OnValue(morkEnv* ev, const morkSpan& inSpan,
const morkBuf& inBuf) override;
virtual void OnValueMid(morkEnv* ev, const morkSpan& inSpan,
const morkMid& inMid) override;
virtual void OnRowMid(morkEnv* ev, const morkSpan& inSpan,
const morkMid& inMid) override;
virtual void OnTableMid(morkEnv* ev, const morkSpan& inSpan,
const morkMid& inMid) override;
// ````` ````` ````` ````` ````` ````` ````` `````
public: // public non-poly morkBuilder methods
public: // typesafe refcounting inlines calling inherited morkNode methods
static void SlotWeakBuilder(morkBuilder* me,
morkEnv* ev, morkBuilder** ioSlot)
{ morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); }
static void SlotStrongBuilder(morkBuilder* me,
morkEnv* ev, morkBuilder** ioSlot)
{ morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); }
};
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
#endif /* _MORKBUILDER_ */
|