mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-24 21:58:06 +00:00
latest mork drop, fix commit code
This commit is contained in:
parent
06d478946f
commit
2e5950d728
@ -48,13 +48,16 @@
|
||||
#endif
|
||||
// } %%%%% end platform defs peculiar to Mork %%%%%
|
||||
|
||||
#if defined (MORK_WIN) || defined(MORK_UNIX)
|
||||
#if defined (MORK_WIN) || defined(MORK_UNIX)
|
||||
#include "stdio.h"
|
||||
#include "ctype.h"
|
||||
#include "errno.h"
|
||||
#include "string.h"
|
||||
#include "memory.h"
|
||||
#include "nsDebug.h"
|
||||
|
||||
#define MORK_ISPRINT(c) isprint(c)
|
||||
|
||||
#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)
|
||||
@ -64,6 +67,9 @@
|
||||
|
||||
#ifdef MORK_MAC
|
||||
#include "xp_file.h"
|
||||
#include "ctype.h"
|
||||
|
||||
#define MORK_ISPRINT(c) isprint(c)
|
||||
|
||||
#define MORK_FILETELL(file) XP_FileTell(file)
|
||||
#define MORK_FILESEEK(file, where, how) XP_FileSeek(file, where, how)
|
||||
|
@ -239,18 +239,23 @@ morkFile::NewFileErrnoError(morkEnv* ev) const
|
||||
# endif /* MORK_WIN */
|
||||
#endif /* MORK_MAC */
|
||||
|
||||
void
|
||||
mork_size
|
||||
morkFile::WriteNewlines(morkEnv* ev, mork_count inNewlines)
|
||||
// WriteNewlines() returns the number of bytes written.
|
||||
{
|
||||
mork_size outSize = 0;
|
||||
while ( inNewlines && ev->Good() ) // more newlines to write?
|
||||
{
|
||||
mork_u4 quantum = inNewlines;
|
||||
if ( quantum > morkFile_kNewlinesCount )
|
||||
quantum = morkFile_kNewlinesCount;
|
||||
|
||||
this->Write(ev, morkFile_kNewlines, quantum * mork_kNewlineSize);
|
||||
mork_size quantumSize = quantum * mork_kNewlineSize;
|
||||
this->Write(ev, morkFile_kNewlines, quantumSize);
|
||||
outSize += quantumSize;
|
||||
inNewlines -= quantum;
|
||||
}
|
||||
return outSize;
|
||||
}
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
@ -309,7 +314,7 @@ morkStdioFile::OpenOldStdioFile(morkEnv* ev, nsIMdbHeap* ioHeap,
|
||||
morkStdioFile* outFile = 0;
|
||||
if ( ioHeap && inFilePath )
|
||||
{
|
||||
const char* mode = (inFrozen)? "r" : "w";
|
||||
const char* mode = (inFrozen)? "rb" : "wb";
|
||||
outFile = new(*ioHeap, ev)
|
||||
morkStdioFile(ev, morkUsage::kHeap, ioHeap, ioHeap, inFilePath, mode);
|
||||
|
||||
@ -331,7 +336,7 @@ morkStdioFile::CreateNewStdioFile(morkEnv* ev, nsIMdbHeap* ioHeap,
|
||||
morkStdioFile* outFile = 0;
|
||||
if ( ioHeap && inFilePath )
|
||||
{
|
||||
const char* mode = "w+";
|
||||
const char* mode = "wb+";
|
||||
outFile = new(*ioHeap, ev)
|
||||
morkStdioFile(ev, morkUsage::kHeap, ioHeap, ioHeap, inFilePath, mode);
|
||||
}
|
||||
@ -386,7 +391,7 @@ morkStdioFile::AcquireBud(morkEnv* ev, nsIMdbHeap* ioHeap)
|
||||
this->SetFileIoOpen(morkBool_kFalse);
|
||||
mStdioFile_File = 0;
|
||||
|
||||
file = fopen(name, "w+"); // open for write, discarding old content
|
||||
file = fopen(name, "wb+"); // open for write, discarding old content
|
||||
if ( file )
|
||||
{
|
||||
mStdioFile_File = file;
|
||||
|
@ -159,7 +159,8 @@ public: // non-poly morkFile methods
|
||||
void NewFileErrnoError(morkEnv* ev) const;
|
||||
// call NewFileErrnoError() to convert std C errno into AB fault
|
||||
|
||||
void WriteNewlines(morkEnv* ev, mork_count inNewlines);
|
||||
mork_size WriteNewlines(morkEnv* ev, mork_count inNewlines);
|
||||
// WriteNewlines() returns the number of bytes written.
|
||||
|
||||
public: // typesafe refcounting inlines calling inherited morkNode methods
|
||||
static void SlotWeakFile(morkFile* me,
|
||||
|
@ -44,6 +44,14 @@
|
||||
#include "morkStream.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKBLOB_
|
||||
#include "morkBlob.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKSINK_
|
||||
#include "morkSink.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
@ -131,6 +139,10 @@ morkParser::CloseParser(morkEnv* ev) /*i*/ // called by CloseMorkNode();
|
||||
{
|
||||
if ( !this->IsShutNode() )
|
||||
{
|
||||
mParser_ScopeSpool.CloseSpool(ev);
|
||||
mParser_ValueSpool.CloseSpool(ev);
|
||||
mParser_ColumnSpool.CloseSpool(ev);
|
||||
mParser_StringSpool.CloseSpool(ev);
|
||||
nsIMdbHeap_SlotStrongHeap((nsIMdbHeap*) 0, ev, &mParser_Heap);
|
||||
morkStream::SlotStrongStream((morkStream*) 0, ev, &mParser_Stream);
|
||||
this->MarkShut();
|
||||
|
@ -209,73 +209,73 @@ class morkParser /*d*/ : public morkNode {
|
||||
protected: // protected morkParser members
|
||||
|
||||
nsIMdbHeap* mParser_Heap; // refcounted heap used for allocation
|
||||
morkStream* mParser_Stream; // refcounted input stream
|
||||
|
||||
mork_u4 mParser_Tag; // must equal morkParser_kTag
|
||||
mork_count mParser_MoreGranularity; // constructor inBytesPerParseSegment
|
||||
morkStream* mParser_Stream; // refcounted input stream
|
||||
|
||||
mork_u4 mParser_State; // state where parser should resume
|
||||
|
||||
// after finding ends of group transactions, we can re-seek the start:
|
||||
mork_pos mParser_GroupContentStartPos; // start of this group
|
||||
|
||||
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?
|
||||
|
||||
mork_bool mParser_InPortRow; // called OnNewPortRow but not OnPortRowEnd?
|
||||
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
|
||||
|
||||
morkAlias mParser_Alias; // current alias being parsed
|
||||
// note that mParser_Alias.mAlias_Buf points at mParser_ScopeSpool 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
|
||||
|
||||
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
|
||||
mork_u4 mParser_Tag; // must equal morkParser_kTag
|
||||
mork_count mParser_MoreGranularity; // constructor inBytesPerParseSegment
|
||||
|
||||
mork_u4 mParser_State; // state where parser should resume
|
||||
|
||||
// after finding ends of group transactions, we can re-seek the start:
|
||||
mork_pos mParser_GroupContentStartPos; // start of this group
|
||||
|
||||
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?
|
||||
|
||||
mork_bool mParser_InPortRow; // called OnNewPortRow but not OnPortRowEnd?
|
||||
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
|
||||
|
||||
morkAlias mParser_Alias; // current alias being parsed
|
||||
// note that mParser_Alias.mAlias_Buf points at mParser_ScopeSpool 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
|
||||
|
||||
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
|
||||
|
||||
// yarns allocated in mParser_Heap
|
||||
morkYarn mParser_AliasYarn; // place to receive from AliasToYarn()
|
||||
|
||||
// yarns allocated in mParser_Heap
|
||||
morkYarn mParser_AliasYarn; // place to receive from AliasToYarn()
|
||||
|
||||
// span showing current ongoing file position status:
|
||||
morkSpan mParser_PortSpan; // span of current db port file
|
||||
|
||||
// various spans denoting nested subspaces inside the file's port span:
|
||||
morkSpan mParser_GroupSpan; // span of current transaction group
|
||||
morkSpan mParser_DictSpan;
|
||||
morkSpan mParser_AliasSpan;
|
||||
morkSpan mParser_MetaSpan;
|
||||
morkSpan mParser_TableSpan;
|
||||
morkSpan mParser_RowSpan;
|
||||
morkSpan mParser_CellSpan;
|
||||
morkSpan mParser_ColumnSpan;
|
||||
morkSpan mParser_SlotSpan;
|
||||
morkSpan mParser_PortSpan; // span of current db port file
|
||||
|
||||
// various spans denoting nested subspaces inside the file's port span:
|
||||
morkSpan mParser_GroupSpan; // span of current transaction group
|
||||
morkSpan mParser_DictSpan;
|
||||
morkSpan mParser_AliasSpan;
|
||||
morkSpan mParser_MetaSpan;
|
||||
morkSpan mParser_TableSpan;
|
||||
morkSpan mParser_RowSpan;
|
||||
morkSpan mParser_CellSpan;
|
||||
morkSpan mParser_ColumnSpan;
|
||||
morkSpan mParser_SlotSpan;
|
||||
|
||||
private: // convenience inlines
|
||||
|
||||
mork_pos HerePos() const
|
||||
{ return mParser_PortSpan.mSpan_End.mPlace_Pos; }
|
||||
mork_pos HerePos() const
|
||||
{ return mParser_PortSpan.mSpan_End.mPlace_Pos; }
|
||||
|
||||
void SetHerePos(mork_pos inPos)
|
||||
{ mParser_PortSpan.mSpan_End.mPlace_Pos = inPos; }
|
||||
|
||||
void AddLine()
|
||||
{ ++ mParser_PortSpan.mSpan_End.mPlace_Line; }
|
||||
void SetHerePos(mork_pos inPos)
|
||||
{ mParser_PortSpan.mSpan_End.mPlace_Pos = inPos; }
|
||||
|
||||
void AddLine()
|
||||
{ ++ mParser_PortSpan.mSpan_End.mPlace_Line; }
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
@ -353,64 +353,64 @@ public: // out virtual morkParser methods, data flow parser to subclass
|
||||
// mp:Slot ::= OnValue | OnValueAlias | OnRowAlias | OnTableAlias
|
||||
|
||||
|
||||
// Note that in interfaces below, mork_change parameters kAdd and kNil
|
||||
// both mean about the same thing by default. Only kCut is interesting,
|
||||
// because this usually means to remove members instead of adding them.
|
||||
// Note that in interfaces below, mork_change parameters kAdd and kNil
|
||||
// both mean about the same thing by default. Only kCut is interesting,
|
||||
// because this usually means to remove members instead of adding them.
|
||||
|
||||
virtual void OnNewPort(morkEnv* ev, const morkPlace& inPlace) = 0;
|
||||
virtual void OnPortGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0;
|
||||
virtual void OnPortEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
virtual void OnNewPort(morkEnv* ev, const morkPlace& inPlace) = 0;
|
||||
virtual void OnPortGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0;
|
||||
virtual void OnPortEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
|
||||
virtual void OnNewGroup(morkEnv* ev, const morkPlace& inPlace, mork_gid inGid) = 0;
|
||||
virtual void OnGroupGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0;
|
||||
virtual void OnGroupCommitEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
virtual void OnGroupAbortEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
virtual void OnNewGroup(morkEnv* ev, const morkPlace& inPlace, mork_gid inGid) = 0;
|
||||
virtual void OnGroupGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0;
|
||||
virtual void OnGroupCommitEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
virtual void OnGroupAbortEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
|
||||
virtual void OnNewPortRow(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange) = 0;
|
||||
virtual void OnPortRowGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0;
|
||||
virtual void OnPortRowEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
virtual void OnNewPortRow(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, 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;
|
||||
virtual void OnTableGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0;
|
||||
virtual void OnTableEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
|
||||
virtual void OnNewMeta(morkEnv* ev, const morkPlace& inPlace) = 0;
|
||||
virtual void OnMetaGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0;
|
||||
virtual void OnMetaEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
virtual void OnNewTable(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange) = 0;
|
||||
virtual void OnTableGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0;
|
||||
virtual void OnTableEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
|
||||
virtual void OnNewMeta(morkEnv* ev, const morkPlace& inPlace) = 0;
|
||||
virtual void OnMetaGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0;
|
||||
virtual void OnMetaEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
|
||||
virtual void OnNewRow(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange) = 0;
|
||||
virtual void OnRowGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0;
|
||||
virtual void OnRowEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
virtual void OnNewRow(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange) = 0;
|
||||
virtual void OnRowGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0;
|
||||
virtual void OnRowEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
|
||||
virtual void OnNewDict(morkEnv* ev, const morkPlace& inPlace) = 0;
|
||||
virtual void OnDictGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0;
|
||||
virtual void OnDictEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
virtual void OnNewDict(morkEnv* ev, const morkPlace& inPlace) = 0;
|
||||
virtual void OnDictGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0;
|
||||
virtual void OnDictEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
|
||||
virtual void OnAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias) = 0;
|
||||
virtual void OnAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias) = 0;
|
||||
|
||||
virtual void OnAliasGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 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;
|
||||
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;
|
||||
|
||||
virtual void OnValue(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkBuf& inBuf) = 0;
|
||||
virtual void OnNewCell(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange) = 0;
|
||||
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;
|
||||
|
||||
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 OnValueAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias) = 0;
|
||||
|
||||
virtual void OnRowAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias) = 0;
|
||||
virtual void OnRowAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias) = 0;
|
||||
|
||||
virtual void OnTableAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias) = 0;
|
||||
virtual void OnTableAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias) = 0;
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
protected: // protected parser helper methods
|
||||
|
@ -327,7 +327,7 @@ morkRowSpace::NewRowWithOid(morkEnv* ev, const mdbOid* inOid)
|
||||
{
|
||||
row->InitRow(ev, inOid, this, /*length*/ 0, pool);
|
||||
|
||||
if ( ev->Good() )
|
||||
if ( ev->Good() && mRowSpace_Rows.AddRow(ev, row) )
|
||||
outRow = row;
|
||||
else
|
||||
pool->ZapRow(ev, row);
|
||||
@ -354,7 +354,7 @@ morkRowSpace::NewRow(morkEnv* ev)
|
||||
{
|
||||
row->InitRow(ev, &oid, this, /*length*/ 0, pool);
|
||||
|
||||
if ( ev->Good() )
|
||||
if ( ev->Good() && mRowSpace_Rows.AddRow(ev, row) )
|
||||
outRow = row;
|
||||
else
|
||||
pool->ZapRow(ev, row);
|
||||
|
@ -156,74 +156,201 @@ morkStream::CloseStream(morkEnv* ev) // called by CloseMorkNode();
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
#define morkStream_kSpacesPerIndent 1 /* one space per indent */
|
||||
#define morkStream_kMaxIndentDepth 70 /* max indent of 70 space bytes */
|
||||
static const char* morkStream_kSpaces // next line to ease length perception
|
||||
= " ";
|
||||
// 123456789_123456789_123456789_123456789_123456789_123456789_123456789_
|
||||
// morkStream_kSpaces above must contain (at least) 70 spaces (ASCII 0x20)
|
||||
|
||||
mork_size
|
||||
morkStream::PutIndent(morkEnv* ev, mork_count inDepth)
|
||||
// PutIndent() puts a linebreak, and then
|
||||
// "indents" by inDepth, and returns the line length after indentation.
|
||||
{
|
||||
mork_size outLength = 0;
|
||||
|
||||
void
|
||||
if ( ev->Good() )
|
||||
{
|
||||
this->PutLineBreak(ev);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
outLength = inDepth;
|
||||
if ( inDepth )
|
||||
this->Write(ev, morkStream_kSpaces, inDepth);
|
||||
}
|
||||
}
|
||||
return outLength;
|
||||
}
|
||||
|
||||
mork_size
|
||||
morkStream::PutByteThenIndent(morkEnv* ev, int inByte, mork_count inDepth)
|
||||
// PutByteThenIndent() puts the byte, then a linebreak, and then
|
||||
// "indents" by inDepth, and returns the line length after indentation.
|
||||
{
|
||||
mork_size outLength = 0;
|
||||
|
||||
if ( inDepth > morkStream_kMaxIndentDepth )
|
||||
inDepth = morkStream_kMaxIndentDepth;
|
||||
|
||||
this->Putc(ev, inByte);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
this->PutLineBreak(ev);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
outLength = inDepth;
|
||||
if ( inDepth )
|
||||
this->Write(ev, morkStream_kSpaces, inDepth);
|
||||
}
|
||||
}
|
||||
return outLength;
|
||||
}
|
||||
|
||||
mork_size
|
||||
morkStream::PutStringThenIndent(morkEnv* ev,
|
||||
const char* inString, mork_count inDepth)
|
||||
// PutStringThenIndent() puts the string, then a linebreak, and then
|
||||
// "indents" by inDepth, and returns the line length after indentation.
|
||||
{
|
||||
mork_size outLength = 0;
|
||||
|
||||
if ( inDepth > morkStream_kMaxIndentDepth )
|
||||
inDepth = morkStream_kMaxIndentDepth;
|
||||
|
||||
if ( inString )
|
||||
{
|
||||
mork_size length = MORK_STRLEN(inString);
|
||||
if ( length && ev->Good() ) // any bytes to write?
|
||||
this->Write(ev, inString, length);
|
||||
}
|
||||
|
||||
if ( ev->Good() )
|
||||
{
|
||||
this->PutLineBreak(ev);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
outLength = inDepth;
|
||||
if ( inDepth )
|
||||
this->Write(ev, morkStream_kSpaces, inDepth);
|
||||
}
|
||||
}
|
||||
return outLength;
|
||||
}
|
||||
|
||||
mork_size
|
||||
morkStream::PutString(morkEnv* ev, const char* inString)
|
||||
{
|
||||
mork_size outSize = 0;
|
||||
if ( inString )
|
||||
{
|
||||
mork_num length = MORK_STRLEN(inString);
|
||||
if ( length && ev->Good() ) // any bytes to write?
|
||||
outSize = MORK_STRLEN(inString);
|
||||
if ( outSize && ev->Good() ) // any bytes to write?
|
||||
{
|
||||
this->Write(ev, inString, length);
|
||||
this->Write(ev, inString, outSize);
|
||||
}
|
||||
}
|
||||
return outSize;
|
||||
}
|
||||
|
||||
void
|
||||
mork_size
|
||||
morkStream::PutStringThenNewline(morkEnv* ev, const char* inString)
|
||||
// PutStringThenNewline() returns total number of bytes written.
|
||||
{
|
||||
mork_size outSize = 0;
|
||||
if ( inString )
|
||||
{
|
||||
mork_num length = MORK_STRLEN(inString);
|
||||
if ( length && ev->Good() ) // any bytes to write?
|
||||
outSize = MORK_STRLEN(inString);
|
||||
if ( outSize && ev->Good() ) // any bytes to write?
|
||||
{
|
||||
this->Write(ev, inString, length);
|
||||
this->Write(ev, inString, outSize);
|
||||
if ( ev->Good() )
|
||||
this->WriteNewlines(ev, /*count*/ 1);
|
||||
outSize += this->PutLineBreak(ev);
|
||||
}
|
||||
}
|
||||
return outSize;
|
||||
}
|
||||
|
||||
void
|
||||
mork_size
|
||||
morkStream::PutStringThenNewlineThenSpace(morkEnv* ev, const char* inString)
|
||||
// PutStringThenNewlineThenSpace() returns total number of bytes written.
|
||||
{
|
||||
mork_size outSize = 0;
|
||||
if ( inString )
|
||||
{
|
||||
mork_num length = MORK_STRLEN(inString);
|
||||
if ( length && ev->Good() ) // any bytes to write?
|
||||
outSize = MORK_STRLEN(inString);
|
||||
if ( outSize && ev->Good() ) // any bytes to write?
|
||||
{
|
||||
this->Write(ev, inString, length);
|
||||
this->Write(ev, inString, outSize);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
this->WriteNewlines(ev, /*count*/ 1);
|
||||
outSize += this->PutLineBreak(ev);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
this->Putc(ev, ' ');
|
||||
++outSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return outSize;
|
||||
}
|
||||
|
||||
void
|
||||
mork_size
|
||||
morkStream::PutByteThenNewline(morkEnv* ev, int inByte)
|
||||
// PutByteThenNewline() returns total number of bytes written.
|
||||
{
|
||||
mork_size outSize = 1; // one for the following byte
|
||||
this->Putc(ev, inByte);
|
||||
if ( ev->Good() )
|
||||
this->WriteNewlines(ev, /*count*/ 1);
|
||||
outSize += this->PutLineBreak(ev);
|
||||
return outSize;
|
||||
}
|
||||
|
||||
void
|
||||
mork_size
|
||||
morkStream::PutByteThenNewlineThenSpace(morkEnv* ev, int inByte)
|
||||
// PutByteThenNewlineThenSpace() returns total number of bytes written.
|
||||
{
|
||||
mork_size outSize = 1; // one for the following byte
|
||||
this->Putc(ev, inByte);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
this->WriteNewlines(ev, /*count*/ 1);
|
||||
outSize += this->PutLineBreak(ev);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
this->Putc(ev, ' ');
|
||||
++outSize;
|
||||
}
|
||||
}
|
||||
return outSize;
|
||||
}
|
||||
|
||||
mork_size
|
||||
morkStream::PutLineBreak(morkEnv* ev)
|
||||
{
|
||||
#ifdef MORK_MAC
|
||||
|
||||
this->Putc(ev, mork_kCR);
|
||||
return 1;
|
||||
|
||||
#else
|
||||
# if defined(MORK_WIN) || defined(MORK_OS2)
|
||||
|
||||
this->Putc(ev, mork_kCR);
|
||||
this->Putc(ev, mork_kLF);
|
||||
return 2;
|
||||
|
||||
# else
|
||||
# ifdef MORK_UNIX
|
||||
|
||||
this->Putc(ev, mork_kLF);
|
||||
return 1;
|
||||
|
||||
# endif /* MORK_UNIX */
|
||||
# endif /* MORK_WIN */
|
||||
#endif /* MORK_MAC */
|
||||
}
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
// public: // virtual morkFile methods
|
||||
|
||||
@ -719,13 +846,9 @@ morkStream::spill_buf(morkEnv* ev) // spill/flush from buffer to file
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef AB_CONFIG_TRACE
|
||||
this->TraceObject(ev);
|
||||
#endif /*AB_CONFIG_TRACE*/
|
||||
|
||||
#ifdef AB_CONFIG_DEBUG
|
||||
ev->Break("<ab:stream:spill:not:dirty me=\"^%lX\"/>", (long) this);
|
||||
#endif /*AB_CONFIG_DEBUG*/
|
||||
#ifdef MORK_DEBUG
|
||||
ev->NewWarning("stream:spill:not:dirty");
|
||||
#endif /*MORK_DEBUG*/
|
||||
}
|
||||
}
|
||||
else this->NewFileDownError(ev);
|
||||
|
@ -63,7 +63,7 @@
|
||||
**| else branch of the statement calls a function that raises an appropriate
|
||||
**| error to complain about either reading a sink or writing a source.
|
||||
**|
|
||||
**|| morkStream is a direct clone of mork_Stream from Communicator 4.5's
|
||||
**|| morkStream is a direct clone of ab_Stream from Communicator 4.5's
|
||||
**| address book code, which in turn was based on the stream class in the
|
||||
**| public domain Mithril programming language.
|
||||
|*/
|
||||
@ -164,11 +164,33 @@ public: // public non-poly morkStream methods
|
||||
morkFile* GetStreamContentFile() const { return mStream_ContentFile; }
|
||||
mork_size GetStreamBufferSize() const { return mStream_BufSize; }
|
||||
|
||||
void PutString(morkEnv* ev, const char* inString);
|
||||
void PutStringThenNewline(morkEnv* ev, const char* inString);
|
||||
void PutStringThenNewlineThenSpace(morkEnv* ev, const char* inString);
|
||||
void PutByteThenNewline(morkEnv* ev, int inByte);
|
||||
void PutByteThenNewlineThenSpace(morkEnv* ev, int inByte);
|
||||
mork_size PutIndent(morkEnv* ev, mork_count inDepth);
|
||||
// PutIndent() puts a linebreak, and then
|
||||
// "indents" by inDepth, and returns the line length after indentation.
|
||||
|
||||
mork_size PutByteThenIndent(morkEnv* ev, int inByte, mork_count inDepth);
|
||||
// PutByteThenIndent() puts the byte, then a linebreak, and then
|
||||
// "indents" by inDepth, and returns the line length after indentation.
|
||||
|
||||
mork_size PutStringThenIndent(morkEnv* ev,
|
||||
const char* inString, mork_count inDepth);
|
||||
// PutStringThenIndent() puts the string, then a linebreak, and then
|
||||
// "indents" by inDepth, and returns the line length after indentation.
|
||||
|
||||
mork_size PutString(morkEnv* ev, const char* inString);
|
||||
// PutString() returns the length of the string written.
|
||||
|
||||
mork_size PutStringThenNewline(morkEnv* ev, const char* inString);
|
||||
// PutStringThenNewline() returns total number of bytes written.
|
||||
|
||||
mork_size PutStringThenNewlineThenSpace(morkEnv* ev, const char* inString);
|
||||
// PutStringThenNewlineThenSpace() returns total number of bytes written.
|
||||
|
||||
mork_size PutByteThenNewline(morkEnv* ev, int inByte);
|
||||
// PutByteThenNewline() returns total number of bytes written.
|
||||
|
||||
mork_size PutByteThenNewlineThenSpace(morkEnv* ev, int inByte);
|
||||
// PutByteThenNewlineThenSpace() returns total number of bytes written.
|
||||
|
||||
// ````` ````` stdio type methods ````` `````
|
||||
void Printf(morkEnv* ev, const char* inFormat, ...);
|
||||
@ -201,6 +223,8 @@ public: // public non-poly morkStream methods
|
||||
else
|
||||
spill_putc(ev, c);
|
||||
}
|
||||
|
||||
mork_size PutLineBreak(morkEnv* ev);
|
||||
|
||||
public: // typesafe refcounting inlines calling inherited morkNode methods
|
||||
static void SlotWeakStream(morkStream* me,
|
||||
|
@ -120,6 +120,9 @@ morkWriter::morkWriter(morkEnv* ev, const morkUsage& inUsage,
|
||||
|
||||
, mWriter_TotalCount( morkWriter_kCountNumberOfPhases )
|
||||
, mWriter_DoneCount( 0 )
|
||||
|
||||
, mWriter_LineSize( 0 )
|
||||
, mWriter_MaxIndent( morkWriter_kMaxIndent )
|
||||
|
||||
, mWriter_TableCharset( 0 )
|
||||
, mWriter_TableAtomScope( 0 )
|
||||
@ -150,8 +153,11 @@ morkWriter::morkWriter(morkEnv* ev, const morkUsage& inUsage,
|
||||
, mWriter_RowSpaceTablesIter( )
|
||||
, mWriter_RowSpaceRowsIter( )
|
||||
{
|
||||
mWriter_SafeNameBuf[ 0 ] = 0;
|
||||
mWriter_SafeNameBuf[ morkWriter_kMaxColumnNameSize * 2 ] = 0;
|
||||
mWriter_ColNameBuf[ 0 ] = 0;
|
||||
mWriter_ColNameBuf[ morkWriter_kMaxColumnNameSize ] = 0;
|
||||
|
||||
mdbYarn* y = &mWriter_ColYarn;
|
||||
y->mYarn_Buf = mWriter_ColNameBuf; // where to put col bytes
|
||||
y->mYarn_Fill = 0; // set later by writer
|
||||
@ -160,6 +166,14 @@ morkWriter::morkWriter(morkEnv* ev, const morkUsage& inUsage,
|
||||
y->mYarn_Form = 0; // set later by writer
|
||||
y->mYarn_Grow = 0; // do not allow buffer growth
|
||||
|
||||
y = &mWriter_SafeYarn;
|
||||
y->mYarn_Buf = mWriter_SafeNameBuf; // where to put col bytes
|
||||
y->mYarn_Fill = 0; // set later by writer
|
||||
y->mYarn_Size = morkWriter_kMaxColumnNameSize * 2; // our buf size
|
||||
y->mYarn_More = 0; // set later by writer
|
||||
y->mYarn_Form = 0; // set later by writer
|
||||
y->mYarn_Grow = 0; // do not allow buffer growth
|
||||
|
||||
if ( ev->Good() )
|
||||
{
|
||||
if ( ioSlotHeap && ioFile && ioStore )
|
||||
@ -328,20 +342,66 @@ morkWriter::WriteMore(morkEnv* ev) // call until IsWritingDone() is true
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
void
|
||||
morkWriter::WriteAtom(morkEnv* ev, const morkAtom* inAtom)
|
||||
{
|
||||
morkBuf buf; // to ref content inside atom
|
||||
static const char* morkWriter_kHexDigits = "0123456789ABCDEF";
|
||||
|
||||
if ( inAtom->AsBuf(buf) )
|
||||
mork_size
|
||||
morkWriter::WriteYarn(morkEnv* ev, const mdbYarn* inYarn)
|
||||
// return number of atom bytes written on the current line (which
|
||||
// implies that escaped line breaks will make the size value smaller
|
||||
// than the entire yarn's size, since only part goes on a last line).
|
||||
{
|
||||
mork_size outSize = 0;
|
||||
morkStream* stream = mWriter_Stream;
|
||||
|
||||
const mork_u1* b = (const mork_u1*) inYarn->mYarn_Buf;
|
||||
if ( b )
|
||||
{
|
||||
// actually we need to escape problem characters instead of this:
|
||||
morkStream* stream = mWriter_Stream;
|
||||
if ( buf.mBuf_Fill ) // any content to write?
|
||||
stream->Write(ev, buf.mBuf_Body, buf.mBuf_Fill);
|
||||
register int c;
|
||||
mork_fill fill = inYarn->mYarn_Fill;
|
||||
const mork_u1* end = b + fill;
|
||||
while ( b < end )
|
||||
{
|
||||
c = *b++; // next byte to print
|
||||
if ( c < 0x080 && MORK_ISPRINT(c) )
|
||||
{
|
||||
if ( c == ')' && c == '$' && c == '\\' )
|
||||
{
|
||||
stream->Putc(ev, '\\');
|
||||
++outSize;
|
||||
}
|
||||
stream->Putc(ev, c);
|
||||
++outSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
outSize += 3; // '$' hex hex
|
||||
stream->Putc(ev, '$');
|
||||
stream->Putc(ev, morkWriter_kHexDigits[ (c >> 4) & 0x0F ]);
|
||||
stream->Putc(ev, morkWriter_kHexDigits[ c & 0x0F ]);
|
||||
}
|
||||
}
|
||||
}
|
||||
mWriter_LineSize += outSize;
|
||||
|
||||
return outSize;
|
||||
}
|
||||
|
||||
mork_size
|
||||
morkWriter::WriteAtom(morkEnv* ev, const morkAtom* inAtom)
|
||||
// return number of atom bytes written on the current line (which
|
||||
// implies that escaped line breaks will make the size value smaller
|
||||
// than the entire atom's size, since only part goes on a last line).
|
||||
{
|
||||
mork_size outSize = 0;
|
||||
mdbYarn yarn; // to ref content inside atom
|
||||
|
||||
if ( inAtom->AliasYarn(&yarn) )
|
||||
outSize = this->WriteYarn(ev, &yarn);
|
||||
// mWriter_LineSize += stream->Write(ev, inYarn->mYarn_Buf, outSize);
|
||||
else
|
||||
inAtom->BadAtomKindError(ev);
|
||||
|
||||
return outSize;
|
||||
}
|
||||
|
||||
void
|
||||
@ -351,10 +411,13 @@ morkWriter::WriteAtomSpaceAsDict(morkEnv* ev, morkAtomSpace* ioSpace)
|
||||
mork_scope scope = ioSpace->mSpace_Scope;
|
||||
if ( scope < 0x80 )
|
||||
{
|
||||
stream->WriteNewlines(ev, /*count*/ 1);
|
||||
stream->PutString(ev, "<<(atomScope=");
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
stream->PutString(ev, "< <(atomScope=");
|
||||
stream->Putc(ev, (int) scope);
|
||||
stream->PutStringThenNewline(ev, ")> // (charset=iso-8859-1)");
|
||||
++mWriter_LineSize;
|
||||
stream->PutString(ev, ")> // (charset=iso-8859-1)");
|
||||
mWriter_LineSize = stream->PutIndent(ev, morkWriter_kDictAliasDepth);
|
||||
}
|
||||
else
|
||||
ioSpace->NonAsciiSpaceScopeName(ev);
|
||||
@ -379,11 +442,18 @@ morkWriter::WriteAtomSpaceAsDict(morkEnv* ev, morkAtomSpace* ioSpace)
|
||||
{
|
||||
atom->mAtom_Change = morkChange_kNil; // neutralize change
|
||||
|
||||
this->IndentAsNeeded(ev, morkWriter_kDictAliasDepth);
|
||||
mork_size size = ev->TokenAsHex(idBuf, atom->mBookAtom_Id);
|
||||
idBuf[ size ] = '=';
|
||||
stream->Write(ev, buf, size+2); // plus two for '(' and '='
|
||||
mWriter_LineSize += stream->Write(ev, buf, size+1); // '('
|
||||
|
||||
this->IndentAsNeeded(ev, morkWriter_kDictAliasValueDepth);
|
||||
stream->Putc(ev, '='); // end alias
|
||||
++mWriter_LineSize;
|
||||
|
||||
this->WriteAtom(ev, atom);
|
||||
stream->PutByteThenNewlineThenSpace(ev, ')'); // end alias
|
||||
stream->Putc(ev, ')'); // end alias
|
||||
++mWriter_LineSize;
|
||||
|
||||
++mWriter_DoneCount;
|
||||
}
|
||||
else // temporarily warn about wrong change slot value
|
||||
@ -396,7 +466,10 @@ morkWriter::WriteAtomSpaceAsDict(morkEnv* ev, morkAtomSpace* ioSpace)
|
||||
}
|
||||
|
||||
if ( ev->Good() )
|
||||
{
|
||||
this->IndentAsNeeded(ev, 0);
|
||||
stream->PutByteThenNewline(ev, '>'); // end dict
|
||||
}
|
||||
}
|
||||
|
||||
mork_bool
|
||||
@ -556,6 +629,7 @@ morkWriter::OnDirtyAllDone(morkEnv* ev)
|
||||
if ( ev->Good() )
|
||||
{
|
||||
stream->PutStringThenNewline(ev, "// <!-- <mdb:mork:z v=\"1.1\"/> -->");
|
||||
mWriter_LineSize = 0;
|
||||
}
|
||||
|
||||
if ( ev->Good() )
|
||||
@ -570,8 +644,10 @@ mork_bool
|
||||
morkWriter::OnPutHeaderDone(morkEnv* ev)
|
||||
{
|
||||
morkStream* stream = mWriter_Stream;
|
||||
stream->WriteNewlines(ev, /*count*/ 1);
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
stream->PutStringThenNewline(ev, "// OnPutHeaderDone()");
|
||||
mWriter_LineSize = 0;
|
||||
|
||||
morkStore* store = mWriter_Store;
|
||||
if ( store )
|
||||
@ -591,8 +667,10 @@ mork_bool
|
||||
morkWriter::OnRenumberAllDone(morkEnv* ev)
|
||||
{
|
||||
morkStream* stream = mWriter_Stream;
|
||||
stream->WriteNewlines(ev, /*count*/ 1);
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
stream->PutStringThenNewline(ev, "// OnRenumberAllDone()");
|
||||
mWriter_LineSize = 0;
|
||||
|
||||
if ( ev->Good() )
|
||||
mWriter_Phase = morkWriter_kPhaseStoreAtomSpaces;
|
||||
@ -606,8 +684,10 @@ mork_bool
|
||||
morkWriter::OnStoreAtomSpaces(morkEnv* ev)
|
||||
{
|
||||
morkStream* stream = mWriter_Stream;
|
||||
stream->WriteNewlines(ev, /*count*/ 1);
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
stream->PutStringThenNewline(ev, "// OnStoreAtomSpaces()");
|
||||
mWriter_LineSize = 0;
|
||||
|
||||
if ( ev->Good() )
|
||||
{
|
||||
@ -618,6 +698,7 @@ morkWriter::OnStoreAtomSpaces(morkEnv* ev)
|
||||
if ( space )
|
||||
{
|
||||
stream->PutStringThenNewline(ev, "// ground column space dict:");
|
||||
mWriter_LineSize = 0;
|
||||
this->WriteAtomSpaceAsDict(ev, space);
|
||||
}
|
||||
}
|
||||
@ -637,8 +718,10 @@ mork_bool
|
||||
morkWriter::OnAtomSpaceAtomAids(morkEnv* ev)
|
||||
{
|
||||
morkStream* stream = mWriter_Stream;
|
||||
stream->WriteNewlines(ev, /*count*/ 1);
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
stream->PutStringThenNewline(ev, "// OnAtomSpaceAtomAids()");
|
||||
mWriter_LineSize = 0;
|
||||
|
||||
if ( ev->Good() )
|
||||
mWriter_Phase = morkWriter_kPhaseStoreRowSpacesTables;
|
||||
@ -711,8 +794,10 @@ mork_bool
|
||||
morkWriter::OnStoreRowSpacesTables(morkEnv* ev)
|
||||
{
|
||||
morkStream* stream = mWriter_Stream;
|
||||
stream->WriteNewlines(ev, /*count*/ 1);
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
stream->PutStringThenNewline(ev, "// OnStoreRowSpacesTables()");
|
||||
mWriter_LineSize = 0;
|
||||
|
||||
// later we'll break this up, but today we'll write all in one shot:
|
||||
this->WriteAllStoreTables(ev);
|
||||
@ -729,8 +814,10 @@ mork_bool
|
||||
morkWriter::OnRowSpaceTables(morkEnv* ev)
|
||||
{
|
||||
morkStream* stream = mWriter_Stream;
|
||||
stream->WriteNewlines(ev, /*count*/ 1);
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
stream->PutStringThenNewline(ev, "// OnRowSpaceTables()");
|
||||
mWriter_LineSize = 0;
|
||||
|
||||
if ( ev->Good() )
|
||||
mWriter_Phase = morkWriter_kPhaseStoreRowSpacesRows;
|
||||
@ -744,8 +831,10 @@ mork_bool
|
||||
morkWriter::OnTableRowArray(morkEnv* ev)
|
||||
{
|
||||
morkStream* stream = mWriter_Stream;
|
||||
stream->WriteNewlines(ev, /*count*/ 1);
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
stream->PutStringThenNewline(ev, "// OnTableRowArray()");
|
||||
mWriter_LineSize = 0;
|
||||
|
||||
if ( ev->Good() )
|
||||
mWriter_Phase = morkWriter_kPhaseStoreRowSpacesRows;
|
||||
@ -759,8 +848,10 @@ mork_bool
|
||||
morkWriter::OnStoreRowSpacesRows(morkEnv* ev)
|
||||
{
|
||||
morkStream* stream = mWriter_Stream;
|
||||
stream->WriteNewlines(ev, /*count*/ 1);
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
stream->PutStringThenNewline(ev, "// OnStoreRowSpacesRows()");
|
||||
mWriter_LineSize = 0;
|
||||
|
||||
if ( ev->Good() )
|
||||
mWriter_Phase = morkWriter_kPhaseContentDone;
|
||||
@ -774,8 +865,10 @@ mork_bool
|
||||
morkWriter::OnRowSpaceRows(morkEnv* ev)
|
||||
{
|
||||
morkStream* stream = mWriter_Stream;
|
||||
stream->WriteNewlines(ev, /*count*/ 1);
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
stream->PutStringThenNewline(ev, "// OnRowSpaceRows()");
|
||||
mWriter_LineSize = 0;
|
||||
|
||||
if ( ev->Good() )
|
||||
mWriter_Phase = morkWriter_kPhaseContentDone;
|
||||
@ -789,8 +882,10 @@ mork_bool
|
||||
morkWriter::OnContentDone(morkEnv* ev)
|
||||
{
|
||||
morkStream* stream = mWriter_Stream;
|
||||
stream->WriteNewlines(ev, /*count*/ 1);
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
stream->PutStringThenNewline(ev, "// OnContentDone()");
|
||||
mWriter_LineSize = 0;
|
||||
stream->Flush(ev);
|
||||
morkFile* bud = mWriter_Bud;
|
||||
if ( bud )
|
||||
@ -820,7 +915,7 @@ mork_bool
|
||||
morkWriter::PutTable(morkEnv* ev, morkTable* ioTable)
|
||||
{
|
||||
if ( ev->Good() )
|
||||
this->StartTable(ev, ioTable->mTable_Id);
|
||||
this->StartTable(ev, ioTable);
|
||||
|
||||
if ( ev->Good() )
|
||||
{
|
||||
@ -904,13 +999,21 @@ morkWriter::WriteTokenToTokenMetaCell(morkEnv* ev,
|
||||
*p++ = '^'; // indicates col is hex ID
|
||||
|
||||
mork_size colSize = ev->TokenAsHex(p, inCol);
|
||||
p += colSize; // advance past the col in hex
|
||||
*p++ = ' '; // space between hex IDs
|
||||
*p++ = '^'; // indicates value is hex ID
|
||||
mork_size valSize = ev->TokenAsHex(p, inValue);
|
||||
p += valSize; // advance past the value in hex
|
||||
*p = ')';
|
||||
stream->Write(ev, buf, colSize + valSize + 5);
|
||||
p += colSize;
|
||||
*p++ = '='; // we always start with open paren
|
||||
mWriter_LineSize += stream->Write(ev, buf, colSize + 3);
|
||||
|
||||
this->IndentAsNeeded(ev, morkWriter_kTableMetaCellValueDepth);
|
||||
mdbYarn* yarn = &mWriter_ColYarn;
|
||||
// mork_u1* yarnBuf = (mork_u1*) yarn->mYarn_Buf;
|
||||
mWriter_Store->TokenToString(ev, inValue, yarn);
|
||||
this->WriteYarn(ev, yarn);
|
||||
stream->Putc(ev, ')');
|
||||
++mWriter_LineSize;
|
||||
|
||||
// mork_fill fill = yarn->mYarn_Fill;
|
||||
// yarnBuf[ fill ] = ')'; // append terminator
|
||||
// mWriter_LineSize += stream->Write(ev, yarnBuf, fill + 1); // +1 for ')'
|
||||
}
|
||||
|
||||
void
|
||||
@ -918,14 +1021,20 @@ morkWriter::WriteStringToTokenDictCell(morkEnv* ev,
|
||||
const char* inCol, mork_token inValue)
|
||||
// Note inCol should begin with '(' and end with '=', with col in between.
|
||||
{
|
||||
mdbYarn* yarn = &mWriter_ColYarn;
|
||||
mork_u1* yarnBuf = (mork_u1*) yarn->mYarn_Buf;
|
||||
morkStream* stream = mWriter_Stream;
|
||||
stream->PutString(ev, inCol);
|
||||
mWriter_LineSize += stream->PutString(ev, inCol);
|
||||
|
||||
this->IndentAsNeeded(ev, morkWriter_kDictMetaCellValueDepth);
|
||||
mdbYarn* yarn = &mWriter_ColYarn;
|
||||
// mork_u1* yarnBuf = (mork_u1*) yarn->mYarn_Buf;
|
||||
mWriter_Store->TokenToString(ev, inValue, yarn);
|
||||
mork_fill fill = yarn->mYarn_Fill;
|
||||
yarnBuf[ fill ] = ')'; // append terminator
|
||||
stream->Write(ev, yarnBuf, fill + 1); // plus one for ')'
|
||||
this->WriteYarn(ev, yarn);
|
||||
stream->Putc(ev, ')');
|
||||
++mWriter_LineSize;
|
||||
|
||||
// mork_fill fill = yarn->mYarn_Fill;
|
||||
// yarnBuf[ fill ] = ')'; // append terminator
|
||||
// mWriter_LineSize += stream->Write(ev, yarnBuf, fill + 1); // +1 for ')'
|
||||
}
|
||||
|
||||
void
|
||||
@ -934,28 +1043,35 @@ morkWriter::StartDict(morkEnv* ev)
|
||||
morkStream* stream = mWriter_Stream;
|
||||
if ( mWriter_DidStartDict )
|
||||
{
|
||||
stream->WriteNewlines(ev, /*count*/ 1);
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
stream->PutStringThenNewline(ev, "> // end dict");
|
||||
mWriter_LineSize = 0;
|
||||
}
|
||||
mWriter_DidStartDict = morkBool_kTrue;
|
||||
|
||||
stream->WriteNewlines(ev, /*count*/ 1);
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
mWriter_LineSize = 0;
|
||||
if ( mWriter_DictCharset || mWriter_DictAtomScope != 'a' )
|
||||
{
|
||||
stream->Putc(ev, '<');
|
||||
stream->Putc(ev, ' ');
|
||||
stream->Putc(ev, '<');
|
||||
mWriter_LineSize = 3;
|
||||
if ( mWriter_DictCharset )
|
||||
this->WriteStringToTokenDictCell(ev, "(charset=", mWriter_DictCharset);
|
||||
if ( mWriter_DictAtomScope != 'a' )
|
||||
this->WriteStringToTokenDictCell(ev, "(atomScope=", mWriter_DictAtomScope);
|
||||
|
||||
stream->PutByteThenNewlineThenSpace(ev, '>');
|
||||
stream->Putc(ev, '>');
|
||||
++mWriter_LineSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
stream->PutStringThenNewlineThenSpace(ev,
|
||||
"< // <(charset=iso-8859-1)(atomScope=a)>");
|
||||
stream->PutString(ev, "< // <(charset=iso-8859-1)(atomScope=a)>");
|
||||
}
|
||||
mWriter_LineSize = stream->PutIndent(ev, morkWriter_kDictAliasDepth);
|
||||
}
|
||||
|
||||
void
|
||||
@ -964,45 +1080,63 @@ morkWriter::EndDict(morkEnv* ev)
|
||||
morkStream* stream = mWriter_Stream;
|
||||
if ( mWriter_DidStartDict )
|
||||
{
|
||||
stream->WriteNewlines(ev, /*count*/ 1);
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
stream->PutStringThenNewline(ev, "> // end dict");
|
||||
mWriter_LineSize = 0;
|
||||
}
|
||||
mWriter_DidStartDict = morkBool_kFalse;
|
||||
}
|
||||
|
||||
void
|
||||
morkWriter::StartTable(morkEnv* ev, mork_tid inTid)
|
||||
morkWriter::StartTable(morkEnv* ev, morkTable* ioTable)
|
||||
{
|
||||
morkStream* stream = mWriter_Stream;
|
||||
stream->WriteNewlines(ev, /*count*/ 1);
|
||||
|
||||
char buf[ 64 ]; // buffer for staging hex
|
||||
char* p = buf;
|
||||
*p++ = '{';
|
||||
mork_size size = ev->TokenAsHex(p, inTid);
|
||||
p += size;
|
||||
*p++ = ' ';
|
||||
*p = '{';
|
||||
stream->Write(ev, buf, size + 3);
|
||||
mdbOid toid; // to receive table oid
|
||||
ioTable->GetTableOid(ev, &toid);
|
||||
|
||||
morkStore* store = mWriter_Store;
|
||||
mork_scope rs = mWriter_TableRowScope;
|
||||
if ( rs )
|
||||
this->WriteTokenToTokenMetaCell(ev, store->mStore_RowScopeToken, rs);
|
||||
|
||||
mork_kind tk = mWriter_TableKind;
|
||||
if ( tk )
|
||||
this->WriteTokenToTokenMetaCell(ev, store->mStore_TableKindToken, tk);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
morkStream* stream = mWriter_Stream;
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
mWriter_LineSize = 0;
|
||||
|
||||
stream->PutByteThenNewlineThenSpace(ev, '}');
|
||||
char buf[ 64 ]; // buffer for staging hex
|
||||
char* p = buf;
|
||||
*p++ = '{';
|
||||
mork_size size = ev->OidAsHex(p, toid);
|
||||
p += size;
|
||||
*p++ = ' ';
|
||||
*p = '{';
|
||||
mWriter_LineSize += stream->Write(ev, buf, size + 3);
|
||||
|
||||
morkStore* store = mWriter_Store;
|
||||
mork_scope rs = mWriter_TableRowScope;
|
||||
if ( rs )
|
||||
{
|
||||
this->IndentAsNeeded(ev, morkWriter_kTableMetaCellDepth);
|
||||
this->WriteTokenToTokenMetaCell(ev, store->mStore_RowScopeToken, rs);
|
||||
}
|
||||
mork_kind tk = mWriter_TableKind;
|
||||
if ( tk )
|
||||
{
|
||||
this->IndentAsNeeded(ev, morkWriter_kTableMetaCellDepth);
|
||||
this->WriteTokenToTokenMetaCell(ev, store->mStore_TableKindToken, tk);
|
||||
}
|
||||
stream->Putc(ev, '}');
|
||||
stream->Putc(ev, ' ');
|
||||
mWriter_LineSize += 2;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
morkWriter::EndTable(morkEnv* ev)
|
||||
{
|
||||
morkStream* stream = mWriter_Stream;
|
||||
stream->WriteNewlines(ev, /*count*/ 1);
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
stream->PutStringThenNewline(ev, "} // end table");
|
||||
mWriter_LineSize = 0;
|
||||
}
|
||||
|
||||
mork_bool
|
||||
@ -1018,7 +1152,7 @@ morkWriter::PutRowDict(morkEnv* ev, morkRow* ioRow)
|
||||
|
||||
morkCell* end = cells + ioRow->mRow_Length;
|
||||
--cells; // prepare for preincrement:
|
||||
while ( ++cells < end )
|
||||
while ( ++cells < end && ev->Good() )
|
||||
{
|
||||
morkAtom* atom = cells->GetAtom();
|
||||
if ( atom && atom->mAtom_Change == morkChange_kAdd )
|
||||
@ -1027,12 +1161,19 @@ morkWriter::PutRowDict(morkEnv* ev, morkRow* ioRow)
|
||||
{
|
||||
atom->mAtom_Change = morkChange_kNil; // neutralize change
|
||||
|
||||
this->IndentAsNeeded(ev, morkWriter_kDictAliasDepth);
|
||||
morkBookAtom* ba = (morkBookAtom*) atom;
|
||||
mork_size size = ev->TokenAsHex(idBuf, ba->mBookAtom_Id);
|
||||
idBuf[ size ] = '=';
|
||||
stream->Write(ev, buf, size+2); // plus two for '(' and '='
|
||||
mWriter_LineSize += stream->Write(ev, buf, size+1); // '('
|
||||
|
||||
this->IndentAsNeeded(ev, morkWriter_kDictAliasValueDepth);
|
||||
stream->Putc(ev, '='); // start value
|
||||
++mWriter_LineSize;
|
||||
|
||||
this->WriteAtom(ev, atom);
|
||||
stream->PutByteThenNewlineThenSpace(ev, ')'); // end alias
|
||||
stream->Putc(ev, ')'); // end alias
|
||||
++mWriter_LineSize;
|
||||
|
||||
++mWriter_DoneCount;
|
||||
}
|
||||
}
|
||||
@ -1067,17 +1208,16 @@ 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?
|
||||
{
|
||||
*p++ = ' ';
|
||||
*p++ = '^';
|
||||
morkBookAtom* ba = (morkBookAtom*) atom;
|
||||
mork_size valSize = ev->TokenAsHex(p, ba->mBookAtom_Id);
|
||||
p += valSize;
|
||||
*p = ')';
|
||||
stream->Write(ev, buf, colSize + valSize + 5);
|
||||
stream->WriteNewlines(ev, /*count*/ 1);
|
||||
stream->Putc(ev, ' ');
|
||||
|
||||
mWriter_LineSize += stream->Write(ev, buf, colSize + valSize + 4);
|
||||
|
||||
if ( atom->mAtom_Change == morkChange_kAdd )
|
||||
{
|
||||
@ -1087,10 +1227,15 @@ morkWriter::PutRowCells(morkEnv* ev, morkRow* ioRow)
|
||||
}
|
||||
else // must write an anonymous atom
|
||||
{
|
||||
*p++ = '=';
|
||||
stream->Write(ev, buf, colSize + 3);
|
||||
mWriter_LineSize += stream->Write(ev, buf, colSize + 2);
|
||||
|
||||
this->IndentAsNeeded(ev, morkWriter_kRowCellValueDepth);
|
||||
stream->Putc(ev, '=');
|
||||
++mWriter_LineSize;
|
||||
|
||||
this->WriteAtom(ev, atom);
|
||||
stream->PutByteThenNewlineThenSpace(ev, ')'); // end alias
|
||||
stream->Putc(ev, ')'); // end alias
|
||||
++mWriter_LineSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1107,7 +1252,10 @@ morkWriter::PutRow(morkEnv* ev, morkRow* ioRow)
|
||||
mdbOid* roid = &ioRow->mRow_Oid;
|
||||
mork_size ridSize = 0;
|
||||
|
||||
if ( ioRow->IsRowDirty() )
|
||||
this->IndentAsNeeded(ev, morkWriter_kRowDepth);
|
||||
|
||||
// if ( ioRow->IsRowDirty() )
|
||||
if ( morkBool_kTrue )
|
||||
{
|
||||
ioRow->SetRowClean();
|
||||
mork_rid rid = roid->mOid_Id;
|
||||
@ -1119,10 +1267,12 @@ morkWriter::PutRow(morkEnv* ev, morkRow* ioRow)
|
||||
|
||||
p += ridSize;
|
||||
*p++ = ' ';
|
||||
stream->Write(ev, buf, ridSize + 2);
|
||||
mWriter_LineSize += stream->Write(ev, buf, ridSize + 2);
|
||||
|
||||
this->PutRowCells(ev, ioRow);
|
||||
stream->PutByteThenNewlineThenSpace(ev, ']'); // end row
|
||||
stream->Putc(ev, ']'); // end row
|
||||
stream->Putc(ev, ' '); // end row
|
||||
mWriter_LineSize += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1131,9 +1281,9 @@ morkWriter::PutRow(morkEnv* ev, morkRow* ioRow)
|
||||
else
|
||||
ridSize = ev->OidAsHex(p, *roid);
|
||||
|
||||
stream->Write(ev, buf, ridSize);
|
||||
stream->WriteNewlines(ev, /*count*/ 1);
|
||||
mWriter_LineSize += stream->Write(ev, buf, ridSize);
|
||||
stream->Putc(ev, ' ');
|
||||
++mWriter_LineSize;
|
||||
}
|
||||
|
||||
++mWriter_DoneCount;
|
||||
|
@ -51,6 +51,10 @@
|
||||
#include "morkRowSpace.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKSTREAM_
|
||||
#include "morkStream.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
|
||||
@ -79,7 +83,22 @@
|
||||
|
||||
#define morkWriter_kCountNumberOfPhases 13 /* part of mWrite_TotalCount */
|
||||
|
||||
#define morkWriter_kMaxColumnNameSize 256 /* longest writable col name */
|
||||
#define morkWriter_kMaxColumnNameSize 128 /* longest writable col name */
|
||||
|
||||
#define morkWriter_kMaxIndent 48 /* default value for mWriter_MaxIndent */
|
||||
|
||||
#define morkWriter_kTableMetaCellDepth 4 /* */
|
||||
#define morkWriter_kTableMetaCellValueDepth 6 /* */
|
||||
|
||||
#define morkWriter_kDictMetaCellDepth 4 /* */
|
||||
#define morkWriter_kDictMetaCellValueDepth 6 /* */
|
||||
|
||||
#define morkWriter_kDictAliasDepth 2 /* */
|
||||
#define morkWriter_kDictAliasValueDepth 4 /* */
|
||||
|
||||
#define morkWriter_kRowDepth 2 /* */
|
||||
#define morkWriter_kRowCellDepth 4 /* */
|
||||
#define morkWriter_kRowCellValueDepth 6 /* */
|
||||
|
||||
class morkWriter : public morkNode { // row iterator
|
||||
|
||||
@ -105,6 +124,9 @@ public: // state is public because the entire Mork system is private
|
||||
mork_count mWriter_TotalCount; // count of all things to be written
|
||||
mork_count mWriter_DoneCount; // count of things already written
|
||||
|
||||
mork_size mWriter_LineSize; // length of current line being written
|
||||
mork_size mWriter_MaxIndent; // line size forcing a line break
|
||||
|
||||
mork_cscode mWriter_TableCharset; // current charset metainfo
|
||||
mork_scope mWriter_TableAtomScope; // current atom scope
|
||||
mork_scope mWriter_TableRowScope; // current row scope
|
||||
@ -125,12 +147,18 @@ public: // state is public because the entire Mork system is private
|
||||
mork_bool mWriter_DidEndDict; // true when a dict has been ended
|
||||
|
||||
mork_pos mWriter_TableRowArrayPos; // index into mTable_RowArray
|
||||
|
||||
|
||||
char mWriter_SafeNameBuf[ (morkWriter_kMaxColumnNameSize * 2) + 4 ];
|
||||
// Note: extra four bytes in ColNameBuf means we can always append to yarn
|
||||
|
||||
char mWriter_ColNameBuf[ morkWriter_kMaxColumnNameSize + 4 ];
|
||||
// Note: extra four bytes in ColNameBuf means we can always append to yarn
|
||||
|
||||
mdbYarn mWriter_ColYarn; // a yarn to describe space in ColNameBuf:
|
||||
// mYarn_Buf == mWriter_ColNameBuf, mYarn_Size == morkWriter_kMaxColumnNameSize
|
||||
|
||||
mdbYarn mWriter_SafeYarn; // a yarn to describe space in ColNameBuf:
|
||||
// mYarn_Buf == mWriter_SafeNameBuf, mYarn_Size == (kMaxColumnNameSize * 2)
|
||||
|
||||
morkAtomSpaceMapIter mWriter_StoreAtomSpacesIter; // for mStore_AtomSpaces
|
||||
morkAtomAidMapIter mWriter_AtomSpaceAtomAidsIter; // for AtomSpace_AtomAids
|
||||
@ -169,6 +197,15 @@ public: // typing & errors
|
||||
public: // inlines
|
||||
mork_bool DidStartDict() const { return mWriter_DidStartDict; }
|
||||
mork_bool DidEndDict() const { return mWriter_DidEndDict; }
|
||||
|
||||
mork_bool NeedLineBreak() const
|
||||
{ return ( mWriter_LineSize > mWriter_MaxIndent ); }
|
||||
|
||||
void IndentAsNeeded(morkEnv* ev, mork_size inDepth)
|
||||
{
|
||||
if ( mWriter_LineSize > mWriter_MaxIndent )
|
||||
mWriter_LineSize = mWriter_Stream->PutIndent(ev, inDepth);
|
||||
}
|
||||
|
||||
public: // iterative/asynchronouse writing
|
||||
|
||||
@ -220,8 +257,17 @@ public: // writing node content second pass
|
||||
|
||||
public: // other writer methods
|
||||
|
||||
mork_size WriteYarn(morkEnv* ev, const mdbYarn* inYarn);
|
||||
// return number of atom bytes written on the current line (which
|
||||
// implies that escaped line breaks will make the size value smaller
|
||||
// than the entire yarn's size, since only part goes on a last line).
|
||||
|
||||
mork_size WriteAtom(morkEnv* ev, const morkAtom* inAtom);
|
||||
// return number of atom bytes written on the current line (which
|
||||
// implies that escaped line breaks will make the size value smaller
|
||||
// than the entire atom's size, since only part goes on a last line).
|
||||
|
||||
void WriteAllStoreTables(morkEnv* ev);
|
||||
void WriteAtom(morkEnv* ev, const morkAtom* inAtom);
|
||||
void WriteAtomSpaceAsDict(morkEnv* ev, morkAtomSpace* ioSpace);
|
||||
|
||||
void WriteTokenToTokenMetaCell(morkEnv* ev, mork_token inCol,
|
||||
@ -233,7 +279,7 @@ public: // other writer methods
|
||||
void StartDict(morkEnv* ev);
|
||||
void EndDict(morkEnv* ev);
|
||||
|
||||
void StartTable(morkEnv* ev, mork_tid inTid);
|
||||
void StartTable(morkEnv* ev, morkTable* ioTable);
|
||||
void EndTable(morkEnv* ev);
|
||||
|
||||
public: // typesafe refcounting inlines calling inherited morkNode methods
|
||||
|
@ -48,13 +48,16 @@
|
||||
#endif
|
||||
// } %%%%% end platform defs peculiar to Mork %%%%%
|
||||
|
||||
#if defined (MORK_WIN) || defined(MORK_UNIX)
|
||||
#if defined (MORK_WIN) || defined(MORK_UNIX)
|
||||
#include "stdio.h"
|
||||
#include "ctype.h"
|
||||
#include "errno.h"
|
||||
#include "string.h"
|
||||
#include "memory.h"
|
||||
#include "nsDebug.h"
|
||||
|
||||
#define MORK_ISPRINT(c) isprint(c)
|
||||
|
||||
#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)
|
||||
@ -64,6 +67,9 @@
|
||||
|
||||
#ifdef MORK_MAC
|
||||
#include "xp_file.h"
|
||||
#include "ctype.h"
|
||||
|
||||
#define MORK_ISPRINT(c) isprint(c)
|
||||
|
||||
#define MORK_FILETELL(file) XP_FileTell(file)
|
||||
#define MORK_FILESEEK(file, where, how) XP_FileSeek(file, where, how)
|
||||
|
@ -239,18 +239,23 @@ morkFile::NewFileErrnoError(morkEnv* ev) const
|
||||
# endif /* MORK_WIN */
|
||||
#endif /* MORK_MAC */
|
||||
|
||||
void
|
||||
mork_size
|
||||
morkFile::WriteNewlines(morkEnv* ev, mork_count inNewlines)
|
||||
// WriteNewlines() returns the number of bytes written.
|
||||
{
|
||||
mork_size outSize = 0;
|
||||
while ( inNewlines && ev->Good() ) // more newlines to write?
|
||||
{
|
||||
mork_u4 quantum = inNewlines;
|
||||
if ( quantum > morkFile_kNewlinesCount )
|
||||
quantum = morkFile_kNewlinesCount;
|
||||
|
||||
this->Write(ev, morkFile_kNewlines, quantum * mork_kNewlineSize);
|
||||
mork_size quantumSize = quantum * mork_kNewlineSize;
|
||||
this->Write(ev, morkFile_kNewlines, quantumSize);
|
||||
outSize += quantumSize;
|
||||
inNewlines -= quantum;
|
||||
}
|
||||
return outSize;
|
||||
}
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
@ -309,7 +314,7 @@ morkStdioFile::OpenOldStdioFile(morkEnv* ev, nsIMdbHeap* ioHeap,
|
||||
morkStdioFile* outFile = 0;
|
||||
if ( ioHeap && inFilePath )
|
||||
{
|
||||
const char* mode = (inFrozen)? "r" : "w";
|
||||
const char* mode = (inFrozen)? "rb" : "wb";
|
||||
outFile = new(*ioHeap, ev)
|
||||
morkStdioFile(ev, morkUsage::kHeap, ioHeap, ioHeap, inFilePath, mode);
|
||||
|
||||
@ -331,7 +336,7 @@ morkStdioFile::CreateNewStdioFile(morkEnv* ev, nsIMdbHeap* ioHeap,
|
||||
morkStdioFile* outFile = 0;
|
||||
if ( ioHeap && inFilePath )
|
||||
{
|
||||
const char* mode = "w+";
|
||||
const char* mode = "wb+";
|
||||
outFile = new(*ioHeap, ev)
|
||||
morkStdioFile(ev, morkUsage::kHeap, ioHeap, ioHeap, inFilePath, mode);
|
||||
}
|
||||
@ -386,7 +391,7 @@ morkStdioFile::AcquireBud(morkEnv* ev, nsIMdbHeap* ioHeap)
|
||||
this->SetFileIoOpen(morkBool_kFalse);
|
||||
mStdioFile_File = 0;
|
||||
|
||||
file = fopen(name, "w+"); // open for write, discarding old content
|
||||
file = fopen(name, "wb+"); // open for write, discarding old content
|
||||
if ( file )
|
||||
{
|
||||
mStdioFile_File = file;
|
||||
|
@ -159,7 +159,8 @@ public: // non-poly morkFile methods
|
||||
void NewFileErrnoError(morkEnv* ev) const;
|
||||
// call NewFileErrnoError() to convert std C errno into AB fault
|
||||
|
||||
void WriteNewlines(morkEnv* ev, mork_count inNewlines);
|
||||
mork_size WriteNewlines(morkEnv* ev, mork_count inNewlines);
|
||||
// WriteNewlines() returns the number of bytes written.
|
||||
|
||||
public: // typesafe refcounting inlines calling inherited morkNode methods
|
||||
static void SlotWeakFile(morkFile* me,
|
||||
|
@ -44,6 +44,14 @@
|
||||
#include "morkStream.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKBLOB_
|
||||
#include "morkBlob.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKSINK_
|
||||
#include "morkSink.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
@ -131,6 +139,10 @@ morkParser::CloseParser(morkEnv* ev) /*i*/ // called by CloseMorkNode();
|
||||
{
|
||||
if ( !this->IsShutNode() )
|
||||
{
|
||||
mParser_ScopeSpool.CloseSpool(ev);
|
||||
mParser_ValueSpool.CloseSpool(ev);
|
||||
mParser_ColumnSpool.CloseSpool(ev);
|
||||
mParser_StringSpool.CloseSpool(ev);
|
||||
nsIMdbHeap_SlotStrongHeap((nsIMdbHeap*) 0, ev, &mParser_Heap);
|
||||
morkStream::SlotStrongStream((morkStream*) 0, ev, &mParser_Stream);
|
||||
this->MarkShut();
|
||||
|
@ -209,73 +209,73 @@ class morkParser /*d*/ : public morkNode {
|
||||
protected: // protected morkParser members
|
||||
|
||||
nsIMdbHeap* mParser_Heap; // refcounted heap used for allocation
|
||||
morkStream* mParser_Stream; // refcounted input stream
|
||||
|
||||
mork_u4 mParser_Tag; // must equal morkParser_kTag
|
||||
mork_count mParser_MoreGranularity; // constructor inBytesPerParseSegment
|
||||
morkStream* mParser_Stream; // refcounted input stream
|
||||
|
||||
mork_u4 mParser_State; // state where parser should resume
|
||||
|
||||
// after finding ends of group transactions, we can re-seek the start:
|
||||
mork_pos mParser_GroupContentStartPos; // start of this group
|
||||
|
||||
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?
|
||||
|
||||
mork_bool mParser_InPortRow; // called OnNewPortRow but not OnPortRowEnd?
|
||||
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
|
||||
|
||||
morkAlias mParser_Alias; // current alias being parsed
|
||||
// note that mParser_Alias.mAlias_Buf points at mParser_ScopeSpool 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
|
||||
|
||||
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
|
||||
mork_u4 mParser_Tag; // must equal morkParser_kTag
|
||||
mork_count mParser_MoreGranularity; // constructor inBytesPerParseSegment
|
||||
|
||||
mork_u4 mParser_State; // state where parser should resume
|
||||
|
||||
// after finding ends of group transactions, we can re-seek the start:
|
||||
mork_pos mParser_GroupContentStartPos; // start of this group
|
||||
|
||||
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?
|
||||
|
||||
mork_bool mParser_InPortRow; // called OnNewPortRow but not OnPortRowEnd?
|
||||
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
|
||||
|
||||
morkAlias mParser_Alias; // current alias being parsed
|
||||
// note that mParser_Alias.mAlias_Buf points at mParser_ScopeSpool 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
|
||||
|
||||
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
|
||||
|
||||
// yarns allocated in mParser_Heap
|
||||
morkYarn mParser_AliasYarn; // place to receive from AliasToYarn()
|
||||
|
||||
// yarns allocated in mParser_Heap
|
||||
morkYarn mParser_AliasYarn; // place to receive from AliasToYarn()
|
||||
|
||||
// span showing current ongoing file position status:
|
||||
morkSpan mParser_PortSpan; // span of current db port file
|
||||
|
||||
// various spans denoting nested subspaces inside the file's port span:
|
||||
morkSpan mParser_GroupSpan; // span of current transaction group
|
||||
morkSpan mParser_DictSpan;
|
||||
morkSpan mParser_AliasSpan;
|
||||
morkSpan mParser_MetaSpan;
|
||||
morkSpan mParser_TableSpan;
|
||||
morkSpan mParser_RowSpan;
|
||||
morkSpan mParser_CellSpan;
|
||||
morkSpan mParser_ColumnSpan;
|
||||
morkSpan mParser_SlotSpan;
|
||||
morkSpan mParser_PortSpan; // span of current db port file
|
||||
|
||||
// various spans denoting nested subspaces inside the file's port span:
|
||||
morkSpan mParser_GroupSpan; // span of current transaction group
|
||||
morkSpan mParser_DictSpan;
|
||||
morkSpan mParser_AliasSpan;
|
||||
morkSpan mParser_MetaSpan;
|
||||
morkSpan mParser_TableSpan;
|
||||
morkSpan mParser_RowSpan;
|
||||
morkSpan mParser_CellSpan;
|
||||
morkSpan mParser_ColumnSpan;
|
||||
morkSpan mParser_SlotSpan;
|
||||
|
||||
private: // convenience inlines
|
||||
|
||||
mork_pos HerePos() const
|
||||
{ return mParser_PortSpan.mSpan_End.mPlace_Pos; }
|
||||
mork_pos HerePos() const
|
||||
{ return mParser_PortSpan.mSpan_End.mPlace_Pos; }
|
||||
|
||||
void SetHerePos(mork_pos inPos)
|
||||
{ mParser_PortSpan.mSpan_End.mPlace_Pos = inPos; }
|
||||
|
||||
void AddLine()
|
||||
{ ++ mParser_PortSpan.mSpan_End.mPlace_Line; }
|
||||
void SetHerePos(mork_pos inPos)
|
||||
{ mParser_PortSpan.mSpan_End.mPlace_Pos = inPos; }
|
||||
|
||||
void AddLine()
|
||||
{ ++ mParser_PortSpan.mSpan_End.mPlace_Line; }
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
@ -353,64 +353,64 @@ public: // out virtual morkParser methods, data flow parser to subclass
|
||||
// mp:Slot ::= OnValue | OnValueAlias | OnRowAlias | OnTableAlias
|
||||
|
||||
|
||||
// Note that in interfaces below, mork_change parameters kAdd and kNil
|
||||
// both mean about the same thing by default. Only kCut is interesting,
|
||||
// because this usually means to remove members instead of adding them.
|
||||
// Note that in interfaces below, mork_change parameters kAdd and kNil
|
||||
// both mean about the same thing by default. Only kCut is interesting,
|
||||
// because this usually means to remove members instead of adding them.
|
||||
|
||||
virtual void OnNewPort(morkEnv* ev, const morkPlace& inPlace) = 0;
|
||||
virtual void OnPortGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0;
|
||||
virtual void OnPortEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
virtual void OnNewPort(morkEnv* ev, const morkPlace& inPlace) = 0;
|
||||
virtual void OnPortGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0;
|
||||
virtual void OnPortEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
|
||||
virtual void OnNewGroup(morkEnv* ev, const morkPlace& inPlace, mork_gid inGid) = 0;
|
||||
virtual void OnGroupGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0;
|
||||
virtual void OnGroupCommitEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
virtual void OnGroupAbortEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
virtual void OnNewGroup(morkEnv* ev, const morkPlace& inPlace, mork_gid inGid) = 0;
|
||||
virtual void OnGroupGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0;
|
||||
virtual void OnGroupCommitEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
virtual void OnGroupAbortEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
|
||||
virtual void OnNewPortRow(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange) = 0;
|
||||
virtual void OnPortRowGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0;
|
||||
virtual void OnPortRowEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
virtual void OnNewPortRow(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, 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;
|
||||
virtual void OnTableGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0;
|
||||
virtual void OnTableEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
|
||||
virtual void OnNewMeta(morkEnv* ev, const morkPlace& inPlace) = 0;
|
||||
virtual void OnMetaGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0;
|
||||
virtual void OnMetaEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
virtual void OnNewTable(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange) = 0;
|
||||
virtual void OnTableGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0;
|
||||
virtual void OnTableEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
|
||||
virtual void OnNewMeta(morkEnv* ev, const morkPlace& inPlace) = 0;
|
||||
virtual void OnMetaGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0;
|
||||
virtual void OnMetaEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
|
||||
virtual void OnNewRow(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange) = 0;
|
||||
virtual void OnRowGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0;
|
||||
virtual void OnRowEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
virtual void OnNewRow(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange) = 0;
|
||||
virtual void OnRowGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0;
|
||||
virtual void OnRowEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
|
||||
virtual void OnNewDict(morkEnv* ev, const morkPlace& inPlace) = 0;
|
||||
virtual void OnDictGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0;
|
||||
virtual void OnDictEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
virtual void OnNewDict(morkEnv* ev, const morkPlace& inPlace) = 0;
|
||||
virtual void OnDictGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0;
|
||||
virtual void OnDictEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
|
||||
virtual void OnAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias) = 0;
|
||||
virtual void OnAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias) = 0;
|
||||
|
||||
virtual void OnAliasGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 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;
|
||||
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;
|
||||
|
||||
virtual void OnValue(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkBuf& inBuf) = 0;
|
||||
virtual void OnNewCell(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange) = 0;
|
||||
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;
|
||||
|
||||
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 OnValueAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias) = 0;
|
||||
|
||||
virtual void OnRowAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias) = 0;
|
||||
virtual void OnRowAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias) = 0;
|
||||
|
||||
virtual void OnTableAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias) = 0;
|
||||
virtual void OnTableAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias) = 0;
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
protected: // protected parser helper methods
|
||||
|
@ -327,7 +327,7 @@ morkRowSpace::NewRowWithOid(morkEnv* ev, const mdbOid* inOid)
|
||||
{
|
||||
row->InitRow(ev, inOid, this, /*length*/ 0, pool);
|
||||
|
||||
if ( ev->Good() )
|
||||
if ( ev->Good() && mRowSpace_Rows.AddRow(ev, row) )
|
||||
outRow = row;
|
||||
else
|
||||
pool->ZapRow(ev, row);
|
||||
@ -354,7 +354,7 @@ morkRowSpace::NewRow(morkEnv* ev)
|
||||
{
|
||||
row->InitRow(ev, &oid, this, /*length*/ 0, pool);
|
||||
|
||||
if ( ev->Good() )
|
||||
if ( ev->Good() && mRowSpace_Rows.AddRow(ev, row) )
|
||||
outRow = row;
|
||||
else
|
||||
pool->ZapRow(ev, row);
|
||||
|
@ -156,74 +156,201 @@ morkStream::CloseStream(morkEnv* ev) // called by CloseMorkNode();
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
#define morkStream_kSpacesPerIndent 1 /* one space per indent */
|
||||
#define morkStream_kMaxIndentDepth 70 /* max indent of 70 space bytes */
|
||||
static const char* morkStream_kSpaces // next line to ease length perception
|
||||
= " ";
|
||||
// 123456789_123456789_123456789_123456789_123456789_123456789_123456789_
|
||||
// morkStream_kSpaces above must contain (at least) 70 spaces (ASCII 0x20)
|
||||
|
||||
mork_size
|
||||
morkStream::PutIndent(morkEnv* ev, mork_count inDepth)
|
||||
// PutIndent() puts a linebreak, and then
|
||||
// "indents" by inDepth, and returns the line length after indentation.
|
||||
{
|
||||
mork_size outLength = 0;
|
||||
|
||||
void
|
||||
if ( ev->Good() )
|
||||
{
|
||||
this->PutLineBreak(ev);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
outLength = inDepth;
|
||||
if ( inDepth )
|
||||
this->Write(ev, morkStream_kSpaces, inDepth);
|
||||
}
|
||||
}
|
||||
return outLength;
|
||||
}
|
||||
|
||||
mork_size
|
||||
morkStream::PutByteThenIndent(morkEnv* ev, int inByte, mork_count inDepth)
|
||||
// PutByteThenIndent() puts the byte, then a linebreak, and then
|
||||
// "indents" by inDepth, and returns the line length after indentation.
|
||||
{
|
||||
mork_size outLength = 0;
|
||||
|
||||
if ( inDepth > morkStream_kMaxIndentDepth )
|
||||
inDepth = morkStream_kMaxIndentDepth;
|
||||
|
||||
this->Putc(ev, inByte);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
this->PutLineBreak(ev);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
outLength = inDepth;
|
||||
if ( inDepth )
|
||||
this->Write(ev, morkStream_kSpaces, inDepth);
|
||||
}
|
||||
}
|
||||
return outLength;
|
||||
}
|
||||
|
||||
mork_size
|
||||
morkStream::PutStringThenIndent(morkEnv* ev,
|
||||
const char* inString, mork_count inDepth)
|
||||
// PutStringThenIndent() puts the string, then a linebreak, and then
|
||||
// "indents" by inDepth, and returns the line length after indentation.
|
||||
{
|
||||
mork_size outLength = 0;
|
||||
|
||||
if ( inDepth > morkStream_kMaxIndentDepth )
|
||||
inDepth = morkStream_kMaxIndentDepth;
|
||||
|
||||
if ( inString )
|
||||
{
|
||||
mork_size length = MORK_STRLEN(inString);
|
||||
if ( length && ev->Good() ) // any bytes to write?
|
||||
this->Write(ev, inString, length);
|
||||
}
|
||||
|
||||
if ( ev->Good() )
|
||||
{
|
||||
this->PutLineBreak(ev);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
outLength = inDepth;
|
||||
if ( inDepth )
|
||||
this->Write(ev, morkStream_kSpaces, inDepth);
|
||||
}
|
||||
}
|
||||
return outLength;
|
||||
}
|
||||
|
||||
mork_size
|
||||
morkStream::PutString(morkEnv* ev, const char* inString)
|
||||
{
|
||||
mork_size outSize = 0;
|
||||
if ( inString )
|
||||
{
|
||||
mork_num length = MORK_STRLEN(inString);
|
||||
if ( length && ev->Good() ) // any bytes to write?
|
||||
outSize = MORK_STRLEN(inString);
|
||||
if ( outSize && ev->Good() ) // any bytes to write?
|
||||
{
|
||||
this->Write(ev, inString, length);
|
||||
this->Write(ev, inString, outSize);
|
||||
}
|
||||
}
|
||||
return outSize;
|
||||
}
|
||||
|
||||
void
|
||||
mork_size
|
||||
morkStream::PutStringThenNewline(morkEnv* ev, const char* inString)
|
||||
// PutStringThenNewline() returns total number of bytes written.
|
||||
{
|
||||
mork_size outSize = 0;
|
||||
if ( inString )
|
||||
{
|
||||
mork_num length = MORK_STRLEN(inString);
|
||||
if ( length && ev->Good() ) // any bytes to write?
|
||||
outSize = MORK_STRLEN(inString);
|
||||
if ( outSize && ev->Good() ) // any bytes to write?
|
||||
{
|
||||
this->Write(ev, inString, length);
|
||||
this->Write(ev, inString, outSize);
|
||||
if ( ev->Good() )
|
||||
this->WriteNewlines(ev, /*count*/ 1);
|
||||
outSize += this->PutLineBreak(ev);
|
||||
}
|
||||
}
|
||||
return outSize;
|
||||
}
|
||||
|
||||
void
|
||||
mork_size
|
||||
morkStream::PutStringThenNewlineThenSpace(morkEnv* ev, const char* inString)
|
||||
// PutStringThenNewlineThenSpace() returns total number of bytes written.
|
||||
{
|
||||
mork_size outSize = 0;
|
||||
if ( inString )
|
||||
{
|
||||
mork_num length = MORK_STRLEN(inString);
|
||||
if ( length && ev->Good() ) // any bytes to write?
|
||||
outSize = MORK_STRLEN(inString);
|
||||
if ( outSize && ev->Good() ) // any bytes to write?
|
||||
{
|
||||
this->Write(ev, inString, length);
|
||||
this->Write(ev, inString, outSize);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
this->WriteNewlines(ev, /*count*/ 1);
|
||||
outSize += this->PutLineBreak(ev);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
this->Putc(ev, ' ');
|
||||
++outSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return outSize;
|
||||
}
|
||||
|
||||
void
|
||||
mork_size
|
||||
morkStream::PutByteThenNewline(morkEnv* ev, int inByte)
|
||||
// PutByteThenNewline() returns total number of bytes written.
|
||||
{
|
||||
mork_size outSize = 1; // one for the following byte
|
||||
this->Putc(ev, inByte);
|
||||
if ( ev->Good() )
|
||||
this->WriteNewlines(ev, /*count*/ 1);
|
||||
outSize += this->PutLineBreak(ev);
|
||||
return outSize;
|
||||
}
|
||||
|
||||
void
|
||||
mork_size
|
||||
morkStream::PutByteThenNewlineThenSpace(morkEnv* ev, int inByte)
|
||||
// PutByteThenNewlineThenSpace() returns total number of bytes written.
|
||||
{
|
||||
mork_size outSize = 1; // one for the following byte
|
||||
this->Putc(ev, inByte);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
this->WriteNewlines(ev, /*count*/ 1);
|
||||
outSize += this->PutLineBreak(ev);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
this->Putc(ev, ' ');
|
||||
++outSize;
|
||||
}
|
||||
}
|
||||
return outSize;
|
||||
}
|
||||
|
||||
mork_size
|
||||
morkStream::PutLineBreak(morkEnv* ev)
|
||||
{
|
||||
#ifdef MORK_MAC
|
||||
|
||||
this->Putc(ev, mork_kCR);
|
||||
return 1;
|
||||
|
||||
#else
|
||||
# if defined(MORK_WIN) || defined(MORK_OS2)
|
||||
|
||||
this->Putc(ev, mork_kCR);
|
||||
this->Putc(ev, mork_kLF);
|
||||
return 2;
|
||||
|
||||
# else
|
||||
# ifdef MORK_UNIX
|
||||
|
||||
this->Putc(ev, mork_kLF);
|
||||
return 1;
|
||||
|
||||
# endif /* MORK_UNIX */
|
||||
# endif /* MORK_WIN */
|
||||
#endif /* MORK_MAC */
|
||||
}
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
// public: // virtual morkFile methods
|
||||
|
||||
@ -719,13 +846,9 @@ morkStream::spill_buf(morkEnv* ev) // spill/flush from buffer to file
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef AB_CONFIG_TRACE
|
||||
this->TraceObject(ev);
|
||||
#endif /*AB_CONFIG_TRACE*/
|
||||
|
||||
#ifdef AB_CONFIG_DEBUG
|
||||
ev->Break("<ab:stream:spill:not:dirty me=\"^%lX\"/>", (long) this);
|
||||
#endif /*AB_CONFIG_DEBUG*/
|
||||
#ifdef MORK_DEBUG
|
||||
ev->NewWarning("stream:spill:not:dirty");
|
||||
#endif /*MORK_DEBUG*/
|
||||
}
|
||||
}
|
||||
else this->NewFileDownError(ev);
|
||||
|
@ -63,7 +63,7 @@
|
||||
**| else branch of the statement calls a function that raises an appropriate
|
||||
**| error to complain about either reading a sink or writing a source.
|
||||
**|
|
||||
**|| morkStream is a direct clone of mork_Stream from Communicator 4.5's
|
||||
**|| morkStream is a direct clone of ab_Stream from Communicator 4.5's
|
||||
**| address book code, which in turn was based on the stream class in the
|
||||
**| public domain Mithril programming language.
|
||||
|*/
|
||||
@ -164,11 +164,33 @@ public: // public non-poly morkStream methods
|
||||
morkFile* GetStreamContentFile() const { return mStream_ContentFile; }
|
||||
mork_size GetStreamBufferSize() const { return mStream_BufSize; }
|
||||
|
||||
void PutString(morkEnv* ev, const char* inString);
|
||||
void PutStringThenNewline(morkEnv* ev, const char* inString);
|
||||
void PutStringThenNewlineThenSpace(morkEnv* ev, const char* inString);
|
||||
void PutByteThenNewline(morkEnv* ev, int inByte);
|
||||
void PutByteThenNewlineThenSpace(morkEnv* ev, int inByte);
|
||||
mork_size PutIndent(morkEnv* ev, mork_count inDepth);
|
||||
// PutIndent() puts a linebreak, and then
|
||||
// "indents" by inDepth, and returns the line length after indentation.
|
||||
|
||||
mork_size PutByteThenIndent(morkEnv* ev, int inByte, mork_count inDepth);
|
||||
// PutByteThenIndent() puts the byte, then a linebreak, and then
|
||||
// "indents" by inDepth, and returns the line length after indentation.
|
||||
|
||||
mork_size PutStringThenIndent(morkEnv* ev,
|
||||
const char* inString, mork_count inDepth);
|
||||
// PutStringThenIndent() puts the string, then a linebreak, and then
|
||||
// "indents" by inDepth, and returns the line length after indentation.
|
||||
|
||||
mork_size PutString(morkEnv* ev, const char* inString);
|
||||
// PutString() returns the length of the string written.
|
||||
|
||||
mork_size PutStringThenNewline(morkEnv* ev, const char* inString);
|
||||
// PutStringThenNewline() returns total number of bytes written.
|
||||
|
||||
mork_size PutStringThenNewlineThenSpace(morkEnv* ev, const char* inString);
|
||||
// PutStringThenNewlineThenSpace() returns total number of bytes written.
|
||||
|
||||
mork_size PutByteThenNewline(morkEnv* ev, int inByte);
|
||||
// PutByteThenNewline() returns total number of bytes written.
|
||||
|
||||
mork_size PutByteThenNewlineThenSpace(morkEnv* ev, int inByte);
|
||||
// PutByteThenNewlineThenSpace() returns total number of bytes written.
|
||||
|
||||
// ````` ````` stdio type methods ````` `````
|
||||
void Printf(morkEnv* ev, const char* inFormat, ...);
|
||||
@ -201,6 +223,8 @@ public: // public non-poly morkStream methods
|
||||
else
|
||||
spill_putc(ev, c);
|
||||
}
|
||||
|
||||
mork_size PutLineBreak(morkEnv* ev);
|
||||
|
||||
public: // typesafe refcounting inlines calling inherited morkNode methods
|
||||
static void SlotWeakStream(morkStream* me,
|
||||
|
@ -120,6 +120,9 @@ morkWriter::morkWriter(morkEnv* ev, const morkUsage& inUsage,
|
||||
|
||||
, mWriter_TotalCount( morkWriter_kCountNumberOfPhases )
|
||||
, mWriter_DoneCount( 0 )
|
||||
|
||||
, mWriter_LineSize( 0 )
|
||||
, mWriter_MaxIndent( morkWriter_kMaxIndent )
|
||||
|
||||
, mWriter_TableCharset( 0 )
|
||||
, mWriter_TableAtomScope( 0 )
|
||||
@ -150,8 +153,11 @@ morkWriter::morkWriter(morkEnv* ev, const morkUsage& inUsage,
|
||||
, mWriter_RowSpaceTablesIter( )
|
||||
, mWriter_RowSpaceRowsIter( )
|
||||
{
|
||||
mWriter_SafeNameBuf[ 0 ] = 0;
|
||||
mWriter_SafeNameBuf[ morkWriter_kMaxColumnNameSize * 2 ] = 0;
|
||||
mWriter_ColNameBuf[ 0 ] = 0;
|
||||
mWriter_ColNameBuf[ morkWriter_kMaxColumnNameSize ] = 0;
|
||||
|
||||
mdbYarn* y = &mWriter_ColYarn;
|
||||
y->mYarn_Buf = mWriter_ColNameBuf; // where to put col bytes
|
||||
y->mYarn_Fill = 0; // set later by writer
|
||||
@ -160,6 +166,14 @@ morkWriter::morkWriter(morkEnv* ev, const morkUsage& inUsage,
|
||||
y->mYarn_Form = 0; // set later by writer
|
||||
y->mYarn_Grow = 0; // do not allow buffer growth
|
||||
|
||||
y = &mWriter_SafeYarn;
|
||||
y->mYarn_Buf = mWriter_SafeNameBuf; // where to put col bytes
|
||||
y->mYarn_Fill = 0; // set later by writer
|
||||
y->mYarn_Size = morkWriter_kMaxColumnNameSize * 2; // our buf size
|
||||
y->mYarn_More = 0; // set later by writer
|
||||
y->mYarn_Form = 0; // set later by writer
|
||||
y->mYarn_Grow = 0; // do not allow buffer growth
|
||||
|
||||
if ( ev->Good() )
|
||||
{
|
||||
if ( ioSlotHeap && ioFile && ioStore )
|
||||
@ -328,20 +342,66 @@ morkWriter::WriteMore(morkEnv* ev) // call until IsWritingDone() is true
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
void
|
||||
morkWriter::WriteAtom(morkEnv* ev, const morkAtom* inAtom)
|
||||
{
|
||||
morkBuf buf; // to ref content inside atom
|
||||
static const char* morkWriter_kHexDigits = "0123456789ABCDEF";
|
||||
|
||||
if ( inAtom->AsBuf(buf) )
|
||||
mork_size
|
||||
morkWriter::WriteYarn(morkEnv* ev, const mdbYarn* inYarn)
|
||||
// return number of atom bytes written on the current line (which
|
||||
// implies that escaped line breaks will make the size value smaller
|
||||
// than the entire yarn's size, since only part goes on a last line).
|
||||
{
|
||||
mork_size outSize = 0;
|
||||
morkStream* stream = mWriter_Stream;
|
||||
|
||||
const mork_u1* b = (const mork_u1*) inYarn->mYarn_Buf;
|
||||
if ( b )
|
||||
{
|
||||
// actually we need to escape problem characters instead of this:
|
||||
morkStream* stream = mWriter_Stream;
|
||||
if ( buf.mBuf_Fill ) // any content to write?
|
||||
stream->Write(ev, buf.mBuf_Body, buf.mBuf_Fill);
|
||||
register int c;
|
||||
mork_fill fill = inYarn->mYarn_Fill;
|
||||
const mork_u1* end = b + fill;
|
||||
while ( b < end )
|
||||
{
|
||||
c = *b++; // next byte to print
|
||||
if ( c < 0x080 && MORK_ISPRINT(c) )
|
||||
{
|
||||
if ( c == ')' && c == '$' && c == '\\' )
|
||||
{
|
||||
stream->Putc(ev, '\\');
|
||||
++outSize;
|
||||
}
|
||||
stream->Putc(ev, c);
|
||||
++outSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
outSize += 3; // '$' hex hex
|
||||
stream->Putc(ev, '$');
|
||||
stream->Putc(ev, morkWriter_kHexDigits[ (c >> 4) & 0x0F ]);
|
||||
stream->Putc(ev, morkWriter_kHexDigits[ c & 0x0F ]);
|
||||
}
|
||||
}
|
||||
}
|
||||
mWriter_LineSize += outSize;
|
||||
|
||||
return outSize;
|
||||
}
|
||||
|
||||
mork_size
|
||||
morkWriter::WriteAtom(morkEnv* ev, const morkAtom* inAtom)
|
||||
// return number of atom bytes written on the current line (which
|
||||
// implies that escaped line breaks will make the size value smaller
|
||||
// than the entire atom's size, since only part goes on a last line).
|
||||
{
|
||||
mork_size outSize = 0;
|
||||
mdbYarn yarn; // to ref content inside atom
|
||||
|
||||
if ( inAtom->AliasYarn(&yarn) )
|
||||
outSize = this->WriteYarn(ev, &yarn);
|
||||
// mWriter_LineSize += stream->Write(ev, inYarn->mYarn_Buf, outSize);
|
||||
else
|
||||
inAtom->BadAtomKindError(ev);
|
||||
|
||||
return outSize;
|
||||
}
|
||||
|
||||
void
|
||||
@ -351,10 +411,13 @@ morkWriter::WriteAtomSpaceAsDict(morkEnv* ev, morkAtomSpace* ioSpace)
|
||||
mork_scope scope = ioSpace->mSpace_Scope;
|
||||
if ( scope < 0x80 )
|
||||
{
|
||||
stream->WriteNewlines(ev, /*count*/ 1);
|
||||
stream->PutString(ev, "<<(atomScope=");
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
stream->PutString(ev, "< <(atomScope=");
|
||||
stream->Putc(ev, (int) scope);
|
||||
stream->PutStringThenNewline(ev, ")> // (charset=iso-8859-1)");
|
||||
++mWriter_LineSize;
|
||||
stream->PutString(ev, ")> // (charset=iso-8859-1)");
|
||||
mWriter_LineSize = stream->PutIndent(ev, morkWriter_kDictAliasDepth);
|
||||
}
|
||||
else
|
||||
ioSpace->NonAsciiSpaceScopeName(ev);
|
||||
@ -379,11 +442,18 @@ morkWriter::WriteAtomSpaceAsDict(morkEnv* ev, morkAtomSpace* ioSpace)
|
||||
{
|
||||
atom->mAtom_Change = morkChange_kNil; // neutralize change
|
||||
|
||||
this->IndentAsNeeded(ev, morkWriter_kDictAliasDepth);
|
||||
mork_size size = ev->TokenAsHex(idBuf, atom->mBookAtom_Id);
|
||||
idBuf[ size ] = '=';
|
||||
stream->Write(ev, buf, size+2); // plus two for '(' and '='
|
||||
mWriter_LineSize += stream->Write(ev, buf, size+1); // '('
|
||||
|
||||
this->IndentAsNeeded(ev, morkWriter_kDictAliasValueDepth);
|
||||
stream->Putc(ev, '='); // end alias
|
||||
++mWriter_LineSize;
|
||||
|
||||
this->WriteAtom(ev, atom);
|
||||
stream->PutByteThenNewlineThenSpace(ev, ')'); // end alias
|
||||
stream->Putc(ev, ')'); // end alias
|
||||
++mWriter_LineSize;
|
||||
|
||||
++mWriter_DoneCount;
|
||||
}
|
||||
else // temporarily warn about wrong change slot value
|
||||
@ -396,7 +466,10 @@ morkWriter::WriteAtomSpaceAsDict(morkEnv* ev, morkAtomSpace* ioSpace)
|
||||
}
|
||||
|
||||
if ( ev->Good() )
|
||||
{
|
||||
this->IndentAsNeeded(ev, 0);
|
||||
stream->PutByteThenNewline(ev, '>'); // end dict
|
||||
}
|
||||
}
|
||||
|
||||
mork_bool
|
||||
@ -556,6 +629,7 @@ morkWriter::OnDirtyAllDone(morkEnv* ev)
|
||||
if ( ev->Good() )
|
||||
{
|
||||
stream->PutStringThenNewline(ev, "// <!-- <mdb:mork:z v=\"1.1\"/> -->");
|
||||
mWriter_LineSize = 0;
|
||||
}
|
||||
|
||||
if ( ev->Good() )
|
||||
@ -570,8 +644,10 @@ mork_bool
|
||||
morkWriter::OnPutHeaderDone(morkEnv* ev)
|
||||
{
|
||||
morkStream* stream = mWriter_Stream;
|
||||
stream->WriteNewlines(ev, /*count*/ 1);
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
stream->PutStringThenNewline(ev, "// OnPutHeaderDone()");
|
||||
mWriter_LineSize = 0;
|
||||
|
||||
morkStore* store = mWriter_Store;
|
||||
if ( store )
|
||||
@ -591,8 +667,10 @@ mork_bool
|
||||
morkWriter::OnRenumberAllDone(morkEnv* ev)
|
||||
{
|
||||
morkStream* stream = mWriter_Stream;
|
||||
stream->WriteNewlines(ev, /*count*/ 1);
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
stream->PutStringThenNewline(ev, "// OnRenumberAllDone()");
|
||||
mWriter_LineSize = 0;
|
||||
|
||||
if ( ev->Good() )
|
||||
mWriter_Phase = morkWriter_kPhaseStoreAtomSpaces;
|
||||
@ -606,8 +684,10 @@ mork_bool
|
||||
morkWriter::OnStoreAtomSpaces(morkEnv* ev)
|
||||
{
|
||||
morkStream* stream = mWriter_Stream;
|
||||
stream->WriteNewlines(ev, /*count*/ 1);
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
stream->PutStringThenNewline(ev, "// OnStoreAtomSpaces()");
|
||||
mWriter_LineSize = 0;
|
||||
|
||||
if ( ev->Good() )
|
||||
{
|
||||
@ -618,6 +698,7 @@ morkWriter::OnStoreAtomSpaces(morkEnv* ev)
|
||||
if ( space )
|
||||
{
|
||||
stream->PutStringThenNewline(ev, "// ground column space dict:");
|
||||
mWriter_LineSize = 0;
|
||||
this->WriteAtomSpaceAsDict(ev, space);
|
||||
}
|
||||
}
|
||||
@ -637,8 +718,10 @@ mork_bool
|
||||
morkWriter::OnAtomSpaceAtomAids(morkEnv* ev)
|
||||
{
|
||||
morkStream* stream = mWriter_Stream;
|
||||
stream->WriteNewlines(ev, /*count*/ 1);
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
stream->PutStringThenNewline(ev, "// OnAtomSpaceAtomAids()");
|
||||
mWriter_LineSize = 0;
|
||||
|
||||
if ( ev->Good() )
|
||||
mWriter_Phase = morkWriter_kPhaseStoreRowSpacesTables;
|
||||
@ -711,8 +794,10 @@ mork_bool
|
||||
morkWriter::OnStoreRowSpacesTables(morkEnv* ev)
|
||||
{
|
||||
morkStream* stream = mWriter_Stream;
|
||||
stream->WriteNewlines(ev, /*count*/ 1);
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
stream->PutStringThenNewline(ev, "// OnStoreRowSpacesTables()");
|
||||
mWriter_LineSize = 0;
|
||||
|
||||
// later we'll break this up, but today we'll write all in one shot:
|
||||
this->WriteAllStoreTables(ev);
|
||||
@ -729,8 +814,10 @@ mork_bool
|
||||
morkWriter::OnRowSpaceTables(morkEnv* ev)
|
||||
{
|
||||
morkStream* stream = mWriter_Stream;
|
||||
stream->WriteNewlines(ev, /*count*/ 1);
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
stream->PutStringThenNewline(ev, "// OnRowSpaceTables()");
|
||||
mWriter_LineSize = 0;
|
||||
|
||||
if ( ev->Good() )
|
||||
mWriter_Phase = morkWriter_kPhaseStoreRowSpacesRows;
|
||||
@ -744,8 +831,10 @@ mork_bool
|
||||
morkWriter::OnTableRowArray(morkEnv* ev)
|
||||
{
|
||||
morkStream* stream = mWriter_Stream;
|
||||
stream->WriteNewlines(ev, /*count*/ 1);
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
stream->PutStringThenNewline(ev, "// OnTableRowArray()");
|
||||
mWriter_LineSize = 0;
|
||||
|
||||
if ( ev->Good() )
|
||||
mWriter_Phase = morkWriter_kPhaseStoreRowSpacesRows;
|
||||
@ -759,8 +848,10 @@ mork_bool
|
||||
morkWriter::OnStoreRowSpacesRows(morkEnv* ev)
|
||||
{
|
||||
morkStream* stream = mWriter_Stream;
|
||||
stream->WriteNewlines(ev, /*count*/ 1);
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
stream->PutStringThenNewline(ev, "// OnStoreRowSpacesRows()");
|
||||
mWriter_LineSize = 0;
|
||||
|
||||
if ( ev->Good() )
|
||||
mWriter_Phase = morkWriter_kPhaseContentDone;
|
||||
@ -774,8 +865,10 @@ mork_bool
|
||||
morkWriter::OnRowSpaceRows(morkEnv* ev)
|
||||
{
|
||||
morkStream* stream = mWriter_Stream;
|
||||
stream->WriteNewlines(ev, /*count*/ 1);
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
stream->PutStringThenNewline(ev, "// OnRowSpaceRows()");
|
||||
mWriter_LineSize = 0;
|
||||
|
||||
if ( ev->Good() )
|
||||
mWriter_Phase = morkWriter_kPhaseContentDone;
|
||||
@ -789,8 +882,10 @@ mork_bool
|
||||
morkWriter::OnContentDone(morkEnv* ev)
|
||||
{
|
||||
morkStream* stream = mWriter_Stream;
|
||||
stream->WriteNewlines(ev, /*count*/ 1);
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
stream->PutStringThenNewline(ev, "// OnContentDone()");
|
||||
mWriter_LineSize = 0;
|
||||
stream->Flush(ev);
|
||||
morkFile* bud = mWriter_Bud;
|
||||
if ( bud )
|
||||
@ -820,7 +915,7 @@ mork_bool
|
||||
morkWriter::PutTable(morkEnv* ev, morkTable* ioTable)
|
||||
{
|
||||
if ( ev->Good() )
|
||||
this->StartTable(ev, ioTable->mTable_Id);
|
||||
this->StartTable(ev, ioTable);
|
||||
|
||||
if ( ev->Good() )
|
||||
{
|
||||
@ -904,13 +999,21 @@ morkWriter::WriteTokenToTokenMetaCell(morkEnv* ev,
|
||||
*p++ = '^'; // indicates col is hex ID
|
||||
|
||||
mork_size colSize = ev->TokenAsHex(p, inCol);
|
||||
p += colSize; // advance past the col in hex
|
||||
*p++ = ' '; // space between hex IDs
|
||||
*p++ = '^'; // indicates value is hex ID
|
||||
mork_size valSize = ev->TokenAsHex(p, inValue);
|
||||
p += valSize; // advance past the value in hex
|
||||
*p = ')';
|
||||
stream->Write(ev, buf, colSize + valSize + 5);
|
||||
p += colSize;
|
||||
*p++ = '='; // we always start with open paren
|
||||
mWriter_LineSize += stream->Write(ev, buf, colSize + 3);
|
||||
|
||||
this->IndentAsNeeded(ev, morkWriter_kTableMetaCellValueDepth);
|
||||
mdbYarn* yarn = &mWriter_ColYarn;
|
||||
// mork_u1* yarnBuf = (mork_u1*) yarn->mYarn_Buf;
|
||||
mWriter_Store->TokenToString(ev, inValue, yarn);
|
||||
this->WriteYarn(ev, yarn);
|
||||
stream->Putc(ev, ')');
|
||||
++mWriter_LineSize;
|
||||
|
||||
// mork_fill fill = yarn->mYarn_Fill;
|
||||
// yarnBuf[ fill ] = ')'; // append terminator
|
||||
// mWriter_LineSize += stream->Write(ev, yarnBuf, fill + 1); // +1 for ')'
|
||||
}
|
||||
|
||||
void
|
||||
@ -918,14 +1021,20 @@ morkWriter::WriteStringToTokenDictCell(morkEnv* ev,
|
||||
const char* inCol, mork_token inValue)
|
||||
// Note inCol should begin with '(' and end with '=', with col in between.
|
||||
{
|
||||
mdbYarn* yarn = &mWriter_ColYarn;
|
||||
mork_u1* yarnBuf = (mork_u1*) yarn->mYarn_Buf;
|
||||
morkStream* stream = mWriter_Stream;
|
||||
stream->PutString(ev, inCol);
|
||||
mWriter_LineSize += stream->PutString(ev, inCol);
|
||||
|
||||
this->IndentAsNeeded(ev, morkWriter_kDictMetaCellValueDepth);
|
||||
mdbYarn* yarn = &mWriter_ColYarn;
|
||||
// mork_u1* yarnBuf = (mork_u1*) yarn->mYarn_Buf;
|
||||
mWriter_Store->TokenToString(ev, inValue, yarn);
|
||||
mork_fill fill = yarn->mYarn_Fill;
|
||||
yarnBuf[ fill ] = ')'; // append terminator
|
||||
stream->Write(ev, yarnBuf, fill + 1); // plus one for ')'
|
||||
this->WriteYarn(ev, yarn);
|
||||
stream->Putc(ev, ')');
|
||||
++mWriter_LineSize;
|
||||
|
||||
// mork_fill fill = yarn->mYarn_Fill;
|
||||
// yarnBuf[ fill ] = ')'; // append terminator
|
||||
// mWriter_LineSize += stream->Write(ev, yarnBuf, fill + 1); // +1 for ')'
|
||||
}
|
||||
|
||||
void
|
||||
@ -934,28 +1043,35 @@ morkWriter::StartDict(morkEnv* ev)
|
||||
morkStream* stream = mWriter_Stream;
|
||||
if ( mWriter_DidStartDict )
|
||||
{
|
||||
stream->WriteNewlines(ev, /*count*/ 1);
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
stream->PutStringThenNewline(ev, "> // end dict");
|
||||
mWriter_LineSize = 0;
|
||||
}
|
||||
mWriter_DidStartDict = morkBool_kTrue;
|
||||
|
||||
stream->WriteNewlines(ev, /*count*/ 1);
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
mWriter_LineSize = 0;
|
||||
if ( mWriter_DictCharset || mWriter_DictAtomScope != 'a' )
|
||||
{
|
||||
stream->Putc(ev, '<');
|
||||
stream->Putc(ev, ' ');
|
||||
stream->Putc(ev, '<');
|
||||
mWriter_LineSize = 3;
|
||||
if ( mWriter_DictCharset )
|
||||
this->WriteStringToTokenDictCell(ev, "(charset=", mWriter_DictCharset);
|
||||
if ( mWriter_DictAtomScope != 'a' )
|
||||
this->WriteStringToTokenDictCell(ev, "(atomScope=", mWriter_DictAtomScope);
|
||||
|
||||
stream->PutByteThenNewlineThenSpace(ev, '>');
|
||||
stream->Putc(ev, '>');
|
||||
++mWriter_LineSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
stream->PutStringThenNewlineThenSpace(ev,
|
||||
"< // <(charset=iso-8859-1)(atomScope=a)>");
|
||||
stream->PutString(ev, "< // <(charset=iso-8859-1)(atomScope=a)>");
|
||||
}
|
||||
mWriter_LineSize = stream->PutIndent(ev, morkWriter_kDictAliasDepth);
|
||||
}
|
||||
|
||||
void
|
||||
@ -964,45 +1080,63 @@ morkWriter::EndDict(morkEnv* ev)
|
||||
morkStream* stream = mWriter_Stream;
|
||||
if ( mWriter_DidStartDict )
|
||||
{
|
||||
stream->WriteNewlines(ev, /*count*/ 1);
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
stream->PutStringThenNewline(ev, "> // end dict");
|
||||
mWriter_LineSize = 0;
|
||||
}
|
||||
mWriter_DidStartDict = morkBool_kFalse;
|
||||
}
|
||||
|
||||
void
|
||||
morkWriter::StartTable(morkEnv* ev, mork_tid inTid)
|
||||
morkWriter::StartTable(morkEnv* ev, morkTable* ioTable)
|
||||
{
|
||||
morkStream* stream = mWriter_Stream;
|
||||
stream->WriteNewlines(ev, /*count*/ 1);
|
||||
|
||||
char buf[ 64 ]; // buffer for staging hex
|
||||
char* p = buf;
|
||||
*p++ = '{';
|
||||
mork_size size = ev->TokenAsHex(p, inTid);
|
||||
p += size;
|
||||
*p++ = ' ';
|
||||
*p = '{';
|
||||
stream->Write(ev, buf, size + 3);
|
||||
mdbOid toid; // to receive table oid
|
||||
ioTable->GetTableOid(ev, &toid);
|
||||
|
||||
morkStore* store = mWriter_Store;
|
||||
mork_scope rs = mWriter_TableRowScope;
|
||||
if ( rs )
|
||||
this->WriteTokenToTokenMetaCell(ev, store->mStore_RowScopeToken, rs);
|
||||
|
||||
mork_kind tk = mWriter_TableKind;
|
||||
if ( tk )
|
||||
this->WriteTokenToTokenMetaCell(ev, store->mStore_TableKindToken, tk);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
morkStream* stream = mWriter_Stream;
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
mWriter_LineSize = 0;
|
||||
|
||||
stream->PutByteThenNewlineThenSpace(ev, '}');
|
||||
char buf[ 64 ]; // buffer for staging hex
|
||||
char* p = buf;
|
||||
*p++ = '{';
|
||||
mork_size size = ev->OidAsHex(p, toid);
|
||||
p += size;
|
||||
*p++ = ' ';
|
||||
*p = '{';
|
||||
mWriter_LineSize += stream->Write(ev, buf, size + 3);
|
||||
|
||||
morkStore* store = mWriter_Store;
|
||||
mork_scope rs = mWriter_TableRowScope;
|
||||
if ( rs )
|
||||
{
|
||||
this->IndentAsNeeded(ev, morkWriter_kTableMetaCellDepth);
|
||||
this->WriteTokenToTokenMetaCell(ev, store->mStore_RowScopeToken, rs);
|
||||
}
|
||||
mork_kind tk = mWriter_TableKind;
|
||||
if ( tk )
|
||||
{
|
||||
this->IndentAsNeeded(ev, morkWriter_kTableMetaCellDepth);
|
||||
this->WriteTokenToTokenMetaCell(ev, store->mStore_TableKindToken, tk);
|
||||
}
|
||||
stream->Putc(ev, '}');
|
||||
stream->Putc(ev, ' ');
|
||||
mWriter_LineSize += 2;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
morkWriter::EndTable(morkEnv* ev)
|
||||
{
|
||||
morkStream* stream = mWriter_Stream;
|
||||
stream->WriteNewlines(ev, /*count*/ 1);
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
stream->PutStringThenNewline(ev, "} // end table");
|
||||
mWriter_LineSize = 0;
|
||||
}
|
||||
|
||||
mork_bool
|
||||
@ -1018,7 +1152,7 @@ morkWriter::PutRowDict(morkEnv* ev, morkRow* ioRow)
|
||||
|
||||
morkCell* end = cells + ioRow->mRow_Length;
|
||||
--cells; // prepare for preincrement:
|
||||
while ( ++cells < end )
|
||||
while ( ++cells < end && ev->Good() )
|
||||
{
|
||||
morkAtom* atom = cells->GetAtom();
|
||||
if ( atom && atom->mAtom_Change == morkChange_kAdd )
|
||||
@ -1027,12 +1161,19 @@ morkWriter::PutRowDict(morkEnv* ev, morkRow* ioRow)
|
||||
{
|
||||
atom->mAtom_Change = morkChange_kNil; // neutralize change
|
||||
|
||||
this->IndentAsNeeded(ev, morkWriter_kDictAliasDepth);
|
||||
morkBookAtom* ba = (morkBookAtom*) atom;
|
||||
mork_size size = ev->TokenAsHex(idBuf, ba->mBookAtom_Id);
|
||||
idBuf[ size ] = '=';
|
||||
stream->Write(ev, buf, size+2); // plus two for '(' and '='
|
||||
mWriter_LineSize += stream->Write(ev, buf, size+1); // '('
|
||||
|
||||
this->IndentAsNeeded(ev, morkWriter_kDictAliasValueDepth);
|
||||
stream->Putc(ev, '='); // start value
|
||||
++mWriter_LineSize;
|
||||
|
||||
this->WriteAtom(ev, atom);
|
||||
stream->PutByteThenNewlineThenSpace(ev, ')'); // end alias
|
||||
stream->Putc(ev, ')'); // end alias
|
||||
++mWriter_LineSize;
|
||||
|
||||
++mWriter_DoneCount;
|
||||
}
|
||||
}
|
||||
@ -1067,17 +1208,16 @@ 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?
|
||||
{
|
||||
*p++ = ' ';
|
||||
*p++ = '^';
|
||||
morkBookAtom* ba = (morkBookAtom*) atom;
|
||||
mork_size valSize = ev->TokenAsHex(p, ba->mBookAtom_Id);
|
||||
p += valSize;
|
||||
*p = ')';
|
||||
stream->Write(ev, buf, colSize + valSize + 5);
|
||||
stream->WriteNewlines(ev, /*count*/ 1);
|
||||
stream->Putc(ev, ' ');
|
||||
|
||||
mWriter_LineSize += stream->Write(ev, buf, colSize + valSize + 4);
|
||||
|
||||
if ( atom->mAtom_Change == morkChange_kAdd )
|
||||
{
|
||||
@ -1087,10 +1227,15 @@ morkWriter::PutRowCells(morkEnv* ev, morkRow* ioRow)
|
||||
}
|
||||
else // must write an anonymous atom
|
||||
{
|
||||
*p++ = '=';
|
||||
stream->Write(ev, buf, colSize + 3);
|
||||
mWriter_LineSize += stream->Write(ev, buf, colSize + 2);
|
||||
|
||||
this->IndentAsNeeded(ev, morkWriter_kRowCellValueDepth);
|
||||
stream->Putc(ev, '=');
|
||||
++mWriter_LineSize;
|
||||
|
||||
this->WriteAtom(ev, atom);
|
||||
stream->PutByteThenNewlineThenSpace(ev, ')'); // end alias
|
||||
stream->Putc(ev, ')'); // end alias
|
||||
++mWriter_LineSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1107,7 +1252,10 @@ morkWriter::PutRow(morkEnv* ev, morkRow* ioRow)
|
||||
mdbOid* roid = &ioRow->mRow_Oid;
|
||||
mork_size ridSize = 0;
|
||||
|
||||
if ( ioRow->IsRowDirty() )
|
||||
this->IndentAsNeeded(ev, morkWriter_kRowDepth);
|
||||
|
||||
// if ( ioRow->IsRowDirty() )
|
||||
if ( morkBool_kTrue )
|
||||
{
|
||||
ioRow->SetRowClean();
|
||||
mork_rid rid = roid->mOid_Id;
|
||||
@ -1119,10 +1267,12 @@ morkWriter::PutRow(morkEnv* ev, morkRow* ioRow)
|
||||
|
||||
p += ridSize;
|
||||
*p++ = ' ';
|
||||
stream->Write(ev, buf, ridSize + 2);
|
||||
mWriter_LineSize += stream->Write(ev, buf, ridSize + 2);
|
||||
|
||||
this->PutRowCells(ev, ioRow);
|
||||
stream->PutByteThenNewlineThenSpace(ev, ']'); // end row
|
||||
stream->Putc(ev, ']'); // end row
|
||||
stream->Putc(ev, ' '); // end row
|
||||
mWriter_LineSize += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1131,9 +1281,9 @@ morkWriter::PutRow(morkEnv* ev, morkRow* ioRow)
|
||||
else
|
||||
ridSize = ev->OidAsHex(p, *roid);
|
||||
|
||||
stream->Write(ev, buf, ridSize);
|
||||
stream->WriteNewlines(ev, /*count*/ 1);
|
||||
mWriter_LineSize += stream->Write(ev, buf, ridSize);
|
||||
stream->Putc(ev, ' ');
|
||||
++mWriter_LineSize;
|
||||
}
|
||||
|
||||
++mWriter_DoneCount;
|
||||
|
@ -51,6 +51,10 @@
|
||||
#include "morkRowSpace.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKSTREAM_
|
||||
#include "morkStream.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
|
||||
@ -79,7 +83,22 @@
|
||||
|
||||
#define morkWriter_kCountNumberOfPhases 13 /* part of mWrite_TotalCount */
|
||||
|
||||
#define morkWriter_kMaxColumnNameSize 256 /* longest writable col name */
|
||||
#define morkWriter_kMaxColumnNameSize 128 /* longest writable col name */
|
||||
|
||||
#define morkWriter_kMaxIndent 48 /* default value for mWriter_MaxIndent */
|
||||
|
||||
#define morkWriter_kTableMetaCellDepth 4 /* */
|
||||
#define morkWriter_kTableMetaCellValueDepth 6 /* */
|
||||
|
||||
#define morkWriter_kDictMetaCellDepth 4 /* */
|
||||
#define morkWriter_kDictMetaCellValueDepth 6 /* */
|
||||
|
||||
#define morkWriter_kDictAliasDepth 2 /* */
|
||||
#define morkWriter_kDictAliasValueDepth 4 /* */
|
||||
|
||||
#define morkWriter_kRowDepth 2 /* */
|
||||
#define morkWriter_kRowCellDepth 4 /* */
|
||||
#define morkWriter_kRowCellValueDepth 6 /* */
|
||||
|
||||
class morkWriter : public morkNode { // row iterator
|
||||
|
||||
@ -105,6 +124,9 @@ public: // state is public because the entire Mork system is private
|
||||
mork_count mWriter_TotalCount; // count of all things to be written
|
||||
mork_count mWriter_DoneCount; // count of things already written
|
||||
|
||||
mork_size mWriter_LineSize; // length of current line being written
|
||||
mork_size mWriter_MaxIndent; // line size forcing a line break
|
||||
|
||||
mork_cscode mWriter_TableCharset; // current charset metainfo
|
||||
mork_scope mWriter_TableAtomScope; // current atom scope
|
||||
mork_scope mWriter_TableRowScope; // current row scope
|
||||
@ -125,12 +147,18 @@ public: // state is public because the entire Mork system is private
|
||||
mork_bool mWriter_DidEndDict; // true when a dict has been ended
|
||||
|
||||
mork_pos mWriter_TableRowArrayPos; // index into mTable_RowArray
|
||||
|
||||
|
||||
char mWriter_SafeNameBuf[ (morkWriter_kMaxColumnNameSize * 2) + 4 ];
|
||||
// Note: extra four bytes in ColNameBuf means we can always append to yarn
|
||||
|
||||
char mWriter_ColNameBuf[ morkWriter_kMaxColumnNameSize + 4 ];
|
||||
// Note: extra four bytes in ColNameBuf means we can always append to yarn
|
||||
|
||||
mdbYarn mWriter_ColYarn; // a yarn to describe space in ColNameBuf:
|
||||
// mYarn_Buf == mWriter_ColNameBuf, mYarn_Size == morkWriter_kMaxColumnNameSize
|
||||
|
||||
mdbYarn mWriter_SafeYarn; // a yarn to describe space in ColNameBuf:
|
||||
// mYarn_Buf == mWriter_SafeNameBuf, mYarn_Size == (kMaxColumnNameSize * 2)
|
||||
|
||||
morkAtomSpaceMapIter mWriter_StoreAtomSpacesIter; // for mStore_AtomSpaces
|
||||
morkAtomAidMapIter mWriter_AtomSpaceAtomAidsIter; // for AtomSpace_AtomAids
|
||||
@ -169,6 +197,15 @@ public: // typing & errors
|
||||
public: // inlines
|
||||
mork_bool DidStartDict() const { return mWriter_DidStartDict; }
|
||||
mork_bool DidEndDict() const { return mWriter_DidEndDict; }
|
||||
|
||||
mork_bool NeedLineBreak() const
|
||||
{ return ( mWriter_LineSize > mWriter_MaxIndent ); }
|
||||
|
||||
void IndentAsNeeded(morkEnv* ev, mork_size inDepth)
|
||||
{
|
||||
if ( mWriter_LineSize > mWriter_MaxIndent )
|
||||
mWriter_LineSize = mWriter_Stream->PutIndent(ev, inDepth);
|
||||
}
|
||||
|
||||
public: // iterative/asynchronouse writing
|
||||
|
||||
@ -220,8 +257,17 @@ public: // writing node content second pass
|
||||
|
||||
public: // other writer methods
|
||||
|
||||
mork_size WriteYarn(morkEnv* ev, const mdbYarn* inYarn);
|
||||
// return number of atom bytes written on the current line (which
|
||||
// implies that escaped line breaks will make the size value smaller
|
||||
// than the entire yarn's size, since only part goes on a last line).
|
||||
|
||||
mork_size WriteAtom(morkEnv* ev, const morkAtom* inAtom);
|
||||
// return number of atom bytes written on the current line (which
|
||||
// implies that escaped line breaks will make the size value smaller
|
||||
// than the entire atom's size, since only part goes on a last line).
|
||||
|
||||
void WriteAllStoreTables(morkEnv* ev);
|
||||
void WriteAtom(morkEnv* ev, const morkAtom* inAtom);
|
||||
void WriteAtomSpaceAsDict(morkEnv* ev, morkAtomSpace* ioSpace);
|
||||
|
||||
void WriteTokenToTokenMetaCell(morkEnv* ev, mork_token inCol,
|
||||
@ -233,7 +279,7 @@ public: // other writer methods
|
||||
void StartDict(morkEnv* ev);
|
||||
void EndDict(morkEnv* ev);
|
||||
|
||||
void StartTable(morkEnv* ev, mork_tid inTid);
|
||||
void StartTable(morkEnv* ev, morkTable* ioTable);
|
||||
void EndTable(morkEnv* ev);
|
||||
|
||||
public: // typesafe refcounting inlines calling inherited morkNode methods
|
||||
|
Loading…
x
Reference in New Issue
Block a user