зеркало из https://github.com/mozilla/pjs.git
get mork parsing working so we can read existing databases
This commit is contained in:
Родитель
1dbbb52112
Коммит
18e5d15e51
|
@ -48,6 +48,7 @@ CPPSRCS = \
|
|||
morkBuilder.cpp\
|
||||
morkCell.cpp\
|
||||
morkCellObject.cpp\
|
||||
morkCh.cpp\
|
||||
morkConfig.cpp\
|
||||
morkCursor.cpp \
|
||||
morkDeque.cpp\
|
||||
|
|
|
@ -47,6 +47,7 @@ CPPSRCS= orkinCell.cpp\
|
|||
morkBuilder.cpp\
|
||||
morkCell.cpp\
|
||||
morkCellObject.cpp\
|
||||
morkCh.cpp\
|
||||
morkConfig.cpp\
|
||||
morkCursor.cpp \
|
||||
morkDeque.cpp\
|
||||
|
@ -97,6 +98,7 @@ CPP_OBJS= .\$(OBJDIR)\orkinCell.obj\
|
|||
.\$(OBJDIR)\morkBuilder.obj\
|
||||
.\$(OBJDIR)\morkCell.obj\
|
||||
.\$(OBJDIR)\morkCellObject.obj\
|
||||
.\$(OBJDIR)\morkCh.obj\
|
||||
.\$(OBJDIR)\morkConfig.obj\
|
||||
.\$(OBJDIR)\morkCursor.obj\
|
||||
.\$(OBJDIR)\morkDeque.obj\
|
||||
|
|
|
@ -64,6 +64,8 @@ typedef unsigned long mork_u4; // make sure this is four bytes
|
|||
typedef long mork_i4; // make sure this is four bytes
|
||||
typedef long mork_ip; // make sure sizeof(mork_ip) == sizeof(void*)
|
||||
|
||||
typedef mork_u1 mork_ch; // small byte-sized character (never wide)
|
||||
|
||||
typedef mork_u2 mork_base; // 2-byte magic class signature slot in object
|
||||
typedef mork_u2 mork_derived; // 2-byte magic class signature slot in object
|
||||
typedef mork_u2 mork_uses; // 2-byte strong uses count
|
||||
|
@ -109,6 +111,9 @@ typedef mork_u1 mork_load; // dirty or clean (clone IronDoc's fe_load)
|
|||
#define morkChange_kPut 'p' /* put member */
|
||||
#define morkChange_kSet 's' /* set all members */
|
||||
#define morkChange_kNil 0 /* no change in this member */
|
||||
#define morkChange_kDup 'd' /* duplicate changes have no effect */
|
||||
// kDup is intended to replace another change constant in an object as a
|
||||
// conclusion about change feasibility while staging intended alterations.
|
||||
|
||||
#define morkLoad_kDirty ((mork_load) 0xDD) /* same as IronDoc constant */
|
||||
#define morkLoad_kClean ((mork_load) 0x22) /* same as IronDoc constant */
|
||||
|
@ -147,6 +152,7 @@ typedef mdb_order mork_order; // neg:lessthan, zero:equalto, pos:greaterthan
|
|||
|
||||
// { %%%%% begin class forward defines %%%%%
|
||||
// try to put these in alphabetical order for easier examination:
|
||||
class morkMid;
|
||||
class morkAtom;
|
||||
class morkAtomSpace;
|
||||
class morkBookAtom;
|
||||
|
@ -168,6 +174,7 @@ class morkObject;
|
|||
class morkOidAtom;
|
||||
class morkParser;
|
||||
class morkPool;
|
||||
class morkPlace;
|
||||
class morkPort;
|
||||
class morkPortTableCursor;
|
||||
class morkRow;
|
||||
|
@ -175,6 +182,7 @@ class morkRowCellCursor;
|
|||
class morkRowObject;
|
||||
class morkRowSpace;
|
||||
class morkSpace;
|
||||
class morkSpan;
|
||||
class morkStore;
|
||||
class morkStream;
|
||||
class morkTable;
|
||||
|
|
|
@ -305,7 +305,7 @@ class morkMaxBookAtom : public morkBigBookAtom { //
|
|||
// mork_u1 mBigBookAtom_Body[ 1 ]; // 1st byte of immed content vector
|
||||
|
||||
public:
|
||||
mork_u1 mBigBookAtom_Body[ morkBookAtom_kMaxBodySize + 3 ]; // max bytes
|
||||
mork_u1 mMaxBookAtom_Body[ morkBookAtom_kMaxBodySize + 3 ]; // max bytes
|
||||
|
||||
public: // empty construction does nothing
|
||||
morkMaxBookAtom() { }
|
||||
|
|
|
@ -138,11 +138,11 @@ public: // dynamic type identification
|
|||
// { ===== begin morkMap poly interface =====
|
||||
virtual mork_bool // note: equal(a,b) implies hash(a) == hash(b)
|
||||
Equal(morkEnv* ev, const void* inKeyA, const void* inKeyB) const;
|
||||
// implemented using morkBookAtom::HashFormAndBody()
|
||||
// implemented using morkBookAtom::EqualFormAndBody()
|
||||
|
||||
virtual mork_u4 // note: equal(a,b) implies hash(a) == hash(b)
|
||||
Hash(morkEnv* ev, const void* inKey) const;
|
||||
// implemented using morkBookAtom::EqualFormAndBody()
|
||||
// implemented using morkBookAtom::HashFormAndBody()
|
||||
// } ===== end morkMap poly interface =====
|
||||
|
||||
public: // other map methods
|
||||
|
|
|
@ -153,6 +153,32 @@ morkAtomSpace::CutAllAtoms(morkEnv* ev, morkPool* ioPool)
|
|||
}
|
||||
|
||||
|
||||
morkBookAtom*
|
||||
morkAtomSpace::MakeBookAtomCopyWithAid(morkEnv* ev,
|
||||
const morkBigBookAtom& inAtom, mork_aid inAid)
|
||||
// Make copy of inAtom and put it in both maps, using specified ID.
|
||||
{
|
||||
morkBookAtom* outAtom = 0;
|
||||
if ( ev->Good() )
|
||||
{
|
||||
morkPool* pool = this->GetSpaceStorePool();
|
||||
outAtom = pool->NewBookAtomCopy(ev, inAtom);
|
||||
if ( outAtom )
|
||||
{
|
||||
outAtom->mBookAtom_Id = inAid;
|
||||
outAtom->mBookAtom_Space = this;
|
||||
mAtomSpace_AtomAids.AddAtom(ev, outAtom);
|
||||
mAtomSpace_AtomBodies.AddAtom(ev, outAtom);
|
||||
if ( mSpace_Scope == morkAtomSpace_kColumnScope )
|
||||
outAtom->MakeCellUseForever(ev);
|
||||
|
||||
if ( mAtomSpace_HighUnderId <= inAid )
|
||||
mAtomSpace_HighUnderId = inAid + 1;
|
||||
}
|
||||
}
|
||||
return outAtom;
|
||||
}
|
||||
|
||||
morkBookAtom*
|
||||
morkAtomSpace::MakeBookAtomCopy(morkEnv* ev, const morkBigBookAtom& inAtom)
|
||||
// make copy of inAtom and put it in both maps, using a new ID as needed.
|
||||
|
@ -167,9 +193,12 @@ morkAtomSpace::MakeBookAtomCopy(morkEnv* ev, const morkBigBookAtom& inAtom)
|
|||
mork_aid id = this->MakeNewAtomId(ev, atom);
|
||||
if ( id )
|
||||
{
|
||||
outAtom = atom;
|
||||
outAtom = atom;
|
||||
atom->mBookAtom_Space = this;
|
||||
mAtomSpace_AtomAids.AddAtom(ev, atom);
|
||||
mAtomSpace_AtomBodies.AddAtom(ev, atom);
|
||||
if ( mSpace_Scope == morkAtomSpace_kColumnScope )
|
||||
outAtom->MakeCellUseForever(ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,6 +64,8 @@
|
|||
|
||||
#define morkDerived_kAtomSpace /*i*/ 0x6153 /* ascii 'aS' */
|
||||
|
||||
#define morkAtomSpace_kColumnScope ((mork_scope) 'c') /* column scope is forever */
|
||||
|
||||
/*| morkAtomSpace:
|
||||
|*/
|
||||
class morkAtomSpace : public morkSpace { //
|
||||
|
@ -132,6 +134,10 @@ public: // other space methods
|
|||
mork_num CutAllAtoms(morkEnv* ev, morkPool* ioPool);
|
||||
// CutAllAtoms() puts all the atoms back in the pool.
|
||||
|
||||
morkBookAtom* MakeBookAtomCopyWithAid(morkEnv* ev,
|
||||
const morkBigBookAtom& inAtom, mork_aid inAid);
|
||||
// Make copy of inAtom and put it in both maps, using specified ID.
|
||||
|
||||
morkBookAtom* MakeBookAtomCopy(morkEnv* ev, const morkBigBookAtom& inAtom);
|
||||
// Make copy of inAtom and put it in both maps, using a new ID as needed.
|
||||
|
||||
|
|
|
@ -32,31 +32,92 @@
|
|||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
morkSpool::morkSpool(morkEnv* ev, nsIMdbHeap* ioHeap)
|
||||
/*static*/ void
|
||||
morkBuf::NilBufBodyError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("nil mBuf_Body");
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
/*static*/ void
|
||||
morkBlob::BlobFillOverSizeError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("mBuf_Fill > mBlob_Size");
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
mork_bool
|
||||
morkBlob::GrowBlob(morkEnv* ev, nsIMdbHeap* ioHeap, mork_size inNewSize)
|
||||
{
|
||||
if ( ioHeap )
|
||||
{
|
||||
if ( !mBuf_Body ) // no body? implies zero sized?
|
||||
mBlob_Size = 0;
|
||||
|
||||
if ( mBuf_Fill > mBlob_Size ) // fill more than size?
|
||||
{
|
||||
ev->NewWarning("mBuf_Fill > mBlob_Size");
|
||||
mBuf_Fill = mBlob_Size;
|
||||
}
|
||||
|
||||
if ( inNewSize > mBlob_Size ) // need to allocate larger blob?
|
||||
{
|
||||
mork_u1* body = 0;
|
||||
ioHeap->Alloc(ev->AsMdbEnv(), inNewSize, (void**) &body);
|
||||
if ( body && ev->Good() )
|
||||
{
|
||||
void* oldBody = mBuf_Body;
|
||||
if ( mBlob_Size ) // any old content to transfer?
|
||||
MORK_MEMCPY(body, oldBody, mBlob_Size);
|
||||
|
||||
mBlob_Size = inNewSize; // install new size
|
||||
mBuf_Body = body; // install new body
|
||||
|
||||
if ( oldBody ) // need to free old buffer body?
|
||||
ioHeap->Free(ev->AsMdbEnv(), oldBody);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
|
||||
if ( ev->Good() && mBlob_Size < inNewSize )
|
||||
ev->NewError("mBlob_Size < inNewSize");
|
||||
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
morkCoil::morkCoil(morkEnv* ev, nsIMdbHeap* ioHeap)
|
||||
{
|
||||
mBuf_Body = 0;
|
||||
mBuf_Fill = 0;
|
||||
mBlob_Size = 0;
|
||||
mText_Form = 0;
|
||||
mSpool_Heap = ioHeap;
|
||||
mCoil_Heap = ioHeap;
|
||||
if ( !ioHeap )
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
void
|
||||
morkSpool::CloseSpool(morkEnv* ev)
|
||||
morkCoil::CloseCoil(morkEnv* ev)
|
||||
{
|
||||
void* body = mBuf_Body;
|
||||
nsIMdbHeap* heap = mSpool_Heap;
|
||||
nsIMdbHeap* heap = mCoil_Heap;
|
||||
|
||||
mBuf_Body = 0;
|
||||
mCoil_Heap = 0;
|
||||
|
||||
if ( body && heap )
|
||||
{
|
||||
heap->Free(ev->AsMdbEnv(), body);
|
||||
}
|
||||
mBuf_Body = 0;
|
||||
mSpool_Heap = 0;
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
|
|
@ -39,6 +39,10 @@ public:
|
|||
morkBuf(const void* ioBuf, mork_fill inFill)
|
||||
: mBuf_Body((void*) ioBuf), mBuf_Fill(inFill) { }
|
||||
|
||||
void ClearBufFill() { mBuf_Fill = 0; }
|
||||
|
||||
static void NilBufBodyError(morkEnv* ev);
|
||||
|
||||
private: // copying is not allowed
|
||||
morkBuf(const morkBuf& other);
|
||||
morkBuf& operator=(const morkBuf& other);
|
||||
|
@ -61,9 +65,12 @@ public:
|
|||
morkBlob() { }
|
||||
morkBlob(const void* ioBuf, mork_fill inFill, mork_size inSize)
|
||||
: morkBuf(ioBuf, inFill), mBlob_Size(inSize) { }
|
||||
|
||||
|
||||
static void BlobFillOverSizeError(morkEnv* ev);
|
||||
|
||||
public:
|
||||
mork_bool Grow(morkEnv* ev, nsIMdbHeap* ioHeap, mork_size inNewSize);
|
||||
mork_bool GrowBlob(morkEnv* ev, nsIMdbHeap* ioHeap,
|
||||
mork_size inNewSize);
|
||||
|
||||
private: // copying is not allowed
|
||||
morkBlob(const morkBlob& other);
|
||||
|
@ -94,49 +101,52 @@ private: // copying is not allowed
|
|||
morkText& operator=(const morkText& other);
|
||||
};
|
||||
|
||||
/*| Spool: a text with an associated nsIMdbHeap instance that provides
|
||||
/*| Coil: a text with an associated nsIMdbHeap instance that provides
|
||||
**| all memory management for the space pointed to by mBuf_Body. (This
|
||||
**| was the hardest type to give a name in this small class hierarchy,
|
||||
**| because it's hard to characterize self-management of one's space.)
|
||||
**| A spool is a self-contained blob that knows how to grow itself as
|
||||
**| necessary to hold more content when necessary. Spool descends from
|
||||
**| A coil is a self-contained blob that knows how to grow itself as
|
||||
**| necessary to hold more content when necessary. Coil descends from
|
||||
**| morkText to include the mText_Form slot, even though this won't be
|
||||
**| needed always, because we are not as concerned about the overall
|
||||
**| size of this particular Spool object (if we were concerned about
|
||||
**| the size of an array of Spool instances, we would not bother with
|
||||
**| size of this particular Coil object (if we were concerned about
|
||||
**| the size of an array of Coil instances, we would not bother with
|
||||
**| a separate heap pointer for each of them).
|
||||
**|
|
||||
**|| A spool makes a good medium in which to stream content as a sink,
|
||||
**| so we will have a subclass of morkSink called morkSpoolSink that
|
||||
**| will stream bytes into this self-contained spool object. The name
|
||||
**| of this morkSpool class derives more from this intended usage than
|
||||
**|| A coil makes a good medium in which to stream content as a sink,
|
||||
**| so we will have a subclass of morkSink called morkCoil that
|
||||
**| will stream bytes into this self-contained coil object. The name
|
||||
**| of this morkCoil class derives more from this intended usage than
|
||||
**| from anything else. The Mork code to parse db content will use
|
||||
**| spools with associated sinks to accumulate parsed strings.
|
||||
**| coils with associated sinks to accumulate parsed strings.
|
||||
**|
|
||||
**|| Heap: this is the heap used for memory allocation. This instance
|
||||
**| is NOT refcounted, since this spool always assumes the heap is held
|
||||
**| is NOT refcounted, since this coil always assumes the heap is held
|
||||
**| through a reference elsewhere (for example, through the same object
|
||||
**| that contains or holds the spool itself. This lack of refcounting
|
||||
**| is consistent with the fact that morkSpool itself is not refcounted,
|
||||
**| that contains or holds the coil itself. This lack of refcounting
|
||||
**| is consistent with the fact that morkCoil itself is not refcounted,
|
||||
**| and is not intended for use as a standalone object.
|
||||
|*/
|
||||
class morkSpool : public morkText { // self-managing text blob object
|
||||
class morkCoil : public morkText { // self-managing text blob object
|
||||
|
||||
// void* mBuf_Body; // space for holding any binary content
|
||||
// mdb_fill mBuf_Fill; // logical content in Buf in bytes
|
||||
// mdb_size mBlob_Size; // physical size of Buf in bytes
|
||||
// mdb_cscode mText_Form; // charset format encoding
|
||||
public:
|
||||
nsIMdbHeap* mSpool_Heap; // storage manager for mBuf_Body pointer
|
||||
nsIMdbHeap* mCoil_Heap; // storage manager for mBuf_Body pointer
|
||||
|
||||
public:
|
||||
morkSpool(morkEnv* ev, nsIMdbHeap* ioHeap);
|
||||
morkCoil(morkEnv* ev, nsIMdbHeap* ioHeap);
|
||||
|
||||
void CloseSpool(morkEnv* ev);
|
||||
void CloseCoil(morkEnv* ev);
|
||||
|
||||
mork_bool GrowCoil(morkEnv* ev, mork_size inNewSize)
|
||||
{ return this->GrowBlob(ev, mCoil_Heap, inNewSize); }
|
||||
|
||||
private: // copying is not allowed
|
||||
morkSpool(const morkSpool& other);
|
||||
morkSpool& operator=(const morkSpool& other);
|
||||
morkCoil(const morkCoil& other);
|
||||
morkCoil& operator=(const morkCoil& other);
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
|
|
@ -48,6 +48,34 @@
|
|||
#include "morkCell.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKSTORE_
|
||||
#include "morkStore.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKTABLE_
|
||||
#include "morkTable.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKROW_
|
||||
#include "morkRow.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKCELL_
|
||||
#include "morkCell.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKATOM_
|
||||
#include "morkAtom.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKATOMSPACE_
|
||||
#include "morkAtomSpace.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKROWSPACE_
|
||||
#include "morkRowSpace.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
|
@ -67,7 +95,12 @@ morkBuilder::CloseMorkNode(morkEnv* ev) // CloseBuilder() only if open
|
|||
/*public virtual*/
|
||||
morkBuilder::~morkBuilder() // assert CloseBuilder() executed earlier
|
||||
{
|
||||
MORK_ASSERT(mBuilder_Store==0);
|
||||
MORK_ASSERT(mBuilder_Row==0);
|
||||
MORK_ASSERT(mBuilder_Table==0);
|
||||
MORK_ASSERT(mBuilder_Cell==0);
|
||||
MORK_ASSERT(mBuilder_RowSpace==0);
|
||||
MORK_ASSERT(mBuilder_AtomSpace==0);
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
|
@ -75,11 +108,67 @@ morkBuilder::morkBuilder(morkEnv* ev,
|
|||
const morkUsage& inUsage, nsIMdbHeap* ioHeap,
|
||||
morkStream* ioStream, mdb_count inBytesPerParseSegment,
|
||||
nsIMdbHeap* ioSlotHeap, morkStore* ioStore)
|
||||
|
||||
: morkParser(ev, inUsage, ioHeap, ioStream,
|
||||
inBytesPerParseSegment, ioSlotHeap)
|
||||
|
||||
, mBuilder_Store( 0 )
|
||||
|
||||
, mBuilder_Table( 0 )
|
||||
, mBuilder_Row( 0 )
|
||||
, mBuilder_Cell( 0 )
|
||||
|
||||
, mBuilder_RowSpace( 0 )
|
||||
, mBuilder_AtomSpace( 0 )
|
||||
|
||||
, mBuilder_OidAtomSpace( 0 )
|
||||
, mBuilder_ScopeAtomSpace( 0 )
|
||||
|
||||
, mBuilder_iso_8859_1( 0 )
|
||||
, mBuilder_r( (mork_scope) 'r' )
|
||||
, mBuilder_a( (mork_scope) 'a' )
|
||||
, mBuilder_t( (mork_scope) 't' )
|
||||
|
||||
, mBuilder_MorkNoneToken( 0 )
|
||||
|
||||
, mBuilder_PortForm( 0 )
|
||||
, mBuilder_PortRowScope( (mork_scope) 'r' )
|
||||
, mBuilder_PortAtomScope( (mork_scope) 'a' )
|
||||
|
||||
, mBuilder_TableForm( 0 )
|
||||
, mBuilder_TableRowScope( (mork_scope) 'r' )
|
||||
, mBuilder_TableAtomScope( (mork_scope) 'a' )
|
||||
, mBuilder_TableKind( 0 )
|
||||
|
||||
, mBuilder_RowForm( 0 )
|
||||
, mBuilder_RowRowScope( (mork_scope) 'r' )
|
||||
, mBuilder_RowAtomScope( (mork_scope) 'a' )
|
||||
|
||||
, mBuilder_CellForm( 0 )
|
||||
, mBuilder_CellAtomScope( (mork_scope) 'a' )
|
||||
|
||||
, mBuilder_DictForm( 0 )
|
||||
, mBuilder_DictAtomScope( (mork_scope) 'a' )
|
||||
|
||||
, mBuilder_MetaTokenSlot( 0 )
|
||||
|
||||
, mBuilder_DoCutRow( morkBool_kFalse )
|
||||
, mBuilder_DoCutCell( morkBool_kFalse )
|
||||
, mBuilder_CellsVecFill( 0 )
|
||||
{
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kBuilder;
|
||||
{
|
||||
if ( ioStore )
|
||||
{
|
||||
mBuilder_MorkNoneToken = ioStore->mStore_MorkNoneToken;
|
||||
morkStore::SlotWeakStore(ioStore, ev, &mBuilder_Store);
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kBuilder;
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
|
@ -89,6 +178,24 @@ morkBuilder::CloseBuilder(morkEnv* ev) // called by CloseMorkNode();
|
|||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
mBuilder_Row = 0;
|
||||
mBuilder_Cell = 0;
|
||||
mBuilder_MetaTokenSlot = 0;
|
||||
|
||||
morkTable::SlotStrongTable((morkTable*) 0, ev, &mBuilder_Table);
|
||||
morkStore::SlotWeakStore((morkStore*) 0, ev, &mBuilder_Store);
|
||||
|
||||
morkRowSpace::SlotStrongRowSpace((morkRowSpace*) 0, ev,
|
||||
&mBuilder_RowSpace);
|
||||
|
||||
morkAtomSpace::SlotStrongAtomSpace((morkAtomSpace*) 0, ev,
|
||||
&mBuilder_AtomSpace);
|
||||
|
||||
morkAtomSpace::SlotStrongAtomSpace((morkAtomSpace*) 0, ev,
|
||||
&mBuilder_OidAtomSpace);
|
||||
|
||||
morkAtomSpace::SlotStrongAtomSpace((morkAtomSpace*) 0, ev,
|
||||
&mBuilder_ScopeAtomSpace);
|
||||
this->CloseParser(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
|
@ -108,217 +215,655 @@ morkBuilder::NonBuilderTypeError(morkEnv* ev)
|
|||
ev->NewError("non morkBuilder");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkBuilder::NilBuilderCellError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("nil mBuilder_Cell");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkBuilder::NilBuilderRowError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("nil mBuilder_Row");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkBuilder::NilBuilderTableError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("nil mBuilder_Table");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkBuilder::NonColumnSpaceScopeError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("column space != 'c'");
|
||||
}
|
||||
|
||||
void
|
||||
morkBuilder::LogGlitch(morkEnv* ev, const morkGlitch& inGlitch,
|
||||
const char* inKind)
|
||||
{
|
||||
ev->NewWarning("parsing glitch");
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::AliasToYarn(morkEnv* ev,
|
||||
const morkAlias& inAlias, // typically an alias to concat with strings
|
||||
morkBuilder::MidToYarn(morkEnv* ev,
|
||||
const morkMid& inMid, // typically an alias to concat with strings
|
||||
mdbYarn* outYarn)
|
||||
// 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.
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
mBuilder_Store->MidToYarn(ev, inMid, outYarn);
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnNewPort(morkEnv* ev, const morkPlace& inPlace)
|
||||
// mp:Start ::= OnNewPort mp:PortItem* OnPortEnd
|
||||
// mp:PortItem ::= mp:Content | mp:Group | OnPortGlitch
|
||||
// mp:Content ::= mp:PortRow | mp:Dict | mp:Table | mp:Row
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// mParser_InPort = morkBool_kTrue;
|
||||
mBuilder_PortForm = 0;
|
||||
mBuilder_PortRowScope = (mork_scope) 'r';
|
||||
mBuilder_PortAtomScope = (mork_scope) 'a';
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnPortGlitch(morkEnv* ev, const morkGlitch& inGlitch)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
this->LogGlitch(ev, inGlitch, "port");
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnPortEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
// mp:Start ::= OnNewPort mp:PortItem* OnPortEnd
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// ev->StubMethodOnlyError();
|
||||
// nothing to do?
|
||||
// mParser_InPort = morkBool_kFalse;
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnNewGroup(morkEnv* ev, const morkPlace& inPlace, mork_gid inGid)
|
||||
{
|
||||
// mParser_InGroup = morkBool_kTrue;
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnGroupGlitch(morkEnv* ev, const morkGlitch& inGlitch)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
this->LogGlitch(ev, inGlitch, "group");
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnGroupCommitEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
{
|
||||
// mParser_InGroup = morkBool_kFalse;
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnGroupAbortEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
{
|
||||
// mParser_InGroup = morkBool_kFalse;
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnNewPortRow(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange)
|
||||
const morkMid& inMid, mork_change inChange)
|
||||
{
|
||||
// mParser_InPortRow = morkBool_kTrue;
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnPortRowGlitch(morkEnv* ev, const morkGlitch& inGlitch)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
this->LogGlitch(ev, inGlitch, "port row");
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnPortRowEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
{
|
||||
// mParser_InPortRow = morkBool_kFalse;
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnNewTable(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange)
|
||||
const morkMid& inMid, mork_change inChange)
|
||||
// mp:Table ::= OnNewTable mp:TableItem* OnTableEnd
|
||||
// mp:TableItem ::= mp:Row | mp:Meta | OnTableGlitch
|
||||
// mp:Meta ::= OnNewMeta mp:MetaItem* OnMetaEnd
|
||||
// mp:MetaItem ::= mp:Cell | OnMetaGlitch
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// mParser_InTable = morkBool_kTrue;
|
||||
mBuilder_TableForm = mBuilder_PortForm;
|
||||
mBuilder_TableRowScope = mBuilder_PortRowScope;
|
||||
mBuilder_TableAtomScope = mBuilder_PortAtomScope;
|
||||
mBuilder_TableKind = mBuilder_MorkNoneToken;
|
||||
|
||||
morkTable* table = mBuilder_Store->MidToTable(ev, inMid);
|
||||
morkTable::SlotStrongTable(table, ev, &mBuilder_Table);
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnTableGlitch(morkEnv* ev, const morkGlitch& inGlitch)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
this->LogGlitch(ev, inGlitch, "table");
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnTableEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
// mp:Table ::= OnNewTable mp:TableItem* OnTableEnd
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// mParser_InTable = morkBool_kFalse;
|
||||
if ( mBuilder_Table )
|
||||
{
|
||||
morkTable::SlotStrongTable((morkTable*) 0, ev, &mBuilder_Table);
|
||||
}
|
||||
else
|
||||
this->NilBuilderTableError(ev);
|
||||
|
||||
mBuilder_Row = 0;
|
||||
mBuilder_Cell = 0;
|
||||
|
||||
if ( mBuilder_TableKind == mBuilder_MorkNoneToken )
|
||||
ev->NewError("missing table kind");
|
||||
|
||||
mBuilder_CellAtomScope = mBuilder_RowAtomScope =
|
||||
mBuilder_TableAtomScope = mBuilder_PortAtomScope;
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnNewMeta(morkEnv* ev, const morkPlace& inPlace)
|
||||
// mp:Meta ::= OnNewMeta mp:MetaItem* OnMetaEnd
|
||||
// mp:MetaItem ::= mp:Cell | OnMetaGlitch
|
||||
// mp:Cell ::= OnNewCell mp:CellItem? OnCellEnd
|
||||
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
|
||||
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// mParser_InMeta = morkBool_kTrue;
|
||||
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnMetaGlitch(morkEnv* ev, const morkGlitch& inGlitch)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
this->LogGlitch(ev, inGlitch, "meta");
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnMetaEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
// mp:Meta ::= OnNewMeta mp:MetaItem* OnMetaEnd
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// mParser_InMeta = morkBool_kFalse;
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnNewRow(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange)
|
||||
const morkMid& inMid, mork_change inChange)
|
||||
// mp:Row ::= OnNewRow mp:RowItem* OnRowEnd
|
||||
// mp:RowItem ::= mp:Cell | mp:Meta | OnRowGlitch
|
||||
// mp:Cell ::= OnNewCell mp:CellItem? OnCellEnd
|
||||
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
|
||||
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// mParser_InRow = morkBool_kTrue;
|
||||
if ( mBuilder_Table )
|
||||
{
|
||||
mBuilder_CellForm = mBuilder_RowForm = mBuilder_TableForm;
|
||||
mBuilder_CellAtomScope = mBuilder_RowAtomScope = mBuilder_TableAtomScope;
|
||||
mBuilder_RowRowScope = mBuilder_TableRowScope;
|
||||
morkStore* store = mBuilder_Store;
|
||||
|
||||
if ( !inMid.mMid_Buf && !inMid.mMid_Oid.mOid_Scope )
|
||||
{
|
||||
morkMid mid(inMid);
|
||||
mid.mMid_Oid.mOid_Scope = mBuilder_RowRowScope;
|
||||
mBuilder_Row = store->MidToRow(ev, mid);
|
||||
}
|
||||
else
|
||||
{
|
||||
mBuilder_Row = store->MidToRow(ev, inMid);
|
||||
}
|
||||
|
||||
if ( mBuilder_Row )
|
||||
mBuilder_Table->AddRow(ev, mBuilder_Row);
|
||||
}
|
||||
else
|
||||
this->NilBuilderTableError(ev);
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnRowGlitch(morkEnv* ev, const morkGlitch& inGlitch)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
this->LogGlitch(ev, inGlitch, "row");
|
||||
}
|
||||
|
||||
void
|
||||
morkBuilder::FlushBuilderCells(morkEnv* ev)
|
||||
{
|
||||
if ( mBuilder_Row )
|
||||
{
|
||||
morkPool* pool = mBuilder_Store->StorePool();
|
||||
morkCell* cells = mBuilder_CellsVec;
|
||||
mork_fill fill = mBuilder_CellsVecFill;
|
||||
mBuilder_Row->TakeCells(ev, cells, fill, mBuilder_Store);
|
||||
|
||||
morkCell* end = cells + fill;
|
||||
--cells; // prepare for preincrement
|
||||
while ( ++cells < end )
|
||||
{
|
||||
if ( cells->mCell_Atom )
|
||||
cells->SetAtom(ev, (morkAtom*) 0, pool);
|
||||
}
|
||||
mBuilder_CellsVecFill = 0;
|
||||
}
|
||||
else
|
||||
this->NilBuilderRowError(ev);
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnRowEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
// mp:Row ::= OnNewRow mp:RowItem* OnRowEnd
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// mParser_InRow = morkBool_kFalse;
|
||||
if ( mBuilder_Row )
|
||||
{
|
||||
this->FlushBuilderCells(ev);
|
||||
}
|
||||
else
|
||||
this->NilBuilderRowError(ev);
|
||||
|
||||
mBuilder_Row = 0;
|
||||
mBuilder_Cell = 0;
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnNewDict(morkEnv* ev, const morkPlace& inPlace)
|
||||
// mp:Dict ::= OnNewDict mp:DictItem* OnDictEnd
|
||||
// mp:DictItem ::= OnAlias | OnAliasGlitch | mp:Meta | OnDictGlitch
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// mParser_InDict = morkBool_kTrue;
|
||||
|
||||
mBuilder_CellForm = mBuilder_DictForm = mBuilder_PortForm;
|
||||
mBuilder_CellAtomScope = mBuilder_DictAtomScope = mBuilder_PortAtomScope;
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnDictGlitch(morkEnv* ev, const morkGlitch& inGlitch)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
this->LogGlitch(ev, inGlitch, "dict");
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnDictEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
// mp:Dict ::= OnNewDict mp:DictItem* OnDictEnd
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// mParser_InDict = morkBool_kFalse;
|
||||
|
||||
mBuilder_DictForm = 0;
|
||||
mBuilder_DictAtomScope = 0;
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias)
|
||||
const morkMid& inMid)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
if ( mParser_InDict )
|
||||
{
|
||||
morkMid mid = inMid; // local copy for modification
|
||||
mid.mMid_Oid.mOid_Scope = mBuilder_DictAtomScope;
|
||||
mBuilder_Store->AddAlias(ev, mid, mBuilder_DictForm);
|
||||
}
|
||||
else
|
||||
ev->NewError("alias not in dict");
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnAliasGlitch(morkEnv* ev, const morkGlitch& inGlitch)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
this->LogGlitch(ev, inGlitch, "alias");
|
||||
}
|
||||
|
||||
|
||||
morkCell*
|
||||
morkBuilder::AddBuilderCell(morkEnv* ev,
|
||||
const morkMid& inMid, mork_change inChange)
|
||||
{
|
||||
morkCell* outCell = 0;
|
||||
mork_column column = inMid.mMid_Oid.mOid_Id;
|
||||
|
||||
if ( ev->Good() )
|
||||
{
|
||||
if ( mBuilder_CellsVecFill >= morkBuilder_kCellsVecSize )
|
||||
this->FlushBuilderCells(ev);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
if ( mBuilder_CellsVecFill < morkBuilder_kCellsVecSize )
|
||||
{
|
||||
mork_fill index = mBuilder_CellsVecFill++;
|
||||
outCell = mBuilder_CellsVec + index;
|
||||
outCell->SetColumnAndChange(column, inChange);
|
||||
outCell->mCell_Atom = 0;
|
||||
}
|
||||
else
|
||||
ev->NewError("out of builder cells");
|
||||
}
|
||||
}
|
||||
return outCell;
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnNewCell(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange)
|
||||
const morkMid* inMid, const morkBuf* inBuf, mork_change inChange)
|
||||
// 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.
|
||||
|
||||
// mp:Cell ::= OnNewCell mp:CellItem? OnCellEnd
|
||||
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
|
||||
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// mParser_InCell = morkBool_kTrue;
|
||||
|
||||
mBuilder_CellAtomScope = mBuilder_RowAtomScope;
|
||||
|
||||
mBuilder_Cell = 0; // nil until determined for a row
|
||||
morkStore* store = mBuilder_Store;
|
||||
mork_scope scope = morkStore_kColumnSpaceScope;
|
||||
morkMid tempMid; // space for local and modifiable cell mid
|
||||
morkMid* cellMid = &tempMid; // default to local if inMid==0
|
||||
|
||||
if ( inMid ) // mid parameter is actually provided?
|
||||
{
|
||||
*cellMid = *inMid; // bitwise copy for modifiable local mid
|
||||
|
||||
if ( !cellMid->mMid_Oid.mOid_Scope )
|
||||
{
|
||||
if ( cellMid->mMid_Buf )
|
||||
{
|
||||
scope = store->BufToToken(ev, cellMid->mMid_Buf);
|
||||
cellMid->mMid_Buf = 0; // don't do scope lookup again
|
||||
ev->NewWarning("column mids need column scope");
|
||||
}
|
||||
cellMid->mMid_Oid.mOid_Scope = scope;
|
||||
}
|
||||
}
|
||||
else if ( inBuf ) // buf points to naked column string name?
|
||||
{
|
||||
cellMid->ClearMid();
|
||||
cellMid->mMid_Oid.mOid_Id = store->BufToToken(ev, inBuf);
|
||||
cellMid->mMid_Oid.mOid_Scope = scope; // kColumnSpaceScope
|
||||
}
|
||||
else
|
||||
ev->NilPointerError(); // either inMid or inBuf must be non-nil
|
||||
|
||||
mork_column column = cellMid->mMid_Oid.mOid_Id;
|
||||
|
||||
if ( mParser_InMeta && ev->Good() ) // cell is in metainfo structure?
|
||||
{
|
||||
if ( scope == morkStore_kColumnSpaceScope )
|
||||
{
|
||||
if ( mParser_InTable ) // metainfo for table?
|
||||
{
|
||||
if ( column == store->mStore_TableKindToken )
|
||||
mBuilder_MetaTokenSlot = &mBuilder_TableKind;
|
||||
else if ( column == store->mStore_RowScopeToken )
|
||||
mBuilder_MetaTokenSlot = &mBuilder_TableRowScope;
|
||||
else if ( column == store->mStore_AtomScopeToken )
|
||||
mBuilder_MetaTokenSlot = &mBuilder_TableAtomScope;
|
||||
else if ( column == store->mStore_CharsetToken )
|
||||
mBuilder_MetaTokenSlot = &mBuilder_TableForm;
|
||||
}
|
||||
else if ( mParser_InDict ) // metainfo for dict?
|
||||
{
|
||||
if ( column == store->mStore_AtomScopeToken )
|
||||
mBuilder_MetaTokenSlot = &mBuilder_DictAtomScope;
|
||||
else if ( column == store->mStore_CharsetToken )
|
||||
mBuilder_MetaTokenSlot = &mBuilder_DictForm;
|
||||
}
|
||||
else if ( mParser_InRow ) // metainfo for row?
|
||||
{
|
||||
if ( column == store->mStore_AtomScopeToken )
|
||||
mBuilder_MetaTokenSlot = &mBuilder_RowAtomScope;
|
||||
else if ( column == store->mStore_RowScopeToken )
|
||||
mBuilder_MetaTokenSlot = &mBuilder_RowRowScope;
|
||||
else if ( column == store->mStore_CharsetToken )
|
||||
mBuilder_MetaTokenSlot = &mBuilder_RowForm;
|
||||
}
|
||||
}
|
||||
else
|
||||
ev->NewWarning("expected column scope");
|
||||
}
|
||||
else if ( ev->Good() ) // this cell must be inside a row
|
||||
{
|
||||
if ( mBuilder_Row )
|
||||
{
|
||||
// mBuilder_Cell = this->AddBuilderCell(ev, *cellMid, inChange);
|
||||
|
||||
if ( mBuilder_CellsVecFill >= morkBuilder_kCellsVecSize )
|
||||
this->FlushBuilderCells(ev);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
if ( mBuilder_CellsVecFill < morkBuilder_kCellsVecSize )
|
||||
{
|
||||
mork_fill index = mBuilder_CellsVecFill++;
|
||||
morkCell* cell = mBuilder_CellsVec + index;
|
||||
cell->SetColumnAndChange(column, inChange);
|
||||
cell->mCell_Atom = 0;
|
||||
mBuilder_Cell = cell;
|
||||
}
|
||||
else
|
||||
ev->NewError("out of builder cells");
|
||||
}
|
||||
}
|
||||
else
|
||||
this->NilBuilderRowError(ev);
|
||||
}
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnCellGlitch(morkEnv* ev, const morkGlitch& inGlitch)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
this->LogGlitch(ev, inGlitch, "cell");
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnCellForm(morkEnv* ev, mork_cscode inCharsetFormat)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
morkCell* cell = mBuilder_Cell;
|
||||
if ( cell )
|
||||
{
|
||||
mBuilder_CellForm = inCharsetFormat;
|
||||
}
|
||||
else
|
||||
this->NilBuilderCellError(ev);
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnCellEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
// mp:Cell ::= OnNewCell mp:CellItem? OnCellEnd
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// mParser_InCell = morkBool_kFalse;
|
||||
|
||||
mBuilder_MetaTokenSlot = 0;
|
||||
mBuilder_CellAtomScope = mBuilder_RowAtomScope;
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnValue(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkBuf& inBuf)
|
||||
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
|
||||
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
morkStore* store = mBuilder_Store;
|
||||
morkCell* cell = mBuilder_Cell;
|
||||
if ( cell )
|
||||
{
|
||||
mdbYarn yarn;
|
||||
yarn.mYarn_Buf = inBuf.mBuf_Body;
|
||||
yarn.mYarn_Fill = yarn.mYarn_Size = inBuf.mBuf_Fill;
|
||||
yarn.mYarn_More = 0;
|
||||
yarn.mYarn_Form = mBuilder_CellForm;
|
||||
yarn.mYarn_Grow = 0;
|
||||
morkAtom* atom = store->YarnToAtom(ev, &yarn);
|
||||
cell->SetAtom(ev, atom, store->StorePool());
|
||||
}
|
||||
else if ( mParser_InMeta )
|
||||
{
|
||||
mork_token* metaSlot = mBuilder_MetaTokenSlot;
|
||||
if ( metaSlot )
|
||||
{
|
||||
mork_token token = store->BufToToken(ev, &inBuf);
|
||||
if ( token )
|
||||
{
|
||||
*metaSlot = token;
|
||||
if ( metaSlot == &mBuilder_TableKind ) // table kind?
|
||||
{
|
||||
if ( mParser_InTable && mBuilder_Table )
|
||||
mBuilder_Table->mTable_Kind = token;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
this->NilBuilderCellError(ev);
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnValueAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias)
|
||||
morkBuilder::OnValueMid(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkMid& inMid)
|
||||
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
|
||||
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
morkStore* store = mBuilder_Store;
|
||||
morkCell* cell = mBuilder_Cell;
|
||||
|
||||
morkMid valMid; // local mid for modifications
|
||||
mdbOid* valOid = &valMid.mMid_Oid; // ref to oid inside mid
|
||||
*valOid = inMid.mMid_Oid; // bitwise copy inMid's oid
|
||||
|
||||
if ( inMid.mMid_Buf )
|
||||
{
|
||||
if ( !valOid->mOid_Scope )
|
||||
store->MidToOid(ev, inMid, valOid);
|
||||
}
|
||||
else if ( !valOid->mOid_Scope )
|
||||
valOid->mOid_Scope = mBuilder_CellAtomScope;
|
||||
|
||||
if ( cell )
|
||||
{
|
||||
morkBookAtom* atom = store->MidToAtom(ev, valMid);
|
||||
if ( atom )
|
||||
cell->SetAtom(ev, atom, store->StorePool());
|
||||
else
|
||||
ev->NewError("undefined cell value alias");
|
||||
}
|
||||
else if ( mParser_InMeta )
|
||||
{
|
||||
mork_token* metaSlot = mBuilder_MetaTokenSlot;
|
||||
if ( metaSlot )
|
||||
{
|
||||
if ( valOid->mOid_Scope == morkStore_kColumnSpaceScope )
|
||||
{
|
||||
if ( ev->Good() && valMid.HasSomeId() )
|
||||
{
|
||||
*metaSlot = valOid->mOid_Id;
|
||||
if ( metaSlot == &mBuilder_TableKind ) // table kind?
|
||||
{
|
||||
if ( mParser_InTable && mBuilder_Table )
|
||||
{
|
||||
mBuilder_Table->mTable_Kind = valOid->mOid_Id;
|
||||
}
|
||||
else
|
||||
ev->NewWarning("mBuilder_TableKind not in table");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
this->NonColumnSpaceScopeError(ev);
|
||||
}
|
||||
}
|
||||
else
|
||||
this->NilBuilderCellError(ev);
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnRowAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias)
|
||||
morkBuilder::OnRowMid(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkMid& inMid)
|
||||
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
|
||||
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
morkStore* store = mBuilder_Store;
|
||||
morkCell* cell = mBuilder_Cell;
|
||||
if ( cell )
|
||||
{
|
||||
mdbOid rowOid = inMid.mMid_Oid;
|
||||
if ( inMid.mMid_Buf )
|
||||
{
|
||||
if ( !rowOid.mOid_Scope )
|
||||
store->MidToOid(ev, inMid, &rowOid);
|
||||
}
|
||||
else if ( !rowOid.mOid_Scope )
|
||||
rowOid.mOid_Scope = mBuilder_RowRowScope;
|
||||
|
||||
if ( ev->Good() )
|
||||
{
|
||||
morkPool* pool = store->StorePool();
|
||||
morkAtom* atom = pool->NewRowOidAtom(ev, rowOid);
|
||||
if ( atom )
|
||||
{
|
||||
cell->SetAtom(ev, atom, pool);
|
||||
morkRow* row = store->OidToRow(ev, &rowOid);
|
||||
if ( row ) // found or created such a row?
|
||||
row->AddTableUse(ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
this->NilBuilderCellError(ev);
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnTableAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias)
|
||||
morkBuilder::OnTableMid(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkMid& inMid)
|
||||
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
|
||||
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
morkStore* store = mBuilder_Store;
|
||||
morkCell* cell = mBuilder_Cell;
|
||||
if ( cell )
|
||||
{
|
||||
mdbOid tableOid = inMid.mMid_Oid;
|
||||
if ( inMid.mMid_Buf )
|
||||
{
|
||||
if ( !tableOid.mOid_Scope )
|
||||
store->MidToOid(ev, inMid, &tableOid);
|
||||
}
|
||||
else if ( !tableOid.mOid_Scope )
|
||||
tableOid.mOid_Scope = mBuilder_RowRowScope;
|
||||
|
||||
if ( ev->Good() )
|
||||
{
|
||||
morkPool* pool = store->StorePool();
|
||||
morkAtom* atom = pool->NewTableOidAtom(ev, tableOid);
|
||||
if ( atom )
|
||||
{
|
||||
cell->SetAtom(ev, atom, pool);
|
||||
morkTable* table = store->OidToTable(ev, &tableOid);
|
||||
if ( table ) // found or created such a table?
|
||||
table->AddCellUse(ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
this->NilBuilderCellError(ev);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -65,31 +65,31 @@ class morkBuilder /*d*/ : public morkParser {
|
|||
// 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_tid mParser_TableId; // table ID if inside a table
|
||||
// mork_rid mParser_RowId; // row ID if inside a row
|
||||
|
||||
// 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?
|
||||
|
||||
// morkAlias mParser_Alias; // current alias being parsed
|
||||
// note that mParser_Alias.mAlias_Buf points at mParser_ScopeSpool below:
|
||||
// morkMid mParser_Mid; // current alias being parsed
|
||||
// note that mParser_Mid.mMid_Buf points at mParser_ScopeCoil below:
|
||||
|
||||
// blob spools allocated in mParser_Heap
|
||||
// morkSpool mParser_ScopeSpool; // place to accumulate ID scope blobs
|
||||
// morkSpool mParser_ValueSpool; // place to accumulate value blobs
|
||||
// morkSpool mParser_ColumnSpool; // place to accumulate column blobs
|
||||
// morkSpool mParser_StringSpool; // place to accumulate string blobs
|
||||
// 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
|
||||
|
||||
// morkSpoolSink mParser_ScopeSink; // writes to mParser_ScopeSpool
|
||||
// morkSpoolSink mParser_ValueSink; // writes to mParser_ValueSpool
|
||||
// morkSpoolSink mParser_ColumnSink; // writes to mParser_ColumnSpool
|
||||
// morkSpoolSink mParser_StringSink; // writes to mParser_StringSpool
|
||||
// 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_AliasYarn; // place to receive from AliasToYarn()
|
||||
// morkYarn mParser_MidYarn; // place to receive from MidToYarn()
|
||||
|
||||
// span showing current ongoing file position status:
|
||||
// morkSpan mParser_PortSpan; // span of current db port file
|
||||
|
@ -118,8 +118,8 @@ protected: // protected morkBuilder members
|
|||
morkRow* mBuilder_Row; // current row being built (or nil)
|
||||
morkCell* mBuilder_Cell; // current cell within CellsVec (or nil)
|
||||
|
||||
morkRowSpace* mBuilder_RowSpace; // space for mBuilder_CurrentRowScope
|
||||
morkAtomSpace* mBuilder_AtomSpace; // space for mBuilder_CurrentAtomScope
|
||||
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
|
||||
|
@ -134,6 +134,8 @@ protected: // protected morkBuilder members
|
|||
mork_cscode mBuilder_a; // token for "a"
|
||||
mork_cscode mBuilder_t; // token for "t"
|
||||
|
||||
mork_token mBuilder_MorkNoneToken; // token for "mork:none"
|
||||
|
||||
// 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
|
||||
|
@ -151,21 +153,25 @@ protected: // protected morkBuilder members
|
|||
mork_scope mBuilder_RowAtomScope; // row atom scope
|
||||
|
||||
// meta tokens currently in force, driven by meta info slots above:
|
||||
mork_cscode mBuilder_CurrentForm; // current charset format
|
||||
mork_scope mBuilder_CurrentRowScope; // current row scope
|
||||
mork_scope mBuilder_CurrentAtomScope; // current atom scope
|
||||
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_CutRow; // row with kCut change
|
||||
mork_bool mBuilder_CutCell; // cell with kCut change
|
||||
mork_bool mBuilder_DoCutRow; // row with kCut change
|
||||
mork_bool mBuilder_DoCutCell; // cell with kCut change
|
||||
mork_u1 mBuilder_Pad1; // pad to u4 alignment
|
||||
mork_u1 mBuilder_Pad2; // pad to u4 alignment
|
||||
|
||||
morkCell mBuilder_CellsVec[ morkBuilder_kCellsVecSize ];
|
||||
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
|
||||
|
@ -199,14 +205,28 @@ public: // dynamic type identification
|
|||
{ return IsNode() && mNode_Derived == morkDerived_kBuilder; }
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
public: // typing
|
||||
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 AliasToYarn(morkEnv* ev,
|
||||
const morkAlias& inAlias, // typically an alias to concat with strings
|
||||
virtual void MidToYarn(morkEnv* ev,
|
||||
const morkMid& inMid, // typically an alias to concat with strings
|
||||
mdbYarn* outYarn);
|
||||
// The parser might ask that some aliases be turned into yarns, so they
|
||||
// can be concatenated into longer blobs under some circumstances. This
|
||||
|
@ -216,60 +236,64 @@ public: // in virtual morkParser methods, data flow subclass to parser
|
|||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
public: // out virtual morkParser methods, data flow parser to subclass
|
||||
|
||||
virtual void OnNewPort(morkEnv* ev, const morkPlace& inPlace);
|
||||
virtual void OnPortGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
virtual void OnPortEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
virtual void OnNewPort(morkEnv* ev, const morkPlace& inPlace);
|
||||
virtual void OnPortGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
virtual void OnPortEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
|
||||
virtual void OnNewGroup(morkEnv* ev, const morkPlace& inPlace, mork_gid inGid);
|
||||
virtual void OnGroupGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
virtual void OnGroupCommitEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
virtual void OnGroupAbortEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
virtual void OnNewGroup(morkEnv* ev, const morkPlace& inPlace, mork_gid inGid);
|
||||
virtual void OnGroupGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
virtual void OnGroupCommitEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
virtual void OnGroupAbortEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
|
||||
virtual void OnNewPortRow(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange);
|
||||
virtual void OnPortRowGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
virtual void OnPortRowEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
virtual void OnNewPortRow(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkMid& inMid, mork_change inChange);
|
||||
virtual void OnPortRowGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
virtual void OnPortRowEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
|
||||
virtual void OnNewTable(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange);
|
||||
virtual void OnTableGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
virtual void OnTableEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
|
||||
virtual void OnNewMeta(morkEnv* ev, const morkPlace& inPlace);
|
||||
virtual void OnMetaGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
virtual void OnMetaEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
virtual void OnNewTable(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkMid& inMid, mork_change inChange);
|
||||
virtual void OnTableGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
virtual void OnTableEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
|
||||
virtual void OnNewMeta(morkEnv* ev, const morkPlace& inPlace);
|
||||
virtual void OnMetaGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
virtual void OnMetaEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
|
||||
virtual void OnNewRow(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange);
|
||||
virtual void OnRowGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
virtual void OnRowEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
virtual void OnNewRow(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkMid& inMid, mork_change inChange);
|
||||
virtual void OnRowGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
virtual void OnRowEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
|
||||
virtual void OnNewDict(morkEnv* ev, const morkPlace& inPlace);
|
||||
virtual void OnDictGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
virtual void OnDictEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
virtual void OnNewDict(morkEnv* ev, const morkPlace& inPlace);
|
||||
virtual void OnDictGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
virtual void OnDictEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
|
||||
virtual void OnAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias);
|
||||
virtual void OnAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkMid& inMid);
|
||||
|
||||
virtual void OnAliasGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
virtual void OnAliasGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
|
||||
virtual void OnNewCell(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange);
|
||||
virtual void OnCellGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
virtual void OnCellForm(morkEnv* ev, mork_cscode inCharsetFormat);
|
||||
virtual void OnCellEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
|
||||
virtual void OnValue(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkBuf& inBuf);
|
||||
virtual void OnNewCell(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkMid* inMid, const morkBuf* inBuf, mork_change inChange);
|
||||
// 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 OnValueAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias);
|
||||
virtual void OnCellGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
virtual void OnCellForm(morkEnv* ev, mork_cscode inCharsetFormat);
|
||||
virtual void OnCellEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
|
||||
virtual void OnValue(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkBuf& inBuf);
|
||||
|
||||
virtual void OnRowAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias);
|
||||
virtual void OnValueMid(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkMid& inMid);
|
||||
|
||||
virtual void OnTableAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias);
|
||||
virtual void OnRowMid(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkMid& inMid);
|
||||
|
||||
virtual void OnTableMid(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkMid& inMid);
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
public: // public non-poly morkBuilder methods
|
||||
|
|
|
@ -46,9 +46,6 @@
|
|||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
void
|
||||
morkCell::SetYarn(morkEnv* ev, const mdbYarn* inYarn, morkStore* ioStore)
|
||||
{
|
||||
|
|
|
@ -40,6 +40,9 @@ public:
|
|||
|
||||
public:
|
||||
morkCell() : mCell_Atom( 0 ), mCell_Delta( 0 ) { }
|
||||
|
||||
morkCell(const morkCell& c)
|
||||
: mCell_Atom( c.mCell_Atom ), mCell_Delta( c.mCell_Delta ) { }
|
||||
|
||||
// note if ioAtom is non-nil, caller needs to call ioAtom->AddCellUse():
|
||||
morkCell(mork_column inCol, mork_change inChange, morkAtom* ioAtom)
|
||||
|
|
|
@ -30,8 +30,8 @@
|
|||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
/* ----- ----- ----- ----- MORK_MAC ----- ----- ----- ----- */
|
||||
#ifdef MORK_MAC
|
||||
/* ----- ----- ----- ----- MORK_OBSOLETE ----- ----- ----- ----- */
|
||||
#ifdef MORK_OBSOLETE
|
||||
|
||||
#include <Types.h>
|
||||
|
||||
|
@ -58,14 +58,14 @@
|
|||
|
||||
DebugStr(pascalStr); /* call Mac debugger entry point */
|
||||
}
|
||||
#endif /*MORK_MAC*/
|
||||
/* ----- ----- ----- ----- MORK_MAC ----- ----- ----- ----- */
|
||||
#endif /*MORK_OBSOLETE*/
|
||||
/* ----- ----- ----- ----- MORK_OBSOLETE ----- ----- ----- ----- */
|
||||
|
||||
void mork_assertion_signal(const char* inMessage)
|
||||
{
|
||||
#ifdef XP_MAC
|
||||
#ifdef MORK_OBSOLETE
|
||||
mork_mac_break_string(inMessage);
|
||||
#endif /*XP_MAC*/
|
||||
#endif /*MORK_OBSOLETE*/
|
||||
|
||||
#ifdef MORK_WIN
|
||||
// asm { int 3 }
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
// { %%%%% begin platform defs peculiar to Mork %%%%%
|
||||
#ifdef XP_MAC
|
||||
#define MORK_MAC 1
|
||||
#define MORK_OBSOLETE 1
|
||||
#endif
|
||||
|
||||
#ifdef XP_OS2
|
||||
|
@ -46,9 +47,14 @@
|
|||
#ifdef XP_UNIX
|
||||
#define MORK_UNIX 1
|
||||
#endif
|
||||
|
||||
#ifdef MORK_OBSOLETE
|
||||
#undef MORK_MAC
|
||||
#endif
|
||||
|
||||
// } %%%%% end platform defs peculiar to Mork %%%%%
|
||||
|
||||
#if defined (MORK_WIN) || defined(MORK_UNIX)
|
||||
#if defined(MORK_WIN) || defined(MORK_UNIX) || defined(MORK_MAC)
|
||||
#include "stdio.h"
|
||||
#include "ctype.h"
|
||||
#include "errno.h"
|
||||
|
@ -60,12 +66,12 @@
|
|||
|
||||
#define MORK_FILETELL(file) ftell(file)
|
||||
#define MORK_FILESEEK(file, where, how) fseek(file, where, how)
|
||||
#define MORK_FILEREAD(outbuf, insize, file) fread(outbuf, insize, 1, file)
|
||||
#define MORK_FILEREAD(outbuf, insize, file) fread(outbuf, 1, insize, file)
|
||||
#define MORK_FILEFLUSH(file) fflush(file)
|
||||
#define MORK_FILECLOSE(file) fclose(file)
|
||||
#endif /*MORK_WIN*/
|
||||
|
||||
#ifdef MORK_MAC
|
||||
#ifdef MORK_OBSOLETE
|
||||
#include "xp_file.h"
|
||||
#include "ctype.h"
|
||||
|
||||
|
@ -76,17 +82,17 @@
|
|||
#define MORK_FILEREAD(outbuf, insize, file) XP_FileRead(outbuf, insize, file)
|
||||
#define MORK_FILEFLUSH(file) XP_FileFlush(file)
|
||||
#define MORK_FILECLOSE(file) XP_FileClose(file)
|
||||
#endif /*MORK_MAC*/
|
||||
#endif /*MORK_OBSOLETE*/
|
||||
|
||||
/* ===== ===== ===== ===== line characters ===== ===== ===== ===== */
|
||||
#define mork_kCR '\015'
|
||||
#define mork_kLF '\012'
|
||||
#define mork_kCR 0x0D
|
||||
#define mork_kLF 0x0A
|
||||
#define mork_kVTAB '\013'
|
||||
#define mork_kFF '\014'
|
||||
#define mork_kTAB '\011'
|
||||
#define mork_kCRLF "\015\012" /* A CR LF equivalent string */
|
||||
|
||||
#ifdef MORK_MAC
|
||||
#if defined(MORK_MAC) || defined(MORK_OBSOLETE)
|
||||
# define mork_kNewline "\015"
|
||||
# define mork_kNewlineSize 1
|
||||
#else
|
||||
|
@ -113,18 +119,14 @@ extern void mork_assertion_signal(const char* inMessage);
|
|||
// { %%%%% begin standard c utility methods %%%%%
|
||||
/*define MORK_USE_XP_STDLIB 1*/
|
||||
|
||||
#ifdef MORK_MAC
|
||||
#ifdef MORK_OBSOLETE
|
||||
#define MORK_PROVIDE_STDLIB 1
|
||||
#endif /*MORK_MAC*/
|
||||
#endif /*MORK_OBSOLETE*/
|
||||
|
||||
#ifdef MORK_WIN
|
||||
#if defined(MORK_WIN) || defined(MORK_UNIX) || defined(MORK_MAC)
|
||||
#define MORK_USE_C_STDLIB 1
|
||||
#endif /*MORK_WIN*/
|
||||
|
||||
#ifdef MORK_UNIX
|
||||
#define MORK_USE_NSPR_STDLIB 1
|
||||
#endif
|
||||
|
||||
#ifdef MORK_USE_C_STDLIB
|
||||
#define MORK_MEMCMP(src1,src2,size) memcmp(src1,src2,size)
|
||||
#define MORK_MEMCPY(dest,src,size) memcpy(dest,src,size)
|
||||
|
@ -167,16 +169,6 @@ MORK_LIB(mork_size) mork_strlen(const void* inString);
|
|||
#define MORK_STRLEN(string) XP_STRLEN(string)
|
||||
#endif /*MORK_USE_XP_STDLIB*/
|
||||
|
||||
#ifdef MORK_USE_NSPR_STDLIB
|
||||
#define MORK_MEMCMP(src1,src2, size) memcmp(src1, src2, size)
|
||||
#define MORK_MEMCPY(src1,src2, size) memcpy(src1, src2, size)
|
||||
#define MORK_MEMMOVE(dest, src, size) memmove(src1, src2, size)
|
||||
#define MORK_MEMSET(dest,byte,size) memset(dest,byte,size)
|
||||
#define MORK_STRCPY(dest,src) PL_strcpy(dest,src)
|
||||
#define MORK_STRCMP(one,two) PL_strcmp(one,two)
|
||||
#define MORK_STRNCMP(one,two,length) PL_strncmp(one,two,length)
|
||||
#define MORK_STRLEN(string) PL_strlen(string)
|
||||
#endif
|
||||
|
||||
// } %%%%% end standard c utility methods %%%%%
|
||||
|
||||
|
|
|
@ -221,7 +221,7 @@ morkFile::NewFileErrnoError(morkEnv* ev) const
|
|||
|
||||
// ````` ````` ````` ````` newlines ````` ````` ````` `````
|
||||
|
||||
#ifdef MORK_MAC
|
||||
#if defined(MORK_MAC) || defined(MORK_OBSOLETE)
|
||||
static const char* morkFile_kNewlines =
|
||||
"\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015";
|
||||
# define morkFile_kNewlinesCount 16
|
||||
|
@ -314,7 +314,7 @@ morkStdioFile::OpenOldStdioFile(morkEnv* ev, nsIMdbHeap* ioHeap,
|
|||
morkStdioFile* outFile = 0;
|
||||
if ( ioHeap && inFilePath )
|
||||
{
|
||||
const char* mode = (inFrozen)? "rb" : "wb";
|
||||
const char* mode = (inFrozen)? "rb" : "rb+";
|
||||
outFile = new(*ioHeap, ev)
|
||||
morkStdioFile(ev, morkUsage::kHeap, ioHeap, ioHeap, inFilePath, mode);
|
||||
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -23,10 +23,6 @@
|
|||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKPARSER_
|
||||
#include "morkParser.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKBLOB_
|
||||
#include "morkBlob.h"
|
||||
#endif
|
||||
|
@ -68,6 +64,9 @@ public:
|
|||
|
||||
morkPlace(mork_pos inPos, mork_line inLine)
|
||||
{ mPlace_Pos = inPos; mPlace_Line = inLine; }
|
||||
|
||||
morkPlace(const morkPlace& inPlace)
|
||||
: mPlace_Pos(inPlace.mPlace_Pos), mPlace_Line(inPlace.mPlace_Line) { }
|
||||
};
|
||||
|
||||
/*=============================================================================
|
||||
|
@ -80,48 +79,68 @@ public:
|
|||
const char* mGlitch_Comment; // null-terminated ASCII C string
|
||||
|
||||
morkGlitch() { mGlitch_Comment = 0; }
|
||||
|
||||
morkGlitch(const morkPlace& inPlace, const char* inComment)
|
||||
: mGlitch_Place(inPlace), mGlitch_Comment(inComment) { }
|
||||
};
|
||||
|
||||
/*=============================================================================
|
||||
* morkAlias: all possible ways needed to express an alias ID in Mork syntax
|
||||
* morkMid: all possible ways needed to express an alias ID in Mork syntax
|
||||
*/
|
||||
|
||||
/*| morkAlias: an abstraction of all the variations we might need to support
|
||||
/*| morkMid: an abstraction of all the variations we might need to support
|
||||
**| in order to present an ID through the parser interface most cheaply and
|
||||
**| with minimum transformation away from the original text format.
|
||||
**|
|
||||
**|| An ID can have one of four forms:
|
||||
**| 1) idHex (mAlias_Oid.mOid_Id <- idHex)
|
||||
**| 2) idHex:^scopeHex (mAlias_Oid.mOid_Id <- idHex, mOid_Scope <- scopeHex)
|
||||
**| 3) idHex:scopeName (mAlias_Oid.mOid_Id <- idHex, mAlias_Buf <- scopeName)
|
||||
**| 4) columnName (mAlias_Buf <- columnName, for columns in cells only)
|
||||
**| 1) idHex (mMid_Oid.mOid_Id <- idHex)
|
||||
**| 2) idHex:^scopeHex (mMid_Oid.mOid_Id <- idHex, mOid_Scope <- scopeHex)
|
||||
**| 3) idHex:scopeName (mMid_Oid.mOid_Id <- idHex, mMid_Buf <- scopeName)
|
||||
**| 4) columnName (mMid_Buf <- columnName, for columns in cells only)
|
||||
**|
|
||||
**|| Typically, mAlias_Oid.mOid_Id will hold a nonzero integer value for
|
||||
**|| Typically, mMid_Oid.mOid_Id will hold a nonzero integer value for
|
||||
**| an ID, but we might have an optional scope specified by either an integer
|
||||
**| in hex format, or a string name. (Note that while the first ID can be
|
||||
**| scoped variably, any integer ID for a scope is assumed always located in
|
||||
**| the same scope, so the second ID need not be disambiguated.)
|
||||
**|
|
||||
**|| The only time mAlias_Oid.mOid_Id is ever zero is when mAlias_Buf alone
|
||||
**|| The only time mMid_Oid.mOid_Id is ever zero is when mMid_Buf alone
|
||||
**| is nonzero, to indicate an explicit string instead of an alias appeared.
|
||||
**| This case happens to make the representation of columns in cells somewhat
|
||||
**| easier to represent, since columns can just appear as a string name; and
|
||||
**| this unifies those interfaces with row and table APIs expecting IDs.
|
||||
**|
|
||||
**|| So when the parser passes an instance of morkAlias to a subclass, the
|
||||
**| mAlias_Oid.mOid_Id slot should usually be nonzero. And the other two
|
||||
**| slots, mAlias_Oid.mOid_Scope and mAlias_Buf, might both be zero, or at
|
||||
**|| So when the parser passes an instance of morkMid to a subclass, the
|
||||
**| mMid_Oid.mOid_Id slot should usually be nonzero. And the other two
|
||||
**| slots, mMid_Oid.mOid_Scope and mMid_Buf, might both be zero, or at
|
||||
**| most one of them will be nonzero to indicate an explicit scope; the
|
||||
**| parser is responsible for ensuring at most one of these is nonzero.
|
||||
|*/
|
||||
class morkAlias {
|
||||
class morkMid {
|
||||
public:
|
||||
mdbOid mAlias_Oid; // mOid_Scope is zero when not specified
|
||||
const morkBuf* mAlias_Buf; // points to some specific buf subclass
|
||||
mdbOid mMid_Oid; // mOid_Scope is zero when not specified
|
||||
const morkBuf* mMid_Buf; // points to some specific buf subclass
|
||||
|
||||
morkAlias()
|
||||
{ mAlias_Oid.mOid_Scope = 0; mAlias_Oid.mOid_Id = morkId_kMinusOne;
|
||||
mAlias_Buf = 0; }
|
||||
morkMid()
|
||||
{ mMid_Oid.mOid_Scope = 0; mMid_Oid.mOid_Id = morkId_kMinusOne;
|
||||
mMid_Buf = 0; }
|
||||
|
||||
void InitMidWithCoil(morkCoil* ioCoil)
|
||||
{ mMid_Oid.mOid_Scope = 0; mMid_Oid.mOid_Id = morkId_kMinusOne;
|
||||
mMid_Buf = ioCoil; }
|
||||
|
||||
void ClearMid()
|
||||
{ mMid_Oid.mOid_Scope = 0; mMid_Oid.mOid_Id = morkId_kMinusOne;
|
||||
mMid_Buf = 0; }
|
||||
|
||||
morkMid(const morkMid& other)
|
||||
: mMid_Oid(other.mMid_Oid), mMid_Buf(other.mMid_Buf) { }
|
||||
|
||||
mork_bool HasNoId() const // ID is unspecified?
|
||||
{ return ( mMid_Oid.mOid_Id == morkId_kMinusOne ); }
|
||||
|
||||
mork_bool HasSomeId() const // ID is specified?
|
||||
{ return ( mMid_Oid.mOid_Id != morkId_kMinusOne ); }
|
||||
};
|
||||
|
||||
/*=============================================================================
|
||||
|
@ -138,6 +157,9 @@ public: // methods
|
|||
public: // inlines
|
||||
morkSpan() { } // use inline empty constructor for each place
|
||||
|
||||
morkPlace* AsPlace() { return &mSpan_Start; }
|
||||
const morkPlace* AsConstPlace() const { return &mSpan_Start; }
|
||||
|
||||
void SetSpan(mork_pos inFromPos, mork_line inFromLine,
|
||||
mork_pos inToPos, mork_line inToLine)
|
||||
{
|
||||
|
@ -208,7 +230,7 @@ class morkParser /*d*/ : public morkNode {
|
|||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
protected: // protected morkParser members
|
||||
|
||||
nsIMdbHeap* mParser_Heap; // refcounted heap used for allocation
|
||||
nsIMdbHeap* mParser_Heap; // refcounted heap used for allocation
|
||||
morkStream* mParser_Stream; // refcounted input stream
|
||||
|
||||
mork_u4 mParser_Tag; // must equal morkParser_kTag
|
||||
|
@ -219,9 +241,10 @@ protected: // protected morkParser members
|
|||
// after finding ends of group transactions, we can re-seek the start:
|
||||
mork_pos mParser_GroupContentStartPos; // start of this group
|
||||
|
||||
mork_gid mParser_GroupId; // group ID if inside a group
|
||||
mork_tid mParser_TableId; // table ID if inside a table
|
||||
mork_rid mParser_RowId; // row ID if inside a row
|
||||
morkMid mParser_TableMid; // table mid if inside a table
|
||||
morkMid mParser_RowMid; // row mid if inside a row
|
||||
morkMid mParser_CellMid; // cell mid 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?
|
||||
|
@ -229,28 +252,36 @@ protected: // protected morkParser members
|
|||
mork_bool mParser_InMeta; // called OnNewMeta but not OnMetaEnd?
|
||||
|
||||
mork_bool mParser_InPortRow; // called OnNewPortRow but not OnPortRowEnd?
|
||||
mork_bool mParser_InRow; // called OnNewRow but not OnNewRowEnd?
|
||||
mork_bool mParser_InTable; // called OnNewMeta but not OnMetaEnd?
|
||||
mork_bool mParser_InGroup; // called OnNewGroup but not OnGroupEnd?
|
||||
|
||||
mork_change mParser_AtomChange; // driven by mParser_Change
|
||||
mork_change mParser_CellChange; // driven by mParser_Change
|
||||
mork_change mParser_RowChange; // driven by mParser_Change
|
||||
mork_change mParser_TableChange; // driven by mParser_Change
|
||||
|
||||
mork_change mParser_Change; // driven by modifier in text
|
||||
mork_bool mParser_IsBroken; // has the parse become broken?
|
||||
mork_bool mParser_IsDone; // has the parse finished?
|
||||
mork_bool mParser_DoMore; // mParser_MoreGranularity not exhausted?
|
||||
|
||||
mork_change mParser_Change; // driven by modifier in text
|
||||
morkMid mParser_Mid; // current alias being parsed
|
||||
// note that mParser_Mid.mMid_Buf points at mParser_ScopeCoil below:
|
||||
|
||||
morkAlias mParser_Alias; // current alias being parsed
|
||||
// note that mParser_Alias.mAlias_Buf points at mParser_ScopeSpool 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
|
||||
|
||||
// blob spools allocated in mParser_Heap
|
||||
morkSpool mParser_ScopeSpool; // place to accumulate ID scope blobs
|
||||
morkSpool mParser_ValueSpool; // place to accumulate value blobs
|
||||
morkSpool mParser_ColumnSpool; // place to accumulate column blobs
|
||||
morkSpool mParser_StringSpool; // place to accumulate string blobs
|
||||
|
||||
morkSpoolSink mParser_ScopeSink; // writes to mParser_ScopeSpool
|
||||
morkSpoolSink mParser_ValueSink; // writes to mParser_ValueSpool
|
||||
morkSpoolSink mParser_ColumnSink; // writes to mParser_ColumnSpool
|
||||
morkSpoolSink mParser_StringSink; // writes to mParser_StringSpool
|
||||
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_AliasYarn; // place to receive from AliasToYarn()
|
||||
morkYarn mParser_MidYarn; // place to receive from MidToYarn()
|
||||
|
||||
// span showing current ongoing file position status:
|
||||
morkSpan mParser_PortSpan; // span of current db port file
|
||||
|
@ -274,8 +305,8 @@ private: // convenience inlines
|
|||
void SetHerePos(mork_pos inPos)
|
||||
{ mParser_PortSpan.mSpan_End.mPlace_Pos = inPos; }
|
||||
|
||||
void AddLine()
|
||||
{ ++ mParser_PortSpan.mSpan_End.mPlace_Line; }
|
||||
void CountLineBreak()
|
||||
{ ++mParser_PortSpan.mSpan_End.mPlace_Line; }
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
|
@ -300,8 +331,13 @@ public: // dynamic type identification
|
|||
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
public: // typing
|
||||
void NonParserTypeError(morkEnv* ev);
|
||||
public: // errors and warnings
|
||||
static void UnexpectedEofError(morkEnv* ev);
|
||||
static void EofInsteadOfHexError(morkEnv* ev);
|
||||
static void ExpectedEqualError(morkEnv* ev);
|
||||
static void ExpectedHexDigitError(morkEnv* ev, int c);
|
||||
static void NonParserTypeError(morkEnv* ev);
|
||||
static void UnexpectedByteInMetaWarning(morkEnv* ev);
|
||||
|
||||
public: // other type methods
|
||||
mork_bool GoodParserTag() const { return mParser_Tag == morkParser_kTag; }
|
||||
|
@ -312,8 +348,8 @@ public: // other type methods
|
|||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
public: // in virtual morkParser methods, data flow subclass to parser
|
||||
|
||||
virtual void AliasToYarn(morkEnv* ev,
|
||||
const morkAlias& inAlias, // typically an alias to concat with strings
|
||||
virtual void MidToYarn(morkEnv* ev,
|
||||
const morkMid& inMid, // typically an alias to concat with strings
|
||||
mdbYarn* outYarn) = 0;
|
||||
// The parser might ask that some aliases be turned into yarns, so they
|
||||
// can be concatenated into longer blobs under some circumstances. This
|
||||
|
@ -350,7 +386,7 @@ public: // out virtual morkParser methods, data flow parser to subclass
|
|||
// mp:RowItem ::= mp:Cell | mp:Meta | OnRowGlitch
|
||||
// mp:Cell ::= OnNewCell mp:CellItem? OnCellEnd
|
||||
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
|
||||
// mp:Slot ::= OnValue | OnValueAlias | OnRowAlias | OnTableAlias
|
||||
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
|
||||
|
||||
|
||||
// Note that in interfaces below, mork_change parameters kAdd and kNil
|
||||
|
@ -367,12 +403,12 @@ public: // out virtual morkParser methods, data flow parser to subclass
|
|||
virtual void OnGroupAbortEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
|
||||
virtual void OnNewPortRow(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange) = 0;
|
||||
const morkMid& inMid, mork_change inChange) = 0;
|
||||
virtual void OnPortRowGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0;
|
||||
virtual void OnPortRowEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
|
||||
virtual void OnNewTable(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange) = 0;
|
||||
const morkMid& inMid, mork_change inChange) = 0;
|
||||
virtual void OnTableGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0;
|
||||
virtual void OnTableEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
|
||||
|
@ -381,7 +417,7 @@ public: // out virtual morkParser methods, data flow parser to subclass
|
|||
virtual void OnMetaEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
|
||||
virtual void OnNewRow(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange) = 0;
|
||||
const morkMid& inMid, mork_change inChange) = 0;
|
||||
virtual void OnRowGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0;
|
||||
virtual void OnRowEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
|
||||
|
@ -390,12 +426,16 @@ public: // out virtual morkParser methods, data flow parser to subclass
|
|||
virtual void OnDictEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
|
||||
virtual void OnAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias) = 0;
|
||||
const morkMid& inMid) = 0;
|
||||
|
||||
virtual void OnAliasGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0;
|
||||
|
||||
virtual void OnNewCell(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange) = 0;
|
||||
const morkMid* inMid, const morkBuf* inBuf, mork_change inChange) = 0;
|
||||
// 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) = 0;
|
||||
virtual void OnCellForm(morkEnv* ev, mork_cscode inCharsetFormat) = 0;
|
||||
virtual void OnCellEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
|
@ -403,29 +443,54 @@ public: // out virtual morkParser methods, data flow parser to subclass
|
|||
virtual void OnValue(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkBuf& inBuf) = 0;
|
||||
|
||||
virtual void OnValueAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias) = 0;
|
||||
virtual void OnValueMid(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkMid& inMid) = 0;
|
||||
|
||||
virtual void OnRowAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias) = 0;
|
||||
virtual void OnRowMid(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkMid& inMid) = 0;
|
||||
|
||||
virtual void OnTableAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias) = 0;
|
||||
virtual void OnTableMid(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkMid& inMid) = 0;
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
protected: // protected parser helper methods
|
||||
|
||||
void ParseLoop(morkEnv* ev); // find parse continuation and resume
|
||||
|
||||
void StartParse(morkEnv* ev); // prepare for parsing
|
||||
void StopParse(morkEnv* ev); // terminate parsing & call needed methods
|
||||
void ParseLoop(morkEnv* ev); // find parse continuation and resume
|
||||
|
||||
void StartParse(morkEnv* ev); // prepare for parsing
|
||||
void StopParse(morkEnv* ev); // terminate parsing & call needed methods
|
||||
|
||||
int NextChar(morkEnv* ev); // next non-white content
|
||||
|
||||
void OnCellState(morkEnv* ev);
|
||||
void OnMetaState(morkEnv* ev);
|
||||
void OnRowState(morkEnv* ev);
|
||||
void OnTableState(morkEnv* ev);
|
||||
void OnDictState(morkEnv* ev);
|
||||
void OnPortState(morkEnv* ev);
|
||||
void OnStartState(morkEnv* ev);
|
||||
|
||||
int NextChar(morkEnv* ev); // next non-white content
|
||||
void ReadCell(morkEnv* ev);
|
||||
void ReadRow(morkEnv* ev, int c);
|
||||
void ReadTable(morkEnv* ev);
|
||||
void ReadTableMeta(morkEnv* ev);
|
||||
void ReadDict(morkEnv* ev);
|
||||
void ReadMeta(morkEnv* ev, int inEndMeta);
|
||||
void ReadAlias(morkEnv* ev);
|
||||
mork_id ReadHex(morkEnv* ev, int* outNextChar);
|
||||
morkBuf* ReadValue(morkEnv* ev);
|
||||
morkBuf* ReadName(morkEnv* ev, int c);
|
||||
mork_bool ReadMid(morkEnv* ev, morkMid* outMid);
|
||||
|
||||
void EndSpanOnThisByte(morkEnv* ev, morkSpan* ioSpan);
|
||||
void StartSpanOnLastByte(morkEnv* ev, morkSpan* ioSpan);
|
||||
|
||||
int eat_line_break(morkEnv* ev, int inLast);
|
||||
int eat_line_continue(morkEnv* ev); // last char was '\\'
|
||||
int eat_comment(morkEnv* ev); // last char was '/'
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
public: // public non-poly morkParser methods
|
||||
|
||||
void SetParserStream(morkEnv* ev, morkStream* ioStream);
|
||||
|
||||
mdb_count ParseMore( // return count of bytes consumed now
|
||||
morkEnv* ev, // context
|
||||
|
|
|
@ -199,6 +199,121 @@ morkRow::AcquireCellHandle(morkEnv* ev, morkCell* ioCell,
|
|||
return (nsIMdbCell*) 0;
|
||||
}
|
||||
|
||||
mork_count
|
||||
morkRow::CountOverlap(morkEnv* ev, morkCell* ioVector, mork_fill inFill)
|
||||
// Count cells in ioVector that change existing cells in this row when
|
||||
// ioVector is added to the row (as in TakeCells()). This is the set
|
||||
// of cells with the same columns in ioVector and mRow_Cells, which do
|
||||
// not have exactly the same value in mCell_Atom, and which do not both
|
||||
// have change status equal to morkChange_kCut (because cutting a cut
|
||||
// cell still yields a cell that has been cut). CountOverlap() also
|
||||
// modifies the change attribute of any cell in ioVector to kDup when
|
||||
// the change was previously kCut and the same column cell was found
|
||||
// in this row with change also equal to kCut; this tells callers later
|
||||
// they need not look for that cell in the row again on a second pass.
|
||||
{
|
||||
mork_count outCount = 0;
|
||||
mork_pos pos = 0; // needed by GetCell()
|
||||
morkCell* cells = ioVector;
|
||||
morkCell* end = cells + inFill;
|
||||
--cells; // prepare for preincrement
|
||||
while ( ++cells < end && ev->Good() )
|
||||
{
|
||||
mork_column col = cells->GetColumn();
|
||||
|
||||
morkCell* old = this->GetCell(ev, col, &pos);
|
||||
if ( old ) // same column?
|
||||
{
|
||||
mork_change newChg = cells->GetChange();
|
||||
mork_change oldChg = old->GetChange();
|
||||
if ( newChg != morkChange_kCut || oldChg != newChg ) // not cut+cut?
|
||||
{
|
||||
if ( cells->mCell_Atom != old->mCell_Atom ) // not same atom?
|
||||
++outCount; // cells will replace old significantly when added
|
||||
}
|
||||
else
|
||||
cells->SetColumnAndChange(col, morkChange_kDup); // note dup status
|
||||
}
|
||||
}
|
||||
return outCount;
|
||||
}
|
||||
|
||||
void
|
||||
morkRow::MergeCells(morkEnv* ev, morkCell* ioVector,
|
||||
mork_fill inVecLength, mork_fill inOldRowFill, mork_fill inOverlap)
|
||||
// MergeCells() is the part of TakeCells() that does the insertion.
|
||||
// inOldRowFill is the old value of mRow_Length, and inOverlap is the
|
||||
// number of cells in the intersection that must be updated.
|
||||
{
|
||||
morkCell* newCells = mRow_Cells + inOldRowFill; // 1st new cell in row
|
||||
morkCell* newEnd = newCells + mRow_Length; // one past last cell
|
||||
|
||||
morkCell* srcCells = ioVector;
|
||||
morkCell* srcEnd = srcCells + inVecLength;
|
||||
|
||||
--srcCells; // prepare for preincrement
|
||||
while ( ++srcCells < srcEnd && ev->Good() )
|
||||
{
|
||||
mork_change srcChg = srcCells->GetChange();
|
||||
if ( srcChg != morkChange_kDup ) // anything to be done?
|
||||
{
|
||||
morkCell* dstCell = 0;
|
||||
if ( inOverlap )
|
||||
{
|
||||
mork_pos pos = 0; // needed by GetCell()
|
||||
dstCell = this->GetCell(ev, srcCells->GetColumn(), &pos);
|
||||
}
|
||||
if ( dstCell )
|
||||
{
|
||||
--inOverlap; // one fewer intersections to resolve
|
||||
// swap the atoms in the cells to avoid ref counting here:
|
||||
morkAtom* dstAtom = dstCell->mCell_Atom;
|
||||
*dstCell = *srcCells; // bitwise copy, taking src atom
|
||||
srcCells->mCell_Atom = dstAtom; // forget cell ref, if any
|
||||
}
|
||||
else if ( newCells < newEnd ) // another new cell exists?
|
||||
{
|
||||
dstCell = newCells++; // alloc another new cell
|
||||
// take atom from source cell, transferring ref to this row:
|
||||
*dstCell = *srcCells; // bitwise copy, taking src atom
|
||||
srcCells->mCell_Atom = 0; // forget cell ref, if any
|
||||
}
|
||||
else // oops, we ran out...
|
||||
ev->NewError("out of new cells");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
morkRow::TakeCells(morkEnv* ev, morkCell* ioVector, mork_fill inVecLength,
|
||||
morkStore* ioStore)
|
||||
{
|
||||
if ( ioVector && inVecLength && ev->Good() )
|
||||
{
|
||||
++mRow_Seed; // intend to change structure of mRow_Cells
|
||||
mork_pos length = (mork_pos) mRow_Length;
|
||||
|
||||
mork_count overlap = this->CountOverlap(ev, ioVector, inVecLength);
|
||||
|
||||
mork_size growth = inVecLength - overlap; // cells to add
|
||||
mork_size newLength = length + growth;
|
||||
|
||||
if ( growth && ev->Good() ) // need to add any cells?
|
||||
{
|
||||
morkPool* pool = ioStore->StorePool();
|
||||
if ( !pool->AddRowCells(ev, this, length + growth) )
|
||||
ev->NewError("cannot take cells");
|
||||
}
|
||||
if ( ev->Good() )
|
||||
{
|
||||
if ( mRow_Length >= newLength )
|
||||
this->MergeCells(ev, ioVector, inVecLength, length, overlap);
|
||||
else
|
||||
ev->NewError("not enough new cells");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
morkCell*
|
||||
morkRow::NewCell(morkEnv* ev, mdb_column inColumn,
|
||||
mork_pos* outPos, morkStore* ioStore)
|
||||
|
@ -284,8 +399,7 @@ void
|
|||
morkRow::OnZeroTableUse(morkEnv* ev)
|
||||
// OnZeroTableUse() is called when CutTableUse() returns zero.
|
||||
{
|
||||
// OK, this is a P1 showstopper bug, so I'll comment it out.
|
||||
// ev->NewWarning("need to implement OnZeroTableUse");
|
||||
// ev->NewWarning("need to implement OnZeroTableUse");
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -74,6 +74,27 @@ public: // other row methods
|
|||
|
||||
public: // internal row methods
|
||||
|
||||
mork_count CountOverlap(morkEnv* ev, morkCell* ioVector, mork_fill inFill);
|
||||
// Count cells in ioVector that change existing cells in this row when
|
||||
// ioVector is added to the row (as in TakeCells()). This is the set
|
||||
// of cells with the same columns in ioVector and mRow_Cells, which do
|
||||
// not have exactly the same value in mCell_Atom, and which do not both
|
||||
// have change status equal to morkChange_kCut (because cutting a cut
|
||||
// cell still yields a cell that has been cut). CountOverlap() also
|
||||
// modifies the change attribute of any cell in ioVector to kDup when
|
||||
// the change was previously kCut and the same column cell was found
|
||||
// in this row with change also equal to kCut; this tells callers later
|
||||
// they need not look for that cell in the row again on a second pass.
|
||||
|
||||
void MergeCells(morkEnv* ev, morkCell* ioVector,
|
||||
mork_fill inVecLength, mork_fill inOldRowFill, mork_fill inOverlap);
|
||||
// MergeCells() is the part of TakeCells() that does the insertion.
|
||||
// inOldRowFill is the old value of mRow_Length, and inOverlap is the
|
||||
// number of cells in the intersection that must be updated.
|
||||
|
||||
void TakeCells(morkEnv* ev, morkCell* ioVector, mork_fill inVecLength,
|
||||
morkStore* ioStore);
|
||||
|
||||
morkCell* NewCell(morkEnv* ev, mdb_column inColumn, mork_pos* outPos,
|
||||
morkStore* ioStore);
|
||||
morkCell* GetCell(morkEnv* ev, mdb_column inColumn, mork_pos* outPos) const;
|
||||
|
|
|
@ -230,6 +230,37 @@ morkRowSpace::FindTableByKind(morkEnv* ev, mork_kind inTableKind)
|
|||
return (morkTable*) 0;
|
||||
}
|
||||
|
||||
morkTable*
|
||||
morkRowSpace::NewTableWithTid(morkEnv* ev, mork_tid inTid,
|
||||
mork_kind inTableKind)
|
||||
{
|
||||
morkTable* outTable = 0;
|
||||
|
||||
if ( inTableKind )
|
||||
{
|
||||
mdb_bool mustBeUnique = morkBool_kFalse;
|
||||
nsIMdbHeap* heap = mSpace_Store->mPort_Heap;
|
||||
morkTable* table = new(*heap, ev)
|
||||
morkTable(ev, morkUsage::kHeap, heap, mSpace_Store, heap, this,
|
||||
inTid, inTableKind, mustBeUnique);
|
||||
if ( table )
|
||||
{
|
||||
if ( mRowSpace_Tables.AddTable(ev, table) )
|
||||
{
|
||||
outTable = table;
|
||||
if ( mRowSpace_NextTableId <= inTid )
|
||||
mRowSpace_NextTableId = inTid + 1;
|
||||
}
|
||||
else
|
||||
table->CutStrongRef(ev);
|
||||
}
|
||||
}
|
||||
else
|
||||
this->ZeroKindError(ev);
|
||||
|
||||
return outTable;
|
||||
}
|
||||
|
||||
morkTable*
|
||||
morkRowSpace::NewTable(morkEnv* ev, mork_kind inTableKind,
|
||||
mdb_bool inMustBeUnique)
|
||||
|
@ -328,7 +359,12 @@ morkRowSpace::NewRowWithOid(morkEnv* ev, const mdbOid* inOid)
|
|||
row->InitRow(ev, inOid, this, /*length*/ 0, pool);
|
||||
|
||||
if ( ev->Good() && mRowSpace_Rows.AddRow(ev, row) )
|
||||
{
|
||||
outRow = row;
|
||||
mork_rid rid = inOid->mOid_Id;
|
||||
if ( mRowSpace_NextRowId <= rid )
|
||||
mRowSpace_NextRowId = rid + 1;
|
||||
}
|
||||
else
|
||||
pool->ZapRow(ev, row);
|
||||
}
|
||||
|
|
|
@ -115,6 +115,9 @@ public: // other space methods
|
|||
morkTable* NewTable(morkEnv* ev, mork_kind inTableKind,
|
||||
mdb_bool inMustBeUnique);
|
||||
|
||||
morkTable* NewTableWithTid(morkEnv* ev, mork_tid inTid,
|
||||
mork_kind inTableKind);
|
||||
|
||||
morkTable* FindTableByKind(morkEnv* ev, mork_kind inTableKind);
|
||||
morkTable* FindTableByTid(morkEnv* ev, mork_tid inTid)
|
||||
{ return mRowSpace_Tables.GetTable(ev, inTid); }
|
||||
|
|
|
@ -32,6 +32,10 @@
|
|||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKBLOB_
|
||||
#include "morkBlob.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
/*virtual*/ morkSink::~morkSink()
|
||||
|
@ -41,41 +45,134 @@
|
|||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkSpoolSink::FlushSink(morkEnv* ev) // probably does nothing
|
||||
morkSpool::FlushSink(morkEnv* ev) // sync mSpool_Coil->mBuf_Fill
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
morkCoil* coil = mSpool_Coil;
|
||||
if ( coil )
|
||||
{
|
||||
mork_u1* body = (mork_u1*) coil->mBuf_Body;
|
||||
if ( body )
|
||||
{
|
||||
mork_u1* at = mSink_At;
|
||||
mork_u1* end = mSink_End;
|
||||
if ( at >= body && at <= end ) // expected cursor order?
|
||||
{
|
||||
mork_fill fill = at - body; // current content size
|
||||
if ( fill <= coil->mBlob_Size )
|
||||
coil->mBuf_Fill = fill;
|
||||
else
|
||||
{
|
||||
coil->BlobFillOverSizeError(ev);
|
||||
coil->mBuf_Fill = coil->mBlob_Size; // make it safe
|
||||
}
|
||||
}
|
||||
else
|
||||
this->BadSpoolCursorOrderError(ev);
|
||||
}
|
||||
else
|
||||
coil->NilBufBodyError(ev);
|
||||
}
|
||||
else
|
||||
this->NilSpoolCoilError(ev);
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkSpoolSink::SpillPutc(morkEnv* ev, int c) // grow spool and write byte
|
||||
morkSpool::SpillPutc(morkEnv* ev, int c) // grow coil and write byte
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
morkCoil* coil = mSpool_Coil;
|
||||
if ( coil )
|
||||
{
|
||||
mork_u1* body = (mork_u1*) coil->mBuf_Body;
|
||||
if ( body )
|
||||
{
|
||||
mork_u1* at = mSink_At;
|
||||
mork_u1* end = mSink_End;
|
||||
if ( at >= body && at <= end ) // expected cursor order?
|
||||
{
|
||||
mork_size size = coil->mBlob_Size;
|
||||
mork_fill fill = at - body; // current content size
|
||||
if ( fill <= size ) // less content than medium size?
|
||||
{
|
||||
coil->mBuf_Fill = fill;
|
||||
if ( at >= end ) // need to grow the coil?
|
||||
{
|
||||
if ( size > 2048 ) // grow slower over 2K?
|
||||
size += 512;
|
||||
else
|
||||
{
|
||||
mork_size growth = ( size * 4 ) / 3; // grow by 33%
|
||||
if ( growth < 64 ) // grow faster under (64 * 3)?
|
||||
growth = 64;
|
||||
size += growth;
|
||||
}
|
||||
if ( coil->GrowCoil(ev, size) ) // made coil bigger?
|
||||
{
|
||||
body = (mork_u1*) coil->mBuf_Body;
|
||||
if ( body ) // have a coil body?
|
||||
{
|
||||
mSink_At = at = body + fill;
|
||||
mSink_End = end = body + coil->mBlob_Size;
|
||||
}
|
||||
else
|
||||
coil->NilBufBodyError(ev);
|
||||
}
|
||||
}
|
||||
if ( ev->Good() ) // seem ready to write byte c?
|
||||
{
|
||||
if ( at < end ) // morkSink::Putc() would succeed?
|
||||
{
|
||||
*at++ = c;
|
||||
mSink_At = at;
|
||||
coil->mBuf_Fill = fill + 1;
|
||||
}
|
||||
else
|
||||
this->BadSpoolCursorOrderError(ev);
|
||||
}
|
||||
}
|
||||
else // fill exceeds size
|
||||
{
|
||||
coil->BlobFillOverSizeError(ev);
|
||||
coil->mBuf_Fill = coil->mBlob_Size; // make it safe
|
||||
}
|
||||
}
|
||||
else
|
||||
this->BadSpoolCursorOrderError(ev);
|
||||
}
|
||||
else
|
||||
coil->NilBufBodyError(ev);
|
||||
}
|
||||
else
|
||||
this->NilSpoolCoilError(ev);
|
||||
}
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
// public: // public non-poly morkSink methods
|
||||
|
||||
/*virtual*/
|
||||
morkSpoolSink::~morkSpoolSink()
|
||||
morkSpool::~morkSpool()
|
||||
// Zero all slots to show this sink is disabled, but destroy no memory.
|
||||
// Note it is typically unnecessary to flush this spool sink, since all
|
||||
// content is written directly to the spool without any buffering.
|
||||
// Note it is typically unnecessary to flush this coil sink, since all
|
||||
// content is written directly to the coil without any buffering.
|
||||
{
|
||||
mSink_At = 0;
|
||||
mSink_End = 0;
|
||||
mSpool_Coil = 0;
|
||||
}
|
||||
|
||||
morkSpoolSink::morkSpoolSink(morkEnv* ev, morkSpool* ioSpool)
|
||||
// After installing the spool, calls Seek(ev, 0) to prepare for writing.
|
||||
morkSpool::morkSpool(morkEnv* ev, morkCoil* ioCoil)
|
||||
// After installing the coil, calls Seek(ev, 0) to prepare for writing.
|
||||
: morkSink()
|
||||
, mSpoolSink_Spool( 0 )
|
||||
, mSpool_Coil( 0 )
|
||||
{
|
||||
mSink_At = 0; // set correctly later in Seek()
|
||||
mSink_End = 0; // set correctly later in Seek()
|
||||
|
||||
if ( ev->Good() )
|
||||
{
|
||||
if ( ioSpool )
|
||||
if ( ioCoil )
|
||||
{
|
||||
// ev->StubMethodOnlyError();
|
||||
mSink_At = 0;
|
||||
mSink_End = 0;
|
||||
mSpoolSink_Spool = ioSpool;
|
||||
mSpool_Coil = ioCoil;
|
||||
this->Seek(ev, /*pos*/ 0);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
|
@ -84,29 +181,124 @@ morkSpoolSink::morkSpoolSink(morkEnv* ev, morkSpool* ioSpool)
|
|||
|
||||
// ----- All boolean return values below are equal to ev->Good(): -----
|
||||
|
||||
mork_bool
|
||||
morkSpoolSink::Seek(morkEnv* ev, mork_pos inPos)
|
||||
// Changed the current write position in spool's buffer to inPos.
|
||||
// For example, to start writing the spool from scratch, use inPos==0.
|
||||
/*static*/ void
|
||||
morkSpool::BadSpoolCursorOrderError(morkEnv* ev)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
ev->NewError("bad morkSpool cursor order");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkSpool::NilSpoolCoilError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("nil mSpool_Coil");
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkSpool::Seek(morkEnv* ev, mork_pos inPos)
|
||||
// Changed the current write position in coil's buffer to inPos.
|
||||
// For example, to start writing the coil from scratch, use inPos==0.
|
||||
{
|
||||
morkCoil* coil = mSpool_Coil;
|
||||
if ( coil )
|
||||
{
|
||||
mork_size minSize = inPos + 64;
|
||||
|
||||
if ( coil->mBlob_Size < minSize )
|
||||
coil->GrowCoil(ev, minSize);
|
||||
|
||||
if ( ev->Good() )
|
||||
{
|
||||
coil->mBuf_Fill = inPos;
|
||||
mork_u1* body = (mork_u1*) coil->mBuf_Body;
|
||||
if ( body )
|
||||
{
|
||||
mSink_At = body + inPos;
|
||||
mSink_End = body + coil->mBlob_Size;
|
||||
}
|
||||
else
|
||||
coil->NilBufBodyError(ev);
|
||||
}
|
||||
}
|
||||
else
|
||||
this->NilSpoolCoilError(ev);
|
||||
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkSpoolSink::Write(morkEnv* ev, const void* inBuf, mork_size inSize)
|
||||
// write inSize bytes of inBuf to current position inside spool's buffer
|
||||
morkSpool::Write(morkEnv* ev, const void* inBuf, mork_size inSize)
|
||||
// write inSize bytes of inBuf to current position inside coil's buffer
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// This method is conceptually very similar to morkStream::Write(),
|
||||
// and this code was written while looking at that method for clues.
|
||||
|
||||
morkCoil* coil = mSpool_Coil;
|
||||
if ( coil )
|
||||
{
|
||||
mork_u1* body = (mork_u1*) coil->mBuf_Body;
|
||||
if ( body )
|
||||
{
|
||||
if ( inBuf && inSize ) // anything to write?
|
||||
{
|
||||
mork_u1* at = mSink_At;
|
||||
mork_u1* end = mSink_End;
|
||||
if ( at >= body && at <= end ) // expected cursor order?
|
||||
{
|
||||
// note coil->mBuf_Fill can be stale after morkSink::Putc():
|
||||
mork_pos fill = at - body; // current content size
|
||||
mork_num space = end - at; // space left in body
|
||||
if ( space < inSize ) // not enough to hold write?
|
||||
{
|
||||
mork_size minGrowth = space + 16;
|
||||
mork_size minSize = coil->mBlob_Size + minGrowth;
|
||||
if ( coil->GrowCoil(ev, minSize) )
|
||||
{
|
||||
body = (mork_u1*) coil->mBuf_Body;
|
||||
if ( body )
|
||||
{
|
||||
mSink_At = at = body + fill;
|
||||
mSink_End = end = body + coil->mBlob_Size;
|
||||
space = end - at; // space left in body
|
||||
}
|
||||
else
|
||||
coil->NilBufBodyError(ev);
|
||||
}
|
||||
}
|
||||
if ( ev->Good() )
|
||||
{
|
||||
if ( space >= inSize ) // enough room to hold write?
|
||||
{
|
||||
MORK_MEMCPY(at, inBuf, inSize); // into body
|
||||
mSink_At = at + inSize; // advance past written bytes
|
||||
coil->mBuf_Fill = fill + inSize; // "flush" to fix fill
|
||||
}
|
||||
else
|
||||
ev->NewError("insufficient morkSpool space");
|
||||
}
|
||||
}
|
||||
else
|
||||
this->BadSpoolCursorOrderError(ev);
|
||||
}
|
||||
}
|
||||
else
|
||||
coil->NilBufBodyError(ev);
|
||||
}
|
||||
else
|
||||
this->NilSpoolCoilError(ev);
|
||||
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkSpoolSink::PutString(morkEnv* ev, const char* inString)
|
||||
morkSpool::PutString(morkEnv* ev, const char* inString)
|
||||
// call Write() with inBuf=inString and inSize=strlen(inString),
|
||||
// unless inString is null, in which case we then do nothing at all.
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
if ( inString )
|
||||
{
|
||||
mork_size size = MORK_STRLEN(inString);
|
||||
this->Write(ev, inString, size);
|
||||
}
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
|
|
|
@ -114,47 +114,52 @@ public: // public non-poly morkSink methods
|
|||
}
|
||||
};
|
||||
|
||||
/*| morkSpoolSink: an output sink that efficiently writes individual bytes
|
||||
**| or entire byte sequences to a spool instance, which grows as needed by
|
||||
**| using the heap instance in the spool to grow the internal buffer.
|
||||
/*| morkSpool: an output sink that efficiently writes individual bytes
|
||||
**| or entire byte sequences to a coil instance, which grows as needed by
|
||||
**| using the heap instance in the coil to grow the internal buffer.
|
||||
**|
|
||||
**|| Note we do not "own" the spool referenced by mSpoolSink_Spool, and
|
||||
**| the lifetime of the spool is expected to equal or exceed that of this
|
||||
**|| Note we do not "own" the coil referenced by mSpool_Coil, and
|
||||
**| the lifetime of the coil is expected to equal or exceed that of this
|
||||
**| sink by some external means. Typical usage might involve keeping an
|
||||
**| instance of morkSpool and an instance of morkSpoolSink in the same
|
||||
**| owning parent object, which uses the sink with the associated spool.
|
||||
**| instance of morkCoil and an instance of morkSpool in the same
|
||||
**| owning parent object, which uses the spool with the associated coil.
|
||||
|*/
|
||||
class morkSpoolSink : public morkSink { // for buffered i/o to a morkSpool
|
||||
class morkSpool : public morkSink { // for buffered i/o to a morkCoil
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
public: // public sink virtual methods
|
||||
|
||||
virtual void FlushSink(morkEnv* ev); // probably does nothing
|
||||
virtual void SpillPutc(morkEnv* ev, int c); // grow spool and write byte
|
||||
// when morkSink::Putc() moves mSink_At, mSpool_Coil->mBuf_Fill is wrong:
|
||||
|
||||
virtual void FlushSink(morkEnv* ev); // sync mSpool_Coil->mBuf_Fill
|
||||
virtual void SpillPutc(morkEnv* ev, int c); // grow coil and write byte
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
public: // member variables
|
||||
morkSpool* mSpoolSink_Spool; // destination medium for written bytes
|
||||
morkCoil* mSpool_Coil; // destination medium for written bytes
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
public: // public non-poly morkSink methods
|
||||
|
||||
virtual ~morkSpoolSink();
|
||||
static void BadSpoolCursorOrderError(morkEnv* ev);
|
||||
static void NilSpoolCoilError(morkEnv* ev);
|
||||
|
||||
virtual ~morkSpool();
|
||||
// Zero all slots to show this sink is disabled, but destroy no memory.
|
||||
// Note it is typically unnecessary to flush this spool sink, since all
|
||||
// content is written directly to the spool without any buffering.
|
||||
// Note it is typically unnecessary to flush this coil sink, since all
|
||||
// content is written directly to the coil without any buffering.
|
||||
|
||||
morkSpoolSink(morkEnv* ev, morkSpool* ioSpool);
|
||||
// After installing the spool, calls Seek(ev, 0) to prepare for writing.
|
||||
morkSpool(morkEnv* ev, morkCoil* ioCoil);
|
||||
// After installing the coil, calls Seek(ev, 0) to prepare for writing.
|
||||
|
||||
// ----- All boolean return values below are equal to ev->Good(): -----
|
||||
|
||||
mork_bool Seek(morkEnv* ev, mork_pos inPos);
|
||||
// Changed the current write position in spool's buffer to inPos.
|
||||
// For example, to start writing the spool from scratch, use inPos==0.
|
||||
// Changed the current write position in coil's buffer to inPos.
|
||||
// For example, to start writing the coil from scratch, use inPos==0.
|
||||
|
||||
mork_bool Write(morkEnv* ev, const void* inBuf, mork_size inSize);
|
||||
// write inSize bytes of inBuf to current position inside spool's buffer
|
||||
// write inSize bytes of inBuf to current position inside coil's buffer
|
||||
|
||||
mork_bool PutBuf(morkEnv* ev, const morkBuf& inBuffer)
|
||||
{ return this->Write(ev, inBuffer.mBuf_Body, inBuffer.mBuf_Fill); }
|
||||
|
|
|
@ -92,6 +92,10 @@
|
|||
#include "morkRowMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKPARSER_
|
||||
#include "morkParser.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
|
@ -212,6 +216,15 @@ morkStore::morkStore(morkEnv* ev, const morkUsage& inUsage,
|
|||
, mStore_OidAtomSpace( 0 )
|
||||
, mStore_GroundAtomSpace( 0 )
|
||||
, mStore_GroundColumnSpace( 0 )
|
||||
|
||||
, mStore_MorkNoneToken( 0 )
|
||||
, mStore_CharsetToken( 0 )
|
||||
, mStore_AtomScopeToken( 0 )
|
||||
, mStore_RowScopeToken( 0 )
|
||||
, mStore_TableScopeToken( 0 )
|
||||
, mStore_ColumnScopeToken( 0 )
|
||||
, mStore_TableKindToken( 0 )
|
||||
|
||||
, mStore_RowSpaces(ev, morkUsage::kMember, (nsIMdbHeap*) 0, ioPortHeap)
|
||||
, mStore_AtomSpaces(ev, morkUsage::kMember, (nsIMdbHeap*) 0, ioPortHeap)
|
||||
, mStore_Pool(ev, morkUsage::kMember, (nsIMdbHeap*) 0, ioPortHeap)
|
||||
|
@ -220,6 +233,9 @@ morkStore::morkStore(morkEnv* ev, const morkUsage& inUsage,
|
|||
{
|
||||
mNode_Derived = morkDerived_kStore;
|
||||
|
||||
if ( ev->Good() )
|
||||
mStore_MorkNoneToken = this->StringToToken(ev, "mork:none");
|
||||
|
||||
if ( ev->Good() )
|
||||
mStore_CharsetToken = this->StringToToken(ev, "charset");
|
||||
|
||||
|
@ -302,6 +318,28 @@ morkStore::AcquireStoreHandle(morkEnv* ev)
|
|||
}
|
||||
|
||||
|
||||
morkMaxBookAtom*
|
||||
morkStore::StageAliasAsBookAtom(morkEnv* ev, const morkMid* inMid,
|
||||
morkAtomSpace* ioSpace, mork_cscode inForm)
|
||||
{
|
||||
if ( inMid && inMid->mMid_Buf )
|
||||
{
|
||||
const morkBuf* buf = inMid->mMid_Buf;
|
||||
mork_size length = buf->mBuf_Fill;
|
||||
if ( length <= morkBookAtom_kMaxBodySize )
|
||||
{
|
||||
mork_aid dummyAid = 1;
|
||||
mStore_BookAtom.InitMaxBookAtom(ev, *buf,
|
||||
inForm, ioSpace, dummyAid);
|
||||
return &mStore_BookAtom;
|
||||
}
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
|
||||
return (morkMaxBookAtom*) 0;
|
||||
}
|
||||
|
||||
morkMaxBookAtom*
|
||||
morkStore::StageYarnAsBookAtom(morkEnv* ev, const mdbYarn* inYarn,
|
||||
morkAtomSpace* ioSpace)
|
||||
|
@ -436,6 +474,15 @@ morkStream* morkStore::LazyGetOutStream(morkEnv* ev)
|
|||
return mStore_OutStream;
|
||||
}
|
||||
|
||||
void
|
||||
morkStore::ForgetBuilder(morkEnv* ev)
|
||||
{
|
||||
if ( mStore_Builder )
|
||||
morkBuilder::SlotStrongBuilder((morkBuilder*) 0, ev, &mStore_Builder);
|
||||
if ( mStore_InStream )
|
||||
morkStream::SlotStrongStream((morkStream*) 0, ev, &mStore_InStream);
|
||||
}
|
||||
|
||||
morkBuilder* morkStore::LazyGetBuilder(morkEnv* ev)
|
||||
{
|
||||
if ( !mStore_Builder )
|
||||
|
@ -556,7 +603,7 @@ morkStore::CreateStoreFile(morkEnv* ev,
|
|||
}
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
|
||||
morkAtom*
|
||||
morkStore::YarnToAtom(morkEnv* ev, const mdbYarn* inYarn)
|
||||
{
|
||||
|
@ -586,10 +633,125 @@ morkStore::YarnToAtom(morkEnv* ev, const mdbYarn* inYarn)
|
|||
return outAtom;
|
||||
}
|
||||
|
||||
// mork_bool
|
||||
// morkStore::CutBookAtom(morkEnv* ev, morkBookAtom* ioAtom)
|
||||
// {
|
||||
// }
|
||||
mork_bool
|
||||
morkStore::MidToOid(morkEnv* ev, const morkMid& inMid, mdbOid* outOid)
|
||||
{
|
||||
*outOid = inMid.mMid_Oid;
|
||||
const morkBuf* buf = inMid.mMid_Buf;
|
||||
if ( buf && !outOid->mOid_Scope )
|
||||
{
|
||||
mdbOid oid = inMid.mMid_Oid;
|
||||
if ( buf->mBuf_Fill <= morkBookAtom_kMaxBodySize )
|
||||
{
|
||||
if ( buf->mBuf_Fill == 1 )
|
||||
{
|
||||
mork_u1* name = (mork_u1*) buf->mBuf_Body;
|
||||
if ( name )
|
||||
{
|
||||
outOid->mOid_Scope = (mork_scope) *name;
|
||||
return ev->Good();
|
||||
}
|
||||
}
|
||||
morkAtomSpace* groundSpace = this->LazyGetGroundColumnSpace(ev);
|
||||
if ( groundSpace )
|
||||
{
|
||||
mork_cscode form = 0; // default
|
||||
mork_aid aid = 1; // dummy
|
||||
mStore_BookAtom.InitMaxBookAtom(ev, *buf, form, groundSpace, aid);
|
||||
morkMaxBookAtom* keyAtom = &mStore_BookAtom;
|
||||
morkAtomBodyMap* map = &groundSpace->mAtomSpace_AtomBodies;
|
||||
morkBookAtom* bookAtom = map->GetAtom(ev, keyAtom);
|
||||
if ( bookAtom )
|
||||
outOid->mOid_Scope = bookAtom->mBookAtom_Id;
|
||||
else
|
||||
{
|
||||
bookAtom = groundSpace->MakeBookAtomCopy(ev, *keyAtom);
|
||||
if ( bookAtom )
|
||||
{
|
||||
outOid->mOid_Scope = bookAtom->mBookAtom_Id;
|
||||
bookAtom->MakeCellUseForever(ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
morkRow*
|
||||
morkStore::MidToRow(morkEnv* ev, const morkMid& inMid)
|
||||
{
|
||||
mdbOid tempOid;
|
||||
this->MidToOid(ev, inMid, &tempOid);
|
||||
return this->OidToRow(ev, &tempOid);
|
||||
}
|
||||
|
||||
morkTable*
|
||||
morkStore::MidToTable(morkEnv* ev, const morkMid& inMid)
|
||||
{
|
||||
mdbOid tempOid;
|
||||
this->MidToOid(ev, inMid, &tempOid);
|
||||
return this->OidToTable(ev, &tempOid);
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkStore::MidToYarn(morkEnv* ev, const morkMid& inMid, mdbYarn* outYarn)
|
||||
{
|
||||
mdbOid tempOid;
|
||||
this->MidToOid(ev, inMid, &tempOid);
|
||||
return this->OidToYarn(ev, tempOid, outYarn);
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkStore::OidToYarn(morkEnv* ev, const mdbOid& inOid, mdbYarn* outYarn)
|
||||
{
|
||||
morkBookAtom* atom = 0;
|
||||
|
||||
morkAtomSpace* atomSpace = mStore_AtomSpaces.GetAtomSpace(ev, inOid.mOid_Scope);
|
||||
if ( atomSpace )
|
||||
{
|
||||
morkAtomAidMap* map = &atomSpace->mAtomSpace_AtomAids;
|
||||
atom = map->GetAid(ev, (mork_aid) inOid.mOid_Id);
|
||||
}
|
||||
atom->GetYarn(outYarn); // note this is safe even when atom==nil
|
||||
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
morkBookAtom*
|
||||
morkStore::MidToAtom(morkEnv* ev, const morkMid& inMid)
|
||||
{
|
||||
morkBookAtom* outAtom = 0;
|
||||
mdbOid oid;
|
||||
if ( this->MidToOid(ev, inMid, &oid) )
|
||||
{
|
||||
morkAtomSpace* atomSpace = mStore_AtomSpaces.GetAtomSpace(ev, oid.mOid_Scope);
|
||||
if ( atomSpace )
|
||||
{
|
||||
morkAtomAidMap* map = &atomSpace->mAtomSpace_AtomAids;
|
||||
outAtom = map->GetAid(ev, (mork_aid) oid.mOid_Id);
|
||||
}
|
||||
}
|
||||
return outAtom;
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkStore::SmallTokenToOneByteYarn(morkEnv* ev, mdb_token inToken,
|
||||
mdbYarn* outYarn)
|
||||
{
|
||||
if ( outYarn->mYarn_Buf && outYarn->mYarn_Size ) // any space in yarn at all?
|
||||
{
|
||||
mork_u1* buf = (mork_u1*) outYarn->mYarn_Buf; // for byte arithmetic
|
||||
buf[ 0 ] = (mork_u1) inToken; // write the single byte
|
||||
outYarn->mYarn_Fill = 1;
|
||||
outYarn->mYarn_More = 0;
|
||||
}
|
||||
else // just record we could not write the single byte
|
||||
{
|
||||
outYarn->mYarn_More = 1;
|
||||
outYarn->mYarn_Fill = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
morkStore::TokenToString(morkEnv* ev, mdb_token inToken, mdbYarn* outTokenName)
|
||||
|
@ -604,23 +766,161 @@ morkStore::TokenToString(morkEnv* ev, mdb_token inToken, mdbYarn* outTokenName)
|
|||
atom->GetYarn(outTokenName); // note this is safe even when atom==nil
|
||||
}
|
||||
else // token is an "immediate" single byte string representation?
|
||||
this->SmallTokenToOneByteYarn(ev, inToken, outTokenName);
|
||||
}
|
||||
|
||||
void
|
||||
morkStore::SyncTokenIdChange(morkEnv* ev, const morkBookAtom* inAtom,
|
||||
const mdbOid* inOid)
|
||||
{
|
||||
// mork_token mStore_MorkNoneToken; // token for "mork:none" // fill=9
|
||||
// mork_column mStore_CharsetToken; // token for "charset" // fill=7
|
||||
// mork_column mStore_AtomScopeToken; // token for "atomScope" // fill=9
|
||||
// mork_column mStore_RowScopeToken; // token for "rowScope" // fill=8
|
||||
// mork_column mStore_TableScopeToken; // token for "tableScope" // fill=10
|
||||
// mork_column mStore_ColumnScopeToken; // token for "columnScope" // fill=11
|
||||
// mork_kind mStore_TableKindToken; // token for "tableKind" // fill=9
|
||||
// ---------------------ruler-for-token-length-above---123456789012
|
||||
|
||||
if ( inOid->mOid_Scope == morkStore_kColumnSpaceScope && inAtom->IsWeeBook() )
|
||||
{
|
||||
mdbYarn* y = outTokenName;
|
||||
if ( y->mYarn_Buf && y->mYarn_Size ) // any space in yarn at all?
|
||||
const mork_u1* body = ((const morkWeeBookAtom*) inAtom)->mWeeBookAtom_Body;
|
||||
mork_size size = inAtom->mAtom_Size;
|
||||
|
||||
if ( size >= 7 && size <= 11 )
|
||||
{
|
||||
mork_u1* buf = (mork_u1*) y->mYarn_Buf; // for byte arithmetic
|
||||
buf[ 0 ] = (mork_u1) inToken; // write the single byte
|
||||
y->mYarn_Fill = 1;
|
||||
y->mYarn_More = 0;
|
||||
}
|
||||
else // just record we could not write the single byte
|
||||
{
|
||||
y->mYarn_More = 1;
|
||||
y->mYarn_Fill = 0;
|
||||
if ( size == 9 )
|
||||
{
|
||||
if ( *body == 'm' )
|
||||
{
|
||||
if ( MORK_MEMCMP(body, "mork:none", 9) == 0 )
|
||||
mStore_MorkNoneToken = inAtom->mBookAtom_Id;
|
||||
}
|
||||
else if ( *body == 'a' )
|
||||
{
|
||||
if ( MORK_MEMCMP(body, "atomScope", 9) == 0 )
|
||||
mStore_AtomScopeToken = inAtom->mBookAtom_Id;
|
||||
}
|
||||
else if ( *body == 't' )
|
||||
{
|
||||
if ( MORK_MEMCMP(body, "tableKind", 9) == 0 )
|
||||
mStore_TableKindToken = inAtom->mBookAtom_Id;
|
||||
}
|
||||
}
|
||||
else if ( size == 7 && *body == 'c' )
|
||||
{
|
||||
if ( MORK_MEMCMP(body, "charset", 7) == 0 )
|
||||
mStore_CharsetToken = inAtom->mBookAtom_Id;
|
||||
}
|
||||
else if ( size == 8 && *body == 'r' )
|
||||
{
|
||||
if ( MORK_MEMCMP(body, "rowScope", 8) == 0 )
|
||||
mStore_RowScopeToken = inAtom->mBookAtom_Id;
|
||||
}
|
||||
else if ( size == 10 && *body == 't' )
|
||||
{
|
||||
if ( MORK_MEMCMP(body, "tableScope", 10) == 0 )
|
||||
mStore_TableScopeToken = inAtom->mBookAtom_Id;
|
||||
}
|
||||
else if ( size == 11 && *body == 'c' )
|
||||
{
|
||||
if ( MORK_MEMCMP(body, "columnScope", 11) == 0 )
|
||||
mStore_ColumnScopeToken = inAtom->mBookAtom_Id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
morkAtom*
|
||||
morkStore::AddAlias(morkEnv* ev, const morkMid& inMid, mork_cscode inForm)
|
||||
{
|
||||
morkBookAtom* outAtom = 0;
|
||||
if ( ev->Good() )
|
||||
{
|
||||
const mdbOid* oid = &inMid.mMid_Oid;
|
||||
morkAtomSpace* atomSpace = this->LazyGetAtomSpace(ev, oid->mOid_Scope);
|
||||
if ( atomSpace )
|
||||
{
|
||||
morkMaxBookAtom* keyAtom =
|
||||
this->StageAliasAsBookAtom(ev, &inMid, atomSpace, inForm);
|
||||
if ( keyAtom )
|
||||
{
|
||||
morkAtomAidMap* map = &atomSpace->mAtomSpace_AtomAids;
|
||||
outAtom = map->GetAid(ev, (mork_aid) oid->mOid_Id);
|
||||
if ( outAtom )
|
||||
{
|
||||
if ( !outAtom->EqualFormAndBody(ev, keyAtom) )
|
||||
ev->NewError("duplicate alias ID");
|
||||
}
|
||||
else
|
||||
{
|
||||
keyAtom->mBookAtom_Id = oid->mOid_Id;
|
||||
outAtom = atomSpace->MakeBookAtomCopyWithAid(ev,
|
||||
*keyAtom, (mork_aid) oid->mOid_Id);
|
||||
|
||||
if ( outAtom && outAtom->IsWeeBook() )
|
||||
{
|
||||
if ( oid->mOid_Scope == morkStore_kColumnSpaceScope )
|
||||
{
|
||||
mork_size size = outAtom->mAtom_Size;
|
||||
if ( size >= 7 && size <= 11 )
|
||||
this->SyncTokenIdChange(ev, outAtom, oid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return outAtom;
|
||||
}
|
||||
|
||||
mork_token
|
||||
morkStore::BufToToken(morkEnv* ev, const morkBuf* inBuf)
|
||||
{
|
||||
mork_token outToken = 0;
|
||||
if ( ev->Good() )
|
||||
{
|
||||
const mork_u1* s = (const mork_u1*) inBuf->mBuf_Body;
|
||||
mork_bool nonAscii = ( *s > 0x7F );
|
||||
mork_size length = inBuf->mBuf_Fill;
|
||||
if ( nonAscii || length > 1 ) // more than one byte?
|
||||
{
|
||||
mork_cscode form = 0; // default charset
|
||||
morkAtomSpace* space = this->LazyGetGroundColumnSpace(ev);
|
||||
if ( space )
|
||||
{
|
||||
morkMaxBookAtom* keyAtom = 0;
|
||||
if ( length <= morkBookAtom_kMaxBodySize )
|
||||
{
|
||||
mork_aid aid = 1; // dummy
|
||||
mStore_BookAtom.InitMaxBookAtom(ev, *inBuf, form, space, aid);
|
||||
keyAtom = &mStore_BookAtom;
|
||||
}
|
||||
if ( keyAtom )
|
||||
{
|
||||
morkAtomBodyMap* map = &space->mAtomSpace_AtomBodies;
|
||||
morkBookAtom* bookAtom = map->GetAtom(ev, keyAtom);
|
||||
if ( bookAtom )
|
||||
outToken = bookAtom->mBookAtom_Id;
|
||||
else
|
||||
{
|
||||
bookAtom = space->MakeBookAtomCopy(ev, *keyAtom);
|
||||
if ( bookAtom )
|
||||
{
|
||||
outToken = bookAtom->mBookAtom_Id;
|
||||
bookAtom->MakeCellUseForever(ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else // only a single byte in inTokenName string:
|
||||
outToken = *s;
|
||||
}
|
||||
|
||||
return outToken;
|
||||
}
|
||||
|
||||
mork_token
|
||||
morkStore::StringToToken(morkEnv* ev, const char* inTokenName)
|
||||
{
|
||||
|
@ -702,6 +1002,8 @@ morkStore::HasTableKind(morkEnv* ev, mdb_scope inRowScope,
|
|||
mdb_kind inTableKind, mdb_count* outTableCount)
|
||||
{
|
||||
mork_bool outBool = morkBool_kFalse;
|
||||
|
||||
ev->StubMethodOnlyError();
|
||||
|
||||
return outBool;
|
||||
}
|
||||
|
@ -789,6 +1091,19 @@ morkStore::GetPortTableCursor(morkEnv* ev, mdb_scope inRowScope,
|
|||
return outCursor;
|
||||
}
|
||||
|
||||
morkRow*
|
||||
morkStore::NewRow(morkEnv* ev, mdb_scope inRowScope)
|
||||
{
|
||||
morkRow* outRow = 0;
|
||||
if ( ev->Good() )
|
||||
{
|
||||
morkRowSpace* rowSpace = this->LazyGetRowSpace(ev, inRowScope);
|
||||
if ( rowSpace )
|
||||
outRow = rowSpace->NewRow(ev);
|
||||
}
|
||||
return outRow;
|
||||
}
|
||||
|
||||
morkRow*
|
||||
morkStore::NewRowWithOid(morkEnv* ev, const mdbOid* inOid)
|
||||
{
|
||||
|
@ -803,16 +1118,42 @@ morkStore::NewRowWithOid(morkEnv* ev, const mdbOid* inOid)
|
|||
}
|
||||
|
||||
morkRow*
|
||||
morkStore::NewRow(morkEnv* ev, mdb_scope inRowScope)
|
||||
morkStore::OidToRow(morkEnv* ev, const mdbOid* inOid)
|
||||
// OidToRow() finds old row with oid, or makes new one if not found.
|
||||
{
|
||||
morkRow* outRow = 0;
|
||||
if ( ev->Good() )
|
||||
{
|
||||
morkRowSpace* rowSpace = this->LazyGetRowSpace(ev, inRowScope);
|
||||
morkRowSpace* rowSpace = this->LazyGetRowSpace(ev, inOid->mOid_Scope);
|
||||
if ( rowSpace )
|
||||
outRow = rowSpace->NewRow(ev);
|
||||
{
|
||||
outRow = rowSpace->mRowSpace_Rows.GetOid(ev, inOid);
|
||||
if ( !outRow && ev->Good() )
|
||||
outRow = rowSpace->NewRowWithOid(ev, inOid);
|
||||
}
|
||||
}
|
||||
return outRow;
|
||||
}
|
||||
|
||||
morkTable*
|
||||
morkStore::OidToTable(morkEnv* ev, const mdbOid* inOid)
|
||||
// OidToTable() finds old table with oid, or makes new one if not found.
|
||||
{
|
||||
morkTable* outTable = 0;
|
||||
if ( ev->Good() )
|
||||
{
|
||||
morkRowSpace* rowSpace = this->LazyGetRowSpace(ev, inOid->mOid_Scope);
|
||||
if ( rowSpace )
|
||||
{
|
||||
outTable = rowSpace->mRowSpace_Tables.GetTable(ev, inOid->mOid_Id);
|
||||
if ( !outTable && ev->Good() )
|
||||
{
|
||||
mork_kind tableKind = mStore_MorkNoneToken;
|
||||
outTable = rowSpace->NewTableWithTid(ev, inOid->mOid_Id, tableKind);
|
||||
}
|
||||
}
|
||||
}
|
||||
return outTable;
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
|
|
@ -115,6 +115,7 @@ public: // typesafe refcounting inlines calling inherited morkNode methods
|
|||
**| all other explicitly tokenized strings.
|
||||
|*/
|
||||
#define morkStore_kGroundColumnSpace 'c' /* for mStore_GroundColumnSpace*/
|
||||
#define morkStore_kColumnSpaceScope ((mork_scope) 'c') /*kGroundColumnSpace*/
|
||||
#define morkStore_kGroundAtomSpace 'a' /* for mStore_GroundAtomSpace*/
|
||||
#define morkStore_kStreamBufSize (8 * 1024) /* okay buffer size */
|
||||
|
||||
|
@ -150,6 +151,7 @@ public: // state is public because the entire Mork system is private
|
|||
|
||||
morkStream* mStore_OutStream; // stream using file used by the writer
|
||||
|
||||
mork_token mStore_MorkNoneToken; // token for "mork:none"
|
||||
mork_column mStore_CharsetToken; // token for "charset"
|
||||
mork_column mStore_AtomScopeToken; // token for "atomScope"
|
||||
mork_column mStore_RowScopeToken; // token for "rowScope"
|
||||
|
@ -164,9 +166,17 @@ public: // state is public because the entire Mork system is private
|
|||
|
||||
// we alloc a max size book atom to reuse space for atom map key searches:
|
||||
morkMaxBookAtom mStore_BookAtom; // staging area for atom map searches
|
||||
|
||||
public: // coping with any changes to store token slots above:
|
||||
|
||||
void SyncTokenIdChange(morkEnv* ev, const morkBookAtom* inAtom,
|
||||
const mdbOid* inOid);
|
||||
|
||||
public: // building an atom inside mStore_BookAtom from a char* string
|
||||
|
||||
morkMaxBookAtom* StageAliasAsBookAtom(morkEnv* ev,
|
||||
const morkMid* inMid, morkAtomSpace* ioSpace, mork_cscode inForm);
|
||||
|
||||
morkMaxBookAtom* StageYarnAsBookAtom(morkEnv* ev,
|
||||
const mdbYarn* inYarn, morkAtomSpace* ioSpace);
|
||||
|
||||
|
@ -186,6 +196,7 @@ public: // lazy creation of members and nested row or atom spaces
|
|||
|
||||
morkStream* LazyGetInStream(morkEnv* ev);
|
||||
morkBuilder* LazyGetBuilder(morkEnv* ev);
|
||||
void ForgetBuilder(morkEnv* ev);
|
||||
|
||||
morkStream* LazyGetOutStream(morkEnv* ev);
|
||||
|
||||
|
@ -221,6 +232,8 @@ public: // typing
|
|||
public: // store utilties
|
||||
|
||||
morkAtom* YarnToAtom(morkEnv* ev, const mdbYarn* inYarn);
|
||||
morkAtom* AddAlias(morkEnv* ev, const morkMid& inMid,
|
||||
mork_cscode inForm);
|
||||
|
||||
public: // other store methods
|
||||
|
||||
|
@ -239,11 +252,30 @@ public: // other store methods
|
|||
const char* inFilePath,
|
||||
const mdbOpenPolicy* inOpenPolicy);
|
||||
|
||||
// mork_bool CutBookAtom(morkEnv* ev, morkBookAtom* ioAtom);
|
||||
mork_token BufToToken(morkEnv* ev, const morkBuf* inBuf);
|
||||
mork_token StringToToken(morkEnv* ev, const char* inTokenName);
|
||||
mork_token QueryToken(morkEnv* ev, const char* inTokenName);
|
||||
void TokenToString(morkEnv* ev, mdb_token inToken, mdbYarn* outTokenName);
|
||||
|
||||
mork_bool MidToOid(morkEnv* ev, const morkMid& inMid,
|
||||
mdbOid* outOid);
|
||||
mork_bool OidToYarn(morkEnv* ev, const mdbOid& inOid, mdbYarn* outYarn);
|
||||
mork_bool MidToYarn(morkEnv* ev, const morkMid& inMid,
|
||||
mdbYarn* outYarn);
|
||||
|
||||
morkBookAtom* MidToAtom(morkEnv* ev, const morkMid& inMid);
|
||||
morkRow* MidToRow(morkEnv* ev, const morkMid& inMid);
|
||||
morkTable* MidToTable(morkEnv* ev, const morkMid& inMid);
|
||||
|
||||
morkRow* OidToRow(morkEnv* ev, const mdbOid* inOid);
|
||||
// OidToRow() finds old row with oid, or makes new one if not found.
|
||||
|
||||
morkTable* OidToTable(morkEnv* ev, const mdbOid* inOid);
|
||||
// OidToTable() finds old table with oid, or makes new one if not found.
|
||||
|
||||
static void SmallTokenToOneByteYarn(morkEnv* ev, mdb_token inToken,
|
||||
mdbYarn* outYarn);
|
||||
|
||||
mork_bool HasTableKind(morkEnv* ev, mdb_scope inRowScope,
|
||||
mdb_kind inTableKind, mdb_count* outTableCount);
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ morkStream::morkStream(morkEnv* ev, const morkUsage& inUsage,
|
|||
, mStream_ContentFile( 0 )
|
||||
|
||||
, mStream_Buf( 0 )
|
||||
, mStream_BufSize( 0 )
|
||||
, mStream_BufSize( inBufSize )
|
||||
, mStream_BufPos( 0 )
|
||||
, mStream_Dirty( morkBool_kFalse )
|
||||
, mStream_HitEof( morkBool_kFalse )
|
||||
|
@ -329,7 +329,7 @@ morkStream::PutByteThenNewlineThenSpace(morkEnv* ev, int inByte)
|
|||
mork_size
|
||||
morkStream::PutLineBreak(morkEnv* ev)
|
||||
{
|
||||
#ifdef MORK_MAC
|
||||
#if defined(MORK_MAC) || defined(MORK_OBSOLETE)
|
||||
|
||||
this->Putc(ev, mork_kCR);
|
||||
return 1;
|
||||
|
|
|
@ -212,6 +212,7 @@ public: // public non-poly morkStream methods
|
|||
void Ungetc(int c) /*i*/
|
||||
{ if ( mStream_At > mStream_Buf && c > 0 ) *--mStream_At = c; }
|
||||
|
||||
// Note Getc() returns EOF consistently after any fill_getc() error occurs.
|
||||
int Getc(morkEnv* ev) /*i*/
|
||||
{ return ( mStream_At < mStream_ReadEnd )? *mStream_At++ : fill_getc(ev); }
|
||||
|
||||
|
|
|
@ -147,6 +147,35 @@ morkTable::CloseTable(morkEnv* ev) /*i*/ // called by CloseMorkNode();
|
|||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
mork_u2
|
||||
morkTable::AddCellUse(morkEnv* ev)
|
||||
{
|
||||
if ( mTable_CellUses < morkTable_kMaxCellUses ) // not already maxed out?
|
||||
++mTable_CellUses;
|
||||
|
||||
return mTable_CellUses;
|
||||
}
|
||||
|
||||
mork_u2
|
||||
morkTable::CutCellUse(morkEnv* ev)
|
||||
{
|
||||
if ( mTable_CellUses ) // any outstanding uses to cut?
|
||||
{
|
||||
if ( mTable_CellUses < morkTable_kMaxCellUses ) // not frozen at max?
|
||||
--mTable_CellUses;
|
||||
}
|
||||
else
|
||||
this->CellUsesUnderflowWarning(ev);
|
||||
|
||||
return mTable_CellUses;
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkTable::CellUsesUnderflowWarning(morkEnv* ev)
|
||||
{
|
||||
ev->NewWarning("mTable_CellUses underflow");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkTable::NonTableTypeError(morkEnv* ev)
|
||||
{
|
||||
|
|
|
@ -51,6 +51,7 @@ class nsIMdbTable;
|
|||
#define morkTable_kStartRowArraySize 11 /* modest starting size for array */
|
||||
|
||||
#define morkTable_kStartRowMapSlotCount 128
|
||||
#define morkTable_kMaxCellUses 0x0FFFF /* max for 16-bit unsigned int */
|
||||
|
||||
class morkTable : public morkObject {
|
||||
|
||||
|
@ -85,7 +86,8 @@ public: // state is public because the entire Mork system is private
|
|||
mork_kind mTable_Kind;
|
||||
|
||||
mork_bool mTable_MustBeUnique;
|
||||
mork_u1 mTable_Pad[ 3 ]; // padding to u4 alignment
|
||||
mork_u1 mTable_Pad; // padding for u4 alignment
|
||||
mork_u2 mTable_CellUses; // persistent references from cells
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
|
@ -109,12 +111,18 @@ public: // dynamic type identification
|
|||
{ return IsNode() && mNode_Derived == morkDerived_kTable; }
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
public: // typing
|
||||
public: // errors
|
||||
static void NonTableTypeError(morkEnv* ev);
|
||||
static void NonTableTypeWarning(morkEnv* ev);
|
||||
static void NilRowSpaceError(morkEnv* ev);
|
||||
|
||||
public: // warnings
|
||||
static void CellUsesUnderflowWarning(morkEnv* ev);
|
||||
|
||||
public: // other table methods
|
||||
|
||||
mork_u2 AddCellUse(morkEnv* ev);
|
||||
mork_u2 CutCellUse(morkEnv* ev);
|
||||
|
||||
// void DirtyAllTableContent(morkEnv* ev);
|
||||
|
||||
|
@ -137,7 +145,7 @@ public: // typesafe refcounting inlines calling inherited morkNode methods
|
|||
morkEnv* ev, morkTable** ioSlot)
|
||||
{ morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
|
||||
static void SlotStrongTableS(morkTable* me,
|
||||
static void SlotStrongTable(morkTable* me,
|
||||
morkEnv* ev, morkTable** ioSlot)
|
||||
{ morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
};
|
||||
|
|
|
@ -52,6 +52,18 @@
|
|||
#include "morkWriter.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKPARSER_
|
||||
#include "morkParser.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKBUILDER_
|
||||
#include "morkBuilder.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKFILE_
|
||||
#include "morkFile.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
|
@ -92,6 +104,7 @@ morkThumb::morkThumb(morkEnv* ev,
|
|||
, mThumb_Store( 0 )
|
||||
, mThumb_File( 0 )
|
||||
, mThumb_Writer( 0 )
|
||||
, mThumb_Builder( 0 )
|
||||
, mThumb_SourcePort( 0 )
|
||||
|
||||
, mThumb_DoCollect( morkBool_kFalse )
|
||||
|
@ -111,9 +124,13 @@ morkThumb::CloseThumb(morkEnv* ev) // called by CloseMorkNode();
|
|||
if ( this->IsNode() )
|
||||
{
|
||||
mThumb_Magic = 0;
|
||||
if ( mThumb_Builder && mThumb_Store )
|
||||
mThumb_Store->ForgetBuilder(ev);
|
||||
morkBuilder::SlotStrongBuilder((morkBuilder*) 0, ev, &mThumb_Builder);
|
||||
|
||||
morkWriter::SlotStrongWriter((morkWriter*) 0, ev, &mThumb_Writer);
|
||||
morkFile::SlotStrongFile((morkFile*) 0, ev, &mThumb_File);
|
||||
morkStore::SlotWeakStore((morkStore*) 0, ev, &mThumb_Store);
|
||||
morkStore::SlotStrongStore((morkStore*) 0, ev, &mThumb_Store);
|
||||
morkPort::SlotStrongPort((morkPort*) 0, ev, &mThumb_SourcePort);
|
||||
this->MarkShut();
|
||||
}
|
||||
|
@ -152,6 +169,11 @@ morkThumb::CloseThumb(morkEnv* ev) // called by CloseMorkNode();
|
|||
ev->NewError("nil mThumb_Writer");
|
||||
}
|
||||
|
||||
/*static*/ void morkThumb::NilThumbBuilderError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("nil mThumb_Builder");
|
||||
}
|
||||
|
||||
/*static*/ void morkThumb::NilThumbSourcePortError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("nil mThumb_SourcePort");
|
||||
|
@ -181,14 +203,31 @@ morkThumb::Make_OpenFileStore(morkEnv* ev, nsIMdbHeap* ioHeap,
|
|||
morkThumb* outThumb = 0;
|
||||
if ( ioHeap && ioStore )
|
||||
{
|
||||
outThumb = new(*ioHeap, ev)
|
||||
morkThumb(ev, morkUsage::kHeap, ioHeap, ioHeap,
|
||||
morkThumb_kMagic_OpenFileStore);
|
||||
|
||||
if ( outThumb )
|
||||
morkFile* file = ioStore->mStore_File;
|
||||
if ( file )
|
||||
{
|
||||
morkStore::SlotWeakStore(ioStore, ev, &outThumb->mThumb_Store);
|
||||
mork_pos fileEof = file->Length(ev);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
outThumb = new(*ioHeap, ev)
|
||||
morkThumb(ev, morkUsage::kHeap, ioHeap, ioHeap,
|
||||
morkThumb_kMagic_OpenFileStore);
|
||||
|
||||
if ( outThumb )
|
||||
{
|
||||
morkBuilder* builder = ioStore->LazyGetBuilder(ev);
|
||||
if ( builder )
|
||||
{
|
||||
outThumb->mThumb_Total = fileEof;
|
||||
morkStore::SlotStrongStore(ioStore, ev, &outThumb->mThumb_Store);
|
||||
morkBuilder::SlotStrongBuilder(builder, ev,
|
||||
&outThumb->mThumb_Builder);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
ioStore->NilStoreFileError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
|
@ -219,7 +258,7 @@ morkThumb::Make_CompressCommit(morkEnv* ev,
|
|||
{
|
||||
writer->mWriter_NeedDirtyAll = morkBool_kTrue;
|
||||
outThumb->mThumb_DoCollect = inDoCollect;
|
||||
morkStore::SlotWeakStore(ioStore, ev, &outThumb->mThumb_Store);
|
||||
morkStore::SlotStrongStore(ioStore, ev, &outThumb->mThumb_Store);
|
||||
morkFile::SlotStrongFile(file, ev, &outThumb->mThumb_File);
|
||||
morkWriter::SlotStrongWriter(writer, ev, &outThumb->mThumb_Writer);
|
||||
}
|
||||
|
@ -330,7 +369,21 @@ void morkThumb::DoMore_OpenFilePort(morkEnv* ev)
|
|||
|
||||
void morkThumb::DoMore_OpenFileStore(morkEnv* ev)
|
||||
{
|
||||
this->UnsupportedThumbMagicError(ev);
|
||||
morkBuilder* builder = mThumb_Builder;
|
||||
if ( builder )
|
||||
{
|
||||
mork_pos pos = 0;
|
||||
builder->ParseMore(ev, &pos, &mThumb_Done, &mThumb_Broken);
|
||||
// mThumb_Total = builder->mBuilder_TotalCount;
|
||||
// mThumb_Current = builder->mBuilder_DoneCount;
|
||||
mThumb_Current = pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->NilThumbBuilderError(ev);
|
||||
mThumb_Broken = morkBool_kTrue;
|
||||
mThumb_Done = morkBool_kTrue;
|
||||
}
|
||||
}
|
||||
|
||||
void morkThumb::DoMore_ExportToFormat(morkEnv* ev)
|
||||
|
|
|
@ -84,6 +84,7 @@ public: // state is public because the entire Mork system is private
|
|||
morkStore* mThumb_Store; // weak ref to created store
|
||||
morkFile* mThumb_File; // strong ref to file (store, import, export)
|
||||
morkWriter* mThumb_Writer; // strong ref to writer (for commit)
|
||||
morkBuilder* mThumb_Builder; // strong ref to builder (for store open)
|
||||
morkPort* mThumb_SourcePort; // strong ref to port for import
|
||||
|
||||
mork_bool mThumb_DoCollect; // influence whether a collect happens
|
||||
|
@ -115,6 +116,7 @@ public: // typing
|
|||
static void NilThumbStoreError(morkEnv* ev);
|
||||
static void NilThumbFileError(morkEnv* ev);
|
||||
static void NilThumbWriterError(morkEnv* ev);
|
||||
static void NilThumbBuilderError(morkEnv* ev);
|
||||
static void NilThumbSourcePortError(morkEnv* ev);
|
||||
|
||||
public: // 'do more' methods
|
||||
|
|
|
@ -84,6 +84,10 @@
|
|||
#include "morkAtom.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKCH_
|
||||
#include "morkCh.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
|
@ -123,6 +127,7 @@ morkWriter::morkWriter(morkEnv* ev, const morkUsage& inUsage,
|
|||
|
||||
, mWriter_LineSize( 0 )
|
||||
, mWriter_MaxIndent( morkWriter_kMaxIndent )
|
||||
, mWriter_MaxLine( morkWriter_kMaxLine )
|
||||
|
||||
, mWriter_TableCharset( 0 )
|
||||
, mWriter_TableAtomScope( 0 )
|
||||
|
@ -362,15 +367,16 @@ morkWriter::WriteYarn(morkEnv* ev, const mdbYarn* inYarn)
|
|||
while ( b < end )
|
||||
{
|
||||
c = *b++; // next byte to print
|
||||
if ( c < 0x080 && MORK_ISPRINT(c) )
|
||||
if ( morkCh_IsValue(c) )
|
||||
{
|
||||
if ( c == ')' && c == '$' && c == '\\' )
|
||||
{
|
||||
stream->Putc(ev, '\\');
|
||||
++outSize;
|
||||
}
|
||||
stream->Putc(ev, c);
|
||||
++outSize;
|
||||
++outSize; // c
|
||||
}
|
||||
else if ( c == ')' && c == '$' && c == '\\' )
|
||||
{
|
||||
stream->Putc(ev, '\\');
|
||||
stream->Putc(ev, c);
|
||||
outSize += 2; // '\' c
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -396,8 +402,13 @@ morkWriter::WriteAtom(morkEnv* ev, const morkAtom* inAtom)
|
|||
mdbYarn yarn; // to ref content inside atom
|
||||
|
||||
if ( inAtom->AliasYarn(&yarn) )
|
||||
{
|
||||
if ( mWriter_DidStartDict && yarn.mYarn_Form != mWriter_DictCharset )
|
||||
this->ChangeDictCharset(ev, yarn.mYarn_Form);
|
||||
|
||||
outSize = this->WriteYarn(ev, &yarn);
|
||||
// mWriter_LineSize += stream->Write(ev, inYarn->mYarn_Buf, outSize);
|
||||
}
|
||||
else
|
||||
inAtom->BadAtomKindError(ev);
|
||||
|
||||
|
@ -424,6 +435,7 @@ morkWriter::WriteAtomSpaceAsDict(morkEnv* ev, morkAtomSpace* ioSpace)
|
|||
|
||||
if ( ev->Good() )
|
||||
{
|
||||
mdbYarn yarn; // to ref content inside atom
|
||||
char buf[ 64 ]; // buffer for staging the dict alias hex ID
|
||||
char* idBuf = buf + 1; // where the id always starts
|
||||
buf[ 0 ] = '('; // we always start with open paren
|
||||
|
@ -442,15 +454,23 @@ morkWriter::WriteAtomSpaceAsDict(morkEnv* ev, morkAtomSpace* ioSpace)
|
|||
{
|
||||
atom->mAtom_Change = morkChange_kNil; // neutralize change
|
||||
|
||||
this->IndentAsNeeded(ev, morkWriter_kDictAliasDepth);
|
||||
atom->AliasYarn(&yarn);
|
||||
mork_size size = ev->TokenAsHex(idBuf, atom->mBookAtom_Id);
|
||||
mWriter_LineSize += stream->Write(ev, buf, size+1); // '('
|
||||
|
||||
this->IndentAsNeeded(ev, morkWriter_kDictAliasValueDepth);
|
||||
stream->Putc(ev, '='); // end alias
|
||||
if ( yarn.mYarn_Form != mWriter_DictCharset )
|
||||
this->ChangeDictCharset(ev, yarn.mYarn_Form);
|
||||
|
||||
mork_size pending = yarn.mYarn_Fill + size +
|
||||
morkWriter_kYarnEscapeSlop + 4;
|
||||
this->IndentOverMaxLine(ev, pending, morkWriter_kDictAliasDepth);
|
||||
mWriter_LineSize += stream->Write(ev, buf, size+1); // + '('
|
||||
|
||||
pending -= ( size + 1 );
|
||||
this->IndentOverMaxLine(ev, pending, morkWriter_kDictAliasValueDepth);
|
||||
stream->Putc(ev, '='); // start alias
|
||||
++mWriter_LineSize;
|
||||
|
||||
this->WriteAtom(ev, atom);
|
||||
this->WriteYarn(ev, &yarn);
|
||||
stream->Putc(ev, ')'); // end alias
|
||||
++mWriter_LineSize;
|
||||
|
||||
|
@ -1037,22 +1057,40 @@ morkWriter::WriteStringToTokenDictCell(morkEnv* ev,
|
|||
// mWriter_LineSize += stream->Write(ev, yarnBuf, fill + 1); // +1 for ')'
|
||||
}
|
||||
|
||||
void
|
||||
morkWriter::ChangeDictCharset(morkEnv* ev, mork_cscode inNewForm)
|
||||
{
|
||||
if ( inNewForm != mWriter_DictCharset )
|
||||
{
|
||||
morkStream* stream = mWriter_Stream;
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
mWriter_LineSize = 0;
|
||||
|
||||
stream->Putc(ev, '<');
|
||||
this->WriteStringToTokenDictCell(ev, "(charset=", mWriter_DictCharset);
|
||||
stream->Putc(ev, '>');
|
||||
++mWriter_LineSize;
|
||||
|
||||
mWriter_DictCharset = inNewForm;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
morkWriter::StartDict(morkEnv* ev)
|
||||
{
|
||||
morkStream* stream = mWriter_Stream;
|
||||
if ( mWriter_DidStartDict )
|
||||
{
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
stream->PutStringThenNewline(ev, "> // end dict");
|
||||
mWriter_LineSize = 0;
|
||||
stream->Putc(ev, '>'); // end dict
|
||||
++mWriter_LineSize;
|
||||
}
|
||||
mWriter_DidStartDict = morkBool_kTrue;
|
||||
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
mWriter_LineSize = 0;
|
||||
stream->PutLineBreak(ev);
|
||||
if ( mWriter_DictCharset || mWriter_DictAtomScope != 'a' )
|
||||
{
|
||||
stream->Putc(ev, '<');
|
||||
|
@ -1069,7 +1107,9 @@ morkWriter::StartDict(morkEnv* ev)
|
|||
}
|
||||
else
|
||||
{
|
||||
stream->PutString(ev, "< // <(charset=iso-8859-1)(atomScope=a)>");
|
||||
stream->Putc(ev, '<');
|
||||
stream->Putc(ev, ' ');
|
||||
mWriter_LineSize += 2;
|
||||
}
|
||||
mWriter_LineSize = stream->PutIndent(ev, morkWriter_kDictAliasDepth);
|
||||
}
|
||||
|
@ -1080,10 +1120,8 @@ morkWriter::EndDict(morkEnv* ev)
|
|||
morkStream* stream = mWriter_Stream;
|
||||
if ( mWriter_DidStartDict )
|
||||
{
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
stream->PutStringThenNewline(ev, "> // end dict");
|
||||
mWriter_LineSize = 0;
|
||||
stream->Putc(ev, '>'); // end dict
|
||||
++mWriter_LineSize;
|
||||
}
|
||||
mWriter_DidStartDict = morkBool_kFalse;
|
||||
}
|
||||
|
@ -1100,6 +1138,7 @@ morkWriter::StartTable(morkEnv* ev, morkTable* ioTable)
|
|||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
mWriter_LineSize = 0;
|
||||
stream->PutLineBreak(ev);
|
||||
|
||||
char buf[ 64 ]; // buffer for staging hex
|
||||
char* p = buf;
|
||||
|
@ -1123,9 +1162,8 @@ morkWriter::StartTable(morkEnv* ev, morkTable* ioTable)
|
|||
this->IndentAsNeeded(ev, morkWriter_kTableMetaCellDepth);
|
||||
this->WriteTokenToTokenMetaCell(ev, store->mStore_TableKindToken, tk);
|
||||
}
|
||||
stream->Putc(ev, '}');
|
||||
stream->Putc(ev, ' ');
|
||||
mWriter_LineSize += 2;
|
||||
stream->Putc(ev, '}'); // end meta
|
||||
mWriter_LineSize = stream->PutIndent(ev, morkWriter_kRowCellDepth);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1133,10 +1171,8 @@ void
|
|||
morkWriter::EndTable(morkEnv* ev)
|
||||
{
|
||||
morkStream* stream = mWriter_Stream;
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
stream->PutStringThenNewline(ev, "} // end table");
|
||||
mWriter_LineSize = 0;
|
||||
stream->Putc(ev, '}'); // end table
|
||||
++mWriter_LineSize;
|
||||
}
|
||||
|
||||
mork_bool
|
||||
|
@ -1208,9 +1244,9 @@ morkWriter::PutRowCells(morkEnv* ev, morkRow* ioRow)
|
|||
colSize = ev->TokenAsHex(p, col);
|
||||
p += colSize;
|
||||
|
||||
this->IndentAsNeeded(ev, morkWriter_kRowCellDepth);
|
||||
if ( atom->IsBook() ) // is it possible to write atom ID?
|
||||
{
|
||||
this->IndentAsNeeded(ev, morkWriter_kRowCellDepth);
|
||||
*p++ = '^';
|
||||
morkBookAtom* ba = (morkBookAtom*) atom;
|
||||
mork_size valSize = ev->TokenAsHex(p, ba->mBookAtom_Id);
|
||||
|
@ -1227,13 +1263,24 @@ morkWriter::PutRowCells(morkEnv* ev, morkRow* ioRow)
|
|||
}
|
||||
else // must write an anonymous atom
|
||||
{
|
||||
mdbYarn yarn; // to ref content inside atom
|
||||
atom->AliasYarn(&yarn);
|
||||
|
||||
if ( yarn.mYarn_Form != mWriter_DictCharset )
|
||||
this->ChangeDictCharset(ev, yarn.mYarn_Form);
|
||||
|
||||
mork_size pending = yarn.mYarn_Fill + colSize +
|
||||
morkWriter_kYarnEscapeSlop + 2;
|
||||
this->IndentOverMaxLine(ev, pending, morkWriter_kRowCellDepth);
|
||||
|
||||
mWriter_LineSize += stream->Write(ev, buf, colSize + 2);
|
||||
|
||||
this->IndentAsNeeded(ev, morkWriter_kRowCellValueDepth);
|
||||
pending -= ( colSize + 2 );
|
||||
this->IndentOverMaxLine(ev, pending, morkWriter_kRowCellDepth);
|
||||
stream->Putc(ev, '=');
|
||||
++mWriter_LineSize;
|
||||
|
||||
this->WriteAtom(ev, atom);
|
||||
this->WriteYarn(ev, &yarn);
|
||||
stream->Putc(ev, ')'); // end alias
|
||||
++mWriter_LineSize;
|
||||
}
|
||||
|
@ -1254,8 +1301,8 @@ morkWriter::PutRow(morkEnv* ev, morkRow* ioRow)
|
|||
|
||||
this->IndentAsNeeded(ev, morkWriter_kRowDepth);
|
||||
|
||||
// if ( ioRow->IsRowDirty() )
|
||||
if ( morkBool_kTrue )
|
||||
//if ( morkBool_kTrue )
|
||||
if ( ioRow->IsRowDirty() )
|
||||
{
|
||||
ioRow->SetRowClean();
|
||||
mork_rid rid = roid->mOid_Id;
|
||||
|
@ -1271,8 +1318,7 @@ morkWriter::PutRow(morkEnv* ev, morkRow* ioRow)
|
|||
|
||||
this->PutRowCells(ev, ioRow);
|
||||
stream->Putc(ev, ']'); // end row
|
||||
stream->Putc(ev, ' '); // end row
|
||||
mWriter_LineSize += 2;
|
||||
++mWriter_LineSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
|
||||
#define morkWriter_kStreamBufSize /*i*/ (16) /* buffer size for stream */
|
||||
#define morkWriter_kStreamBufSize /*i*/ (16 * 1024) /* buffer size for stream */
|
||||
|
||||
#define morkDerived_kWriter /*i*/ 0x5772 /* ascii 'Wr' */
|
||||
|
||||
|
@ -85,7 +85,10 @@
|
|||
|
||||
#define morkWriter_kMaxColumnNameSize 128 /* longest writable col name */
|
||||
|
||||
#define morkWriter_kMaxIndent 48 /* default value for mWriter_MaxIndent */
|
||||
#define morkWriter_kMaxIndent 56 /* default value for mWriter_MaxIndent */
|
||||
#define morkWriter_kMaxLine 78 /* default value for mWriter_MaxLine */
|
||||
|
||||
#define morkWriter_kYarnEscapeSlop 4 /* guess average yarn escape overhead */
|
||||
|
||||
#define morkWriter_kTableMetaCellDepth 4 /* */
|
||||
#define morkWriter_kTableMetaCellValueDepth 6 /* */
|
||||
|
@ -126,6 +129,7 @@ public: // state is public because the entire Mork system is private
|
|||
|
||||
mork_size mWriter_LineSize; // length of current line being written
|
||||
mork_size mWriter_MaxIndent; // line size forcing a line break
|
||||
mork_size mWriter_MaxLine; // line size forcing a value continuation
|
||||
|
||||
mork_cscode mWriter_TableCharset; // current charset metainfo
|
||||
mork_scope mWriter_TableAtomScope; // current atom scope
|
||||
|
@ -195,6 +199,7 @@ public: // typing & errors
|
|||
static void UnsupportedPhaseError(morkEnv* ev);
|
||||
|
||||
public: // inlines
|
||||
void ChangeDictCharset(morkEnv* ev, mork_cscode inNewForm);
|
||||
mork_bool DidStartDict() const { return mWriter_DidStartDict; }
|
||||
mork_bool DidEndDict() const { return mWriter_DidEndDict; }
|
||||
|
||||
|
@ -206,6 +211,13 @@ public: // inlines
|
|||
if ( mWriter_LineSize > mWriter_MaxIndent )
|
||||
mWriter_LineSize = mWriter_Stream->PutIndent(ev, inDepth);
|
||||
}
|
||||
|
||||
void IndentOverMaxLine(morkEnv* ev,
|
||||
mork_size inPendingSize, mork_size inDepth)
|
||||
{
|
||||
if ( mWriter_LineSize + inPendingSize > mWriter_MaxLine )
|
||||
mWriter_LineSize = mWriter_Stream->PutIndent(ev, inDepth);
|
||||
}
|
||||
|
||||
public: // iterative/asynchronouse writing
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@ CPPSRCS = \
|
|||
morkBuilder.cpp\
|
||||
morkCell.cpp\
|
||||
morkCellObject.cpp\
|
||||
morkCh.cpp\
|
||||
morkConfig.cpp\
|
||||
morkCursor.cpp \
|
||||
morkDeque.cpp\
|
||||
|
|
|
@ -47,6 +47,7 @@ CPPSRCS= orkinCell.cpp\
|
|||
morkBuilder.cpp\
|
||||
morkCell.cpp\
|
||||
morkCellObject.cpp\
|
||||
morkCh.cpp\
|
||||
morkConfig.cpp\
|
||||
morkCursor.cpp \
|
||||
morkDeque.cpp\
|
||||
|
@ -97,6 +98,7 @@ CPP_OBJS= .\$(OBJDIR)\orkinCell.obj\
|
|||
.\$(OBJDIR)\morkBuilder.obj\
|
||||
.\$(OBJDIR)\morkCell.obj\
|
||||
.\$(OBJDIR)\morkCellObject.obj\
|
||||
.\$(OBJDIR)\morkCh.obj\
|
||||
.\$(OBJDIR)\morkConfig.obj\
|
||||
.\$(OBJDIR)\morkCursor.obj\
|
||||
.\$(OBJDIR)\morkDeque.obj\
|
||||
|
|
|
@ -64,6 +64,8 @@ typedef unsigned long mork_u4; // make sure this is four bytes
|
|||
typedef long mork_i4; // make sure this is four bytes
|
||||
typedef long mork_ip; // make sure sizeof(mork_ip) == sizeof(void*)
|
||||
|
||||
typedef mork_u1 mork_ch; // small byte-sized character (never wide)
|
||||
|
||||
typedef mork_u2 mork_base; // 2-byte magic class signature slot in object
|
||||
typedef mork_u2 mork_derived; // 2-byte magic class signature slot in object
|
||||
typedef mork_u2 mork_uses; // 2-byte strong uses count
|
||||
|
@ -109,6 +111,9 @@ typedef mork_u1 mork_load; // dirty or clean (clone IronDoc's fe_load)
|
|||
#define morkChange_kPut 'p' /* put member */
|
||||
#define morkChange_kSet 's' /* set all members */
|
||||
#define morkChange_kNil 0 /* no change in this member */
|
||||
#define morkChange_kDup 'd' /* duplicate changes have no effect */
|
||||
// kDup is intended to replace another change constant in an object as a
|
||||
// conclusion about change feasibility while staging intended alterations.
|
||||
|
||||
#define morkLoad_kDirty ((mork_load) 0xDD) /* same as IronDoc constant */
|
||||
#define morkLoad_kClean ((mork_load) 0x22) /* same as IronDoc constant */
|
||||
|
@ -147,6 +152,7 @@ typedef mdb_order mork_order; // neg:lessthan, zero:equalto, pos:greaterthan
|
|||
|
||||
// { %%%%% begin class forward defines %%%%%
|
||||
// try to put these in alphabetical order for easier examination:
|
||||
class morkMid;
|
||||
class morkAtom;
|
||||
class morkAtomSpace;
|
||||
class morkBookAtom;
|
||||
|
@ -168,6 +174,7 @@ class morkObject;
|
|||
class morkOidAtom;
|
||||
class morkParser;
|
||||
class morkPool;
|
||||
class morkPlace;
|
||||
class morkPort;
|
||||
class morkPortTableCursor;
|
||||
class morkRow;
|
||||
|
@ -175,6 +182,7 @@ class morkRowCellCursor;
|
|||
class morkRowObject;
|
||||
class morkRowSpace;
|
||||
class morkSpace;
|
||||
class morkSpan;
|
||||
class morkStore;
|
||||
class morkStream;
|
||||
class morkTable;
|
||||
|
|
|
@ -305,7 +305,7 @@ class morkMaxBookAtom : public morkBigBookAtom { //
|
|||
// mork_u1 mBigBookAtom_Body[ 1 ]; // 1st byte of immed content vector
|
||||
|
||||
public:
|
||||
mork_u1 mBigBookAtom_Body[ morkBookAtom_kMaxBodySize + 3 ]; // max bytes
|
||||
mork_u1 mMaxBookAtom_Body[ morkBookAtom_kMaxBodySize + 3 ]; // max bytes
|
||||
|
||||
public: // empty construction does nothing
|
||||
morkMaxBookAtom() { }
|
||||
|
|
|
@ -138,11 +138,11 @@ public: // dynamic type identification
|
|||
// { ===== begin morkMap poly interface =====
|
||||
virtual mork_bool // note: equal(a,b) implies hash(a) == hash(b)
|
||||
Equal(morkEnv* ev, const void* inKeyA, const void* inKeyB) const;
|
||||
// implemented using morkBookAtom::HashFormAndBody()
|
||||
// implemented using morkBookAtom::EqualFormAndBody()
|
||||
|
||||
virtual mork_u4 // note: equal(a,b) implies hash(a) == hash(b)
|
||||
Hash(morkEnv* ev, const void* inKey) const;
|
||||
// implemented using morkBookAtom::EqualFormAndBody()
|
||||
// implemented using morkBookAtom::HashFormAndBody()
|
||||
// } ===== end morkMap poly interface =====
|
||||
|
||||
public: // other map methods
|
||||
|
|
|
@ -153,6 +153,32 @@ morkAtomSpace::CutAllAtoms(morkEnv* ev, morkPool* ioPool)
|
|||
}
|
||||
|
||||
|
||||
morkBookAtom*
|
||||
morkAtomSpace::MakeBookAtomCopyWithAid(morkEnv* ev,
|
||||
const morkBigBookAtom& inAtom, mork_aid inAid)
|
||||
// Make copy of inAtom and put it in both maps, using specified ID.
|
||||
{
|
||||
morkBookAtom* outAtom = 0;
|
||||
if ( ev->Good() )
|
||||
{
|
||||
morkPool* pool = this->GetSpaceStorePool();
|
||||
outAtom = pool->NewBookAtomCopy(ev, inAtom);
|
||||
if ( outAtom )
|
||||
{
|
||||
outAtom->mBookAtom_Id = inAid;
|
||||
outAtom->mBookAtom_Space = this;
|
||||
mAtomSpace_AtomAids.AddAtom(ev, outAtom);
|
||||
mAtomSpace_AtomBodies.AddAtom(ev, outAtom);
|
||||
if ( mSpace_Scope == morkAtomSpace_kColumnScope )
|
||||
outAtom->MakeCellUseForever(ev);
|
||||
|
||||
if ( mAtomSpace_HighUnderId <= inAid )
|
||||
mAtomSpace_HighUnderId = inAid + 1;
|
||||
}
|
||||
}
|
||||
return outAtom;
|
||||
}
|
||||
|
||||
morkBookAtom*
|
||||
morkAtomSpace::MakeBookAtomCopy(morkEnv* ev, const morkBigBookAtom& inAtom)
|
||||
// make copy of inAtom and put it in both maps, using a new ID as needed.
|
||||
|
@ -167,9 +193,12 @@ morkAtomSpace::MakeBookAtomCopy(morkEnv* ev, const morkBigBookAtom& inAtom)
|
|||
mork_aid id = this->MakeNewAtomId(ev, atom);
|
||||
if ( id )
|
||||
{
|
||||
outAtom = atom;
|
||||
outAtom = atom;
|
||||
atom->mBookAtom_Space = this;
|
||||
mAtomSpace_AtomAids.AddAtom(ev, atom);
|
||||
mAtomSpace_AtomBodies.AddAtom(ev, atom);
|
||||
if ( mSpace_Scope == morkAtomSpace_kColumnScope )
|
||||
outAtom->MakeCellUseForever(ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,6 +64,8 @@
|
|||
|
||||
#define morkDerived_kAtomSpace /*i*/ 0x6153 /* ascii 'aS' */
|
||||
|
||||
#define morkAtomSpace_kColumnScope ((mork_scope) 'c') /* column scope is forever */
|
||||
|
||||
/*| morkAtomSpace:
|
||||
|*/
|
||||
class morkAtomSpace : public morkSpace { //
|
||||
|
@ -132,6 +134,10 @@ public: // other space methods
|
|||
mork_num CutAllAtoms(morkEnv* ev, morkPool* ioPool);
|
||||
// CutAllAtoms() puts all the atoms back in the pool.
|
||||
|
||||
morkBookAtom* MakeBookAtomCopyWithAid(morkEnv* ev,
|
||||
const morkBigBookAtom& inAtom, mork_aid inAid);
|
||||
// Make copy of inAtom and put it in both maps, using specified ID.
|
||||
|
||||
morkBookAtom* MakeBookAtomCopy(morkEnv* ev, const morkBigBookAtom& inAtom);
|
||||
// Make copy of inAtom and put it in both maps, using a new ID as needed.
|
||||
|
||||
|
|
|
@ -1,62 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKBLOB_
|
||||
#include "morkBlob.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
morkSpool::morkSpool(morkEnv* ev, nsIMdbHeap* ioHeap)
|
||||
{
|
||||
mBuf_Body = 0;
|
||||
mBuf_Fill = 0;
|
||||
mBlob_Size = 0;
|
||||
mText_Form = 0;
|
||||
mSpool_Heap = ioHeap;
|
||||
if ( !ioHeap )
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
void
|
||||
morkSpool::CloseSpool(morkEnv* ev)
|
||||
{
|
||||
void* body = mBuf_Body;
|
||||
nsIMdbHeap* heap = mSpool_Heap;
|
||||
|
||||
if ( body && heap )
|
||||
{
|
||||
heap->Free(ev->AsMdbEnv(), body);
|
||||
}
|
||||
mBuf_Body = 0;
|
||||
mSpool_Heap = 0;
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
|
@ -1,144 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MORKBLOB_
|
||||
#define _MORKBLOB_ 1
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
/*| Buf: the minimum needed to describe location and content length.
|
||||
**| This is typically only enough to read from this buffer, since
|
||||
**| one cannot write effectively without knowing the size of a buf.
|
||||
|*/
|
||||
class morkBuf { // subset of nsIMdbYarn slots
|
||||
public:
|
||||
void* mBuf_Body; // space for holding any binary content
|
||||
mork_fill mBuf_Fill; // logical content in Buf in bytes
|
||||
|
||||
public:
|
||||
morkBuf() { }
|
||||
morkBuf(const void* ioBuf, mork_fill inFill)
|
||||
: mBuf_Body((void*) ioBuf), mBuf_Fill(inFill) { }
|
||||
|
||||
private: // copying is not allowed
|
||||
morkBuf(const morkBuf& other);
|
||||
morkBuf& operator=(const morkBuf& other);
|
||||
};
|
||||
|
||||
/*| Blob: a buffer with an associated size, to increase known buf info
|
||||
**| to include max capacity in addition to buf location and content.
|
||||
**| This form factor allows us to allocate a vector of such blobs,
|
||||
**| which can share the same managing heap stored elsewhere, and that
|
||||
**| is why we don't include a pointer to a heap in this blob class.
|
||||
|*/
|
||||
class morkBlob : public morkBuf { // greater subset of nsIMdbYarn slots
|
||||
|
||||
// void* mBuf_Body; // space for holding any binary content
|
||||
// mdb_fill mBuf_Fill; // logical content in Buf in bytes
|
||||
public:
|
||||
mork_size mBlob_Size; // physical size of Buf in bytes
|
||||
|
||||
public:
|
||||
morkBlob() { }
|
||||
morkBlob(const void* ioBuf, mork_fill inFill, mork_size inSize)
|
||||
: morkBuf(ioBuf, inFill), mBlob_Size(inSize) { }
|
||||
|
||||
public:
|
||||
mork_bool Grow(morkEnv* ev, nsIMdbHeap* ioHeap, mork_size inNewSize);
|
||||
|
||||
private: // copying is not allowed
|
||||
morkBlob(const morkBlob& other);
|
||||
morkBlob& operator=(const morkBlob& other);
|
||||
|
||||
};
|
||||
|
||||
/*| Text: a blob with an associated charset annotation, where the
|
||||
**| charset actually includes the general notion of typing, and not
|
||||
**| just a specification of character set alone; we want to permit
|
||||
**| arbitrary charset annotations for ad hoc binary types as well.
|
||||
**| (We avoid including a nsIMdbHeap pointer in morkText for the same
|
||||
**| reason morkBlob does: we want minimal size vectors of morkText.)
|
||||
|*/
|
||||
class morkText : public morkBlob { // greater subset of nsIMdbYarn slots
|
||||
|
||||
// void* mBuf_Body; // space for holding any binary content
|
||||
// mdb_fill mBuf_Fill; // logical content in Buf in bytes
|
||||
// mdb_size mBlob_Size; // physical size of Buf in bytes
|
||||
|
||||
public:
|
||||
mork_cscode mText_Form; // charset format encoding
|
||||
|
||||
morkText() { }
|
||||
|
||||
private: // copying is not allowed
|
||||
morkText(const morkText& other);
|
||||
morkText& operator=(const morkText& other);
|
||||
};
|
||||
|
||||
/*| Spool: a text with an associated nsIMdbHeap instance that provides
|
||||
**| all memory management for the space pointed to by mBuf_Body. (This
|
||||
**| was the hardest type to give a name in this small class hierarchy,
|
||||
**| because it's hard to characterize self-management of one's space.)
|
||||
**| A spool is a self-contained blob that knows how to grow itself as
|
||||
**| necessary to hold more content when necessary. Spool descends from
|
||||
**| morkText to include the mText_Form slot, even though this won't be
|
||||
**| needed always, because we are not as concerned about the overall
|
||||
**| size of this particular Spool object (if we were concerned about
|
||||
**| the size of an array of Spool instances, we would not bother with
|
||||
**| a separate heap pointer for each of them).
|
||||
**|
|
||||
**|| A spool makes a good medium in which to stream content as a sink,
|
||||
**| so we will have a subclass of morkSink called morkSpoolSink that
|
||||
**| will stream bytes into this self-contained spool object. The name
|
||||
**| of this morkSpool class derives more from this intended usage than
|
||||
**| from anything else. The Mork code to parse db content will use
|
||||
**| spools with associated sinks to accumulate parsed strings.
|
||||
**|
|
||||
**|| Heap: this is the heap used for memory allocation. This instance
|
||||
**| is NOT refcounted, since this spool always assumes the heap is held
|
||||
**| through a reference elsewhere (for example, through the same object
|
||||
**| that contains or holds the spool itself. This lack of refcounting
|
||||
**| is consistent with the fact that morkSpool itself is not refcounted,
|
||||
**| and is not intended for use as a standalone object.
|
||||
|*/
|
||||
class morkSpool : public morkText { // self-managing text blob object
|
||||
|
||||
// void* mBuf_Body; // space for holding any binary content
|
||||
// mdb_fill mBuf_Fill; // logical content in Buf in bytes
|
||||
// mdb_size mBlob_Size; // physical size of Buf in bytes
|
||||
// mdb_cscode mText_Form; // charset format encoding
|
||||
public:
|
||||
nsIMdbHeap* mSpool_Heap; // storage manager for mBuf_Body pointer
|
||||
|
||||
public:
|
||||
morkSpool(morkEnv* ev, nsIMdbHeap* ioHeap);
|
||||
|
||||
void CloseSpool(morkEnv* ev);
|
||||
|
||||
private: // copying is not allowed
|
||||
morkSpool(const morkSpool& other);
|
||||
morkSpool& operator=(const morkSpool& other);
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKBLOB_ */
|
|
@ -48,6 +48,34 @@
|
|||
#include "morkCell.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKSTORE_
|
||||
#include "morkStore.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKTABLE_
|
||||
#include "morkTable.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKROW_
|
||||
#include "morkRow.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKCELL_
|
||||
#include "morkCell.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKATOM_
|
||||
#include "morkAtom.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKATOMSPACE_
|
||||
#include "morkAtomSpace.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKROWSPACE_
|
||||
#include "morkRowSpace.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
|
@ -67,7 +95,12 @@ morkBuilder::CloseMorkNode(morkEnv* ev) // CloseBuilder() only if open
|
|||
/*public virtual*/
|
||||
morkBuilder::~morkBuilder() // assert CloseBuilder() executed earlier
|
||||
{
|
||||
MORK_ASSERT(mBuilder_Store==0);
|
||||
MORK_ASSERT(mBuilder_Row==0);
|
||||
MORK_ASSERT(mBuilder_Table==0);
|
||||
MORK_ASSERT(mBuilder_Cell==0);
|
||||
MORK_ASSERT(mBuilder_RowSpace==0);
|
||||
MORK_ASSERT(mBuilder_AtomSpace==0);
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
|
@ -75,11 +108,67 @@ morkBuilder::morkBuilder(morkEnv* ev,
|
|||
const morkUsage& inUsage, nsIMdbHeap* ioHeap,
|
||||
morkStream* ioStream, mdb_count inBytesPerParseSegment,
|
||||
nsIMdbHeap* ioSlotHeap, morkStore* ioStore)
|
||||
|
||||
: morkParser(ev, inUsage, ioHeap, ioStream,
|
||||
inBytesPerParseSegment, ioSlotHeap)
|
||||
|
||||
, mBuilder_Store( 0 )
|
||||
|
||||
, mBuilder_Table( 0 )
|
||||
, mBuilder_Row( 0 )
|
||||
, mBuilder_Cell( 0 )
|
||||
|
||||
, mBuilder_RowSpace( 0 )
|
||||
, mBuilder_AtomSpace( 0 )
|
||||
|
||||
, mBuilder_OidAtomSpace( 0 )
|
||||
, mBuilder_ScopeAtomSpace( 0 )
|
||||
|
||||
, mBuilder_iso_8859_1( 0 )
|
||||
, mBuilder_r( (mork_scope) 'r' )
|
||||
, mBuilder_a( (mork_scope) 'a' )
|
||||
, mBuilder_t( (mork_scope) 't' )
|
||||
|
||||
, mBuilder_MorkNoneToken( 0 )
|
||||
|
||||
, mBuilder_PortForm( 0 )
|
||||
, mBuilder_PortRowScope( (mork_scope) 'r' )
|
||||
, mBuilder_PortAtomScope( (mork_scope) 'a' )
|
||||
|
||||
, mBuilder_TableForm( 0 )
|
||||
, mBuilder_TableRowScope( (mork_scope) 'r' )
|
||||
, mBuilder_TableAtomScope( (mork_scope) 'a' )
|
||||
, mBuilder_TableKind( 0 )
|
||||
|
||||
, mBuilder_RowForm( 0 )
|
||||
, mBuilder_RowRowScope( (mork_scope) 'r' )
|
||||
, mBuilder_RowAtomScope( (mork_scope) 'a' )
|
||||
|
||||
, mBuilder_CellForm( 0 )
|
||||
, mBuilder_CellAtomScope( (mork_scope) 'a' )
|
||||
|
||||
, mBuilder_DictForm( 0 )
|
||||
, mBuilder_DictAtomScope( (mork_scope) 'a' )
|
||||
|
||||
, mBuilder_MetaTokenSlot( 0 )
|
||||
|
||||
, mBuilder_DoCutRow( morkBool_kFalse )
|
||||
, mBuilder_DoCutCell( morkBool_kFalse )
|
||||
, mBuilder_CellsVecFill( 0 )
|
||||
{
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kBuilder;
|
||||
{
|
||||
if ( ioStore )
|
||||
{
|
||||
mBuilder_MorkNoneToken = ioStore->mStore_MorkNoneToken;
|
||||
morkStore::SlotWeakStore(ioStore, ev, &mBuilder_Store);
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kBuilder;
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
|
@ -89,6 +178,24 @@ morkBuilder::CloseBuilder(morkEnv* ev) // called by CloseMorkNode();
|
|||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
mBuilder_Row = 0;
|
||||
mBuilder_Cell = 0;
|
||||
mBuilder_MetaTokenSlot = 0;
|
||||
|
||||
morkTable::SlotStrongTable((morkTable*) 0, ev, &mBuilder_Table);
|
||||
morkStore::SlotWeakStore((morkStore*) 0, ev, &mBuilder_Store);
|
||||
|
||||
morkRowSpace::SlotStrongRowSpace((morkRowSpace*) 0, ev,
|
||||
&mBuilder_RowSpace);
|
||||
|
||||
morkAtomSpace::SlotStrongAtomSpace((morkAtomSpace*) 0, ev,
|
||||
&mBuilder_AtomSpace);
|
||||
|
||||
morkAtomSpace::SlotStrongAtomSpace((morkAtomSpace*) 0, ev,
|
||||
&mBuilder_OidAtomSpace);
|
||||
|
||||
morkAtomSpace::SlotStrongAtomSpace((morkAtomSpace*) 0, ev,
|
||||
&mBuilder_ScopeAtomSpace);
|
||||
this->CloseParser(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
|
@ -108,217 +215,655 @@ morkBuilder::NonBuilderTypeError(morkEnv* ev)
|
|||
ev->NewError("non morkBuilder");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkBuilder::NilBuilderCellError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("nil mBuilder_Cell");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkBuilder::NilBuilderRowError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("nil mBuilder_Row");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkBuilder::NilBuilderTableError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("nil mBuilder_Table");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkBuilder::NonColumnSpaceScopeError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("column space != 'c'");
|
||||
}
|
||||
|
||||
void
|
||||
morkBuilder::LogGlitch(morkEnv* ev, const morkGlitch& inGlitch,
|
||||
const char* inKind)
|
||||
{
|
||||
ev->NewWarning("parsing glitch");
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::AliasToYarn(morkEnv* ev,
|
||||
const morkAlias& inAlias, // typically an alias to concat with strings
|
||||
morkBuilder::MidToYarn(morkEnv* ev,
|
||||
const morkMid& inMid, // typically an alias to concat with strings
|
||||
mdbYarn* outYarn)
|
||||
// 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.
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
mBuilder_Store->MidToYarn(ev, inMid, outYarn);
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnNewPort(morkEnv* ev, const morkPlace& inPlace)
|
||||
// mp:Start ::= OnNewPort mp:PortItem* OnPortEnd
|
||||
// mp:PortItem ::= mp:Content | mp:Group | OnPortGlitch
|
||||
// mp:Content ::= mp:PortRow | mp:Dict | mp:Table | mp:Row
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// mParser_InPort = morkBool_kTrue;
|
||||
mBuilder_PortForm = 0;
|
||||
mBuilder_PortRowScope = (mork_scope) 'r';
|
||||
mBuilder_PortAtomScope = (mork_scope) 'a';
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnPortGlitch(morkEnv* ev, const morkGlitch& inGlitch)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
this->LogGlitch(ev, inGlitch, "port");
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnPortEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
// mp:Start ::= OnNewPort mp:PortItem* OnPortEnd
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// ev->StubMethodOnlyError();
|
||||
// nothing to do?
|
||||
// mParser_InPort = morkBool_kFalse;
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnNewGroup(morkEnv* ev, const morkPlace& inPlace, mork_gid inGid)
|
||||
{
|
||||
// mParser_InGroup = morkBool_kTrue;
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnGroupGlitch(morkEnv* ev, const morkGlitch& inGlitch)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
this->LogGlitch(ev, inGlitch, "group");
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnGroupCommitEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
{
|
||||
// mParser_InGroup = morkBool_kFalse;
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnGroupAbortEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
{
|
||||
// mParser_InGroup = morkBool_kFalse;
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnNewPortRow(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange)
|
||||
const morkMid& inMid, mork_change inChange)
|
||||
{
|
||||
// mParser_InPortRow = morkBool_kTrue;
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnPortRowGlitch(morkEnv* ev, const morkGlitch& inGlitch)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
this->LogGlitch(ev, inGlitch, "port row");
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnPortRowEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
{
|
||||
// mParser_InPortRow = morkBool_kFalse;
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnNewTable(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange)
|
||||
const morkMid& inMid, mork_change inChange)
|
||||
// mp:Table ::= OnNewTable mp:TableItem* OnTableEnd
|
||||
// mp:TableItem ::= mp:Row | mp:Meta | OnTableGlitch
|
||||
// mp:Meta ::= OnNewMeta mp:MetaItem* OnMetaEnd
|
||||
// mp:MetaItem ::= mp:Cell | OnMetaGlitch
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// mParser_InTable = morkBool_kTrue;
|
||||
mBuilder_TableForm = mBuilder_PortForm;
|
||||
mBuilder_TableRowScope = mBuilder_PortRowScope;
|
||||
mBuilder_TableAtomScope = mBuilder_PortAtomScope;
|
||||
mBuilder_TableKind = mBuilder_MorkNoneToken;
|
||||
|
||||
morkTable* table = mBuilder_Store->MidToTable(ev, inMid);
|
||||
morkTable::SlotStrongTable(table, ev, &mBuilder_Table);
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnTableGlitch(morkEnv* ev, const morkGlitch& inGlitch)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
this->LogGlitch(ev, inGlitch, "table");
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnTableEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
// mp:Table ::= OnNewTable mp:TableItem* OnTableEnd
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// mParser_InTable = morkBool_kFalse;
|
||||
if ( mBuilder_Table )
|
||||
{
|
||||
morkTable::SlotStrongTable((morkTable*) 0, ev, &mBuilder_Table);
|
||||
}
|
||||
else
|
||||
this->NilBuilderTableError(ev);
|
||||
|
||||
mBuilder_Row = 0;
|
||||
mBuilder_Cell = 0;
|
||||
|
||||
if ( mBuilder_TableKind == mBuilder_MorkNoneToken )
|
||||
ev->NewError("missing table kind");
|
||||
|
||||
mBuilder_CellAtomScope = mBuilder_RowAtomScope =
|
||||
mBuilder_TableAtomScope = mBuilder_PortAtomScope;
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnNewMeta(morkEnv* ev, const morkPlace& inPlace)
|
||||
// mp:Meta ::= OnNewMeta mp:MetaItem* OnMetaEnd
|
||||
// mp:MetaItem ::= mp:Cell | OnMetaGlitch
|
||||
// mp:Cell ::= OnNewCell mp:CellItem? OnCellEnd
|
||||
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
|
||||
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// mParser_InMeta = morkBool_kTrue;
|
||||
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnMetaGlitch(morkEnv* ev, const morkGlitch& inGlitch)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
this->LogGlitch(ev, inGlitch, "meta");
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnMetaEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
// mp:Meta ::= OnNewMeta mp:MetaItem* OnMetaEnd
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// mParser_InMeta = morkBool_kFalse;
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnNewRow(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange)
|
||||
const morkMid& inMid, mork_change inChange)
|
||||
// mp:Row ::= OnNewRow mp:RowItem* OnRowEnd
|
||||
// mp:RowItem ::= mp:Cell | mp:Meta | OnRowGlitch
|
||||
// mp:Cell ::= OnNewCell mp:CellItem? OnCellEnd
|
||||
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
|
||||
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// mParser_InRow = morkBool_kTrue;
|
||||
if ( mBuilder_Table )
|
||||
{
|
||||
mBuilder_CellForm = mBuilder_RowForm = mBuilder_TableForm;
|
||||
mBuilder_CellAtomScope = mBuilder_RowAtomScope = mBuilder_TableAtomScope;
|
||||
mBuilder_RowRowScope = mBuilder_TableRowScope;
|
||||
morkStore* store = mBuilder_Store;
|
||||
|
||||
if ( !inMid.mMid_Buf && !inMid.mMid_Oid.mOid_Scope )
|
||||
{
|
||||
morkMid mid(inMid);
|
||||
mid.mMid_Oid.mOid_Scope = mBuilder_RowRowScope;
|
||||
mBuilder_Row = store->MidToRow(ev, mid);
|
||||
}
|
||||
else
|
||||
{
|
||||
mBuilder_Row = store->MidToRow(ev, inMid);
|
||||
}
|
||||
|
||||
if ( mBuilder_Row )
|
||||
mBuilder_Table->AddRow(ev, mBuilder_Row);
|
||||
}
|
||||
else
|
||||
this->NilBuilderTableError(ev);
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnRowGlitch(morkEnv* ev, const morkGlitch& inGlitch)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
this->LogGlitch(ev, inGlitch, "row");
|
||||
}
|
||||
|
||||
void
|
||||
morkBuilder::FlushBuilderCells(morkEnv* ev)
|
||||
{
|
||||
if ( mBuilder_Row )
|
||||
{
|
||||
morkPool* pool = mBuilder_Store->StorePool();
|
||||
morkCell* cells = mBuilder_CellsVec;
|
||||
mork_fill fill = mBuilder_CellsVecFill;
|
||||
mBuilder_Row->TakeCells(ev, cells, fill, mBuilder_Store);
|
||||
|
||||
morkCell* end = cells + fill;
|
||||
--cells; // prepare for preincrement
|
||||
while ( ++cells < end )
|
||||
{
|
||||
if ( cells->mCell_Atom )
|
||||
cells->SetAtom(ev, (morkAtom*) 0, pool);
|
||||
}
|
||||
mBuilder_CellsVecFill = 0;
|
||||
}
|
||||
else
|
||||
this->NilBuilderRowError(ev);
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnRowEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
// mp:Row ::= OnNewRow mp:RowItem* OnRowEnd
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// mParser_InRow = morkBool_kFalse;
|
||||
if ( mBuilder_Row )
|
||||
{
|
||||
this->FlushBuilderCells(ev);
|
||||
}
|
||||
else
|
||||
this->NilBuilderRowError(ev);
|
||||
|
||||
mBuilder_Row = 0;
|
||||
mBuilder_Cell = 0;
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnNewDict(morkEnv* ev, const morkPlace& inPlace)
|
||||
// mp:Dict ::= OnNewDict mp:DictItem* OnDictEnd
|
||||
// mp:DictItem ::= OnAlias | OnAliasGlitch | mp:Meta | OnDictGlitch
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// mParser_InDict = morkBool_kTrue;
|
||||
|
||||
mBuilder_CellForm = mBuilder_DictForm = mBuilder_PortForm;
|
||||
mBuilder_CellAtomScope = mBuilder_DictAtomScope = mBuilder_PortAtomScope;
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnDictGlitch(morkEnv* ev, const morkGlitch& inGlitch)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
this->LogGlitch(ev, inGlitch, "dict");
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnDictEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
// mp:Dict ::= OnNewDict mp:DictItem* OnDictEnd
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// mParser_InDict = morkBool_kFalse;
|
||||
|
||||
mBuilder_DictForm = 0;
|
||||
mBuilder_DictAtomScope = 0;
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias)
|
||||
const morkMid& inMid)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
if ( mParser_InDict )
|
||||
{
|
||||
morkMid mid = inMid; // local copy for modification
|
||||
mid.mMid_Oid.mOid_Scope = mBuilder_DictAtomScope;
|
||||
mBuilder_Store->AddAlias(ev, mid, mBuilder_DictForm);
|
||||
}
|
||||
else
|
||||
ev->NewError("alias not in dict");
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnAliasGlitch(morkEnv* ev, const morkGlitch& inGlitch)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
this->LogGlitch(ev, inGlitch, "alias");
|
||||
}
|
||||
|
||||
|
||||
morkCell*
|
||||
morkBuilder::AddBuilderCell(morkEnv* ev,
|
||||
const morkMid& inMid, mork_change inChange)
|
||||
{
|
||||
morkCell* outCell = 0;
|
||||
mork_column column = inMid.mMid_Oid.mOid_Id;
|
||||
|
||||
if ( ev->Good() )
|
||||
{
|
||||
if ( mBuilder_CellsVecFill >= morkBuilder_kCellsVecSize )
|
||||
this->FlushBuilderCells(ev);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
if ( mBuilder_CellsVecFill < morkBuilder_kCellsVecSize )
|
||||
{
|
||||
mork_fill index = mBuilder_CellsVecFill++;
|
||||
outCell = mBuilder_CellsVec + index;
|
||||
outCell->SetColumnAndChange(column, inChange);
|
||||
outCell->mCell_Atom = 0;
|
||||
}
|
||||
else
|
||||
ev->NewError("out of builder cells");
|
||||
}
|
||||
}
|
||||
return outCell;
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnNewCell(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange)
|
||||
const morkMid* inMid, const morkBuf* inBuf, mork_change inChange)
|
||||
// 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.
|
||||
|
||||
// mp:Cell ::= OnNewCell mp:CellItem? OnCellEnd
|
||||
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
|
||||
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// mParser_InCell = morkBool_kTrue;
|
||||
|
||||
mBuilder_CellAtomScope = mBuilder_RowAtomScope;
|
||||
|
||||
mBuilder_Cell = 0; // nil until determined for a row
|
||||
morkStore* store = mBuilder_Store;
|
||||
mork_scope scope = morkStore_kColumnSpaceScope;
|
||||
morkMid tempMid; // space for local and modifiable cell mid
|
||||
morkMid* cellMid = &tempMid; // default to local if inMid==0
|
||||
|
||||
if ( inMid ) // mid parameter is actually provided?
|
||||
{
|
||||
*cellMid = *inMid; // bitwise copy for modifiable local mid
|
||||
|
||||
if ( !cellMid->mMid_Oid.mOid_Scope )
|
||||
{
|
||||
if ( cellMid->mMid_Buf )
|
||||
{
|
||||
scope = store->BufToToken(ev, cellMid->mMid_Buf);
|
||||
cellMid->mMid_Buf = 0; // don't do scope lookup again
|
||||
ev->NewWarning("column mids need column scope");
|
||||
}
|
||||
cellMid->mMid_Oid.mOid_Scope = scope;
|
||||
}
|
||||
}
|
||||
else if ( inBuf ) // buf points to naked column string name?
|
||||
{
|
||||
cellMid->ClearMid();
|
||||
cellMid->mMid_Oid.mOid_Id = store->BufToToken(ev, inBuf);
|
||||
cellMid->mMid_Oid.mOid_Scope = scope; // kColumnSpaceScope
|
||||
}
|
||||
else
|
||||
ev->NilPointerError(); // either inMid or inBuf must be non-nil
|
||||
|
||||
mork_column column = cellMid->mMid_Oid.mOid_Id;
|
||||
|
||||
if ( mParser_InMeta && ev->Good() ) // cell is in metainfo structure?
|
||||
{
|
||||
if ( scope == morkStore_kColumnSpaceScope )
|
||||
{
|
||||
if ( mParser_InTable ) // metainfo for table?
|
||||
{
|
||||
if ( column == store->mStore_TableKindToken )
|
||||
mBuilder_MetaTokenSlot = &mBuilder_TableKind;
|
||||
else if ( column == store->mStore_RowScopeToken )
|
||||
mBuilder_MetaTokenSlot = &mBuilder_TableRowScope;
|
||||
else if ( column == store->mStore_AtomScopeToken )
|
||||
mBuilder_MetaTokenSlot = &mBuilder_TableAtomScope;
|
||||
else if ( column == store->mStore_CharsetToken )
|
||||
mBuilder_MetaTokenSlot = &mBuilder_TableForm;
|
||||
}
|
||||
else if ( mParser_InDict ) // metainfo for dict?
|
||||
{
|
||||
if ( column == store->mStore_AtomScopeToken )
|
||||
mBuilder_MetaTokenSlot = &mBuilder_DictAtomScope;
|
||||
else if ( column == store->mStore_CharsetToken )
|
||||
mBuilder_MetaTokenSlot = &mBuilder_DictForm;
|
||||
}
|
||||
else if ( mParser_InRow ) // metainfo for row?
|
||||
{
|
||||
if ( column == store->mStore_AtomScopeToken )
|
||||
mBuilder_MetaTokenSlot = &mBuilder_RowAtomScope;
|
||||
else if ( column == store->mStore_RowScopeToken )
|
||||
mBuilder_MetaTokenSlot = &mBuilder_RowRowScope;
|
||||
else if ( column == store->mStore_CharsetToken )
|
||||
mBuilder_MetaTokenSlot = &mBuilder_RowForm;
|
||||
}
|
||||
}
|
||||
else
|
||||
ev->NewWarning("expected column scope");
|
||||
}
|
||||
else if ( ev->Good() ) // this cell must be inside a row
|
||||
{
|
||||
if ( mBuilder_Row )
|
||||
{
|
||||
// mBuilder_Cell = this->AddBuilderCell(ev, *cellMid, inChange);
|
||||
|
||||
if ( mBuilder_CellsVecFill >= morkBuilder_kCellsVecSize )
|
||||
this->FlushBuilderCells(ev);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
if ( mBuilder_CellsVecFill < morkBuilder_kCellsVecSize )
|
||||
{
|
||||
mork_fill index = mBuilder_CellsVecFill++;
|
||||
morkCell* cell = mBuilder_CellsVec + index;
|
||||
cell->SetColumnAndChange(column, inChange);
|
||||
cell->mCell_Atom = 0;
|
||||
mBuilder_Cell = cell;
|
||||
}
|
||||
else
|
||||
ev->NewError("out of builder cells");
|
||||
}
|
||||
}
|
||||
else
|
||||
this->NilBuilderRowError(ev);
|
||||
}
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnCellGlitch(morkEnv* ev, const morkGlitch& inGlitch)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
this->LogGlitch(ev, inGlitch, "cell");
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnCellForm(morkEnv* ev, mork_cscode inCharsetFormat)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
morkCell* cell = mBuilder_Cell;
|
||||
if ( cell )
|
||||
{
|
||||
mBuilder_CellForm = inCharsetFormat;
|
||||
}
|
||||
else
|
||||
this->NilBuilderCellError(ev);
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnCellEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
// mp:Cell ::= OnNewCell mp:CellItem? OnCellEnd
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// mParser_InCell = morkBool_kFalse;
|
||||
|
||||
mBuilder_MetaTokenSlot = 0;
|
||||
mBuilder_CellAtomScope = mBuilder_RowAtomScope;
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnValue(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkBuf& inBuf)
|
||||
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
|
||||
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
morkStore* store = mBuilder_Store;
|
||||
morkCell* cell = mBuilder_Cell;
|
||||
if ( cell )
|
||||
{
|
||||
mdbYarn yarn;
|
||||
yarn.mYarn_Buf = inBuf.mBuf_Body;
|
||||
yarn.mYarn_Fill = yarn.mYarn_Size = inBuf.mBuf_Fill;
|
||||
yarn.mYarn_More = 0;
|
||||
yarn.mYarn_Form = mBuilder_CellForm;
|
||||
yarn.mYarn_Grow = 0;
|
||||
morkAtom* atom = store->YarnToAtom(ev, &yarn);
|
||||
cell->SetAtom(ev, atom, store->StorePool());
|
||||
}
|
||||
else if ( mParser_InMeta )
|
||||
{
|
||||
mork_token* metaSlot = mBuilder_MetaTokenSlot;
|
||||
if ( metaSlot )
|
||||
{
|
||||
mork_token token = store->BufToToken(ev, &inBuf);
|
||||
if ( token )
|
||||
{
|
||||
*metaSlot = token;
|
||||
if ( metaSlot == &mBuilder_TableKind ) // table kind?
|
||||
{
|
||||
if ( mParser_InTable && mBuilder_Table )
|
||||
mBuilder_Table->mTable_Kind = token;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
this->NilBuilderCellError(ev);
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnValueAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias)
|
||||
morkBuilder::OnValueMid(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkMid& inMid)
|
||||
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
|
||||
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
morkStore* store = mBuilder_Store;
|
||||
morkCell* cell = mBuilder_Cell;
|
||||
|
||||
morkMid valMid; // local mid for modifications
|
||||
mdbOid* valOid = &valMid.mMid_Oid; // ref to oid inside mid
|
||||
*valOid = inMid.mMid_Oid; // bitwise copy inMid's oid
|
||||
|
||||
if ( inMid.mMid_Buf )
|
||||
{
|
||||
if ( !valOid->mOid_Scope )
|
||||
store->MidToOid(ev, inMid, valOid);
|
||||
}
|
||||
else if ( !valOid->mOid_Scope )
|
||||
valOid->mOid_Scope = mBuilder_CellAtomScope;
|
||||
|
||||
if ( cell )
|
||||
{
|
||||
morkBookAtom* atom = store->MidToAtom(ev, valMid);
|
||||
if ( atom )
|
||||
cell->SetAtom(ev, atom, store->StorePool());
|
||||
else
|
||||
ev->NewError("undefined cell value alias");
|
||||
}
|
||||
else if ( mParser_InMeta )
|
||||
{
|
||||
mork_token* metaSlot = mBuilder_MetaTokenSlot;
|
||||
if ( metaSlot )
|
||||
{
|
||||
if ( valOid->mOid_Scope == morkStore_kColumnSpaceScope )
|
||||
{
|
||||
if ( ev->Good() && valMid.HasSomeId() )
|
||||
{
|
||||
*metaSlot = valOid->mOid_Id;
|
||||
if ( metaSlot == &mBuilder_TableKind ) // table kind?
|
||||
{
|
||||
if ( mParser_InTable && mBuilder_Table )
|
||||
{
|
||||
mBuilder_Table->mTable_Kind = valOid->mOid_Id;
|
||||
}
|
||||
else
|
||||
ev->NewWarning("mBuilder_TableKind not in table");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
this->NonColumnSpaceScopeError(ev);
|
||||
}
|
||||
}
|
||||
else
|
||||
this->NilBuilderCellError(ev);
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnRowAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias)
|
||||
morkBuilder::OnRowMid(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkMid& inMid)
|
||||
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
|
||||
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
morkStore* store = mBuilder_Store;
|
||||
morkCell* cell = mBuilder_Cell;
|
||||
if ( cell )
|
||||
{
|
||||
mdbOid rowOid = inMid.mMid_Oid;
|
||||
if ( inMid.mMid_Buf )
|
||||
{
|
||||
if ( !rowOid.mOid_Scope )
|
||||
store->MidToOid(ev, inMid, &rowOid);
|
||||
}
|
||||
else if ( !rowOid.mOid_Scope )
|
||||
rowOid.mOid_Scope = mBuilder_RowRowScope;
|
||||
|
||||
if ( ev->Good() )
|
||||
{
|
||||
morkPool* pool = store->StorePool();
|
||||
morkAtom* atom = pool->NewRowOidAtom(ev, rowOid);
|
||||
if ( atom )
|
||||
{
|
||||
cell->SetAtom(ev, atom, pool);
|
||||
morkRow* row = store->OidToRow(ev, &rowOid);
|
||||
if ( row ) // found or created such a row?
|
||||
row->AddTableUse(ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
this->NilBuilderCellError(ev);
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnTableAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias)
|
||||
morkBuilder::OnTableMid(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkMid& inMid)
|
||||
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
|
||||
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
morkStore* store = mBuilder_Store;
|
||||
morkCell* cell = mBuilder_Cell;
|
||||
if ( cell )
|
||||
{
|
||||
mdbOid tableOid = inMid.mMid_Oid;
|
||||
if ( inMid.mMid_Buf )
|
||||
{
|
||||
if ( !tableOid.mOid_Scope )
|
||||
store->MidToOid(ev, inMid, &tableOid);
|
||||
}
|
||||
else if ( !tableOid.mOid_Scope )
|
||||
tableOid.mOid_Scope = mBuilder_RowRowScope;
|
||||
|
||||
if ( ev->Good() )
|
||||
{
|
||||
morkPool* pool = store->StorePool();
|
||||
morkAtom* atom = pool->NewTableOidAtom(ev, tableOid);
|
||||
if ( atom )
|
||||
{
|
||||
cell->SetAtom(ev, atom, pool);
|
||||
morkTable* table = store->OidToTable(ev, &tableOid);
|
||||
if ( table ) // found or created such a table?
|
||||
table->AddCellUse(ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
this->NilBuilderCellError(ev);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -65,31 +65,31 @@ class morkBuilder /*d*/ : public morkParser {
|
|||
// 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_tid mParser_TableId; // table ID if inside a table
|
||||
// mork_rid mParser_RowId; // row ID if inside a row
|
||||
|
||||
// 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?
|
||||
|
||||
// morkAlias mParser_Alias; // current alias being parsed
|
||||
// note that mParser_Alias.mAlias_Buf points at mParser_ScopeSpool below:
|
||||
// morkMid mParser_Mid; // current alias being parsed
|
||||
// note that mParser_Mid.mMid_Buf points at mParser_ScopeCoil below:
|
||||
|
||||
// blob spools allocated in mParser_Heap
|
||||
// morkSpool mParser_ScopeSpool; // place to accumulate ID scope blobs
|
||||
// morkSpool mParser_ValueSpool; // place to accumulate value blobs
|
||||
// morkSpool mParser_ColumnSpool; // place to accumulate column blobs
|
||||
// morkSpool mParser_StringSpool; // place to accumulate string blobs
|
||||
// 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
|
||||
|
||||
// morkSpoolSink mParser_ScopeSink; // writes to mParser_ScopeSpool
|
||||
// morkSpoolSink mParser_ValueSink; // writes to mParser_ValueSpool
|
||||
// morkSpoolSink mParser_ColumnSink; // writes to mParser_ColumnSpool
|
||||
// morkSpoolSink mParser_StringSink; // writes to mParser_StringSpool
|
||||
// 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_AliasYarn; // place to receive from AliasToYarn()
|
||||
// morkYarn mParser_MidYarn; // place to receive from MidToYarn()
|
||||
|
||||
// span showing current ongoing file position status:
|
||||
// morkSpan mParser_PortSpan; // span of current db port file
|
||||
|
@ -118,8 +118,8 @@ protected: // protected morkBuilder members
|
|||
morkRow* mBuilder_Row; // current row being built (or nil)
|
||||
morkCell* mBuilder_Cell; // current cell within CellsVec (or nil)
|
||||
|
||||
morkRowSpace* mBuilder_RowSpace; // space for mBuilder_CurrentRowScope
|
||||
morkAtomSpace* mBuilder_AtomSpace; // space for mBuilder_CurrentAtomScope
|
||||
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
|
||||
|
@ -134,6 +134,8 @@ protected: // protected morkBuilder members
|
|||
mork_cscode mBuilder_a; // token for "a"
|
||||
mork_cscode mBuilder_t; // token for "t"
|
||||
|
||||
mork_token mBuilder_MorkNoneToken; // token for "mork:none"
|
||||
|
||||
// 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
|
||||
|
@ -151,21 +153,25 @@ protected: // protected morkBuilder members
|
|||
mork_scope mBuilder_RowAtomScope; // row atom scope
|
||||
|
||||
// meta tokens currently in force, driven by meta info slots above:
|
||||
mork_cscode mBuilder_CurrentForm; // current charset format
|
||||
mork_scope mBuilder_CurrentRowScope; // current row scope
|
||||
mork_scope mBuilder_CurrentAtomScope; // current atom scope
|
||||
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_CutRow; // row with kCut change
|
||||
mork_bool mBuilder_CutCell; // cell with kCut change
|
||||
mork_bool mBuilder_DoCutRow; // row with kCut change
|
||||
mork_bool mBuilder_DoCutCell; // cell with kCut change
|
||||
mork_u1 mBuilder_Pad1; // pad to u4 alignment
|
||||
mork_u1 mBuilder_Pad2; // pad to u4 alignment
|
||||
|
||||
morkCell mBuilder_CellsVec[ morkBuilder_kCellsVecSize ];
|
||||
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
|
||||
|
@ -199,14 +205,28 @@ public: // dynamic type identification
|
|||
{ return IsNode() && mNode_Derived == morkDerived_kBuilder; }
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
public: // typing
|
||||
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 AliasToYarn(morkEnv* ev,
|
||||
const morkAlias& inAlias, // typically an alias to concat with strings
|
||||
virtual void MidToYarn(morkEnv* ev,
|
||||
const morkMid& inMid, // typically an alias to concat with strings
|
||||
mdbYarn* outYarn);
|
||||
// The parser might ask that some aliases be turned into yarns, so they
|
||||
// can be concatenated into longer blobs under some circumstances. This
|
||||
|
@ -216,60 +236,64 @@ public: // in virtual morkParser methods, data flow subclass to parser
|
|||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
public: // out virtual morkParser methods, data flow parser to subclass
|
||||
|
||||
virtual void OnNewPort(morkEnv* ev, const morkPlace& inPlace);
|
||||
virtual void OnPortGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
virtual void OnPortEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
virtual void OnNewPort(morkEnv* ev, const morkPlace& inPlace);
|
||||
virtual void OnPortGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
virtual void OnPortEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
|
||||
virtual void OnNewGroup(morkEnv* ev, const morkPlace& inPlace, mork_gid inGid);
|
||||
virtual void OnGroupGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
virtual void OnGroupCommitEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
virtual void OnGroupAbortEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
virtual void OnNewGroup(morkEnv* ev, const morkPlace& inPlace, mork_gid inGid);
|
||||
virtual void OnGroupGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
virtual void OnGroupCommitEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
virtual void OnGroupAbortEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
|
||||
virtual void OnNewPortRow(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange);
|
||||
virtual void OnPortRowGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
virtual void OnPortRowEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
virtual void OnNewPortRow(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkMid& inMid, mork_change inChange);
|
||||
virtual void OnPortRowGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
virtual void OnPortRowEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
|
||||
virtual void OnNewTable(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange);
|
||||
virtual void OnTableGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
virtual void OnTableEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
|
||||
virtual void OnNewMeta(morkEnv* ev, const morkPlace& inPlace);
|
||||
virtual void OnMetaGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
virtual void OnMetaEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
virtual void OnNewTable(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkMid& inMid, mork_change inChange);
|
||||
virtual void OnTableGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
virtual void OnTableEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
|
||||
virtual void OnNewMeta(morkEnv* ev, const morkPlace& inPlace);
|
||||
virtual void OnMetaGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
virtual void OnMetaEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
|
||||
virtual void OnNewRow(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange);
|
||||
virtual void OnRowGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
virtual void OnRowEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
virtual void OnNewRow(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkMid& inMid, mork_change inChange);
|
||||
virtual void OnRowGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
virtual void OnRowEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
|
||||
virtual void OnNewDict(morkEnv* ev, const morkPlace& inPlace);
|
||||
virtual void OnDictGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
virtual void OnDictEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
virtual void OnNewDict(morkEnv* ev, const morkPlace& inPlace);
|
||||
virtual void OnDictGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
virtual void OnDictEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
|
||||
virtual void OnAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias);
|
||||
virtual void OnAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkMid& inMid);
|
||||
|
||||
virtual void OnAliasGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
virtual void OnAliasGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
|
||||
virtual void OnNewCell(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange);
|
||||
virtual void OnCellGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
virtual void OnCellForm(morkEnv* ev, mork_cscode inCharsetFormat);
|
||||
virtual void OnCellEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
|
||||
virtual void OnValue(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkBuf& inBuf);
|
||||
virtual void OnNewCell(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkMid* inMid, const morkBuf* inBuf, mork_change inChange);
|
||||
// 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 OnValueAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias);
|
||||
virtual void OnCellGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
virtual void OnCellForm(morkEnv* ev, mork_cscode inCharsetFormat);
|
||||
virtual void OnCellEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
|
||||
virtual void OnValue(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkBuf& inBuf);
|
||||
|
||||
virtual void OnRowAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias);
|
||||
virtual void OnValueMid(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkMid& inMid);
|
||||
|
||||
virtual void OnTableAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias);
|
||||
virtual void OnRowMid(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkMid& inMid);
|
||||
|
||||
virtual void OnTableMid(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkMid& inMid);
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
public: // public non-poly morkBuilder methods
|
||||
|
|
|
@ -46,9 +46,6 @@
|
|||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
void
|
||||
morkCell::SetYarn(morkEnv* ev, const mdbYarn* inYarn, morkStore* ioStore)
|
||||
{
|
||||
|
|
|
@ -40,6 +40,9 @@ public:
|
|||
|
||||
public:
|
||||
morkCell() : mCell_Atom( 0 ), mCell_Delta( 0 ) { }
|
||||
|
||||
morkCell(const morkCell& c)
|
||||
: mCell_Atom( c.mCell_Atom ), mCell_Delta( c.mCell_Delta ) { }
|
||||
|
||||
// note if ioAtom is non-nil, caller needs to call ioAtom->AddCellUse():
|
||||
morkCell(mork_column inCol, mork_change inChange, morkAtom* ioAtom)
|
||||
|
|
|
@ -30,8 +30,8 @@
|
|||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
/* ----- ----- ----- ----- MORK_MAC ----- ----- ----- ----- */
|
||||
#ifdef MORK_MAC
|
||||
/* ----- ----- ----- ----- MORK_OBSOLETE ----- ----- ----- ----- */
|
||||
#ifdef MORK_OBSOLETE
|
||||
|
||||
#include <Types.h>
|
||||
|
||||
|
@ -58,14 +58,14 @@
|
|||
|
||||
DebugStr(pascalStr); /* call Mac debugger entry point */
|
||||
}
|
||||
#endif /*MORK_MAC*/
|
||||
/* ----- ----- ----- ----- MORK_MAC ----- ----- ----- ----- */
|
||||
#endif /*MORK_OBSOLETE*/
|
||||
/* ----- ----- ----- ----- MORK_OBSOLETE ----- ----- ----- ----- */
|
||||
|
||||
void mork_assertion_signal(const char* inMessage)
|
||||
{
|
||||
#ifdef XP_MAC
|
||||
#ifdef MORK_OBSOLETE
|
||||
mork_mac_break_string(inMessage);
|
||||
#endif /*XP_MAC*/
|
||||
#endif /*MORK_OBSOLETE*/
|
||||
|
||||
#ifdef MORK_WIN
|
||||
// asm { int 3 }
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
// { %%%%% begin platform defs peculiar to Mork %%%%%
|
||||
#ifdef XP_MAC
|
||||
#define MORK_MAC 1
|
||||
#define MORK_OBSOLETE 1
|
||||
#endif
|
||||
|
||||
#ifdef XP_OS2
|
||||
|
@ -46,9 +47,14 @@
|
|||
#ifdef XP_UNIX
|
||||
#define MORK_UNIX 1
|
||||
#endif
|
||||
|
||||
#ifdef MORK_OBSOLETE
|
||||
#undef MORK_MAC
|
||||
#endif
|
||||
|
||||
// } %%%%% end platform defs peculiar to Mork %%%%%
|
||||
|
||||
#if defined (MORK_WIN) || defined(MORK_UNIX)
|
||||
#if defined(MORK_WIN) || defined(MORK_UNIX) || defined(MORK_MAC)
|
||||
#include "stdio.h"
|
||||
#include "ctype.h"
|
||||
#include "errno.h"
|
||||
|
@ -60,12 +66,12 @@
|
|||
|
||||
#define MORK_FILETELL(file) ftell(file)
|
||||
#define MORK_FILESEEK(file, where, how) fseek(file, where, how)
|
||||
#define MORK_FILEREAD(outbuf, insize, file) fread(outbuf, insize, 1, file)
|
||||
#define MORK_FILEREAD(outbuf, insize, file) fread(outbuf, 1, insize, file)
|
||||
#define MORK_FILEFLUSH(file) fflush(file)
|
||||
#define MORK_FILECLOSE(file) fclose(file)
|
||||
#endif /*MORK_WIN*/
|
||||
|
||||
#ifdef MORK_MAC
|
||||
#ifdef MORK_OBSOLETE
|
||||
#include "xp_file.h"
|
||||
#include "ctype.h"
|
||||
|
||||
|
@ -76,17 +82,17 @@
|
|||
#define MORK_FILEREAD(outbuf, insize, file) XP_FileRead(outbuf, insize, file)
|
||||
#define MORK_FILEFLUSH(file) XP_FileFlush(file)
|
||||
#define MORK_FILECLOSE(file) XP_FileClose(file)
|
||||
#endif /*MORK_MAC*/
|
||||
#endif /*MORK_OBSOLETE*/
|
||||
|
||||
/* ===== ===== ===== ===== line characters ===== ===== ===== ===== */
|
||||
#define mork_kCR '\015'
|
||||
#define mork_kLF '\012'
|
||||
#define mork_kCR 0x0D
|
||||
#define mork_kLF 0x0A
|
||||
#define mork_kVTAB '\013'
|
||||
#define mork_kFF '\014'
|
||||
#define mork_kTAB '\011'
|
||||
#define mork_kCRLF "\015\012" /* A CR LF equivalent string */
|
||||
|
||||
#ifdef MORK_MAC
|
||||
#if defined(MORK_MAC) || defined(MORK_OBSOLETE)
|
||||
# define mork_kNewline "\015"
|
||||
# define mork_kNewlineSize 1
|
||||
#else
|
||||
|
@ -113,18 +119,14 @@ extern void mork_assertion_signal(const char* inMessage);
|
|||
// { %%%%% begin standard c utility methods %%%%%
|
||||
/*define MORK_USE_XP_STDLIB 1*/
|
||||
|
||||
#ifdef MORK_MAC
|
||||
#ifdef MORK_OBSOLETE
|
||||
#define MORK_PROVIDE_STDLIB 1
|
||||
#endif /*MORK_MAC*/
|
||||
#endif /*MORK_OBSOLETE*/
|
||||
|
||||
#ifdef MORK_WIN
|
||||
#if defined(MORK_WIN) || defined(MORK_UNIX) || defined(MORK_MAC)
|
||||
#define MORK_USE_C_STDLIB 1
|
||||
#endif /*MORK_WIN*/
|
||||
|
||||
#ifdef MORK_UNIX
|
||||
#define MORK_USE_NSPR_STDLIB 1
|
||||
#endif
|
||||
|
||||
#ifdef MORK_USE_C_STDLIB
|
||||
#define MORK_MEMCMP(src1,src2,size) memcmp(src1,src2,size)
|
||||
#define MORK_MEMCPY(dest,src,size) memcpy(dest,src,size)
|
||||
|
@ -167,16 +169,6 @@ MORK_LIB(mork_size) mork_strlen(const void* inString);
|
|||
#define MORK_STRLEN(string) XP_STRLEN(string)
|
||||
#endif /*MORK_USE_XP_STDLIB*/
|
||||
|
||||
#ifdef MORK_USE_NSPR_STDLIB
|
||||
#define MORK_MEMCMP(src1,src2, size) memcmp(src1, src2, size)
|
||||
#define MORK_MEMCPY(src1,src2, size) memcpy(src1, src2, size)
|
||||
#define MORK_MEMMOVE(dest, src, size) memmove(src1, src2, size)
|
||||
#define MORK_MEMSET(dest,byte,size) memset(dest,byte,size)
|
||||
#define MORK_STRCPY(dest,src) PL_strcpy(dest,src)
|
||||
#define MORK_STRCMP(one,two) PL_strcmp(one,two)
|
||||
#define MORK_STRNCMP(one,two,length) PL_strncmp(one,two,length)
|
||||
#define MORK_STRLEN(string) PL_strlen(string)
|
||||
#endif
|
||||
|
||||
// } %%%%% end standard c utility methods %%%%%
|
||||
|
||||
|
|
|
@ -221,7 +221,7 @@ morkFile::NewFileErrnoError(morkEnv* ev) const
|
|||
|
||||
// ````` ````` ````` ````` newlines ````` ````` ````` `````
|
||||
|
||||
#ifdef MORK_MAC
|
||||
#if defined(MORK_MAC) || defined(MORK_OBSOLETE)
|
||||
static const char* morkFile_kNewlines =
|
||||
"\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015";
|
||||
# define morkFile_kNewlinesCount 16
|
||||
|
@ -314,7 +314,7 @@ morkStdioFile::OpenOldStdioFile(morkEnv* ev, nsIMdbHeap* ioHeap,
|
|||
morkStdioFile* outFile = 0;
|
||||
if ( ioHeap && inFilePath )
|
||||
{
|
||||
const char* mode = (inFrozen)? "rb" : "wb";
|
||||
const char* mode = (inFrozen)? "rb" : "rb+";
|
||||
outFile = new(*ioHeap, ev)
|
||||
morkStdioFile(ev, morkUsage::kHeap, ioHeap, ioHeap, inFilePath, mode);
|
||||
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -23,10 +23,6 @@
|
|||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKPARSER_
|
||||
#include "morkParser.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKBLOB_
|
||||
#include "morkBlob.h"
|
||||
#endif
|
||||
|
@ -68,6 +64,9 @@ public:
|
|||
|
||||
morkPlace(mork_pos inPos, mork_line inLine)
|
||||
{ mPlace_Pos = inPos; mPlace_Line = inLine; }
|
||||
|
||||
morkPlace(const morkPlace& inPlace)
|
||||
: mPlace_Pos(inPlace.mPlace_Pos), mPlace_Line(inPlace.mPlace_Line) { }
|
||||
};
|
||||
|
||||
/*=============================================================================
|
||||
|
@ -80,48 +79,68 @@ public:
|
|||
const char* mGlitch_Comment; // null-terminated ASCII C string
|
||||
|
||||
morkGlitch() { mGlitch_Comment = 0; }
|
||||
|
||||
morkGlitch(const morkPlace& inPlace, const char* inComment)
|
||||
: mGlitch_Place(inPlace), mGlitch_Comment(inComment) { }
|
||||
};
|
||||
|
||||
/*=============================================================================
|
||||
* morkAlias: all possible ways needed to express an alias ID in Mork syntax
|
||||
* morkMid: all possible ways needed to express an alias ID in Mork syntax
|
||||
*/
|
||||
|
||||
/*| morkAlias: an abstraction of all the variations we might need to support
|
||||
/*| morkMid: an abstraction of all the variations we might need to support
|
||||
**| in order to present an ID through the parser interface most cheaply and
|
||||
**| with minimum transformation away from the original text format.
|
||||
**|
|
||||
**|| An ID can have one of four forms:
|
||||
**| 1) idHex (mAlias_Oid.mOid_Id <- idHex)
|
||||
**| 2) idHex:^scopeHex (mAlias_Oid.mOid_Id <- idHex, mOid_Scope <- scopeHex)
|
||||
**| 3) idHex:scopeName (mAlias_Oid.mOid_Id <- idHex, mAlias_Buf <- scopeName)
|
||||
**| 4) columnName (mAlias_Buf <- columnName, for columns in cells only)
|
||||
**| 1) idHex (mMid_Oid.mOid_Id <- idHex)
|
||||
**| 2) idHex:^scopeHex (mMid_Oid.mOid_Id <- idHex, mOid_Scope <- scopeHex)
|
||||
**| 3) idHex:scopeName (mMid_Oid.mOid_Id <- idHex, mMid_Buf <- scopeName)
|
||||
**| 4) columnName (mMid_Buf <- columnName, for columns in cells only)
|
||||
**|
|
||||
**|| Typically, mAlias_Oid.mOid_Id will hold a nonzero integer value for
|
||||
**|| Typically, mMid_Oid.mOid_Id will hold a nonzero integer value for
|
||||
**| an ID, but we might have an optional scope specified by either an integer
|
||||
**| in hex format, or a string name. (Note that while the first ID can be
|
||||
**| scoped variably, any integer ID for a scope is assumed always located in
|
||||
**| the same scope, so the second ID need not be disambiguated.)
|
||||
**|
|
||||
**|| The only time mAlias_Oid.mOid_Id is ever zero is when mAlias_Buf alone
|
||||
**|| The only time mMid_Oid.mOid_Id is ever zero is when mMid_Buf alone
|
||||
**| is nonzero, to indicate an explicit string instead of an alias appeared.
|
||||
**| This case happens to make the representation of columns in cells somewhat
|
||||
**| easier to represent, since columns can just appear as a string name; and
|
||||
**| this unifies those interfaces with row and table APIs expecting IDs.
|
||||
**|
|
||||
**|| So when the parser passes an instance of morkAlias to a subclass, the
|
||||
**| mAlias_Oid.mOid_Id slot should usually be nonzero. And the other two
|
||||
**| slots, mAlias_Oid.mOid_Scope and mAlias_Buf, might both be zero, or at
|
||||
**|| So when the parser passes an instance of morkMid to a subclass, the
|
||||
**| mMid_Oid.mOid_Id slot should usually be nonzero. And the other two
|
||||
**| slots, mMid_Oid.mOid_Scope and mMid_Buf, might both be zero, or at
|
||||
**| most one of them will be nonzero to indicate an explicit scope; the
|
||||
**| parser is responsible for ensuring at most one of these is nonzero.
|
||||
|*/
|
||||
class morkAlias {
|
||||
class morkMid {
|
||||
public:
|
||||
mdbOid mAlias_Oid; // mOid_Scope is zero when not specified
|
||||
const morkBuf* mAlias_Buf; // points to some specific buf subclass
|
||||
mdbOid mMid_Oid; // mOid_Scope is zero when not specified
|
||||
const morkBuf* mMid_Buf; // points to some specific buf subclass
|
||||
|
||||
morkAlias()
|
||||
{ mAlias_Oid.mOid_Scope = 0; mAlias_Oid.mOid_Id = morkId_kMinusOne;
|
||||
mAlias_Buf = 0; }
|
||||
morkMid()
|
||||
{ mMid_Oid.mOid_Scope = 0; mMid_Oid.mOid_Id = morkId_kMinusOne;
|
||||
mMid_Buf = 0; }
|
||||
|
||||
void InitMidWithCoil(morkCoil* ioCoil)
|
||||
{ mMid_Oid.mOid_Scope = 0; mMid_Oid.mOid_Id = morkId_kMinusOne;
|
||||
mMid_Buf = ioCoil; }
|
||||
|
||||
void ClearMid()
|
||||
{ mMid_Oid.mOid_Scope = 0; mMid_Oid.mOid_Id = morkId_kMinusOne;
|
||||
mMid_Buf = 0; }
|
||||
|
||||
morkMid(const morkMid& other)
|
||||
: mMid_Oid(other.mMid_Oid), mMid_Buf(other.mMid_Buf) { }
|
||||
|
||||
mork_bool HasNoId() const // ID is unspecified?
|
||||
{ return ( mMid_Oid.mOid_Id == morkId_kMinusOne ); }
|
||||
|
||||
mork_bool HasSomeId() const // ID is specified?
|
||||
{ return ( mMid_Oid.mOid_Id != morkId_kMinusOne ); }
|
||||
};
|
||||
|
||||
/*=============================================================================
|
||||
|
@ -138,6 +157,9 @@ public: // methods
|
|||
public: // inlines
|
||||
morkSpan() { } // use inline empty constructor for each place
|
||||
|
||||
morkPlace* AsPlace() { return &mSpan_Start; }
|
||||
const morkPlace* AsConstPlace() const { return &mSpan_Start; }
|
||||
|
||||
void SetSpan(mork_pos inFromPos, mork_line inFromLine,
|
||||
mork_pos inToPos, mork_line inToLine)
|
||||
{
|
||||
|
@ -208,7 +230,7 @@ class morkParser /*d*/ : public morkNode {
|
|||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
protected: // protected morkParser members
|
||||
|
||||
nsIMdbHeap* mParser_Heap; // refcounted heap used for allocation
|
||||
nsIMdbHeap* mParser_Heap; // refcounted heap used for allocation
|
||||
morkStream* mParser_Stream; // refcounted input stream
|
||||
|
||||
mork_u4 mParser_Tag; // must equal morkParser_kTag
|
||||
|
@ -219,9 +241,10 @@ protected: // protected morkParser members
|
|||
// after finding ends of group transactions, we can re-seek the start:
|
||||
mork_pos mParser_GroupContentStartPos; // start of this group
|
||||
|
||||
mork_gid mParser_GroupId; // group ID if inside a group
|
||||
mork_tid mParser_TableId; // table ID if inside a table
|
||||
mork_rid mParser_RowId; // row ID if inside a row
|
||||
morkMid mParser_TableMid; // table mid if inside a table
|
||||
morkMid mParser_RowMid; // row mid if inside a row
|
||||
morkMid mParser_CellMid; // cell mid 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?
|
||||
|
@ -229,28 +252,36 @@ protected: // protected morkParser members
|
|||
mork_bool mParser_InMeta; // called OnNewMeta but not OnMetaEnd?
|
||||
|
||||
mork_bool mParser_InPortRow; // called OnNewPortRow but not OnPortRowEnd?
|
||||
mork_bool mParser_InRow; // called OnNewRow but not OnNewRowEnd?
|
||||
mork_bool mParser_InTable; // called OnNewMeta but not OnMetaEnd?
|
||||
mork_bool mParser_InGroup; // called OnNewGroup but not OnGroupEnd?
|
||||
|
||||
mork_change mParser_AtomChange; // driven by mParser_Change
|
||||
mork_change mParser_CellChange; // driven by mParser_Change
|
||||
mork_change mParser_RowChange; // driven by mParser_Change
|
||||
mork_change mParser_TableChange; // driven by mParser_Change
|
||||
|
||||
mork_change mParser_Change; // driven by modifier in text
|
||||
mork_bool mParser_IsBroken; // has the parse become broken?
|
||||
mork_bool mParser_IsDone; // has the parse finished?
|
||||
mork_bool mParser_DoMore; // mParser_MoreGranularity not exhausted?
|
||||
|
||||
mork_change mParser_Change; // driven by modifier in text
|
||||
morkMid mParser_Mid; // current alias being parsed
|
||||
// note that mParser_Mid.mMid_Buf points at mParser_ScopeCoil below:
|
||||
|
||||
morkAlias mParser_Alias; // current alias being parsed
|
||||
// note that mParser_Alias.mAlias_Buf points at mParser_ScopeSpool 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
|
||||
|
||||
// blob spools allocated in mParser_Heap
|
||||
morkSpool mParser_ScopeSpool; // place to accumulate ID scope blobs
|
||||
morkSpool mParser_ValueSpool; // place to accumulate value blobs
|
||||
morkSpool mParser_ColumnSpool; // place to accumulate column blobs
|
||||
morkSpool mParser_StringSpool; // place to accumulate string blobs
|
||||
|
||||
morkSpoolSink mParser_ScopeSink; // writes to mParser_ScopeSpool
|
||||
morkSpoolSink mParser_ValueSink; // writes to mParser_ValueSpool
|
||||
morkSpoolSink mParser_ColumnSink; // writes to mParser_ColumnSpool
|
||||
morkSpoolSink mParser_StringSink; // writes to mParser_StringSpool
|
||||
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_AliasYarn; // place to receive from AliasToYarn()
|
||||
morkYarn mParser_MidYarn; // place to receive from MidToYarn()
|
||||
|
||||
// span showing current ongoing file position status:
|
||||
morkSpan mParser_PortSpan; // span of current db port file
|
||||
|
@ -274,8 +305,8 @@ private: // convenience inlines
|
|||
void SetHerePos(mork_pos inPos)
|
||||
{ mParser_PortSpan.mSpan_End.mPlace_Pos = inPos; }
|
||||
|
||||
void AddLine()
|
||||
{ ++ mParser_PortSpan.mSpan_End.mPlace_Line; }
|
||||
void CountLineBreak()
|
||||
{ ++mParser_PortSpan.mSpan_End.mPlace_Line; }
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
|
@ -300,8 +331,13 @@ public: // dynamic type identification
|
|||
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
public: // typing
|
||||
void NonParserTypeError(morkEnv* ev);
|
||||
public: // errors and warnings
|
||||
static void UnexpectedEofError(morkEnv* ev);
|
||||
static void EofInsteadOfHexError(morkEnv* ev);
|
||||
static void ExpectedEqualError(morkEnv* ev);
|
||||
static void ExpectedHexDigitError(morkEnv* ev, int c);
|
||||
static void NonParserTypeError(morkEnv* ev);
|
||||
static void UnexpectedByteInMetaWarning(morkEnv* ev);
|
||||
|
||||
public: // other type methods
|
||||
mork_bool GoodParserTag() const { return mParser_Tag == morkParser_kTag; }
|
||||
|
@ -312,8 +348,8 @@ public: // other type methods
|
|||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
public: // in virtual morkParser methods, data flow subclass to parser
|
||||
|
||||
virtual void AliasToYarn(morkEnv* ev,
|
||||
const morkAlias& inAlias, // typically an alias to concat with strings
|
||||
virtual void MidToYarn(morkEnv* ev,
|
||||
const morkMid& inMid, // typically an alias to concat with strings
|
||||
mdbYarn* outYarn) = 0;
|
||||
// The parser might ask that some aliases be turned into yarns, so they
|
||||
// can be concatenated into longer blobs under some circumstances. This
|
||||
|
@ -350,7 +386,7 @@ public: // out virtual morkParser methods, data flow parser to subclass
|
|||
// mp:RowItem ::= mp:Cell | mp:Meta | OnRowGlitch
|
||||
// mp:Cell ::= OnNewCell mp:CellItem? OnCellEnd
|
||||
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
|
||||
// mp:Slot ::= OnValue | OnValueAlias | OnRowAlias | OnTableAlias
|
||||
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
|
||||
|
||||
|
||||
// Note that in interfaces below, mork_change parameters kAdd and kNil
|
||||
|
@ -367,12 +403,12 @@ public: // out virtual morkParser methods, data flow parser to subclass
|
|||
virtual void OnGroupAbortEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
|
||||
virtual void OnNewPortRow(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange) = 0;
|
||||
const morkMid& inMid, mork_change inChange) = 0;
|
||||
virtual void OnPortRowGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0;
|
||||
virtual void OnPortRowEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
|
||||
virtual void OnNewTable(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange) = 0;
|
||||
const morkMid& inMid, mork_change inChange) = 0;
|
||||
virtual void OnTableGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0;
|
||||
virtual void OnTableEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
|
||||
|
@ -381,7 +417,7 @@ public: // out virtual morkParser methods, data flow parser to subclass
|
|||
virtual void OnMetaEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
|
||||
virtual void OnNewRow(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange) = 0;
|
||||
const morkMid& inMid, mork_change inChange) = 0;
|
||||
virtual void OnRowGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0;
|
||||
virtual void OnRowEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
|
||||
|
@ -390,12 +426,16 @@ public: // out virtual morkParser methods, data flow parser to subclass
|
|||
virtual void OnDictEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
|
||||
virtual void OnAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias) = 0;
|
||||
const morkMid& inMid) = 0;
|
||||
|
||||
virtual void OnAliasGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0;
|
||||
|
||||
virtual void OnNewCell(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange) = 0;
|
||||
const morkMid* inMid, const morkBuf* inBuf, mork_change inChange) = 0;
|
||||
// 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) = 0;
|
||||
virtual void OnCellForm(morkEnv* ev, mork_cscode inCharsetFormat) = 0;
|
||||
virtual void OnCellEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
|
@ -403,29 +443,54 @@ public: // out virtual morkParser methods, data flow parser to subclass
|
|||
virtual void OnValue(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkBuf& inBuf) = 0;
|
||||
|
||||
virtual void OnValueAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias) = 0;
|
||||
virtual void OnValueMid(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkMid& inMid) = 0;
|
||||
|
||||
virtual void OnRowAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias) = 0;
|
||||
virtual void OnRowMid(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkMid& inMid) = 0;
|
||||
|
||||
virtual void OnTableAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias) = 0;
|
||||
virtual void OnTableMid(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkMid& inMid) = 0;
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
protected: // protected parser helper methods
|
||||
|
||||
void ParseLoop(morkEnv* ev); // find parse continuation and resume
|
||||
|
||||
void StartParse(morkEnv* ev); // prepare for parsing
|
||||
void StopParse(morkEnv* ev); // terminate parsing & call needed methods
|
||||
void ParseLoop(morkEnv* ev); // find parse continuation and resume
|
||||
|
||||
void StartParse(morkEnv* ev); // prepare for parsing
|
||||
void StopParse(morkEnv* ev); // terminate parsing & call needed methods
|
||||
|
||||
int NextChar(morkEnv* ev); // next non-white content
|
||||
|
||||
void OnCellState(morkEnv* ev);
|
||||
void OnMetaState(morkEnv* ev);
|
||||
void OnRowState(morkEnv* ev);
|
||||
void OnTableState(morkEnv* ev);
|
||||
void OnDictState(morkEnv* ev);
|
||||
void OnPortState(morkEnv* ev);
|
||||
void OnStartState(morkEnv* ev);
|
||||
|
||||
int NextChar(morkEnv* ev); // next non-white content
|
||||
void ReadCell(morkEnv* ev);
|
||||
void ReadRow(morkEnv* ev, int c);
|
||||
void ReadTable(morkEnv* ev);
|
||||
void ReadTableMeta(morkEnv* ev);
|
||||
void ReadDict(morkEnv* ev);
|
||||
void ReadMeta(morkEnv* ev, int inEndMeta);
|
||||
void ReadAlias(morkEnv* ev);
|
||||
mork_id ReadHex(morkEnv* ev, int* outNextChar);
|
||||
morkBuf* ReadValue(morkEnv* ev);
|
||||
morkBuf* ReadName(morkEnv* ev, int c);
|
||||
mork_bool ReadMid(morkEnv* ev, morkMid* outMid);
|
||||
|
||||
void EndSpanOnThisByte(morkEnv* ev, morkSpan* ioSpan);
|
||||
void StartSpanOnLastByte(morkEnv* ev, morkSpan* ioSpan);
|
||||
|
||||
int eat_line_break(morkEnv* ev, int inLast);
|
||||
int eat_line_continue(morkEnv* ev); // last char was '\\'
|
||||
int eat_comment(morkEnv* ev); // last char was '/'
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
public: // public non-poly morkParser methods
|
||||
|
||||
void SetParserStream(morkEnv* ev, morkStream* ioStream);
|
||||
|
||||
mdb_count ParseMore( // return count of bytes consumed now
|
||||
morkEnv* ev, // context
|
||||
|
|
|
@ -199,6 +199,121 @@ morkRow::AcquireCellHandle(morkEnv* ev, morkCell* ioCell,
|
|||
return (nsIMdbCell*) 0;
|
||||
}
|
||||
|
||||
mork_count
|
||||
morkRow::CountOverlap(morkEnv* ev, morkCell* ioVector, mork_fill inFill)
|
||||
// Count cells in ioVector that change existing cells in this row when
|
||||
// ioVector is added to the row (as in TakeCells()). This is the set
|
||||
// of cells with the same columns in ioVector and mRow_Cells, which do
|
||||
// not have exactly the same value in mCell_Atom, and which do not both
|
||||
// have change status equal to morkChange_kCut (because cutting a cut
|
||||
// cell still yields a cell that has been cut). CountOverlap() also
|
||||
// modifies the change attribute of any cell in ioVector to kDup when
|
||||
// the change was previously kCut and the same column cell was found
|
||||
// in this row with change also equal to kCut; this tells callers later
|
||||
// they need not look for that cell in the row again on a second pass.
|
||||
{
|
||||
mork_count outCount = 0;
|
||||
mork_pos pos = 0; // needed by GetCell()
|
||||
morkCell* cells = ioVector;
|
||||
morkCell* end = cells + inFill;
|
||||
--cells; // prepare for preincrement
|
||||
while ( ++cells < end && ev->Good() )
|
||||
{
|
||||
mork_column col = cells->GetColumn();
|
||||
|
||||
morkCell* old = this->GetCell(ev, col, &pos);
|
||||
if ( old ) // same column?
|
||||
{
|
||||
mork_change newChg = cells->GetChange();
|
||||
mork_change oldChg = old->GetChange();
|
||||
if ( newChg != morkChange_kCut || oldChg != newChg ) // not cut+cut?
|
||||
{
|
||||
if ( cells->mCell_Atom != old->mCell_Atom ) // not same atom?
|
||||
++outCount; // cells will replace old significantly when added
|
||||
}
|
||||
else
|
||||
cells->SetColumnAndChange(col, morkChange_kDup); // note dup status
|
||||
}
|
||||
}
|
||||
return outCount;
|
||||
}
|
||||
|
||||
void
|
||||
morkRow::MergeCells(morkEnv* ev, morkCell* ioVector,
|
||||
mork_fill inVecLength, mork_fill inOldRowFill, mork_fill inOverlap)
|
||||
// MergeCells() is the part of TakeCells() that does the insertion.
|
||||
// inOldRowFill is the old value of mRow_Length, and inOverlap is the
|
||||
// number of cells in the intersection that must be updated.
|
||||
{
|
||||
morkCell* newCells = mRow_Cells + inOldRowFill; // 1st new cell in row
|
||||
morkCell* newEnd = newCells + mRow_Length; // one past last cell
|
||||
|
||||
morkCell* srcCells = ioVector;
|
||||
morkCell* srcEnd = srcCells + inVecLength;
|
||||
|
||||
--srcCells; // prepare for preincrement
|
||||
while ( ++srcCells < srcEnd && ev->Good() )
|
||||
{
|
||||
mork_change srcChg = srcCells->GetChange();
|
||||
if ( srcChg != morkChange_kDup ) // anything to be done?
|
||||
{
|
||||
morkCell* dstCell = 0;
|
||||
if ( inOverlap )
|
||||
{
|
||||
mork_pos pos = 0; // needed by GetCell()
|
||||
dstCell = this->GetCell(ev, srcCells->GetColumn(), &pos);
|
||||
}
|
||||
if ( dstCell )
|
||||
{
|
||||
--inOverlap; // one fewer intersections to resolve
|
||||
// swap the atoms in the cells to avoid ref counting here:
|
||||
morkAtom* dstAtom = dstCell->mCell_Atom;
|
||||
*dstCell = *srcCells; // bitwise copy, taking src atom
|
||||
srcCells->mCell_Atom = dstAtom; // forget cell ref, if any
|
||||
}
|
||||
else if ( newCells < newEnd ) // another new cell exists?
|
||||
{
|
||||
dstCell = newCells++; // alloc another new cell
|
||||
// take atom from source cell, transferring ref to this row:
|
||||
*dstCell = *srcCells; // bitwise copy, taking src atom
|
||||
srcCells->mCell_Atom = 0; // forget cell ref, if any
|
||||
}
|
||||
else // oops, we ran out...
|
||||
ev->NewError("out of new cells");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
morkRow::TakeCells(morkEnv* ev, morkCell* ioVector, mork_fill inVecLength,
|
||||
morkStore* ioStore)
|
||||
{
|
||||
if ( ioVector && inVecLength && ev->Good() )
|
||||
{
|
||||
++mRow_Seed; // intend to change structure of mRow_Cells
|
||||
mork_pos length = (mork_pos) mRow_Length;
|
||||
|
||||
mork_count overlap = this->CountOverlap(ev, ioVector, inVecLength);
|
||||
|
||||
mork_size growth = inVecLength - overlap; // cells to add
|
||||
mork_size newLength = length + growth;
|
||||
|
||||
if ( growth && ev->Good() ) // need to add any cells?
|
||||
{
|
||||
morkPool* pool = ioStore->StorePool();
|
||||
if ( !pool->AddRowCells(ev, this, length + growth) )
|
||||
ev->NewError("cannot take cells");
|
||||
}
|
||||
if ( ev->Good() )
|
||||
{
|
||||
if ( mRow_Length >= newLength )
|
||||
this->MergeCells(ev, ioVector, inVecLength, length, overlap);
|
||||
else
|
||||
ev->NewError("not enough new cells");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
morkCell*
|
||||
morkRow::NewCell(morkEnv* ev, mdb_column inColumn,
|
||||
mork_pos* outPos, morkStore* ioStore)
|
||||
|
@ -284,8 +399,7 @@ void
|
|||
morkRow::OnZeroTableUse(morkEnv* ev)
|
||||
// OnZeroTableUse() is called when CutTableUse() returns zero.
|
||||
{
|
||||
// OK, this is a P1 showstopper bug, so I'll comment it out.
|
||||
// ev->NewWarning("need to implement OnZeroTableUse");
|
||||
// ev->NewWarning("need to implement OnZeroTableUse");
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -74,6 +74,27 @@ public: // other row methods
|
|||
|
||||
public: // internal row methods
|
||||
|
||||
mork_count CountOverlap(morkEnv* ev, morkCell* ioVector, mork_fill inFill);
|
||||
// Count cells in ioVector that change existing cells in this row when
|
||||
// ioVector is added to the row (as in TakeCells()). This is the set
|
||||
// of cells with the same columns in ioVector and mRow_Cells, which do
|
||||
// not have exactly the same value in mCell_Atom, and which do not both
|
||||
// have change status equal to morkChange_kCut (because cutting a cut
|
||||
// cell still yields a cell that has been cut). CountOverlap() also
|
||||
// modifies the change attribute of any cell in ioVector to kDup when
|
||||
// the change was previously kCut and the same column cell was found
|
||||
// in this row with change also equal to kCut; this tells callers later
|
||||
// they need not look for that cell in the row again on a second pass.
|
||||
|
||||
void MergeCells(morkEnv* ev, morkCell* ioVector,
|
||||
mork_fill inVecLength, mork_fill inOldRowFill, mork_fill inOverlap);
|
||||
// MergeCells() is the part of TakeCells() that does the insertion.
|
||||
// inOldRowFill is the old value of mRow_Length, and inOverlap is the
|
||||
// number of cells in the intersection that must be updated.
|
||||
|
||||
void TakeCells(morkEnv* ev, morkCell* ioVector, mork_fill inVecLength,
|
||||
morkStore* ioStore);
|
||||
|
||||
morkCell* NewCell(morkEnv* ev, mdb_column inColumn, mork_pos* outPos,
|
||||
morkStore* ioStore);
|
||||
morkCell* GetCell(morkEnv* ev, mdb_column inColumn, mork_pos* outPos) const;
|
||||
|
|
|
@ -230,6 +230,37 @@ morkRowSpace::FindTableByKind(morkEnv* ev, mork_kind inTableKind)
|
|||
return (morkTable*) 0;
|
||||
}
|
||||
|
||||
morkTable*
|
||||
morkRowSpace::NewTableWithTid(morkEnv* ev, mork_tid inTid,
|
||||
mork_kind inTableKind)
|
||||
{
|
||||
morkTable* outTable = 0;
|
||||
|
||||
if ( inTableKind )
|
||||
{
|
||||
mdb_bool mustBeUnique = morkBool_kFalse;
|
||||
nsIMdbHeap* heap = mSpace_Store->mPort_Heap;
|
||||
morkTable* table = new(*heap, ev)
|
||||
morkTable(ev, morkUsage::kHeap, heap, mSpace_Store, heap, this,
|
||||
inTid, inTableKind, mustBeUnique);
|
||||
if ( table )
|
||||
{
|
||||
if ( mRowSpace_Tables.AddTable(ev, table) )
|
||||
{
|
||||
outTable = table;
|
||||
if ( mRowSpace_NextTableId <= inTid )
|
||||
mRowSpace_NextTableId = inTid + 1;
|
||||
}
|
||||
else
|
||||
table->CutStrongRef(ev);
|
||||
}
|
||||
}
|
||||
else
|
||||
this->ZeroKindError(ev);
|
||||
|
||||
return outTable;
|
||||
}
|
||||
|
||||
morkTable*
|
||||
morkRowSpace::NewTable(morkEnv* ev, mork_kind inTableKind,
|
||||
mdb_bool inMustBeUnique)
|
||||
|
@ -328,7 +359,12 @@ morkRowSpace::NewRowWithOid(morkEnv* ev, const mdbOid* inOid)
|
|||
row->InitRow(ev, inOid, this, /*length*/ 0, pool);
|
||||
|
||||
if ( ev->Good() && mRowSpace_Rows.AddRow(ev, row) )
|
||||
{
|
||||
outRow = row;
|
||||
mork_rid rid = inOid->mOid_Id;
|
||||
if ( mRowSpace_NextRowId <= rid )
|
||||
mRowSpace_NextRowId = rid + 1;
|
||||
}
|
||||
else
|
||||
pool->ZapRow(ev, row);
|
||||
}
|
||||
|
|
|
@ -115,6 +115,9 @@ public: // other space methods
|
|||
morkTable* NewTable(morkEnv* ev, mork_kind inTableKind,
|
||||
mdb_bool inMustBeUnique);
|
||||
|
||||
morkTable* NewTableWithTid(morkEnv* ev, mork_tid inTid,
|
||||
mork_kind inTableKind);
|
||||
|
||||
morkTable* FindTableByKind(morkEnv* ev, mork_kind inTableKind);
|
||||
morkTable* FindTableByTid(morkEnv* ev, mork_tid inTid)
|
||||
{ return mRowSpace_Tables.GetTable(ev, inTid); }
|
||||
|
|
|
@ -32,6 +32,10 @@
|
|||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKBLOB_
|
||||
#include "morkBlob.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
/*virtual*/ morkSink::~morkSink()
|
||||
|
@ -41,41 +45,134 @@
|
|||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkSpoolSink::FlushSink(morkEnv* ev) // probably does nothing
|
||||
morkSpool::FlushSink(morkEnv* ev) // sync mSpool_Coil->mBuf_Fill
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
morkCoil* coil = mSpool_Coil;
|
||||
if ( coil )
|
||||
{
|
||||
mork_u1* body = (mork_u1*) coil->mBuf_Body;
|
||||
if ( body )
|
||||
{
|
||||
mork_u1* at = mSink_At;
|
||||
mork_u1* end = mSink_End;
|
||||
if ( at >= body && at <= end ) // expected cursor order?
|
||||
{
|
||||
mork_fill fill = at - body; // current content size
|
||||
if ( fill <= coil->mBlob_Size )
|
||||
coil->mBuf_Fill = fill;
|
||||
else
|
||||
{
|
||||
coil->BlobFillOverSizeError(ev);
|
||||
coil->mBuf_Fill = coil->mBlob_Size; // make it safe
|
||||
}
|
||||
}
|
||||
else
|
||||
this->BadSpoolCursorOrderError(ev);
|
||||
}
|
||||
else
|
||||
coil->NilBufBodyError(ev);
|
||||
}
|
||||
else
|
||||
this->NilSpoolCoilError(ev);
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkSpoolSink::SpillPutc(morkEnv* ev, int c) // grow spool and write byte
|
||||
morkSpool::SpillPutc(morkEnv* ev, int c) // grow coil and write byte
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
morkCoil* coil = mSpool_Coil;
|
||||
if ( coil )
|
||||
{
|
||||
mork_u1* body = (mork_u1*) coil->mBuf_Body;
|
||||
if ( body )
|
||||
{
|
||||
mork_u1* at = mSink_At;
|
||||
mork_u1* end = mSink_End;
|
||||
if ( at >= body && at <= end ) // expected cursor order?
|
||||
{
|
||||
mork_size size = coil->mBlob_Size;
|
||||
mork_fill fill = at - body; // current content size
|
||||
if ( fill <= size ) // less content than medium size?
|
||||
{
|
||||
coil->mBuf_Fill = fill;
|
||||
if ( at >= end ) // need to grow the coil?
|
||||
{
|
||||
if ( size > 2048 ) // grow slower over 2K?
|
||||
size += 512;
|
||||
else
|
||||
{
|
||||
mork_size growth = ( size * 4 ) / 3; // grow by 33%
|
||||
if ( growth < 64 ) // grow faster under (64 * 3)?
|
||||
growth = 64;
|
||||
size += growth;
|
||||
}
|
||||
if ( coil->GrowCoil(ev, size) ) // made coil bigger?
|
||||
{
|
||||
body = (mork_u1*) coil->mBuf_Body;
|
||||
if ( body ) // have a coil body?
|
||||
{
|
||||
mSink_At = at = body + fill;
|
||||
mSink_End = end = body + coil->mBlob_Size;
|
||||
}
|
||||
else
|
||||
coil->NilBufBodyError(ev);
|
||||
}
|
||||
}
|
||||
if ( ev->Good() ) // seem ready to write byte c?
|
||||
{
|
||||
if ( at < end ) // morkSink::Putc() would succeed?
|
||||
{
|
||||
*at++ = c;
|
||||
mSink_At = at;
|
||||
coil->mBuf_Fill = fill + 1;
|
||||
}
|
||||
else
|
||||
this->BadSpoolCursorOrderError(ev);
|
||||
}
|
||||
}
|
||||
else // fill exceeds size
|
||||
{
|
||||
coil->BlobFillOverSizeError(ev);
|
||||
coil->mBuf_Fill = coil->mBlob_Size; // make it safe
|
||||
}
|
||||
}
|
||||
else
|
||||
this->BadSpoolCursorOrderError(ev);
|
||||
}
|
||||
else
|
||||
coil->NilBufBodyError(ev);
|
||||
}
|
||||
else
|
||||
this->NilSpoolCoilError(ev);
|
||||
}
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
// public: // public non-poly morkSink methods
|
||||
|
||||
/*virtual*/
|
||||
morkSpoolSink::~morkSpoolSink()
|
||||
morkSpool::~morkSpool()
|
||||
// Zero all slots to show this sink is disabled, but destroy no memory.
|
||||
// Note it is typically unnecessary to flush this spool sink, since all
|
||||
// content is written directly to the spool without any buffering.
|
||||
// Note it is typically unnecessary to flush this coil sink, since all
|
||||
// content is written directly to the coil without any buffering.
|
||||
{
|
||||
mSink_At = 0;
|
||||
mSink_End = 0;
|
||||
mSpool_Coil = 0;
|
||||
}
|
||||
|
||||
morkSpoolSink::morkSpoolSink(morkEnv* ev, morkSpool* ioSpool)
|
||||
// After installing the spool, calls Seek(ev, 0) to prepare for writing.
|
||||
morkSpool::morkSpool(morkEnv* ev, morkCoil* ioCoil)
|
||||
// After installing the coil, calls Seek(ev, 0) to prepare for writing.
|
||||
: morkSink()
|
||||
, mSpoolSink_Spool( 0 )
|
||||
, mSpool_Coil( 0 )
|
||||
{
|
||||
mSink_At = 0; // set correctly later in Seek()
|
||||
mSink_End = 0; // set correctly later in Seek()
|
||||
|
||||
if ( ev->Good() )
|
||||
{
|
||||
if ( ioSpool )
|
||||
if ( ioCoil )
|
||||
{
|
||||
// ev->StubMethodOnlyError();
|
||||
mSink_At = 0;
|
||||
mSink_End = 0;
|
||||
mSpoolSink_Spool = ioSpool;
|
||||
mSpool_Coil = ioCoil;
|
||||
this->Seek(ev, /*pos*/ 0);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
|
@ -84,29 +181,124 @@ morkSpoolSink::morkSpoolSink(morkEnv* ev, morkSpool* ioSpool)
|
|||
|
||||
// ----- All boolean return values below are equal to ev->Good(): -----
|
||||
|
||||
mork_bool
|
||||
morkSpoolSink::Seek(morkEnv* ev, mork_pos inPos)
|
||||
// Changed the current write position in spool's buffer to inPos.
|
||||
// For example, to start writing the spool from scratch, use inPos==0.
|
||||
/*static*/ void
|
||||
morkSpool::BadSpoolCursorOrderError(morkEnv* ev)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
ev->NewError("bad morkSpool cursor order");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkSpool::NilSpoolCoilError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("nil mSpool_Coil");
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkSpool::Seek(morkEnv* ev, mork_pos inPos)
|
||||
// Changed the current write position in coil's buffer to inPos.
|
||||
// For example, to start writing the coil from scratch, use inPos==0.
|
||||
{
|
||||
morkCoil* coil = mSpool_Coil;
|
||||
if ( coil )
|
||||
{
|
||||
mork_size minSize = inPos + 64;
|
||||
|
||||
if ( coil->mBlob_Size < minSize )
|
||||
coil->GrowCoil(ev, minSize);
|
||||
|
||||
if ( ev->Good() )
|
||||
{
|
||||
coil->mBuf_Fill = inPos;
|
||||
mork_u1* body = (mork_u1*) coil->mBuf_Body;
|
||||
if ( body )
|
||||
{
|
||||
mSink_At = body + inPos;
|
||||
mSink_End = body + coil->mBlob_Size;
|
||||
}
|
||||
else
|
||||
coil->NilBufBodyError(ev);
|
||||
}
|
||||
}
|
||||
else
|
||||
this->NilSpoolCoilError(ev);
|
||||
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkSpoolSink::Write(morkEnv* ev, const void* inBuf, mork_size inSize)
|
||||
// write inSize bytes of inBuf to current position inside spool's buffer
|
||||
morkSpool::Write(morkEnv* ev, const void* inBuf, mork_size inSize)
|
||||
// write inSize bytes of inBuf to current position inside coil's buffer
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// This method is conceptually very similar to morkStream::Write(),
|
||||
// and this code was written while looking at that method for clues.
|
||||
|
||||
morkCoil* coil = mSpool_Coil;
|
||||
if ( coil )
|
||||
{
|
||||
mork_u1* body = (mork_u1*) coil->mBuf_Body;
|
||||
if ( body )
|
||||
{
|
||||
if ( inBuf && inSize ) // anything to write?
|
||||
{
|
||||
mork_u1* at = mSink_At;
|
||||
mork_u1* end = mSink_End;
|
||||
if ( at >= body && at <= end ) // expected cursor order?
|
||||
{
|
||||
// note coil->mBuf_Fill can be stale after morkSink::Putc():
|
||||
mork_pos fill = at - body; // current content size
|
||||
mork_num space = end - at; // space left in body
|
||||
if ( space < inSize ) // not enough to hold write?
|
||||
{
|
||||
mork_size minGrowth = space + 16;
|
||||
mork_size minSize = coil->mBlob_Size + minGrowth;
|
||||
if ( coil->GrowCoil(ev, minSize) )
|
||||
{
|
||||
body = (mork_u1*) coil->mBuf_Body;
|
||||
if ( body )
|
||||
{
|
||||
mSink_At = at = body + fill;
|
||||
mSink_End = end = body + coil->mBlob_Size;
|
||||
space = end - at; // space left in body
|
||||
}
|
||||
else
|
||||
coil->NilBufBodyError(ev);
|
||||
}
|
||||
}
|
||||
if ( ev->Good() )
|
||||
{
|
||||
if ( space >= inSize ) // enough room to hold write?
|
||||
{
|
||||
MORK_MEMCPY(at, inBuf, inSize); // into body
|
||||
mSink_At = at + inSize; // advance past written bytes
|
||||
coil->mBuf_Fill = fill + inSize; // "flush" to fix fill
|
||||
}
|
||||
else
|
||||
ev->NewError("insufficient morkSpool space");
|
||||
}
|
||||
}
|
||||
else
|
||||
this->BadSpoolCursorOrderError(ev);
|
||||
}
|
||||
}
|
||||
else
|
||||
coil->NilBufBodyError(ev);
|
||||
}
|
||||
else
|
||||
this->NilSpoolCoilError(ev);
|
||||
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkSpoolSink::PutString(morkEnv* ev, const char* inString)
|
||||
morkSpool::PutString(morkEnv* ev, const char* inString)
|
||||
// call Write() with inBuf=inString and inSize=strlen(inString),
|
||||
// unless inString is null, in which case we then do nothing at all.
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
if ( inString )
|
||||
{
|
||||
mork_size size = MORK_STRLEN(inString);
|
||||
this->Write(ev, inString, size);
|
||||
}
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,169 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MORKSINK_
|
||||
#define _MORKSINK_ 1
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKBLOB_
|
||||
#include "morkBlob.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
/*| morkSink is intended to be a very cheap buffered i/o sink which
|
||||
**| writes to bufs and other strings a single byte at a time. The
|
||||
**| basic idea is that writing a single byte has a very cheap average
|
||||
**| cost, because a polymophic function call need only occur when the
|
||||
**| space between At and End is exhausted. The rest of the time a
|
||||
**| very cheap inline method will write a byte, and then bump a pointer.
|
||||
**|
|
||||
**|| At: the current position in some sequence of bytes at which to
|
||||
**| write the next byte put into the sink. Presumably At points into
|
||||
**| the private storage of some space which is not yet filled (except
|
||||
**| when At reaches End, and the overflow must then spill). Note both
|
||||
**| At and End are zeroed in the destructor to help show that a sink
|
||||
**| is no longer usable; this is safe because At==End causes the case
|
||||
**| where SpillPutc() is called to handled an exhausted buffer space.
|
||||
**|
|
||||
**|| End: an address one byte past the last byte which can be written
|
||||
**| without needing to make a buffer larger than previously. When At
|
||||
**| and End are equal, this means there is no space to write a byte,
|
||||
**| and that some underlying buffer space must be grown before another
|
||||
**| byte can be written. Note At must always be less than or equal to
|
||||
**| End, and otherwise an important invariant has failed severely.
|
||||
**|
|
||||
**|| Buf: this original class slot has been commented out in the new
|
||||
**| and more abstract version of this sink class, but the general idea
|
||||
**| behind this slot should be explained to help design subclasses.
|
||||
**| Each subclass should provide space into which At and End can point,
|
||||
**| where End is beyond the last writable byte, and At is less than or
|
||||
**| equal to this point inside the same buffer. With some kinds of
|
||||
**| medium, such as writing to an instance of morkBlob, it is feasible
|
||||
**| to point directly into the final resting place for all the content
|
||||
**| written to the medium. Other mediums such as files, which write
|
||||
**| only through function calls, will typically need a local buffer
|
||||
**| to efficiently accumulate many bytes between such function calls.
|
||||
**|
|
||||
**|| FlushSink: this flush method should move any buffered content to
|
||||
**| it's final destination. For example, for buffered writes to a
|
||||
**| string medium, where string methods are function calls and not just
|
||||
**| inline macros, it is faster to accumulate many bytes in a small
|
||||
**| local buffer and then move these en masse later in a single call.
|
||||
**|
|
||||
**|| SpillPutc: when At is greater than or equal to End, this means an
|
||||
**| underlying buffer has become full, so the buffer must be flushed
|
||||
**| before a new byte can be written. The intention is that SpillPutc()
|
||||
**| will be equivalent to calling FlushSink() followed by another call
|
||||
**| to Putc(), where the flush is expected to make At less then End once
|
||||
**| again. Except that FlushSink() need not make the underlying buffer
|
||||
**| any larger, and SpillPutc() typically must make room for more bytes.
|
||||
**| Note subclasses might want to guard against the case that both At
|
||||
**| and End are null, which happens when a sink is destroyed, which sets
|
||||
**| both these pointers to null as an indication the sink is disabled.
|
||||
|*/
|
||||
class morkSink {
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
public: // public sink virtual methods
|
||||
|
||||
virtual void FlushSink(morkEnv* ev) = 0;
|
||||
virtual void SpillPutc(morkEnv* ev, int c) = 0;
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
public: // member variables
|
||||
|
||||
mork_u1* mSink_At; // pointer into mSink_Buf
|
||||
mork_u1* mSink_End; // one byte past last content byte
|
||||
|
||||
// define morkSink_kBufSize 256 /* small enough to go on stack */
|
||||
|
||||
// mork_u1 mSink_Buf[ morkSink_kBufSize + 4 ];
|
||||
// want plus one for any needed end null byte; use plus 4 for alignment
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
public: // public non-poly morkSink methods
|
||||
|
||||
virtual ~morkSink(); // zero both At and End; virtual for subclasses
|
||||
morkSink() { } // does nothing; subclasses must set At and End suitably
|
||||
|
||||
void Putc(morkEnv* ev, int c)
|
||||
{
|
||||
if ( mSink_At < mSink_End )
|
||||
*mSink_At++ = (mork_u1) c;
|
||||
else
|
||||
this->SpillPutc(ev, c);
|
||||
}
|
||||
};
|
||||
|
||||
/*| morkSpoolSink: an output sink that efficiently writes individual bytes
|
||||
**| or entire byte sequences to a spool instance, which grows as needed by
|
||||
**| using the heap instance in the spool to grow the internal buffer.
|
||||
**|
|
||||
**|| Note we do not "own" the spool referenced by mSpoolSink_Spool, and
|
||||
**| the lifetime of the spool is expected to equal or exceed that of this
|
||||
**| sink by some external means. Typical usage might involve keeping an
|
||||
**| instance of morkSpool and an instance of morkSpoolSink in the same
|
||||
**| owning parent object, which uses the sink with the associated spool.
|
||||
|*/
|
||||
class morkSpoolSink : public morkSink { // for buffered i/o to a morkSpool
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
public: // public sink virtual methods
|
||||
|
||||
virtual void FlushSink(morkEnv* ev); // probably does nothing
|
||||
virtual void SpillPutc(morkEnv* ev, int c); // grow spool and write byte
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
public: // member variables
|
||||
morkSpool* mSpoolSink_Spool; // destination medium for written bytes
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
public: // public non-poly morkSink methods
|
||||
|
||||
virtual ~morkSpoolSink();
|
||||
// Zero all slots to show this sink is disabled, but destroy no memory.
|
||||
// Note it is typically unnecessary to flush this spool sink, since all
|
||||
// content is written directly to the spool without any buffering.
|
||||
|
||||
morkSpoolSink(morkEnv* ev, morkSpool* ioSpool);
|
||||
// After installing the spool, calls Seek(ev, 0) to prepare for writing.
|
||||
|
||||
// ----- All boolean return values below are equal to ev->Good(): -----
|
||||
|
||||
mork_bool Seek(morkEnv* ev, mork_pos inPos);
|
||||
// Changed the current write position in spool's buffer to inPos.
|
||||
// For example, to start writing the spool from scratch, use inPos==0.
|
||||
|
||||
mork_bool Write(morkEnv* ev, const void* inBuf, mork_size inSize);
|
||||
// write inSize bytes of inBuf to current position inside spool's buffer
|
||||
|
||||
mork_bool PutBuf(morkEnv* ev, const morkBuf& inBuffer)
|
||||
{ return this->Write(ev, inBuffer.mBuf_Body, inBuffer.mBuf_Fill); }
|
||||
|
||||
mork_bool PutString(morkEnv* ev, const char* inString);
|
||||
// call Write() with inBuf=inString and inSize=strlen(inString),
|
||||
// unless inString is null, in which case we then do nothing at all.
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKSINK_ */
|
|
@ -92,6 +92,10 @@
|
|||
#include "morkRowMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKPARSER_
|
||||
#include "morkParser.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
|
@ -212,6 +216,15 @@ morkStore::morkStore(morkEnv* ev, const morkUsage& inUsage,
|
|||
, mStore_OidAtomSpace( 0 )
|
||||
, mStore_GroundAtomSpace( 0 )
|
||||
, mStore_GroundColumnSpace( 0 )
|
||||
|
||||
, mStore_MorkNoneToken( 0 )
|
||||
, mStore_CharsetToken( 0 )
|
||||
, mStore_AtomScopeToken( 0 )
|
||||
, mStore_RowScopeToken( 0 )
|
||||
, mStore_TableScopeToken( 0 )
|
||||
, mStore_ColumnScopeToken( 0 )
|
||||
, mStore_TableKindToken( 0 )
|
||||
|
||||
, mStore_RowSpaces(ev, morkUsage::kMember, (nsIMdbHeap*) 0, ioPortHeap)
|
||||
, mStore_AtomSpaces(ev, morkUsage::kMember, (nsIMdbHeap*) 0, ioPortHeap)
|
||||
, mStore_Pool(ev, morkUsage::kMember, (nsIMdbHeap*) 0, ioPortHeap)
|
||||
|
@ -220,6 +233,9 @@ morkStore::morkStore(morkEnv* ev, const morkUsage& inUsage,
|
|||
{
|
||||
mNode_Derived = morkDerived_kStore;
|
||||
|
||||
if ( ev->Good() )
|
||||
mStore_MorkNoneToken = this->StringToToken(ev, "mork:none");
|
||||
|
||||
if ( ev->Good() )
|
||||
mStore_CharsetToken = this->StringToToken(ev, "charset");
|
||||
|
||||
|
@ -302,6 +318,28 @@ morkStore::AcquireStoreHandle(morkEnv* ev)
|
|||
}
|
||||
|
||||
|
||||
morkMaxBookAtom*
|
||||
morkStore::StageAliasAsBookAtom(morkEnv* ev, const morkMid* inMid,
|
||||
morkAtomSpace* ioSpace, mork_cscode inForm)
|
||||
{
|
||||
if ( inMid && inMid->mMid_Buf )
|
||||
{
|
||||
const morkBuf* buf = inMid->mMid_Buf;
|
||||
mork_size length = buf->mBuf_Fill;
|
||||
if ( length <= morkBookAtom_kMaxBodySize )
|
||||
{
|
||||
mork_aid dummyAid = 1;
|
||||
mStore_BookAtom.InitMaxBookAtom(ev, *buf,
|
||||
inForm, ioSpace, dummyAid);
|
||||
return &mStore_BookAtom;
|
||||
}
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
|
||||
return (morkMaxBookAtom*) 0;
|
||||
}
|
||||
|
||||
morkMaxBookAtom*
|
||||
morkStore::StageYarnAsBookAtom(morkEnv* ev, const mdbYarn* inYarn,
|
||||
morkAtomSpace* ioSpace)
|
||||
|
@ -436,6 +474,15 @@ morkStream* morkStore::LazyGetOutStream(morkEnv* ev)
|
|||
return mStore_OutStream;
|
||||
}
|
||||
|
||||
void
|
||||
morkStore::ForgetBuilder(morkEnv* ev)
|
||||
{
|
||||
if ( mStore_Builder )
|
||||
morkBuilder::SlotStrongBuilder((morkBuilder*) 0, ev, &mStore_Builder);
|
||||
if ( mStore_InStream )
|
||||
morkStream::SlotStrongStream((morkStream*) 0, ev, &mStore_InStream);
|
||||
}
|
||||
|
||||
morkBuilder* morkStore::LazyGetBuilder(morkEnv* ev)
|
||||
{
|
||||
if ( !mStore_Builder )
|
||||
|
@ -556,7 +603,7 @@ morkStore::CreateStoreFile(morkEnv* ev,
|
|||
}
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
|
||||
morkAtom*
|
||||
morkStore::YarnToAtom(morkEnv* ev, const mdbYarn* inYarn)
|
||||
{
|
||||
|
@ -586,10 +633,125 @@ morkStore::YarnToAtom(morkEnv* ev, const mdbYarn* inYarn)
|
|||
return outAtom;
|
||||
}
|
||||
|
||||
// mork_bool
|
||||
// morkStore::CutBookAtom(morkEnv* ev, morkBookAtom* ioAtom)
|
||||
// {
|
||||
// }
|
||||
mork_bool
|
||||
morkStore::MidToOid(morkEnv* ev, const morkMid& inMid, mdbOid* outOid)
|
||||
{
|
||||
*outOid = inMid.mMid_Oid;
|
||||
const morkBuf* buf = inMid.mMid_Buf;
|
||||
if ( buf && !outOid->mOid_Scope )
|
||||
{
|
||||
mdbOid oid = inMid.mMid_Oid;
|
||||
if ( buf->mBuf_Fill <= morkBookAtom_kMaxBodySize )
|
||||
{
|
||||
if ( buf->mBuf_Fill == 1 )
|
||||
{
|
||||
mork_u1* name = (mork_u1*) buf->mBuf_Body;
|
||||
if ( name )
|
||||
{
|
||||
outOid->mOid_Scope = (mork_scope) *name;
|
||||
return ev->Good();
|
||||
}
|
||||
}
|
||||
morkAtomSpace* groundSpace = this->LazyGetGroundColumnSpace(ev);
|
||||
if ( groundSpace )
|
||||
{
|
||||
mork_cscode form = 0; // default
|
||||
mork_aid aid = 1; // dummy
|
||||
mStore_BookAtom.InitMaxBookAtom(ev, *buf, form, groundSpace, aid);
|
||||
morkMaxBookAtom* keyAtom = &mStore_BookAtom;
|
||||
morkAtomBodyMap* map = &groundSpace->mAtomSpace_AtomBodies;
|
||||
morkBookAtom* bookAtom = map->GetAtom(ev, keyAtom);
|
||||
if ( bookAtom )
|
||||
outOid->mOid_Scope = bookAtom->mBookAtom_Id;
|
||||
else
|
||||
{
|
||||
bookAtom = groundSpace->MakeBookAtomCopy(ev, *keyAtom);
|
||||
if ( bookAtom )
|
||||
{
|
||||
outOid->mOid_Scope = bookAtom->mBookAtom_Id;
|
||||
bookAtom->MakeCellUseForever(ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
morkRow*
|
||||
morkStore::MidToRow(morkEnv* ev, const morkMid& inMid)
|
||||
{
|
||||
mdbOid tempOid;
|
||||
this->MidToOid(ev, inMid, &tempOid);
|
||||
return this->OidToRow(ev, &tempOid);
|
||||
}
|
||||
|
||||
morkTable*
|
||||
morkStore::MidToTable(morkEnv* ev, const morkMid& inMid)
|
||||
{
|
||||
mdbOid tempOid;
|
||||
this->MidToOid(ev, inMid, &tempOid);
|
||||
return this->OidToTable(ev, &tempOid);
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkStore::MidToYarn(morkEnv* ev, const morkMid& inMid, mdbYarn* outYarn)
|
||||
{
|
||||
mdbOid tempOid;
|
||||
this->MidToOid(ev, inMid, &tempOid);
|
||||
return this->OidToYarn(ev, tempOid, outYarn);
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkStore::OidToYarn(morkEnv* ev, const mdbOid& inOid, mdbYarn* outYarn)
|
||||
{
|
||||
morkBookAtom* atom = 0;
|
||||
|
||||
morkAtomSpace* atomSpace = mStore_AtomSpaces.GetAtomSpace(ev, inOid.mOid_Scope);
|
||||
if ( atomSpace )
|
||||
{
|
||||
morkAtomAidMap* map = &atomSpace->mAtomSpace_AtomAids;
|
||||
atom = map->GetAid(ev, (mork_aid) inOid.mOid_Id);
|
||||
}
|
||||
atom->GetYarn(outYarn); // note this is safe even when atom==nil
|
||||
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
morkBookAtom*
|
||||
morkStore::MidToAtom(morkEnv* ev, const morkMid& inMid)
|
||||
{
|
||||
morkBookAtom* outAtom = 0;
|
||||
mdbOid oid;
|
||||
if ( this->MidToOid(ev, inMid, &oid) )
|
||||
{
|
||||
morkAtomSpace* atomSpace = mStore_AtomSpaces.GetAtomSpace(ev, oid.mOid_Scope);
|
||||
if ( atomSpace )
|
||||
{
|
||||
morkAtomAidMap* map = &atomSpace->mAtomSpace_AtomAids;
|
||||
outAtom = map->GetAid(ev, (mork_aid) oid.mOid_Id);
|
||||
}
|
||||
}
|
||||
return outAtom;
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkStore::SmallTokenToOneByteYarn(morkEnv* ev, mdb_token inToken,
|
||||
mdbYarn* outYarn)
|
||||
{
|
||||
if ( outYarn->mYarn_Buf && outYarn->mYarn_Size ) // any space in yarn at all?
|
||||
{
|
||||
mork_u1* buf = (mork_u1*) outYarn->mYarn_Buf; // for byte arithmetic
|
||||
buf[ 0 ] = (mork_u1) inToken; // write the single byte
|
||||
outYarn->mYarn_Fill = 1;
|
||||
outYarn->mYarn_More = 0;
|
||||
}
|
||||
else // just record we could not write the single byte
|
||||
{
|
||||
outYarn->mYarn_More = 1;
|
||||
outYarn->mYarn_Fill = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
morkStore::TokenToString(morkEnv* ev, mdb_token inToken, mdbYarn* outTokenName)
|
||||
|
@ -604,23 +766,161 @@ morkStore::TokenToString(morkEnv* ev, mdb_token inToken, mdbYarn* outTokenName)
|
|||
atom->GetYarn(outTokenName); // note this is safe even when atom==nil
|
||||
}
|
||||
else // token is an "immediate" single byte string representation?
|
||||
this->SmallTokenToOneByteYarn(ev, inToken, outTokenName);
|
||||
}
|
||||
|
||||
void
|
||||
morkStore::SyncTokenIdChange(morkEnv* ev, const morkBookAtom* inAtom,
|
||||
const mdbOid* inOid)
|
||||
{
|
||||
// mork_token mStore_MorkNoneToken; // token for "mork:none" // fill=9
|
||||
// mork_column mStore_CharsetToken; // token for "charset" // fill=7
|
||||
// mork_column mStore_AtomScopeToken; // token for "atomScope" // fill=9
|
||||
// mork_column mStore_RowScopeToken; // token for "rowScope" // fill=8
|
||||
// mork_column mStore_TableScopeToken; // token for "tableScope" // fill=10
|
||||
// mork_column mStore_ColumnScopeToken; // token for "columnScope" // fill=11
|
||||
// mork_kind mStore_TableKindToken; // token for "tableKind" // fill=9
|
||||
// ---------------------ruler-for-token-length-above---123456789012
|
||||
|
||||
if ( inOid->mOid_Scope == morkStore_kColumnSpaceScope && inAtom->IsWeeBook() )
|
||||
{
|
||||
mdbYarn* y = outTokenName;
|
||||
if ( y->mYarn_Buf && y->mYarn_Size ) // any space in yarn at all?
|
||||
const mork_u1* body = ((const morkWeeBookAtom*) inAtom)->mWeeBookAtom_Body;
|
||||
mork_size size = inAtom->mAtom_Size;
|
||||
|
||||
if ( size >= 7 && size <= 11 )
|
||||
{
|
||||
mork_u1* buf = (mork_u1*) y->mYarn_Buf; // for byte arithmetic
|
||||
buf[ 0 ] = (mork_u1) inToken; // write the single byte
|
||||
y->mYarn_Fill = 1;
|
||||
y->mYarn_More = 0;
|
||||
}
|
||||
else // just record we could not write the single byte
|
||||
{
|
||||
y->mYarn_More = 1;
|
||||
y->mYarn_Fill = 0;
|
||||
if ( size == 9 )
|
||||
{
|
||||
if ( *body == 'm' )
|
||||
{
|
||||
if ( MORK_MEMCMP(body, "mork:none", 9) == 0 )
|
||||
mStore_MorkNoneToken = inAtom->mBookAtom_Id;
|
||||
}
|
||||
else if ( *body == 'a' )
|
||||
{
|
||||
if ( MORK_MEMCMP(body, "atomScope", 9) == 0 )
|
||||
mStore_AtomScopeToken = inAtom->mBookAtom_Id;
|
||||
}
|
||||
else if ( *body == 't' )
|
||||
{
|
||||
if ( MORK_MEMCMP(body, "tableKind", 9) == 0 )
|
||||
mStore_TableKindToken = inAtom->mBookAtom_Id;
|
||||
}
|
||||
}
|
||||
else if ( size == 7 && *body == 'c' )
|
||||
{
|
||||
if ( MORK_MEMCMP(body, "charset", 7) == 0 )
|
||||
mStore_CharsetToken = inAtom->mBookAtom_Id;
|
||||
}
|
||||
else if ( size == 8 && *body == 'r' )
|
||||
{
|
||||
if ( MORK_MEMCMP(body, "rowScope", 8) == 0 )
|
||||
mStore_RowScopeToken = inAtom->mBookAtom_Id;
|
||||
}
|
||||
else if ( size == 10 && *body == 't' )
|
||||
{
|
||||
if ( MORK_MEMCMP(body, "tableScope", 10) == 0 )
|
||||
mStore_TableScopeToken = inAtom->mBookAtom_Id;
|
||||
}
|
||||
else if ( size == 11 && *body == 'c' )
|
||||
{
|
||||
if ( MORK_MEMCMP(body, "columnScope", 11) == 0 )
|
||||
mStore_ColumnScopeToken = inAtom->mBookAtom_Id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
morkAtom*
|
||||
morkStore::AddAlias(morkEnv* ev, const morkMid& inMid, mork_cscode inForm)
|
||||
{
|
||||
morkBookAtom* outAtom = 0;
|
||||
if ( ev->Good() )
|
||||
{
|
||||
const mdbOid* oid = &inMid.mMid_Oid;
|
||||
morkAtomSpace* atomSpace = this->LazyGetAtomSpace(ev, oid->mOid_Scope);
|
||||
if ( atomSpace )
|
||||
{
|
||||
morkMaxBookAtom* keyAtom =
|
||||
this->StageAliasAsBookAtom(ev, &inMid, atomSpace, inForm);
|
||||
if ( keyAtom )
|
||||
{
|
||||
morkAtomAidMap* map = &atomSpace->mAtomSpace_AtomAids;
|
||||
outAtom = map->GetAid(ev, (mork_aid) oid->mOid_Id);
|
||||
if ( outAtom )
|
||||
{
|
||||
if ( !outAtom->EqualFormAndBody(ev, keyAtom) )
|
||||
ev->NewError("duplicate alias ID");
|
||||
}
|
||||
else
|
||||
{
|
||||
keyAtom->mBookAtom_Id = oid->mOid_Id;
|
||||
outAtom = atomSpace->MakeBookAtomCopyWithAid(ev,
|
||||
*keyAtom, (mork_aid) oid->mOid_Id);
|
||||
|
||||
if ( outAtom && outAtom->IsWeeBook() )
|
||||
{
|
||||
if ( oid->mOid_Scope == morkStore_kColumnSpaceScope )
|
||||
{
|
||||
mork_size size = outAtom->mAtom_Size;
|
||||
if ( size >= 7 && size <= 11 )
|
||||
this->SyncTokenIdChange(ev, outAtom, oid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return outAtom;
|
||||
}
|
||||
|
||||
mork_token
|
||||
morkStore::BufToToken(morkEnv* ev, const morkBuf* inBuf)
|
||||
{
|
||||
mork_token outToken = 0;
|
||||
if ( ev->Good() )
|
||||
{
|
||||
const mork_u1* s = (const mork_u1*) inBuf->mBuf_Body;
|
||||
mork_bool nonAscii = ( *s > 0x7F );
|
||||
mork_size length = inBuf->mBuf_Fill;
|
||||
if ( nonAscii || length > 1 ) // more than one byte?
|
||||
{
|
||||
mork_cscode form = 0; // default charset
|
||||
morkAtomSpace* space = this->LazyGetGroundColumnSpace(ev);
|
||||
if ( space )
|
||||
{
|
||||
morkMaxBookAtom* keyAtom = 0;
|
||||
if ( length <= morkBookAtom_kMaxBodySize )
|
||||
{
|
||||
mork_aid aid = 1; // dummy
|
||||
mStore_BookAtom.InitMaxBookAtom(ev, *inBuf, form, space, aid);
|
||||
keyAtom = &mStore_BookAtom;
|
||||
}
|
||||
if ( keyAtom )
|
||||
{
|
||||
morkAtomBodyMap* map = &space->mAtomSpace_AtomBodies;
|
||||
morkBookAtom* bookAtom = map->GetAtom(ev, keyAtom);
|
||||
if ( bookAtom )
|
||||
outToken = bookAtom->mBookAtom_Id;
|
||||
else
|
||||
{
|
||||
bookAtom = space->MakeBookAtomCopy(ev, *keyAtom);
|
||||
if ( bookAtom )
|
||||
{
|
||||
outToken = bookAtom->mBookAtom_Id;
|
||||
bookAtom->MakeCellUseForever(ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else // only a single byte in inTokenName string:
|
||||
outToken = *s;
|
||||
}
|
||||
|
||||
return outToken;
|
||||
}
|
||||
|
||||
mork_token
|
||||
morkStore::StringToToken(morkEnv* ev, const char* inTokenName)
|
||||
{
|
||||
|
@ -702,6 +1002,8 @@ morkStore::HasTableKind(morkEnv* ev, mdb_scope inRowScope,
|
|||
mdb_kind inTableKind, mdb_count* outTableCount)
|
||||
{
|
||||
mork_bool outBool = morkBool_kFalse;
|
||||
|
||||
ev->StubMethodOnlyError();
|
||||
|
||||
return outBool;
|
||||
}
|
||||
|
@ -789,6 +1091,19 @@ morkStore::GetPortTableCursor(morkEnv* ev, mdb_scope inRowScope,
|
|||
return outCursor;
|
||||
}
|
||||
|
||||
morkRow*
|
||||
morkStore::NewRow(morkEnv* ev, mdb_scope inRowScope)
|
||||
{
|
||||
morkRow* outRow = 0;
|
||||
if ( ev->Good() )
|
||||
{
|
||||
morkRowSpace* rowSpace = this->LazyGetRowSpace(ev, inRowScope);
|
||||
if ( rowSpace )
|
||||
outRow = rowSpace->NewRow(ev);
|
||||
}
|
||||
return outRow;
|
||||
}
|
||||
|
||||
morkRow*
|
||||
morkStore::NewRowWithOid(morkEnv* ev, const mdbOid* inOid)
|
||||
{
|
||||
|
@ -803,16 +1118,42 @@ morkStore::NewRowWithOid(morkEnv* ev, const mdbOid* inOid)
|
|||
}
|
||||
|
||||
morkRow*
|
||||
morkStore::NewRow(morkEnv* ev, mdb_scope inRowScope)
|
||||
morkStore::OidToRow(morkEnv* ev, const mdbOid* inOid)
|
||||
// OidToRow() finds old row with oid, or makes new one if not found.
|
||||
{
|
||||
morkRow* outRow = 0;
|
||||
if ( ev->Good() )
|
||||
{
|
||||
morkRowSpace* rowSpace = this->LazyGetRowSpace(ev, inRowScope);
|
||||
morkRowSpace* rowSpace = this->LazyGetRowSpace(ev, inOid->mOid_Scope);
|
||||
if ( rowSpace )
|
||||
outRow = rowSpace->NewRow(ev);
|
||||
{
|
||||
outRow = rowSpace->mRowSpace_Rows.GetOid(ev, inOid);
|
||||
if ( !outRow && ev->Good() )
|
||||
outRow = rowSpace->NewRowWithOid(ev, inOid);
|
||||
}
|
||||
}
|
||||
return outRow;
|
||||
}
|
||||
|
||||
morkTable*
|
||||
morkStore::OidToTable(morkEnv* ev, const mdbOid* inOid)
|
||||
// OidToTable() finds old table with oid, or makes new one if not found.
|
||||
{
|
||||
morkTable* outTable = 0;
|
||||
if ( ev->Good() )
|
||||
{
|
||||
morkRowSpace* rowSpace = this->LazyGetRowSpace(ev, inOid->mOid_Scope);
|
||||
if ( rowSpace )
|
||||
{
|
||||
outTable = rowSpace->mRowSpace_Tables.GetTable(ev, inOid->mOid_Id);
|
||||
if ( !outTable && ev->Good() )
|
||||
{
|
||||
mork_kind tableKind = mStore_MorkNoneToken;
|
||||
outTable = rowSpace->NewTableWithTid(ev, inOid->mOid_Id, tableKind);
|
||||
}
|
||||
}
|
||||
}
|
||||
return outTable;
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
|
|
@ -115,6 +115,7 @@ public: // typesafe refcounting inlines calling inherited morkNode methods
|
|||
**| all other explicitly tokenized strings.
|
||||
|*/
|
||||
#define morkStore_kGroundColumnSpace 'c' /* for mStore_GroundColumnSpace*/
|
||||
#define morkStore_kColumnSpaceScope ((mork_scope) 'c') /*kGroundColumnSpace*/
|
||||
#define morkStore_kGroundAtomSpace 'a' /* for mStore_GroundAtomSpace*/
|
||||
#define morkStore_kStreamBufSize (8 * 1024) /* okay buffer size */
|
||||
|
||||
|
@ -150,6 +151,7 @@ public: // state is public because the entire Mork system is private
|
|||
|
||||
morkStream* mStore_OutStream; // stream using file used by the writer
|
||||
|
||||
mork_token mStore_MorkNoneToken; // token for "mork:none"
|
||||
mork_column mStore_CharsetToken; // token for "charset"
|
||||
mork_column mStore_AtomScopeToken; // token for "atomScope"
|
||||
mork_column mStore_RowScopeToken; // token for "rowScope"
|
||||
|
@ -164,9 +166,17 @@ public: // state is public because the entire Mork system is private
|
|||
|
||||
// we alloc a max size book atom to reuse space for atom map key searches:
|
||||
morkMaxBookAtom mStore_BookAtom; // staging area for atom map searches
|
||||
|
||||
public: // coping with any changes to store token slots above:
|
||||
|
||||
void SyncTokenIdChange(morkEnv* ev, const morkBookAtom* inAtom,
|
||||
const mdbOid* inOid);
|
||||
|
||||
public: // building an atom inside mStore_BookAtom from a char* string
|
||||
|
||||
morkMaxBookAtom* StageAliasAsBookAtom(morkEnv* ev,
|
||||
const morkMid* inMid, morkAtomSpace* ioSpace, mork_cscode inForm);
|
||||
|
||||
morkMaxBookAtom* StageYarnAsBookAtom(morkEnv* ev,
|
||||
const mdbYarn* inYarn, morkAtomSpace* ioSpace);
|
||||
|
||||
|
@ -186,6 +196,7 @@ public: // lazy creation of members and nested row or atom spaces
|
|||
|
||||
morkStream* LazyGetInStream(morkEnv* ev);
|
||||
morkBuilder* LazyGetBuilder(morkEnv* ev);
|
||||
void ForgetBuilder(morkEnv* ev);
|
||||
|
||||
morkStream* LazyGetOutStream(morkEnv* ev);
|
||||
|
||||
|
@ -221,6 +232,8 @@ public: // typing
|
|||
public: // store utilties
|
||||
|
||||
morkAtom* YarnToAtom(morkEnv* ev, const mdbYarn* inYarn);
|
||||
morkAtom* AddAlias(morkEnv* ev, const morkMid& inMid,
|
||||
mork_cscode inForm);
|
||||
|
||||
public: // other store methods
|
||||
|
||||
|
@ -239,11 +252,30 @@ public: // other store methods
|
|||
const char* inFilePath,
|
||||
const mdbOpenPolicy* inOpenPolicy);
|
||||
|
||||
// mork_bool CutBookAtom(morkEnv* ev, morkBookAtom* ioAtom);
|
||||
mork_token BufToToken(morkEnv* ev, const morkBuf* inBuf);
|
||||
mork_token StringToToken(morkEnv* ev, const char* inTokenName);
|
||||
mork_token QueryToken(morkEnv* ev, const char* inTokenName);
|
||||
void TokenToString(morkEnv* ev, mdb_token inToken, mdbYarn* outTokenName);
|
||||
|
||||
mork_bool MidToOid(morkEnv* ev, const morkMid& inMid,
|
||||
mdbOid* outOid);
|
||||
mork_bool OidToYarn(morkEnv* ev, const mdbOid& inOid, mdbYarn* outYarn);
|
||||
mork_bool MidToYarn(morkEnv* ev, const morkMid& inMid,
|
||||
mdbYarn* outYarn);
|
||||
|
||||
morkBookAtom* MidToAtom(morkEnv* ev, const morkMid& inMid);
|
||||
morkRow* MidToRow(morkEnv* ev, const morkMid& inMid);
|
||||
morkTable* MidToTable(morkEnv* ev, const morkMid& inMid);
|
||||
|
||||
morkRow* OidToRow(morkEnv* ev, const mdbOid* inOid);
|
||||
// OidToRow() finds old row with oid, or makes new one if not found.
|
||||
|
||||
morkTable* OidToTable(morkEnv* ev, const mdbOid* inOid);
|
||||
// OidToTable() finds old table with oid, or makes new one if not found.
|
||||
|
||||
static void SmallTokenToOneByteYarn(morkEnv* ev, mdb_token inToken,
|
||||
mdbYarn* outYarn);
|
||||
|
||||
mork_bool HasTableKind(morkEnv* ev, mdb_scope inRowScope,
|
||||
mdb_kind inTableKind, mdb_count* outTableCount);
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ morkStream::morkStream(morkEnv* ev, const morkUsage& inUsage,
|
|||
, mStream_ContentFile( 0 )
|
||||
|
||||
, mStream_Buf( 0 )
|
||||
, mStream_BufSize( 0 )
|
||||
, mStream_BufSize( inBufSize )
|
||||
, mStream_BufPos( 0 )
|
||||
, mStream_Dirty( morkBool_kFalse )
|
||||
, mStream_HitEof( morkBool_kFalse )
|
||||
|
@ -329,7 +329,7 @@ morkStream::PutByteThenNewlineThenSpace(morkEnv* ev, int inByte)
|
|||
mork_size
|
||||
morkStream::PutLineBreak(morkEnv* ev)
|
||||
{
|
||||
#ifdef MORK_MAC
|
||||
#if defined(MORK_MAC) || defined(MORK_OBSOLETE)
|
||||
|
||||
this->Putc(ev, mork_kCR);
|
||||
return 1;
|
||||
|
|
|
@ -212,6 +212,7 @@ public: // public non-poly morkStream methods
|
|||
void Ungetc(int c) /*i*/
|
||||
{ if ( mStream_At > mStream_Buf && c > 0 ) *--mStream_At = c; }
|
||||
|
||||
// Note Getc() returns EOF consistently after any fill_getc() error occurs.
|
||||
int Getc(morkEnv* ev) /*i*/
|
||||
{ return ( mStream_At < mStream_ReadEnd )? *mStream_At++ : fill_getc(ev); }
|
||||
|
||||
|
|
|
@ -147,6 +147,35 @@ morkTable::CloseTable(morkEnv* ev) /*i*/ // called by CloseMorkNode();
|
|||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
mork_u2
|
||||
morkTable::AddCellUse(morkEnv* ev)
|
||||
{
|
||||
if ( mTable_CellUses < morkTable_kMaxCellUses ) // not already maxed out?
|
||||
++mTable_CellUses;
|
||||
|
||||
return mTable_CellUses;
|
||||
}
|
||||
|
||||
mork_u2
|
||||
morkTable::CutCellUse(morkEnv* ev)
|
||||
{
|
||||
if ( mTable_CellUses ) // any outstanding uses to cut?
|
||||
{
|
||||
if ( mTable_CellUses < morkTable_kMaxCellUses ) // not frozen at max?
|
||||
--mTable_CellUses;
|
||||
}
|
||||
else
|
||||
this->CellUsesUnderflowWarning(ev);
|
||||
|
||||
return mTable_CellUses;
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkTable::CellUsesUnderflowWarning(morkEnv* ev)
|
||||
{
|
||||
ev->NewWarning("mTable_CellUses underflow");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkTable::NonTableTypeError(morkEnv* ev)
|
||||
{
|
||||
|
|
|
@ -51,6 +51,7 @@ class nsIMdbTable;
|
|||
#define morkTable_kStartRowArraySize 11 /* modest starting size for array */
|
||||
|
||||
#define morkTable_kStartRowMapSlotCount 128
|
||||
#define morkTable_kMaxCellUses 0x0FFFF /* max for 16-bit unsigned int */
|
||||
|
||||
class morkTable : public morkObject {
|
||||
|
||||
|
@ -85,7 +86,8 @@ public: // state is public because the entire Mork system is private
|
|||
mork_kind mTable_Kind;
|
||||
|
||||
mork_bool mTable_MustBeUnique;
|
||||
mork_u1 mTable_Pad[ 3 ]; // padding to u4 alignment
|
||||
mork_u1 mTable_Pad; // padding for u4 alignment
|
||||
mork_u2 mTable_CellUses; // persistent references from cells
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
|
@ -109,12 +111,18 @@ public: // dynamic type identification
|
|||
{ return IsNode() && mNode_Derived == morkDerived_kTable; }
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
public: // typing
|
||||
public: // errors
|
||||
static void NonTableTypeError(morkEnv* ev);
|
||||
static void NonTableTypeWarning(morkEnv* ev);
|
||||
static void NilRowSpaceError(morkEnv* ev);
|
||||
|
||||
public: // warnings
|
||||
static void CellUsesUnderflowWarning(morkEnv* ev);
|
||||
|
||||
public: // other table methods
|
||||
|
||||
mork_u2 AddCellUse(morkEnv* ev);
|
||||
mork_u2 CutCellUse(morkEnv* ev);
|
||||
|
||||
// void DirtyAllTableContent(morkEnv* ev);
|
||||
|
||||
|
@ -137,7 +145,7 @@ public: // typesafe refcounting inlines calling inherited morkNode methods
|
|||
morkEnv* ev, morkTable** ioSlot)
|
||||
{ morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
|
||||
static void SlotStrongTableS(morkTable* me,
|
||||
static void SlotStrongTable(morkTable* me,
|
||||
morkEnv* ev, morkTable** ioSlot)
|
||||
{ morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
};
|
||||
|
|
|
@ -52,6 +52,18 @@
|
|||
#include "morkWriter.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKPARSER_
|
||||
#include "morkParser.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKBUILDER_
|
||||
#include "morkBuilder.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKFILE_
|
||||
#include "morkFile.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
|
@ -92,6 +104,7 @@ morkThumb::morkThumb(morkEnv* ev,
|
|||
, mThumb_Store( 0 )
|
||||
, mThumb_File( 0 )
|
||||
, mThumb_Writer( 0 )
|
||||
, mThumb_Builder( 0 )
|
||||
, mThumb_SourcePort( 0 )
|
||||
|
||||
, mThumb_DoCollect( morkBool_kFalse )
|
||||
|
@ -111,9 +124,13 @@ morkThumb::CloseThumb(morkEnv* ev) // called by CloseMorkNode();
|
|||
if ( this->IsNode() )
|
||||
{
|
||||
mThumb_Magic = 0;
|
||||
if ( mThumb_Builder && mThumb_Store )
|
||||
mThumb_Store->ForgetBuilder(ev);
|
||||
morkBuilder::SlotStrongBuilder((morkBuilder*) 0, ev, &mThumb_Builder);
|
||||
|
||||
morkWriter::SlotStrongWriter((morkWriter*) 0, ev, &mThumb_Writer);
|
||||
morkFile::SlotStrongFile((morkFile*) 0, ev, &mThumb_File);
|
||||
morkStore::SlotWeakStore((morkStore*) 0, ev, &mThumb_Store);
|
||||
morkStore::SlotStrongStore((morkStore*) 0, ev, &mThumb_Store);
|
||||
morkPort::SlotStrongPort((morkPort*) 0, ev, &mThumb_SourcePort);
|
||||
this->MarkShut();
|
||||
}
|
||||
|
@ -152,6 +169,11 @@ morkThumb::CloseThumb(morkEnv* ev) // called by CloseMorkNode();
|
|||
ev->NewError("nil mThumb_Writer");
|
||||
}
|
||||
|
||||
/*static*/ void morkThumb::NilThumbBuilderError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("nil mThumb_Builder");
|
||||
}
|
||||
|
||||
/*static*/ void morkThumb::NilThumbSourcePortError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("nil mThumb_SourcePort");
|
||||
|
@ -181,14 +203,31 @@ morkThumb::Make_OpenFileStore(morkEnv* ev, nsIMdbHeap* ioHeap,
|
|||
morkThumb* outThumb = 0;
|
||||
if ( ioHeap && ioStore )
|
||||
{
|
||||
outThumb = new(*ioHeap, ev)
|
||||
morkThumb(ev, morkUsage::kHeap, ioHeap, ioHeap,
|
||||
morkThumb_kMagic_OpenFileStore);
|
||||
|
||||
if ( outThumb )
|
||||
morkFile* file = ioStore->mStore_File;
|
||||
if ( file )
|
||||
{
|
||||
morkStore::SlotWeakStore(ioStore, ev, &outThumb->mThumb_Store);
|
||||
mork_pos fileEof = file->Length(ev);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
outThumb = new(*ioHeap, ev)
|
||||
morkThumb(ev, morkUsage::kHeap, ioHeap, ioHeap,
|
||||
morkThumb_kMagic_OpenFileStore);
|
||||
|
||||
if ( outThumb )
|
||||
{
|
||||
morkBuilder* builder = ioStore->LazyGetBuilder(ev);
|
||||
if ( builder )
|
||||
{
|
||||
outThumb->mThumb_Total = fileEof;
|
||||
morkStore::SlotStrongStore(ioStore, ev, &outThumb->mThumb_Store);
|
||||
morkBuilder::SlotStrongBuilder(builder, ev,
|
||||
&outThumb->mThumb_Builder);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
ioStore->NilStoreFileError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
|
@ -219,7 +258,7 @@ morkThumb::Make_CompressCommit(morkEnv* ev,
|
|||
{
|
||||
writer->mWriter_NeedDirtyAll = morkBool_kTrue;
|
||||
outThumb->mThumb_DoCollect = inDoCollect;
|
||||
morkStore::SlotWeakStore(ioStore, ev, &outThumb->mThumb_Store);
|
||||
morkStore::SlotStrongStore(ioStore, ev, &outThumb->mThumb_Store);
|
||||
morkFile::SlotStrongFile(file, ev, &outThumb->mThumb_File);
|
||||
morkWriter::SlotStrongWriter(writer, ev, &outThumb->mThumb_Writer);
|
||||
}
|
||||
|
@ -330,7 +369,21 @@ void morkThumb::DoMore_OpenFilePort(morkEnv* ev)
|
|||
|
||||
void morkThumb::DoMore_OpenFileStore(morkEnv* ev)
|
||||
{
|
||||
this->UnsupportedThumbMagicError(ev);
|
||||
morkBuilder* builder = mThumb_Builder;
|
||||
if ( builder )
|
||||
{
|
||||
mork_pos pos = 0;
|
||||
builder->ParseMore(ev, &pos, &mThumb_Done, &mThumb_Broken);
|
||||
// mThumb_Total = builder->mBuilder_TotalCount;
|
||||
// mThumb_Current = builder->mBuilder_DoneCount;
|
||||
mThumb_Current = pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->NilThumbBuilderError(ev);
|
||||
mThumb_Broken = morkBool_kTrue;
|
||||
mThumb_Done = morkBool_kTrue;
|
||||
}
|
||||
}
|
||||
|
||||
void morkThumb::DoMore_ExportToFormat(morkEnv* ev)
|
||||
|
|
|
@ -84,6 +84,7 @@ public: // state is public because the entire Mork system is private
|
|||
morkStore* mThumb_Store; // weak ref to created store
|
||||
morkFile* mThumb_File; // strong ref to file (store, import, export)
|
||||
morkWriter* mThumb_Writer; // strong ref to writer (for commit)
|
||||
morkBuilder* mThumb_Builder; // strong ref to builder (for store open)
|
||||
morkPort* mThumb_SourcePort; // strong ref to port for import
|
||||
|
||||
mork_bool mThumb_DoCollect; // influence whether a collect happens
|
||||
|
@ -115,6 +116,7 @@ public: // typing
|
|||
static void NilThumbStoreError(morkEnv* ev);
|
||||
static void NilThumbFileError(morkEnv* ev);
|
||||
static void NilThumbWriterError(morkEnv* ev);
|
||||
static void NilThumbBuilderError(morkEnv* ev);
|
||||
static void NilThumbSourcePortError(morkEnv* ev);
|
||||
|
||||
public: // 'do more' methods
|
||||
|
|
|
@ -84,6 +84,10 @@
|
|||
#include "morkAtom.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKCH_
|
||||
#include "morkCh.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
|
@ -123,6 +127,7 @@ morkWriter::morkWriter(morkEnv* ev, const morkUsage& inUsage,
|
|||
|
||||
, mWriter_LineSize( 0 )
|
||||
, mWriter_MaxIndent( morkWriter_kMaxIndent )
|
||||
, mWriter_MaxLine( morkWriter_kMaxLine )
|
||||
|
||||
, mWriter_TableCharset( 0 )
|
||||
, mWriter_TableAtomScope( 0 )
|
||||
|
@ -362,15 +367,16 @@ morkWriter::WriteYarn(morkEnv* ev, const mdbYarn* inYarn)
|
|||
while ( b < end )
|
||||
{
|
||||
c = *b++; // next byte to print
|
||||
if ( c < 0x080 && MORK_ISPRINT(c) )
|
||||
if ( morkCh_IsValue(c) )
|
||||
{
|
||||
if ( c == ')' && c == '$' && c == '\\' )
|
||||
{
|
||||
stream->Putc(ev, '\\');
|
||||
++outSize;
|
||||
}
|
||||
stream->Putc(ev, c);
|
||||
++outSize;
|
||||
++outSize; // c
|
||||
}
|
||||
else if ( c == ')' && c == '$' && c == '\\' )
|
||||
{
|
||||
stream->Putc(ev, '\\');
|
||||
stream->Putc(ev, c);
|
||||
outSize += 2; // '\' c
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -396,8 +402,13 @@ morkWriter::WriteAtom(morkEnv* ev, const morkAtom* inAtom)
|
|||
mdbYarn yarn; // to ref content inside atom
|
||||
|
||||
if ( inAtom->AliasYarn(&yarn) )
|
||||
{
|
||||
if ( mWriter_DidStartDict && yarn.mYarn_Form != mWriter_DictCharset )
|
||||
this->ChangeDictCharset(ev, yarn.mYarn_Form);
|
||||
|
||||
outSize = this->WriteYarn(ev, &yarn);
|
||||
// mWriter_LineSize += stream->Write(ev, inYarn->mYarn_Buf, outSize);
|
||||
}
|
||||
else
|
||||
inAtom->BadAtomKindError(ev);
|
||||
|
||||
|
@ -424,6 +435,7 @@ morkWriter::WriteAtomSpaceAsDict(morkEnv* ev, morkAtomSpace* ioSpace)
|
|||
|
||||
if ( ev->Good() )
|
||||
{
|
||||
mdbYarn yarn; // to ref content inside atom
|
||||
char buf[ 64 ]; // buffer for staging the dict alias hex ID
|
||||
char* idBuf = buf + 1; // where the id always starts
|
||||
buf[ 0 ] = '('; // we always start with open paren
|
||||
|
@ -442,15 +454,23 @@ morkWriter::WriteAtomSpaceAsDict(morkEnv* ev, morkAtomSpace* ioSpace)
|
|||
{
|
||||
atom->mAtom_Change = morkChange_kNil; // neutralize change
|
||||
|
||||
this->IndentAsNeeded(ev, morkWriter_kDictAliasDepth);
|
||||
atom->AliasYarn(&yarn);
|
||||
mork_size size = ev->TokenAsHex(idBuf, atom->mBookAtom_Id);
|
||||
mWriter_LineSize += stream->Write(ev, buf, size+1); // '('
|
||||
|
||||
this->IndentAsNeeded(ev, morkWriter_kDictAliasValueDepth);
|
||||
stream->Putc(ev, '='); // end alias
|
||||
if ( yarn.mYarn_Form != mWriter_DictCharset )
|
||||
this->ChangeDictCharset(ev, yarn.mYarn_Form);
|
||||
|
||||
mork_size pending = yarn.mYarn_Fill + size +
|
||||
morkWriter_kYarnEscapeSlop + 4;
|
||||
this->IndentOverMaxLine(ev, pending, morkWriter_kDictAliasDepth);
|
||||
mWriter_LineSize += stream->Write(ev, buf, size+1); // + '('
|
||||
|
||||
pending -= ( size + 1 );
|
||||
this->IndentOverMaxLine(ev, pending, morkWriter_kDictAliasValueDepth);
|
||||
stream->Putc(ev, '='); // start alias
|
||||
++mWriter_LineSize;
|
||||
|
||||
this->WriteAtom(ev, atom);
|
||||
this->WriteYarn(ev, &yarn);
|
||||
stream->Putc(ev, ')'); // end alias
|
||||
++mWriter_LineSize;
|
||||
|
||||
|
@ -1037,22 +1057,40 @@ morkWriter::WriteStringToTokenDictCell(morkEnv* ev,
|
|||
// mWriter_LineSize += stream->Write(ev, yarnBuf, fill + 1); // +1 for ')'
|
||||
}
|
||||
|
||||
void
|
||||
morkWriter::ChangeDictCharset(morkEnv* ev, mork_cscode inNewForm)
|
||||
{
|
||||
if ( inNewForm != mWriter_DictCharset )
|
||||
{
|
||||
morkStream* stream = mWriter_Stream;
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
mWriter_LineSize = 0;
|
||||
|
||||
stream->Putc(ev, '<');
|
||||
this->WriteStringToTokenDictCell(ev, "(charset=", mWriter_DictCharset);
|
||||
stream->Putc(ev, '>');
|
||||
++mWriter_LineSize;
|
||||
|
||||
mWriter_DictCharset = inNewForm;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
morkWriter::StartDict(morkEnv* ev)
|
||||
{
|
||||
morkStream* stream = mWriter_Stream;
|
||||
if ( mWriter_DidStartDict )
|
||||
{
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
stream->PutStringThenNewline(ev, "> // end dict");
|
||||
mWriter_LineSize = 0;
|
||||
stream->Putc(ev, '>'); // end dict
|
||||
++mWriter_LineSize;
|
||||
}
|
||||
mWriter_DidStartDict = morkBool_kTrue;
|
||||
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
mWriter_LineSize = 0;
|
||||
stream->PutLineBreak(ev);
|
||||
if ( mWriter_DictCharset || mWriter_DictAtomScope != 'a' )
|
||||
{
|
||||
stream->Putc(ev, '<');
|
||||
|
@ -1069,7 +1107,9 @@ morkWriter::StartDict(morkEnv* ev)
|
|||
}
|
||||
else
|
||||
{
|
||||
stream->PutString(ev, "< // <(charset=iso-8859-1)(atomScope=a)>");
|
||||
stream->Putc(ev, '<');
|
||||
stream->Putc(ev, ' ');
|
||||
mWriter_LineSize += 2;
|
||||
}
|
||||
mWriter_LineSize = stream->PutIndent(ev, morkWriter_kDictAliasDepth);
|
||||
}
|
||||
|
@ -1080,10 +1120,8 @@ morkWriter::EndDict(morkEnv* ev)
|
|||
morkStream* stream = mWriter_Stream;
|
||||
if ( mWriter_DidStartDict )
|
||||
{
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
stream->PutStringThenNewline(ev, "> // end dict");
|
||||
mWriter_LineSize = 0;
|
||||
stream->Putc(ev, '>'); // end dict
|
||||
++mWriter_LineSize;
|
||||
}
|
||||
mWriter_DidStartDict = morkBool_kFalse;
|
||||
}
|
||||
|
@ -1100,6 +1138,7 @@ morkWriter::StartTable(morkEnv* ev, morkTable* ioTable)
|
|||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
mWriter_LineSize = 0;
|
||||
stream->PutLineBreak(ev);
|
||||
|
||||
char buf[ 64 ]; // buffer for staging hex
|
||||
char* p = buf;
|
||||
|
@ -1123,9 +1162,8 @@ morkWriter::StartTable(morkEnv* ev, morkTable* ioTable)
|
|||
this->IndentAsNeeded(ev, morkWriter_kTableMetaCellDepth);
|
||||
this->WriteTokenToTokenMetaCell(ev, store->mStore_TableKindToken, tk);
|
||||
}
|
||||
stream->Putc(ev, '}');
|
||||
stream->Putc(ev, ' ');
|
||||
mWriter_LineSize += 2;
|
||||
stream->Putc(ev, '}'); // end meta
|
||||
mWriter_LineSize = stream->PutIndent(ev, morkWriter_kRowCellDepth);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1133,10 +1171,8 @@ void
|
|||
morkWriter::EndTable(morkEnv* ev)
|
||||
{
|
||||
morkStream* stream = mWriter_Stream;
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
stream->PutStringThenNewline(ev, "} // end table");
|
||||
mWriter_LineSize = 0;
|
||||
stream->Putc(ev, '}'); // end table
|
||||
++mWriter_LineSize;
|
||||
}
|
||||
|
||||
mork_bool
|
||||
|
@ -1208,9 +1244,9 @@ morkWriter::PutRowCells(morkEnv* ev, morkRow* ioRow)
|
|||
colSize = ev->TokenAsHex(p, col);
|
||||
p += colSize;
|
||||
|
||||
this->IndentAsNeeded(ev, morkWriter_kRowCellDepth);
|
||||
if ( atom->IsBook() ) // is it possible to write atom ID?
|
||||
{
|
||||
this->IndentAsNeeded(ev, morkWriter_kRowCellDepth);
|
||||
*p++ = '^';
|
||||
morkBookAtom* ba = (morkBookAtom*) atom;
|
||||
mork_size valSize = ev->TokenAsHex(p, ba->mBookAtom_Id);
|
||||
|
@ -1227,13 +1263,24 @@ morkWriter::PutRowCells(morkEnv* ev, morkRow* ioRow)
|
|||
}
|
||||
else // must write an anonymous atom
|
||||
{
|
||||
mdbYarn yarn; // to ref content inside atom
|
||||
atom->AliasYarn(&yarn);
|
||||
|
||||
if ( yarn.mYarn_Form != mWriter_DictCharset )
|
||||
this->ChangeDictCharset(ev, yarn.mYarn_Form);
|
||||
|
||||
mork_size pending = yarn.mYarn_Fill + colSize +
|
||||
morkWriter_kYarnEscapeSlop + 2;
|
||||
this->IndentOverMaxLine(ev, pending, morkWriter_kRowCellDepth);
|
||||
|
||||
mWriter_LineSize += stream->Write(ev, buf, colSize + 2);
|
||||
|
||||
this->IndentAsNeeded(ev, morkWriter_kRowCellValueDepth);
|
||||
pending -= ( colSize + 2 );
|
||||
this->IndentOverMaxLine(ev, pending, morkWriter_kRowCellDepth);
|
||||
stream->Putc(ev, '=');
|
||||
++mWriter_LineSize;
|
||||
|
||||
this->WriteAtom(ev, atom);
|
||||
this->WriteYarn(ev, &yarn);
|
||||
stream->Putc(ev, ')'); // end alias
|
||||
++mWriter_LineSize;
|
||||
}
|
||||
|
@ -1254,8 +1301,8 @@ morkWriter::PutRow(morkEnv* ev, morkRow* ioRow)
|
|||
|
||||
this->IndentAsNeeded(ev, morkWriter_kRowDepth);
|
||||
|
||||
// if ( ioRow->IsRowDirty() )
|
||||
if ( morkBool_kTrue )
|
||||
//if ( morkBool_kTrue )
|
||||
if ( ioRow->IsRowDirty() )
|
||||
{
|
||||
ioRow->SetRowClean();
|
||||
mork_rid rid = roid->mOid_Id;
|
||||
|
@ -1271,8 +1318,7 @@ morkWriter::PutRow(morkEnv* ev, morkRow* ioRow)
|
|||
|
||||
this->PutRowCells(ev, ioRow);
|
||||
stream->Putc(ev, ']'); // end row
|
||||
stream->Putc(ev, ' '); // end row
|
||||
mWriter_LineSize += 2;
|
||||
++mWriter_LineSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
|
||||
#define morkWriter_kStreamBufSize /*i*/ (16) /* buffer size for stream */
|
||||
#define morkWriter_kStreamBufSize /*i*/ (16 * 1024) /* buffer size for stream */
|
||||
|
||||
#define morkDerived_kWriter /*i*/ 0x5772 /* ascii 'Wr' */
|
||||
|
||||
|
@ -85,7 +85,10 @@
|
|||
|
||||
#define morkWriter_kMaxColumnNameSize 128 /* longest writable col name */
|
||||
|
||||
#define morkWriter_kMaxIndent 48 /* default value for mWriter_MaxIndent */
|
||||
#define morkWriter_kMaxIndent 56 /* default value for mWriter_MaxIndent */
|
||||
#define morkWriter_kMaxLine 78 /* default value for mWriter_MaxLine */
|
||||
|
||||
#define morkWriter_kYarnEscapeSlop 4 /* guess average yarn escape overhead */
|
||||
|
||||
#define morkWriter_kTableMetaCellDepth 4 /* */
|
||||
#define morkWriter_kTableMetaCellValueDepth 6 /* */
|
||||
|
@ -126,6 +129,7 @@ public: // state is public because the entire Mork system is private
|
|||
|
||||
mork_size mWriter_LineSize; // length of current line being written
|
||||
mork_size mWriter_MaxIndent; // line size forcing a line break
|
||||
mork_size mWriter_MaxLine; // line size forcing a value continuation
|
||||
|
||||
mork_cscode mWriter_TableCharset; // current charset metainfo
|
||||
mork_scope mWriter_TableAtomScope; // current atom scope
|
||||
|
@ -195,6 +199,7 @@ public: // typing & errors
|
|||
static void UnsupportedPhaseError(morkEnv* ev);
|
||||
|
||||
public: // inlines
|
||||
void ChangeDictCharset(morkEnv* ev, mork_cscode inNewForm);
|
||||
mork_bool DidStartDict() const { return mWriter_DidStartDict; }
|
||||
mork_bool DidEndDict() const { return mWriter_DidEndDict; }
|
||||
|
||||
|
@ -206,6 +211,13 @@ public: // inlines
|
|||
if ( mWriter_LineSize > mWriter_MaxIndent )
|
||||
mWriter_LineSize = mWriter_Stream->PutIndent(ev, inDepth);
|
||||
}
|
||||
|
||||
void IndentOverMaxLine(morkEnv* ev,
|
||||
mork_size inPendingSize, mork_size inDepth)
|
||||
{
|
||||
if ( mWriter_LineSize + inPendingSize > mWriter_MaxLine )
|
||||
mWriter_LineSize = mWriter_Stream->PutIndent(ev, inDepth);
|
||||
}
|
||||
|
||||
public: // iterative/asynchronouse writing
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче