Back to index

lightning-sunbird  0.9+nobinonly
morkBuilder.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-  */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1999
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #ifndef _MORKBUILDER_
00039 #define _MORKBUILDER_ 1
00040 
00041 #ifndef _MORK_
00042 #include "mork.h"
00043 #endif
00044 
00045 #ifndef _MORKPARSER_
00046 #include "morkParser.h"
00047 #endif
00048 
00049 //3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
00050  
00051 /*| kCellsVecSize: length of cell vector buffer inside morkBuilder
00052 |*/
00053 #define morkBuilder_kCellsVecSize 64
00054 
00055 #define morkBuilder_kDefaultBytesPerParseSegment 512 /* plausible to big */
00056 
00057 #define morkDerived_kBuilder     /*i*/ 0x4275 /* ascii 'Bu' */
00058 
00059 class morkBuilder /*d*/ : public morkParser {
00060 
00061 // public: // slots inherited from morkParser (meant to inform only)
00062   // nsIMdbHeap*       mNode_Heap;
00063 
00064   // mork_base      mNode_Base;     // must equal morkBase_kNode
00065   // mork_derived   mNode_Derived;  // depends on specific node subclass
00066   
00067   // mork_access    mNode_Access;   // kOpen, kClosing, kShut, or kDead
00068   // mork_usage     mNode_Usage;    // kHeap, kStack, kMember, kGlobal, kNone
00069   // mork_able      mNode_Mutable;  // can this node be modified?
00070   // mork_load      mNode_Load;     // is this node clean or dirty?
00071   
00072   // mork_uses      mNode_Uses;     // refcount for strong refs
00073   // mork_refs      mNode_Refs;     // refcount for strong refs + weak refs
00074 
00075 
00076   // nsIMdbHeap*      mParser_Heap;   // refcounted heap used for allocation
00077   // morkStream*   mParser_Stream; // refcounted input stream
00078     
00079   // mork_u4       mParser_Tag; // must equal morkParser_kTag
00080   // mork_count    mParser_MoreGranularity; // constructor inBytesPerParseSegment
00081 
00082   // mork_u4       mParser_State; // state where parser should resume
00083  
00084   // after finding ends of group transactions, we can re-seek the start:
00085   // mork_pos      mParser_GroupContentStartPos; // start of this group
00086     
00087   // mdbOid        mParser_TableOid; // table oid if inside a table
00088   // mdbOid        mParser_RowOid;   // row oid if inside a row
00089   // mork_gid      mParser_GroupId; // group ID if inside a group
00090     
00091   // mork_bool     mParser_InPort;  // called OnNewPort but not OnPortEnd?
00092   // mork_bool     mParser_InDict;  // called OnNewDict but not OnDictEnd?
00093   // mork_bool     mParser_InCell;  // called OnNewCell but not OnCellEnd?
00094   // mork_bool     mParser_InMeta;  // called OnNewMeta but not OnMetaEnd?
00095     
00096   // morkMid     mParser_Mid;   // current alias being parsed
00097   // note that mParser_Mid.mMid_Buf points at mParser_ScopeCoil below:
00098     
00099   // blob coils allocated in mParser_Heap
00100   // morkCoil     mParser_ScopeCoil;   // place to accumulate ID scope blobs
00101   // morkCoil     mParser_ValueCoil;   // place to accumulate value blobs
00102   // morkCoil     mParser_ColumnCoil;  // place to accumulate column blobs
00103   // morkCoil     mParser_StringCoil;  // place to accumulate string blobs
00104     
00105   // morkSpool    mParser_ScopeSpool;  // writes to mParser_ScopeCoil
00106   // morkSpool    mParser_ValueSpool;  // writes to mParser_ValueCoil
00107   // morkSpool    mParser_ColumnSpool; // writes to mParser_ColumnCoil
00108   // morkSpool    mParser_StringSpool; // writes to mParser_StringCoil
00109 
00110   // yarns allocated in mParser_Heap
00111   // morkYarn      mParser_MidYarn;   // place to receive from MidToYarn()
00112   
00113   // span showing current ongoing file position status:
00114   // morkSpan      mParser_PortSpan; // span of current db port file
00115     
00116   // various spans denoting nested subspaces inside the file's port span:
00117   // morkSpan      mParser_GroupSpan; // span of current transaction group
00118   // morkSpan      mParser_DictSpan;
00119   // morkSpan      mParser_AliasSpan;
00120   // morkSpan      mParser_MetaDictSpan;
00121   // morkSpan      mParser_TableSpan;
00122   // morkSpan      mParser_MetaTableSpan;
00123   // morkSpan      mParser_RowSpan;
00124   // morkSpan      mParser_MetaRowSpan;
00125   // morkSpan      mParser_CellSpan;
00126   // morkSpan      mParser_ColumnSpan;
00127   // morkSpan      mParser_SlotSpan;
00128 
00129 // ````` ````` ````` `````   ````` ````` ````` `````  
00130 protected: // protected morkBuilder members
00131   
00132   // weak refs that do not prevent closure of referenced nodes:
00133   morkStore*       mBuilder_Store; // weak ref to builder's store
00134   
00135   // strong refs that do indeed prevent closure of referenced nodes:
00136   morkTable*       mBuilder_Table;    // current table being built (or nil)
00137   morkRow*         mBuilder_Row;      // current row being built (or nil)
00138   morkCell*        mBuilder_Cell;     // current cell within CellsVec (or nil)
00139   
00140   morkRowSpace*    mBuilder_RowSpace;  // space for mBuilder_CellRowScope
00141   morkAtomSpace*   mBuilder_AtomSpace; // space for mBuilder_CellAtomScope
00142   
00143   morkAtomSpace*   mBuilder_OidAtomSpace;   // ground atom space for oids
00144   morkAtomSpace*   mBuilder_ScopeAtomSpace; // ground atom space for scopes
00145   
00146   // scoped object ids for current objects under construction:
00147   mdbOid           mBuilder_TableOid; // full oid for current table
00148   mdbOid           mBuilder_RowOid;   // full oid for current row
00149       
00150   // tokens that become set as the result of meta cells in port rows:
00151   mork_cscode      mBuilder_PortForm;       // default port charset format
00152   mork_scope       mBuilder_PortRowScope;   // port row scope
00153   mork_scope       mBuilder_PortAtomScope;  // port atom scope
00154 
00155   // tokens that become set as the result of meta cells in meta tables:
00156   mork_cscode      mBuilder_TableForm;       // default table charset format
00157   mork_scope       mBuilder_TableRowScope;   // table row scope
00158   mork_scope       mBuilder_TableAtomScope;  // table atom scope
00159   mork_kind        mBuilder_TableKind;       // table kind
00160   
00161   mork_token       mBuilder_TableStatus;  // dummy: priority/unique/verbose
00162   
00163   mork_priority    mBuilder_TablePriority;   // table priority
00164   mork_bool        mBuilder_TableIsUnique;   // table uniqueness
00165   mork_bool        mBuilder_TableIsVerbose;  // table verboseness
00166   mork_u1          mBuilder_TablePadByte;    // for u4 alignment
00167   
00168   // tokens that become set as the result of meta cells in meta rows:
00169   mork_cscode      mBuilder_RowForm;       // default row charset format
00170   mork_scope       mBuilder_RowRowScope;   // row scope per row metainfo
00171   mork_scope       mBuilder_RowAtomScope;  // row atom scope
00172 
00173   // meta tokens currently in force, driven by meta info slots above:
00174   mork_cscode      mBuilder_CellForm;       // cell charset format
00175   mork_scope       mBuilder_CellAtomScope;  // cell atom scope
00176 
00177   mork_cscode      mBuilder_DictForm;       // dict charset format
00178   mork_scope       mBuilder_DictAtomScope;  // dict atom scope
00179 
00180   mork_token*      mBuilder_MetaTokenSlot; // pointer to some slot above
00181   
00182   // If any of these 'cut' bools are true, it means a minus was seen in the
00183   // Mork source text to indicate removal of content from some container.
00184   // (Note there is no corresponding 'add' bool, since add is the default.)
00185   // CutRow implies the current row should be cut from the table.
00186   // CutCell implies the current column should be cut from the row.
00187   mork_bool        mBuilder_DoCutRow;    // row with kCut change
00188   mork_bool        mBuilder_DoCutCell;   // cell with kCut change
00189   mork_u1          mBuilder_row_pad;    // pad to u4 alignment
00190   mork_u1          mBuilder_cell_pad;   // pad to u4 alignment
00191   
00192   morkCell         mBuilder_CellsVec[ morkBuilder_kCellsVecSize + 1 ];
00193   mork_fill        mBuilder_CellsVecFill; // count used in CellsVec
00194   // Note when mBuilder_CellsVecFill equals morkBuilder_kCellsVecSize, and 
00195   // another cell is added, this means all the cells in the vector above
00196   // must be flushed to the current row being built to create more room.
00197   
00198 protected: // protected inlines
00199 
00200   mork_bool  CellVectorIsFull() const
00201   { return ( mBuilder_CellsVecFill == morkBuilder_kCellsVecSize ); };
00202   
00203 // { ===== begin morkNode interface =====
00204 public: // morkNode virtual methods
00205   virtual void CloseMorkNode(morkEnv* ev); // CloseBuilder() only if open
00206   virtual ~morkBuilder(); // assert that CloseBuilder() executed earlier
00207   
00208 public: // morkYarn construction & destruction
00209   morkBuilder(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap,
00210     morkStream* ioStream,  // the readonly stream for input bytes
00211     mdb_count inBytesPerParseSegment, // target for ParseMore()
00212     nsIMdbHeap* ioSlotHeap, morkStore* ioStore
00213     );
00214       
00215   void CloseBuilder(morkEnv* ev); // called by CloseMorkNode();
00216 
00217 private: // copying is not allowed
00218   morkBuilder(const morkBuilder& other);
00219   morkBuilder& operator=(const morkBuilder& other);
00220 
00221 public: // dynamic type identification
00222   mork_bool IsBuilder() const
00223   { return IsNode() && mNode_Derived == morkDerived_kBuilder; }
00224 // } ===== end morkNode methods =====
00225 
00226 public: // errors
00227   static void NonBuilderTypeError(morkEnv* ev);
00228   static void NilBuilderCellError(morkEnv* ev);
00229   static void NilBuilderRowError(morkEnv* ev);
00230   static void NilBuilderTableError(morkEnv* ev);
00231   static void NonColumnSpaceScopeError(morkEnv* ev);
00232   
00233   void LogGlitch(morkEnv* ev, const morkGlitch& inGlitch, 
00234     const char* inKind);
00235 
00236 public: // other builder methods
00237 
00238   morkCell* AddBuilderCell(morkEnv* ev,
00239     const morkMid& inMid, mork_change inChange);
00240 
00241   void FlushBuilderCells(morkEnv* ev);
00242   
00243 // ````` ````` ````` `````   ````` ````` ````` `````  
00244 public: // in virtual morkParser methods, data flow subclass to parser
00245 
00246     virtual void MidToYarn(morkEnv* ev,
00247       const morkMid& inMid,  // typically an alias to concat with strings
00248       mdbYarn* outYarn);
00249     // The parser might ask that some aliases be turned into yarns, so they
00250     // can be concatenated into longer blobs under some circumstances.  This
00251     // is an alternative to using a long and complex callback for many parts
00252     // for a single cell value.
00253   
00254 // ````` ````` ````` `````   ````` ````` ````` `````  
00255 public: // out virtual morkParser methods, data flow parser to subclass
00256 
00257   virtual void OnNewPort(morkEnv* ev, const morkPlace& inPlace);
00258   virtual void OnPortGlitch(morkEnv* ev, const morkGlitch& inGlitch);  
00259   virtual void OnPortEnd(morkEnv* ev, const morkSpan& inSpan);  
00260 
00261   virtual void OnNewGroup(morkEnv* ev, const morkPlace& inPlace, mork_gid inGid);
00262   virtual void OnGroupGlitch(morkEnv* ev, const morkGlitch& inGlitch);  
00263   virtual void OnGroupCommitEnd(morkEnv* ev, const morkSpan& inSpan);  
00264   virtual void OnGroupAbortEnd(morkEnv* ev, const morkSpan& inSpan);  
00265 
00266   virtual void OnNewPortRow(morkEnv* ev, const morkPlace& inPlace, 
00267     const morkMid& inMid, mork_change inChange);
00268   virtual void OnPortRowGlitch(morkEnv* ev, const morkGlitch& inGlitch);  
00269   virtual void OnPortRowEnd(morkEnv* ev, const morkSpan& inSpan);  
00270 
00271   virtual void OnNewTable(morkEnv* ev, const morkPlace& inPlace,
00272     const morkMid& inMid, mork_bool inCutAllRows);
00273   virtual void OnTableGlitch(morkEnv* ev, const morkGlitch& inGlitch);
00274   virtual void OnTableEnd(morkEnv* ev, const morkSpan& inSpan);
00275     
00276   virtual void OnNewMeta(morkEnv* ev, const morkPlace& inPlace);
00277   virtual void OnMetaGlitch(morkEnv* ev, const morkGlitch& inGlitch);
00278   virtual void OnMetaEnd(morkEnv* ev, const morkSpan& inSpan);
00279 
00280   virtual void OnMinusRow(morkEnv* ev);
00281   virtual void OnNewRow(morkEnv* ev, const morkPlace& inPlace, 
00282     const morkMid& inMid, mork_bool inCutAllCols);
00283   virtual void OnRowPos(morkEnv* ev, mork_pos inRowPos);  
00284   virtual void OnRowGlitch(morkEnv* ev, const morkGlitch& inGlitch);  
00285   virtual void OnRowEnd(morkEnv* ev, const morkSpan& inSpan);  
00286 
00287   virtual void OnNewDict(morkEnv* ev, const morkPlace& inPlace);
00288   virtual void OnDictGlitch(morkEnv* ev, const morkGlitch& inGlitch);  
00289   virtual void OnDictEnd(morkEnv* ev, const morkSpan& inSpan);  
00290 
00291   virtual void OnAlias(morkEnv* ev, const morkSpan& inSpan,
00292     const morkMid& inMid);
00293 
00294   virtual void OnAliasGlitch(morkEnv* ev, const morkGlitch& inGlitch);
00295 
00296   virtual void OnMinusCell(morkEnv* ev);
00297   virtual void OnNewCell(morkEnv* ev, const morkPlace& inPlace,
00298     const morkMid* inMid, const morkBuf* inBuf);
00299   // Exactly one of inMid and inBuf is nil, and the other is non-nil.
00300   // When hex ID syntax is used for a column, then inMid is not nil, and
00301   // when a naked string names a column, then inBuf is not nil.
00302 
00303   virtual void OnCellGlitch(morkEnv* ev, const morkGlitch& inGlitch);
00304   virtual void OnCellForm(morkEnv* ev, mork_cscode inCharsetFormat);
00305   virtual void OnCellEnd(morkEnv* ev, const morkSpan& inSpan);
00306     
00307   virtual void OnValue(morkEnv* ev, const morkSpan& inSpan,
00308     const morkBuf& inBuf);
00309 
00310   virtual void OnValueMid(morkEnv* ev, const morkSpan& inSpan,
00311     const morkMid& inMid);
00312 
00313   virtual void OnRowMid(morkEnv* ev, const morkSpan& inSpan,
00314     const morkMid& inMid);
00315 
00316   virtual void OnTableMid(morkEnv* ev, const morkSpan& inSpan,
00317     const morkMid& inMid);
00318   
00319 // ````` ````` ````` `````   ````` ````` ````` `````  
00320 public: // public non-poly morkBuilder methods
00321   
00322   
00323 public: // typesafe refcounting inlines calling inherited morkNode methods
00324   static void SlotWeakBuilder(morkBuilder* me,
00325     morkEnv* ev, morkBuilder** ioSlot)
00326   { morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); }
00327   
00328   static void SlotStrongBuilder(morkBuilder* me,
00329     morkEnv* ev, morkBuilder** ioSlot)
00330   { morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); }
00331 };
00332 
00333 //3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
00334 
00335 #endif /* _MORKBUILDER_ */