1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1999
20 * the Initial Developer. All Rights Reserved.
24 * Alternatively, the contents of this file may be used under the terms of
25 * either of the GNU General Public License Version 2 or later (the "GPL"),
26 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
39 #define _MORKBUILDER_ 1
46 #include "morkParser.h"
49 //3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
51 /*| kCellsVecSize: length of cell vector buffer inside morkBuilder
53 #define morkBuilder_kCellsVecSize 64
55 #define morkBuilder_kDefaultBytesPerParseSegment 512 /* plausible to big */
57 #define morkDerived_kBuilder /*i*/ 0x4275 /* ascii 'Bu' */
59 class morkBuilder
/*d*/ : public morkParser
{
61 // public: // slots inherited from morkParser (meant to inform only)
62 // nsIMdbHeap* mNode_Heap;
64 // mork_base mNode_Base; // must equal morkBase_kNode
65 // mork_derived mNode_Derived; // depends on specific node subclass
67 // mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead
68 // mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone
69 // mork_able mNode_Mutable; // can this node be modified?
70 // mork_load mNode_Load; // is this node clean or dirty?
72 // mork_uses mNode_Uses; // refcount for strong refs
73 // mork_refs mNode_Refs; // refcount for strong refs + weak refs
76 // nsIMdbHeap* mParser_Heap; // refcounted heap used for allocation
77 // morkStream* mParser_Stream; // refcounted input stream
79 // mork_u4 mParser_Tag; // must equal morkParser_kTag
80 // mork_count mParser_MoreGranularity; // constructor inBytesPerParseSegment
82 // mork_u4 mParser_State; // state where parser should resume
84 // after finding ends of group transactions, we can re-seek the start:
85 // mork_pos mParser_GroupContentStartPos; // start of this group
87 // mdbOid mParser_TableOid; // table oid if inside a table
88 // mdbOid mParser_RowOid; // row oid if inside a row
89 // mork_gid mParser_GroupId; // group ID if inside a group
91 // mork_bool mParser_InPort; // called OnNewPort but not OnPortEnd?
92 // mork_bool mParser_InDict; // called OnNewDict but not OnDictEnd?
93 // mork_bool mParser_InCell; // called OnNewCell but not OnCellEnd?
94 // mork_bool mParser_InMeta; // called OnNewMeta but not OnMetaEnd?
96 // morkMid mParser_Mid; // current alias being parsed
97 // note that mParser_Mid.mMid_Buf points at mParser_ScopeCoil below:
99 // blob coils allocated in mParser_Heap
100 // morkCoil mParser_ScopeCoil; // place to accumulate ID scope blobs
101 // morkCoil mParser_ValueCoil; // place to accumulate value blobs
102 // morkCoil mParser_ColumnCoil; // place to accumulate column blobs
103 // morkCoil mParser_StringCoil; // place to accumulate string blobs
105 // morkSpool mParser_ScopeSpool; // writes to mParser_ScopeCoil
106 // morkSpool mParser_ValueSpool; // writes to mParser_ValueCoil
107 // morkSpool mParser_ColumnSpool; // writes to mParser_ColumnCoil
108 // morkSpool mParser_StringSpool; // writes to mParser_StringCoil
110 // yarns allocated in mParser_Heap
111 // morkYarn mParser_MidYarn; // place to receive from MidToYarn()
113 // span showing current ongoing file position status:
114 // morkSpan mParser_PortSpan; // span of current db port file
116 // various spans denoting nested subspaces inside the file's port span:
117 // morkSpan mParser_GroupSpan; // span of current transaction group
118 // morkSpan mParser_DictSpan;
119 // morkSpan mParser_AliasSpan;
120 // morkSpan mParser_MetaDictSpan;
121 // morkSpan mParser_TableSpan;
122 // morkSpan mParser_MetaTableSpan;
123 // morkSpan mParser_RowSpan;
124 // morkSpan mParser_MetaRowSpan;
125 // morkSpan mParser_CellSpan;
126 // morkSpan mParser_ColumnSpan;
127 // morkSpan mParser_SlotSpan;
129 // ````` ````` ````` ````` ````` ````` ````` `````
130 protected: // protected morkBuilder members
132 // weak refs that do not prevent closure of referenced nodes:
133 morkStore
* mBuilder_Store
; // weak ref to builder's store
135 // strong refs that do indeed prevent closure of referenced nodes:
136 morkTable
* mBuilder_Table
; // current table being built (or nil)
137 morkRow
* mBuilder_Row
; // current row being built (or nil)
138 morkCell
* mBuilder_Cell
; // current cell within CellsVec (or nil)
140 morkRowSpace
* mBuilder_RowSpace
; // space for mBuilder_CellRowScope
141 morkAtomSpace
* mBuilder_AtomSpace
; // space for mBuilder_CellAtomScope
143 morkAtomSpace
* mBuilder_OidAtomSpace
; // ground atom space for oids
144 morkAtomSpace
* mBuilder_ScopeAtomSpace
; // ground atom space for scopes
146 // scoped object ids for current objects under construction:
147 mdbOid mBuilder_TableOid
; // full oid for current table
148 mdbOid mBuilder_RowOid
; // full oid for current row
150 // tokens that become set as the result of meta cells in port rows:
151 mork_cscode mBuilder_PortForm
; // default port charset format
152 mork_scope mBuilder_PortRowScope
; // port row scope
153 mork_scope mBuilder_PortAtomScope
; // port atom scope
155 // tokens that become set as the result of meta cells in meta tables:
156 mork_cscode mBuilder_TableForm
; // default table charset format
157 mork_scope mBuilder_TableRowScope
; // table row scope
158 mork_scope mBuilder_TableAtomScope
; // table atom scope
159 mork_kind mBuilder_TableKind
; // table kind
161 mork_token mBuilder_TableStatus
; // dummy: priority/unique/verbose
163 mork_priority mBuilder_TablePriority
; // table priority
164 mork_bool mBuilder_TableIsUnique
; // table uniqueness
165 mork_bool mBuilder_TableIsVerbose
; // table verboseness
166 mork_u1 mBuilder_TablePadByte
; // for u4 alignment
168 // tokens that become set as the result of meta cells in meta rows:
169 mork_cscode mBuilder_RowForm
; // default row charset format
170 mork_scope mBuilder_RowRowScope
; // row scope per row metainfo
171 mork_scope mBuilder_RowAtomScope
; // row atom scope
173 // meta tokens currently in force, driven by meta info slots above:
174 mork_cscode mBuilder_CellForm
; // cell charset format
175 mork_scope mBuilder_CellAtomScope
; // cell atom scope
177 mork_cscode mBuilder_DictForm
; // dict charset format
178 mork_scope mBuilder_DictAtomScope
; // dict atom scope
180 mork_token
* mBuilder_MetaTokenSlot
; // pointer to some slot above
182 // If any of these 'cut' bools are true, it means a minus was seen in the
183 // Mork source text to indicate removal of content from some container.
184 // (Note there is no corresponding 'add' bool, since add is the default.)
185 // CutRow implies the current row should be cut from the table.
186 // CutCell implies the current column should be cut from the row.
187 mork_bool mBuilder_DoCutRow
; // row with kCut change
188 mork_bool mBuilder_DoCutCell
; // cell with kCut change
189 mork_u1 mBuilder_row_pad
; // pad to u4 alignment
190 mork_u1 mBuilder_cell_pad
; // pad to u4 alignment
192 morkCell mBuilder_CellsVec
[ morkBuilder_kCellsVecSize
+ 1 ];
193 mork_fill mBuilder_CellsVecFill
; // count used in CellsVec
194 // Note when mBuilder_CellsVecFill equals morkBuilder_kCellsVecSize, and
195 // another cell is added, this means all the cells in the vector above
196 // must be flushed to the current row being built to create more room.
198 protected: // protected inlines
200 mork_bool
CellVectorIsFull() const
201 { return ( mBuilder_CellsVecFill
== morkBuilder_kCellsVecSize
); }
203 // { ===== begin morkNode interface =====
204 public: // morkNode virtual methods
205 virtual void CloseMorkNode(morkEnv
* ev
); // CloseBuilder() only if open
206 virtual ~morkBuilder(); // assert that CloseBuilder() executed earlier
208 public: // morkYarn construction & destruction
209 morkBuilder(morkEnv
* ev
, const morkUsage
& inUsage
, nsIMdbHeap
* ioHeap
,
210 morkStream
* ioStream
, // the readonly stream for input bytes
211 mdb_count inBytesPerParseSegment
, // target for ParseMore()
212 nsIMdbHeap
* ioSlotHeap
, morkStore
* ioStore
215 void CloseBuilder(morkEnv
* ev
); // called by CloseMorkNode();
217 private: // copying is not allowed
218 morkBuilder(const morkBuilder
& other
);
219 morkBuilder
& operator=(const morkBuilder
& other
);
221 public: // dynamic type identification
222 mork_bool
IsBuilder() const
223 { return IsNode() && mNode_Derived
== morkDerived_kBuilder
; }
224 // } ===== end morkNode methods =====
227 static void NonBuilderTypeError(morkEnv
* ev
);
228 static void NilBuilderCellError(morkEnv
* ev
);
229 static void NilBuilderRowError(morkEnv
* ev
);
230 static void NilBuilderTableError(morkEnv
* ev
);
231 static void NonColumnSpaceScopeError(morkEnv
* ev
);
233 void LogGlitch(morkEnv
* ev
, const morkGlitch
& inGlitch
,
236 public: // other builder methods
238 morkCell
* AddBuilderCell(morkEnv
* ev
,
239 const morkMid
& inMid
, mork_change inChange
);
241 void FlushBuilderCells(morkEnv
* ev
);
243 // ````` ````` ````` ````` ````` ````` ````` `````
244 public: // in virtual morkParser methods, data flow subclass to parser
246 virtual void MidToYarn(morkEnv
* ev
,
247 const morkMid
& inMid
, // typically an alias to concat with strings
249 // The parser might ask that some aliases be turned into yarns, so they
250 // can be concatenated into longer blobs under some circumstances. This
251 // is an alternative to using a long and complex callback for many parts
252 // for a single cell value.
254 // ````` ````` ````` ````` ````` ````` ````` `````
255 public: // out virtual morkParser methods, data flow parser to subclass
257 virtual void OnNewPort(morkEnv
* ev
, const morkPlace
& inPlace
);
258 virtual void OnPortGlitch(morkEnv
* ev
, const morkGlitch
& inGlitch
);
259 virtual void OnPortEnd(morkEnv
* ev
, const morkSpan
& inSpan
);
261 virtual void OnNewGroup(morkEnv
* ev
, const morkPlace
& inPlace
, mork_gid inGid
);
262 virtual void OnGroupGlitch(morkEnv
* ev
, const morkGlitch
& inGlitch
);
263 virtual void OnGroupCommitEnd(morkEnv
* ev
, const morkSpan
& inSpan
);
264 virtual void OnGroupAbortEnd(morkEnv
* ev
, const morkSpan
& inSpan
);
266 virtual void OnNewPortRow(morkEnv
* ev
, const morkPlace
& inPlace
,
267 const morkMid
& inMid
, mork_change inChange
);
268 virtual void OnPortRowGlitch(morkEnv
* ev
, const morkGlitch
& inGlitch
);
269 virtual void OnPortRowEnd(morkEnv
* ev
, const morkSpan
& inSpan
);
271 virtual void OnNewTable(morkEnv
* ev
, const morkPlace
& inPlace
,
272 const morkMid
& inMid
, mork_bool inCutAllRows
);
273 virtual void OnTableGlitch(morkEnv
* ev
, const morkGlitch
& inGlitch
);
274 virtual void OnTableEnd(morkEnv
* ev
, const morkSpan
& inSpan
);
276 virtual void OnNewMeta(morkEnv
* ev
, const morkPlace
& inPlace
);
277 virtual void OnMetaGlitch(morkEnv
* ev
, const morkGlitch
& inGlitch
);
278 virtual void OnMetaEnd(morkEnv
* ev
, const morkSpan
& inSpan
);
280 virtual void OnMinusRow(morkEnv
* ev
);
281 virtual void OnNewRow(morkEnv
* ev
, const morkPlace
& inPlace
,
282 const morkMid
& inMid
, mork_bool inCutAllCols
);
283 virtual void OnRowPos(morkEnv
* ev
, mork_pos inRowPos
);
284 virtual void OnRowGlitch(morkEnv
* ev
, const morkGlitch
& inGlitch
);
285 virtual void OnRowEnd(morkEnv
* ev
, const morkSpan
& inSpan
);
287 virtual void OnNewDict(morkEnv
* ev
, const morkPlace
& inPlace
);
288 virtual void OnDictGlitch(morkEnv
* ev
, const morkGlitch
& inGlitch
);
289 virtual void OnDictEnd(morkEnv
* ev
, const morkSpan
& inSpan
);
291 virtual void OnAlias(morkEnv
* ev
, const morkSpan
& inSpan
,
292 const morkMid
& inMid
);
294 virtual void OnAliasGlitch(morkEnv
* ev
, const morkGlitch
& inGlitch
);
296 virtual void OnMinusCell(morkEnv
* ev
);
297 virtual void OnNewCell(morkEnv
* ev
, const morkPlace
& inPlace
,
298 const morkMid
* inMid
, const morkBuf
* inBuf
);
299 // Exactly one of inMid and inBuf is nil, and the other is non-nil.
300 // When hex ID syntax is used for a column, then inMid is not nil, and
301 // when a naked string names a column, then inBuf is not nil.
303 virtual void OnCellGlitch(morkEnv
* ev
, const morkGlitch
& inGlitch
);
304 virtual void OnCellForm(morkEnv
* ev
, mork_cscode inCharsetFormat
);
305 virtual void OnCellEnd(morkEnv
* ev
, const morkSpan
& inSpan
);
307 virtual void OnValue(morkEnv
* ev
, const morkSpan
& inSpan
,
308 const morkBuf
& inBuf
);
310 virtual void OnValueMid(morkEnv
* ev
, const morkSpan
& inSpan
,
311 const morkMid
& inMid
);
313 virtual void OnRowMid(morkEnv
* ev
, const morkSpan
& inSpan
,
314 const morkMid
& inMid
);
316 virtual void OnTableMid(morkEnv
* ev
, const morkSpan
& inSpan
,
317 const morkMid
& inMid
);
319 // ````` ````` ````` ````` ````` ````` ````` `````
320 public: // public non-poly morkBuilder methods
323 public: // typesafe refcounting inlines calling inherited morkNode methods
324 static void SlotWeakBuilder(morkBuilder
* me
,
325 morkEnv
* ev
, morkBuilder
** ioSlot
)
326 { morkNode::SlotWeakNode((morkNode
*) me
, ev
, (morkNode
**) ioSlot
); }
328 static void SlotStrongBuilder(morkBuilder
* me
,
329 morkEnv
* ev
, morkBuilder
** ioSlot
)
330 { morkNode::SlotStrongNode((morkNode
*) me
, ev
, (morkNode
**) ioSlot
); }
333 //3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
335 #endif /* _MORKBUILDER_ */