get mork parsing working so we can read existing databases

This commit is contained in:
bienvenu%netscape.com 1999-03-23 23:01:37 +00:00
Родитель d91f32f0f5
Коммит 324262095c
68 изменённых файлов: 5786 добавлений и 994 удалений

Просмотреть файл

@ -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.

Просмотреть файл

@ -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