mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 03:15:11 +00:00
latest mork drop, fix ref counting bug, add meta table info
This commit is contained in:
parent
af224c9bc6
commit
0484e4a350
@ -690,6 +690,88 @@ public:
|
||||
|
||||
extern "C" nsIMdbFactory* MakeMdbFactory();
|
||||
|
||||
/*| nsIMdbFile: abstract file interface resembling the original morkFile
|
||||
**| abstract interface (which was in turn modeled on the file interface
|
||||
**| from public domain IronDoc). The design of this file interface is
|
||||
**| complicated by the fact that some DB's will not find this interface
|
||||
**| adequate for all runtime requirements (even though this file API is
|
||||
**| enough to implement text-based DB's like Mork). For this reason,
|
||||
**| more methods have been added to let a DB library force the file to
|
||||
**| become closed so the DB can reopen the file in some other manner.
|
||||
**| Folks are encouraged to suggest ways to tune this interface to suit
|
||||
**| DB's that cannot manage to pull their maneuvers even given this API.
|
||||
**|
|
||||
**|| Tell: get the current i/o position in file
|
||||
**|
|
||||
**|| Seek: change the current i/o position in file
|
||||
**|
|
||||
**|| Eof: return file's total length in bytes
|
||||
**|
|
||||
**|| Read: input inSize bytes into outBuf, returning actual transfer size
|
||||
**|
|
||||
**|| Get: read starting at specific file offset (e.g. Seek(); Read();)
|
||||
**|
|
||||
**|| Write: output inSize bytes from inBuf, returning actual transfer size
|
||||
**|
|
||||
**|| Put: write starting at specific file offset (e.g. Seek(); Write();)
|
||||
**|
|
||||
**|| Flush: if written bytes are buffered, push them to final destination
|
||||
**|
|
||||
**|| Path: get file path in some string representation. This is intended
|
||||
**| either to support the display of file name in a user presentation, or
|
||||
**| to support the closing and reopening of the file when the DB needs more
|
||||
**| exotic file access than is presented by the nsIMdbFile interface.
|
||||
**|
|
||||
**|| Steal: tell this file to close any associated i/o stream in the file
|
||||
**| system, because the file ioThief intends to reopen the file in order
|
||||
**| to provide the MDB implementation with more exotic file access than is
|
||||
**| offered by the nsIMdbFile alone. Presumably the thief knows enough
|
||||
**| from Path() in order to know which file to reopen. If Steal() is
|
||||
**| successful, this file should probably delegate all future calls to
|
||||
**| the nsIMdbFile interface down to the thief files, so that even after
|
||||
**| the file has been stolen, it can still be read, written, or forcibly
|
||||
**| closed (by a call to CloseMdbObject()).
|
||||
**|
|
||||
**|| Thief: acquire and return thief passed to an earlier call to Steal().
|
||||
|*/
|
||||
class nsIMdbFile : public nsIMdbObject { // minimal file interface
|
||||
public:
|
||||
|
||||
// { ===== begin nsIMdbFile methods =====
|
||||
|
||||
// { ----- begin pos methods -----
|
||||
virtual mdb_err Tell(nsIMdbEnv* ev, mdb_pos* outPos) const = 0;
|
||||
virtual mdb_err Seek(nsIMdbEnv* ev, mdb_pos inPos) = 0;
|
||||
virtual mdb_err Eof(nsIMdbEnv* ev, mdb_pos* outPos) const = 0;
|
||||
// } ----- end pos methods -----
|
||||
|
||||
// { ----- begin read methods -----
|
||||
virtual mdb_err Read(nsIMdbEnv* ev, void* outBuf, mdb_size inSize,
|
||||
mdb_size* outActualSize) = 0;
|
||||
virtual mdb_err Get(nsIMdbEnv* ev, void* outBuf, mdb_size inSize,
|
||||
mdb_pos inPos, mdb_size* outActualSize) = 0;
|
||||
// } ----- end read methods -----
|
||||
|
||||
// { ----- begin write methods -----
|
||||
virtual mdb_err Write(nsIMdbEnv* ev, const void* inBuf, mdb_size inSize,
|
||||
mdb_size* outActualSize) = 0;
|
||||
virtual mdb_err Put(nsIMdbEnv* ev, const void* inBuf, mdb_size inSize,
|
||||
mdb_pos inPos, mdb_size* outActualSize) = 0;
|
||||
virtual mdb_err Flush(nsIMdbEnv* ev) = 0;
|
||||
// } ----- end attribute methods -----
|
||||
|
||||
// { ----- begin path methods -----
|
||||
virtual mdb_err Path(nsIMdbEnv* ev, mdbYarn* outFilePath) = 0;
|
||||
// } ----- end path methods -----
|
||||
|
||||
// { ----- begin replacement methods -----
|
||||
virtual mdb_err Steal(nsIMdbEnv* ev, nsIMdbFile* ioThief) = 0;
|
||||
virtual mdb_err Thief(nsIMdbEnv* ev, nsIMdbFile** acqThief) = 0;
|
||||
// } ----- end replacement methods -----
|
||||
|
||||
// } ===== end nsIMdbFile methods =====
|
||||
};
|
||||
|
||||
/*| nsIMdbPort: a readonly interface to a specific database file. The mutable
|
||||
**| nsIMdbStore interface is a subclass that includes writing behavior, but
|
||||
**| most of the needed db methods appear in the readonly nsIMdbPort interface.
|
||||
@ -995,6 +1077,15 @@ public:
|
||||
mdb_scope inRowScope, // row scope for row ids
|
||||
mdb_kind inTableKind, // the type of table to access
|
||||
mdb_bool inMustBeUnique, // whether store can hold only one of these
|
||||
const mdbOid* inOptionalMetaRowOid, // can be nil to avoid specifying
|
||||
nsIMdbTable** acqTable) = 0; // acquire scoped collection of rows
|
||||
|
||||
virtual mdb_err NewTableWithOid( // make one new table of specific type
|
||||
nsIMdbEnv* ev, // context
|
||||
const mdbOid* inOid, // caller assigned oid
|
||||
mdb_kind inTableKind, // the type of table to access
|
||||
mdb_bool inMustBeUnique, // whether store can hold only one of these
|
||||
const mdbOid* inOptionalMetaRowOid, // can be nil to avoid specifying
|
||||
nsIMdbTable** acqTable) = 0; // acquire scoped collection of rows
|
||||
// } ----- end table methods -----
|
||||
|
||||
@ -1333,7 +1424,7 @@ public:
|
||||
**| complain not at all. Cutting a row from a table only does something when
|
||||
**| the row was actually a member, and otherwise does nothing silently.
|
||||
**|
|
||||
**|| row ref count: one can query the number of tables (and or cells)
|
||||
**|| row ref count: one can query the number of tables (and/or cells)
|
||||
**| containing a row as a member or a child.
|
||||
**|
|
||||
**|| row content: one can access or modify the cell content in a table's row
|
||||
@ -1355,11 +1446,38 @@ public:
|
||||
|
||||
// { ===== begin nsIMdbTable methods =====
|
||||
|
||||
// { ----- begin attribute methods -----
|
||||
// { ----- begin meta attribute methods -----
|
||||
virtual mdb_err GetTableKind(nsIMdbEnv* ev, mdb_kind* outTableKind) = 0;
|
||||
virtual mdb_err GetRowScope(nsIMdbEnv* ev, mdb_scope* outRowScope) = 0;
|
||||
|
||||
// } ----- end attribute methods -----
|
||||
virtual mdb_err GetMetaRow(
|
||||
nsIMdbEnv* ev, // context
|
||||
const mdbOid* inOptionalMetaRowOid, // can be nil to avoid specifying
|
||||
mdbOid* outOid, // output meta row oid, can be nil to suppress output
|
||||
nsIMdbRow** acqRow) = 0; // acquire table's unique singleton meta row
|
||||
// The purpose of a meta row is to support the persistent recording of
|
||||
// meta info about a table as cells put into the distinguished meta row.
|
||||
// Each table has exactly one meta row, which is not considered a member
|
||||
// of the collection of rows inside the table. The only way to tell
|
||||
// whether a row is a meta row is by the fact that it is returned by this
|
||||
// GetMetaRow() method from some table. Otherwise nothing distinguishes
|
||||
// a meta row from any other row. A meta row can be used anyplace that
|
||||
// any other row can be used, and can even be put into other tables (or
|
||||
// the same table) as a table member, if this is useful for some reason.
|
||||
// The first attempt to access a table's meta row using GetMetaRow() will
|
||||
// cause the meta row to be created if it did not already exist. When the
|
||||
// meta row is created, it will have the row oid that was previously
|
||||
// requested for this table's meta row; or if no oid was ever explicitly
|
||||
// specified for this meta row, then a unique oid will be generated in
|
||||
// the row scope named "metaScope" (so obviously MDB clients should not
|
||||
// manually allocate any row IDs from that special meta scope namespace).
|
||||
// The meta row oid can be specified either when the table is created, or
|
||||
// else the first time that GetMetaRow() is called, by passing a non-nil
|
||||
// pointer to an oid for parameter inOptionalMetaRowOid. The meta row's
|
||||
// actual oid is returned in outOid (if this is a non-nil pointer), and
|
||||
// it will be different from inOptionalMetaRowOid when the meta row was
|
||||
// already given a different oid earlier.
|
||||
// } ----- end meta attribute methods -----
|
||||
|
||||
// { ----- begin cursor methods -----
|
||||
virtual mdb_err GetTableRowCursor( // make a cursor, starting iteration at inRowPos
|
||||
@ -1374,7 +1492,10 @@ public:
|
||||
mdb_pos inRowPos, // zero-based ordinal position of row in table
|
||||
mdbOid* outOid) = 0; // row oid at the specified position
|
||||
|
||||
// Note that HasRow() performs the inverse oid->pos mapping
|
||||
virtual mdb_err RowToPos( // test for the table position of a row member
|
||||
nsIMdbEnv* ev, // context
|
||||
nsIMdbRow* ioRow, // row to find in table
|
||||
mdb_pos* outPos) = 0; // zero-based ordinal position of row in table
|
||||
// } ----- end row position methods -----
|
||||
|
||||
// { ----- begin oid set methods -----
|
||||
@ -1383,6 +1504,11 @@ public:
|
||||
const mdbOid* inOid) = 0; // row to ensure membership in table
|
||||
|
||||
virtual mdb_err HasOid( // test for the table position of a row member
|
||||
nsIMdbEnv* ev, // context
|
||||
const mdbOid* inOid, // row to find in table
|
||||
mdb_bool* outHasOid) = 0; // whether inOid is a member row
|
||||
|
||||
virtual mdb_err OidToPos( // test for the table position of a row member
|
||||
nsIMdbEnv* ev, // context
|
||||
const mdbOid* inOid, // row to find in table
|
||||
mdb_pos* outPos) = 0; // zero-based ordinal position of row in table
|
||||
@ -1395,7 +1521,7 @@ public:
|
||||
// { ----- begin row set methods -----
|
||||
virtual mdb_err NewRow( // create a new row instance in table
|
||||
nsIMdbEnv* ev, // context
|
||||
mdbOid* ioOid, // please use zero (unbound) rowId for db-assigned IDs
|
||||
mdbOid* ioOid, // please use minus one (unbound) rowId for db-assigned IDs
|
||||
nsIMdbRow** acqRow) = 0; // create new row
|
||||
|
||||
virtual mdb_err AddRow( // make sure the row with inOid is a table member
|
||||
@ -1405,7 +1531,7 @@ public:
|
||||
virtual mdb_err HasRow( // test for the table position of a row member
|
||||
nsIMdbEnv* ev, // context
|
||||
nsIMdbRow* ioRow, // row to find in table
|
||||
mdb_pos* outPos) = 0; // zero-based ordinal position of row in table
|
||||
mdb_bool* outHasRow) = 0; // whether row is a table member
|
||||
|
||||
virtual mdb_err CutRow( // make sure the row with inOid is not a member
|
||||
nsIMdbEnv* ev, // context
|
||||
|
@ -131,6 +131,12 @@ public: // setup
|
||||
|
||||
public: // other space methods
|
||||
|
||||
// void ReserveColumnAidCount(mork_count inCount)
|
||||
// {
|
||||
// mAtomSpace_HighUnderId = morkAtomSpace_kMinUnderId + inCount;
|
||||
// mAtomSpace_HighOverId = morkAtomSpace_kMinOverId + inCount;
|
||||
// }
|
||||
|
||||
mork_num CutAllAtoms(morkEnv* ev, morkPool* ioPool);
|
||||
// CutAllAtoms() puts all the atoms back in the pool.
|
||||
|
||||
|
@ -123,32 +123,25 @@ morkBuilder::morkBuilder(morkEnv* ev,
|
||||
|
||||
, mBuilder_OidAtomSpace( 0 )
|
||||
, mBuilder_ScopeAtomSpace( 0 )
|
||||
|
||||
, mBuilder_iso_8859_1( 0 )
|
||||
, mBuilder_r( (mork_scope) 'r' )
|
||||
, mBuilder_a( (mork_scope) 'a' )
|
||||
, mBuilder_t( (mork_scope) 't' )
|
||||
|
||||
, mBuilder_MorkNoneToken( 0 )
|
||||
|
||||
, mBuilder_PortForm( 0 )
|
||||
, mBuilder_PortRowScope( (mork_scope) 'r' )
|
||||
, mBuilder_PortAtomScope( (mork_scope) 'a' )
|
||||
, mBuilder_PortAtomScope( (mork_scope) 'v' )
|
||||
|
||||
, mBuilder_TableForm( 0 )
|
||||
, mBuilder_TableRowScope( (mork_scope) 'r' )
|
||||
, mBuilder_TableAtomScope( (mork_scope) 'a' )
|
||||
, mBuilder_TableAtomScope( (mork_scope) 'v' )
|
||||
, mBuilder_TableKind( 0 )
|
||||
|
||||
, mBuilder_RowForm( 0 )
|
||||
, mBuilder_RowRowScope( (mork_scope) 'r' )
|
||||
, mBuilder_RowAtomScope( (mork_scope) 'a' )
|
||||
, mBuilder_RowAtomScope( (mork_scope) 'v' )
|
||||
|
||||
, mBuilder_CellForm( 0 )
|
||||
, mBuilder_CellAtomScope( (mork_scope) 'a' )
|
||||
, mBuilder_CellAtomScope( (mork_scope) 'v' )
|
||||
|
||||
, mBuilder_DictForm( 0 )
|
||||
, mBuilder_DictAtomScope( (mork_scope) 'a' )
|
||||
, mBuilder_DictAtomScope( (mork_scope) 'v' )
|
||||
|
||||
, mBuilder_MetaTokenSlot( 0 )
|
||||
|
||||
@ -160,7 +153,6 @@ morkBuilder::morkBuilder(morkEnv* ev,
|
||||
{
|
||||
if ( ioStore )
|
||||
{
|
||||
mBuilder_MorkNoneToken = ioStore->mStore_MorkNoneToken;
|
||||
morkStore::SlotWeakStore(ioStore, ev, &mBuilder_Store);
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kBuilder;
|
||||
@ -267,7 +259,7 @@ morkBuilder::OnNewPort(morkEnv* ev, const morkPlace& inPlace)
|
||||
// mParser_InPort = morkBool_kTrue;
|
||||
mBuilder_PortForm = 0;
|
||||
mBuilder_PortRowScope = (mork_scope) 'r';
|
||||
mBuilder_PortAtomScope = (mork_scope) 'a';
|
||||
mBuilder_PortAtomScope = (mork_scope) 'v';
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
@ -337,7 +329,8 @@ morkBuilder::OnPortRowEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
morkBuilder::OnNewTable(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkMid& inMid, mork_change inChange)
|
||||
// mp:Table ::= OnNewTable mp:TableItem* OnTableEnd
|
||||
// mp:TableItem ::= mp:Row | mp:Meta | OnTableGlitch
|
||||
// mp:TableItem ::= mp:Row | mp:MetaTable | OnTableGlitch
|
||||
// mp:MetaTable ::= OnNewMeta mp:MetaItem* mp:Row OnMetaEnd
|
||||
// mp:Meta ::= OnNewMeta mp:MetaItem* OnMetaEnd
|
||||
// mp:MetaItem ::= mp:Cell | OnMetaGlitch
|
||||
{
|
||||
@ -345,7 +338,7 @@ morkBuilder::OnNewTable(morkEnv* ev, const morkPlace& inPlace,
|
||||
mBuilder_TableForm = mBuilder_PortForm;
|
||||
mBuilder_TableRowScope = mBuilder_PortRowScope;
|
||||
mBuilder_TableAtomScope = mBuilder_PortAtomScope;
|
||||
mBuilder_TableKind = mBuilder_MorkNoneToken;
|
||||
mBuilder_TableKind = morkStore_kNoneToken;
|
||||
|
||||
morkTable* table = mBuilder_Store->MidToTable(ev, inMid);
|
||||
morkTable::SlotStrongTable(table, ev, &mBuilder_Table);
|
||||
@ -372,7 +365,7 @@ morkBuilder::OnTableEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
mBuilder_Row = 0;
|
||||
mBuilder_Cell = 0;
|
||||
|
||||
if ( mBuilder_TableKind == mBuilder_MorkNoneToken )
|
||||
if ( mBuilder_TableKind == morkStore_kNoneToken )
|
||||
ev->NewError("missing table kind");
|
||||
|
||||
mBuilder_CellAtomScope = mBuilder_RowAtomScope =
|
||||
@ -407,6 +400,9 @@ morkBuilder::OnMetaEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnNewRow(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkMid& inMid, mork_change inChange)
|
||||
// mp:Table ::= OnNewTable mp:TableItem* OnTableEnd
|
||||
// mp:TableItem ::= mp:Row | mp:MetaTable | OnTableGlitch
|
||||
// mp:MetaTable ::= OnNewMeta mp:MetaItem* mp:Row OnMetaEnd
|
||||
// mp:Row ::= OnNewRow mp:RowItem* OnRowEnd
|
||||
// mp:RowItem ::= mp:Cell | mp:Meta | OnRowGlitch
|
||||
// mp:Cell ::= OnNewCell mp:CellItem? OnCellEnd
|
||||
@ -432,8 +428,24 @@ morkBuilder::OnNewRow(morkEnv* ev, const morkPlace& inPlace,
|
||||
mBuilder_Row = store->MidToRow(ev, inMid);
|
||||
}
|
||||
|
||||
if ( mBuilder_Row )
|
||||
mBuilder_Table->AddRow(ev, mBuilder_Row);
|
||||
morkRow* row = mBuilder_Row;
|
||||
if ( row )
|
||||
{
|
||||
morkTable* table = mBuilder_Table;
|
||||
if ( mParser_InMeta )
|
||||
{
|
||||
if ( !table->mTable_MetaRow )
|
||||
{
|
||||
table->mTable_MetaRow = row;
|
||||
table->mTable_MetaRowOid = row->mRow_Oid;
|
||||
row->AddTableUse(ev);
|
||||
}
|
||||
else
|
||||
ev->NewError("duplicate table meta row");
|
||||
}
|
||||
else
|
||||
table->AddRow(ev, row);
|
||||
}
|
||||
}
|
||||
else
|
||||
this->NilBuilderTableError(ev);
|
||||
@ -612,29 +624,29 @@ morkBuilder::OnNewCell(morkEnv* ev, const morkPlace& inPlace,
|
||||
{
|
||||
if ( mParser_InTable ) // metainfo for table?
|
||||
{
|
||||
if ( column == store->mStore_TableKindToken )
|
||||
if ( column == morkStore_kKindColumn )
|
||||
mBuilder_MetaTokenSlot = &mBuilder_TableKind;
|
||||
else if ( column == store->mStore_RowScopeToken )
|
||||
else if ( column == morkStore_kRowScopeColumn )
|
||||
mBuilder_MetaTokenSlot = &mBuilder_TableRowScope;
|
||||
else if ( column == store->mStore_AtomScopeToken )
|
||||
else if ( column == morkStore_kAtomScopeColumn )
|
||||
mBuilder_MetaTokenSlot = &mBuilder_TableAtomScope;
|
||||
else if ( column == store->mStore_CharsetToken )
|
||||
else if ( column == morkStore_kFormColumn )
|
||||
mBuilder_MetaTokenSlot = &mBuilder_TableForm;
|
||||
}
|
||||
else if ( mParser_InDict ) // metainfo for dict?
|
||||
{
|
||||
if ( column == store->mStore_AtomScopeToken )
|
||||
if ( column == morkStore_kAtomScopeColumn )
|
||||
mBuilder_MetaTokenSlot = &mBuilder_DictAtomScope;
|
||||
else if ( column == store->mStore_CharsetToken )
|
||||
else if ( column == morkStore_kFormColumn )
|
||||
mBuilder_MetaTokenSlot = &mBuilder_DictForm;
|
||||
}
|
||||
else if ( mParser_InRow ) // metainfo for row?
|
||||
{
|
||||
if ( column == store->mStore_AtomScopeToken )
|
||||
if ( column == morkStore_kAtomScopeColumn )
|
||||
mBuilder_MetaTokenSlot = &mBuilder_RowAtomScope;
|
||||
else if ( column == store->mStore_RowScopeToken )
|
||||
else if ( column == morkStore_kRowScopeColumn )
|
||||
mBuilder_MetaTokenSlot = &mBuilder_RowRowScope;
|
||||
else if ( column == store->mStore_CharsetToken )
|
||||
else if ( column == morkStore_kFormColumn )
|
||||
mBuilder_MetaTokenSlot = &mBuilder_RowForm;
|
||||
}
|
||||
}
|
||||
@ -856,7 +868,8 @@ morkBuilder::OnTableMid(morkEnv* ev, const morkSpan& inSpan,
|
||||
if ( atom )
|
||||
{
|
||||
cell->SetAtom(ev, atom, pool);
|
||||
morkTable* table = store->OidToTable(ev, &tableOid);
|
||||
morkTable* table = store->OidToTable(ev, &tableOid,
|
||||
/*optionalMetaRowOid*/ (mdbOid*) 0);
|
||||
if ( table ) // found or created such a table?
|
||||
table->AddCellUse(ev);
|
||||
}
|
||||
|
@ -127,15 +127,7 @@ protected: // protected morkBuilder members
|
||||
// scoped object ids for current objects under construction:
|
||||
mdbOid mBuilder_TableOid; // full oid for current table
|
||||
mdbOid mBuilder_RowOid; // full oid for current row
|
||||
|
||||
// standard tokens that we want to know about for this port:
|
||||
mork_cscode mBuilder_iso_8859_1; // token for "iso-8859-1"
|
||||
mork_cscode mBuilder_r; // token for "r"
|
||||
mork_cscode mBuilder_a; // token for "a"
|
||||
mork_cscode mBuilder_t; // token for "t"
|
||||
|
||||
mork_token mBuilder_MorkNoneToken; // token for "mork:none"
|
||||
|
||||
|
||||
// tokens that become set as the result of meta cells in port rows:
|
||||
mork_cscode mBuilder_PortForm; // default port charset format
|
||||
mork_scope mBuilder_PortRowScope; // port row scope
|
||||
|
@ -99,14 +99,17 @@ morkCellObject::morkCellObject(morkEnv* ev, const morkUsage& inUsage,
|
||||
morkStore* store = ioRow->GetRowSpaceStore(ev);
|
||||
if ( store )
|
||||
{
|
||||
morkRowObject* rowObj = ioRow->GetRowObject(ev, store);
|
||||
morkRowObject* rowObj = ioRow->AcquireRowObject(ev, store);
|
||||
if ( rowObj )
|
||||
{
|
||||
mCellObject_Row = ioRow;
|
||||
mCellObject_Cell = ioCell;
|
||||
mCellObject_RowSeed = ioRow->mRow_Seed;
|
||||
morkRowObject::SlotStrongRowObject(rowObj, ev,
|
||||
&mCellObject_RowObject);
|
||||
|
||||
// morkRowObject::SlotStrongRowObject(rowObj, ev,
|
||||
// &mCellObject_RowObject);
|
||||
|
||||
mCellObject_RowObject = rowObj; // assume control of strong ref
|
||||
}
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kCellObject;
|
||||
|
@ -87,7 +87,7 @@ const mork_u1 morkCh_Type[] = /* derives from public domain Mithril ch table */
|
||||
0, /* 0x29 ) cannot be kV because needs escape */
|
||||
morkCh_kV, /* 0x2A * */
|
||||
morkCh_kV|morkCh_kM, /* 0x2B + */
|
||||
0, /* 0x2C , */
|
||||
morkCh_kV, /* 0x2C , */
|
||||
morkCh_kV|morkCh_kM, /* 0x2D - */
|
||||
morkCh_kV, /* 0x2E . */
|
||||
morkCh_kV, /* 0x2F / */
|
||||
|
@ -31,8 +31,8 @@
|
||||
|
||||
// { %%%%% begin platform defs peculiar to Mork %%%%%
|
||||
#ifdef XP_MAC
|
||||
#define MORK_MAC 1
|
||||
#define MORK_OBSOLETE 1
|
||||
#define MORK_MAC 1
|
||||
#endif
|
||||
|
||||
#ifdef XP_OS2
|
||||
|
@ -113,7 +113,7 @@ morkHandle::CloseHandle(morkEnv* ev) // called by CloseMorkNode();
|
||||
this->MarkShut();
|
||||
|
||||
if ( objDidRefSelf )
|
||||
this->CutWeakRef(ev);
|
||||
this->CutWeakRef(ev); // do last, because it might self destroy
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
|
@ -917,8 +917,18 @@ void morkParser::ReadMeta(morkEnv* ev, int inEndMeta)
|
||||
this->UnexpectedByteInMetaWarning(ev);
|
||||
break;
|
||||
|
||||
case '[': // maybe table meta row?
|
||||
if ( mParser_InTable )
|
||||
this->ReadRow(ev, '[');
|
||||
else
|
||||
this->UnexpectedByteInMetaWarning(ev);
|
||||
break;
|
||||
|
||||
default:
|
||||
this->UnexpectedByteInMetaWarning(ev);
|
||||
if ( mParser_InTable && morkCh_IsHex(c) )
|
||||
this->ReadRow(ev, c);
|
||||
else
|
||||
this->UnexpectedByteInMetaWarning(ev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -379,7 +379,8 @@ public: // out virtual morkParser methods, data flow parser to subclass
|
||||
// mp:Dict ::= OnNewDict mp:DictItem* OnDictEnd
|
||||
// mp:DictItem ::= OnAlias | OnAliasGlitch | mp:Meta | OnDictGlitch
|
||||
// mp:Table ::= OnNewTable mp:TableItem* OnTableEnd
|
||||
// mp:TableItem ::= mp:Row | mp:Meta | OnTableGlitch
|
||||
// mp:TableItem ::= mp:Row | mp:MetaTable | OnTableGlitch
|
||||
// mp:MetaTable ::= OnNewMeta mp:MetaItem* mp:Row OnMetaEnd
|
||||
// mp:Meta ::= OnNewMeta mp:MetaItem* OnMetaEnd
|
||||
// mp:MetaItem ::= mp:Cell | OnMetaGlitch
|
||||
// mp:Row ::= OnNewRow mp:RowItem* OnRowEnd
|
||||
|
@ -217,7 +217,8 @@ morkPool::AddRowCells(morkEnv* ev, morkRow* ioRow, mork_size inNewSize)
|
||||
ioRow->mRow_Length = inNewSize;
|
||||
++ioRow->mRow_Seed;
|
||||
|
||||
this->ZapCells(ev, oldCells, fill);
|
||||
if ( oldCells )
|
||||
this->ZapCells(ev, oldCells, fill);
|
||||
}
|
||||
}
|
||||
return ( ev->Good() && ioRow->mRow_Length >= inNewSize );
|
||||
@ -230,28 +231,42 @@ morkPool::CutRowCells(morkEnv* ev, morkRow* ioRow,
|
||||
mork_fill fill = ioRow->mRow_Length;
|
||||
if ( ev->Good() && fill > inNewSize ) // need fewer cells?
|
||||
{
|
||||
morkCell* newCells = this->NewCells(ev, inNewSize);
|
||||
if ( newCells )
|
||||
if ( inNewSize ) // want any row cells at all?
|
||||
{
|
||||
morkCell* newCells = this->NewCells(ev, inNewSize);
|
||||
if ( newCells )
|
||||
{
|
||||
morkCell* oldCells = ioRow->mRow_Cells;
|
||||
morkCell* oldEnd = oldCells + fill; // one past all old cells
|
||||
morkCell* newEnd = oldCells + inNewSize; // copy only kept old cells
|
||||
while ( oldCells < newEnd )
|
||||
{
|
||||
*newCells++ = *oldCells++; // bitwise copy each old cell struct
|
||||
}
|
||||
while ( oldCells < oldEnd )
|
||||
{
|
||||
if ( oldCells->mCell_Atom ) // need to unref old cell atom?
|
||||
oldCells->SetAtom(ev, (morkAtom*) 0, this); // unref cell atom
|
||||
++oldCells;
|
||||
}
|
||||
oldCells = ioRow->mRow_Cells;
|
||||
ioRow->mRow_Cells = newCells;
|
||||
ioRow->mRow_Length = inNewSize;
|
||||
++ioRow->mRow_Seed;
|
||||
|
||||
if ( oldCells )
|
||||
this->ZapCells(ev, oldCells, fill);
|
||||
}
|
||||
}
|
||||
else // get rid of all row cells
|
||||
{
|
||||
morkCell* oldCells = ioRow->mRow_Cells;
|
||||
morkCell* oldEnd = oldCells + fill; // one past all old cells
|
||||
morkCell* newEnd = oldCells + inNewSize; // copy only kept old cells
|
||||
while ( oldCells < newEnd )
|
||||
{
|
||||
*newCells++ = *oldCells++; // bitwise copy each old cell struct
|
||||
}
|
||||
while ( oldCells < oldEnd )
|
||||
{
|
||||
if ( oldCells->mCell_Atom ) // need to unref old cell atom?
|
||||
oldCells->SetAtom(ev, (morkAtom*) 0, this); // unref cell atom
|
||||
++oldCells;
|
||||
}
|
||||
oldCells = ioRow->mRow_Cells;
|
||||
ioRow->mRow_Cells = newCells;
|
||||
ioRow->mRow_Length = inNewSize;
|
||||
ioRow->mRow_Cells = 0;
|
||||
ioRow->mRow_Length = 0;
|
||||
++ioRow->mRow_Seed;
|
||||
|
||||
this->ZapCells(ev, oldCells, fill);
|
||||
if ( oldCells )
|
||||
this->ZapCells(ev, oldCells, fill);
|
||||
}
|
||||
}
|
||||
return ( ev->Good() && ioRow->mRow_Length <= inNewSize );
|
||||
|
@ -163,15 +163,18 @@ morkRow::InitRow(morkEnv* ev, const mdbOid* inOid, morkRowSpace* ioSpace,
|
||||
}
|
||||
|
||||
morkRowObject*
|
||||
morkRow::GetRowObject(morkEnv* ev, morkStore* ioStore)
|
||||
morkRow::AcquireRowObject(morkEnv* ev, morkStore* ioStore)
|
||||
{
|
||||
morkRowObject* ro = mRow_Object;
|
||||
if ( !ro ) // need new row object?
|
||||
if ( ro ) // need new row object?
|
||||
ro->AddStrongRef(ev);
|
||||
else
|
||||
{
|
||||
nsIMdbHeap* heap = ioStore->mPort_Heap;
|
||||
ro = new (*heap, ev)
|
||||
morkRowObject(ev, morkUsage::kHeap, heap, this, ioStore);
|
||||
mRow_Object = ro;
|
||||
|
||||
morkRowObject::SlotWeakRowObject(ro, ev, &mRow_Object);
|
||||
}
|
||||
return ro;
|
||||
}
|
||||
@ -179,10 +182,13 @@ morkRow::GetRowObject(morkEnv* ev, morkStore* ioStore)
|
||||
nsIMdbRow*
|
||||
morkRow::AcquireRowHandle(morkEnv* ev, morkStore* ioStore)
|
||||
{
|
||||
morkRowObject* object = this->GetRowObject(ev, ioStore);
|
||||
morkRowObject* object = this->AcquireRowObject(ev, ioStore);
|
||||
if ( object )
|
||||
return object->AcquireRowHandle(ev);
|
||||
|
||||
{
|
||||
nsIMdbRow* rowHandle = object->AcquireRowHandle(ev);
|
||||
object->CutStrongRef(ev);
|
||||
return rowHandle;
|
||||
}
|
||||
return (nsIMdbRow*) 0;
|
||||
}
|
||||
|
||||
@ -387,12 +393,74 @@ morkRow::EmptyAllCells(morkEnv* ev)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
morkRow::CutAllColumns(morkEnv* ev)
|
||||
{
|
||||
morkStore* store = this->GetRowSpaceStore(ev);
|
||||
if ( store )
|
||||
{
|
||||
morkPool* pool = store->StorePool();
|
||||
pool->CutRowCells(ev, this, /*newSize*/ 0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
morkRow::SetRow(morkEnv* ev, const morkRow* inSourceRow)
|
||||
{
|
||||
// note inSourceRow might be in another DB, with a different store...
|
||||
morkStore* store = this->GetRowSpaceStore(ev);
|
||||
morkStore* srcStore = inSourceRow->GetRowSpaceStore(ev);
|
||||
if ( store && srcStore )
|
||||
{
|
||||
mork_bool sameStore = ( store == srcStore ); // identical stores?
|
||||
morkPool* pool = store->StorePool();
|
||||
if ( pool->CutRowCells(ev, this, /*newSize*/ 0) )
|
||||
{
|
||||
mork_fill fill = inSourceRow->mRow_Length;
|
||||
if ( pool->AddRowCells(ev, this, fill) )
|
||||
{
|
||||
morkCell* dst = mRow_Cells;
|
||||
morkCell* dstEnd = dst + mRow_Length;
|
||||
|
||||
const morkCell* src = inSourceRow->mRow_Cells;
|
||||
const morkCell* srcEnd = src + fill;
|
||||
--dst; --src; // prepare both for preincrement:
|
||||
|
||||
while ( ++dst < dstEnd && ++src < srcEnd && ev->Good() )
|
||||
{
|
||||
morkAtom* atom = src->mCell_Atom;
|
||||
mork_column col = src->GetColumn();
|
||||
if ( sameStore ) // source and dest in same store?
|
||||
{
|
||||
dst->SetColumnAndChange(col, morkChange_kAdd);
|
||||
dst->mCell_Atom = atom;
|
||||
if ( atom ) // another ref to non-nil atom?
|
||||
atom->AddCellUse(ev);
|
||||
}
|
||||
else // need to dup items from src store in a dest store
|
||||
{
|
||||
mork_column dstCol = store->CopyToken(ev, col, srcStore);
|
||||
if ( dstCol )
|
||||
{
|
||||
dst->SetColumnAndChange(dstCol, morkChange_kAdd);
|
||||
dst->mCell_Atom = store->CopyAtom(ev, atom);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
morkRow::AddRow(morkEnv* ev, const morkRow* inSourceRow)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// $$$$$ need to iterate over inSourceRow cells adding them to this row.
|
||||
// When the atoms are book atoms, we can just incr the use count.
|
||||
if ( mRow_Length ) // any existing cells we might need to keep?
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
else
|
||||
this->SetRow(ev, inSourceRow); // just exactly duplicate inSourceRow
|
||||
}
|
||||
|
||||
void
|
||||
@ -444,6 +512,41 @@ morkRow::GetRowSpaceStore(morkEnv* ev) const
|
||||
return (morkStore*) 0;
|
||||
}
|
||||
|
||||
void morkRow::CutColumn(morkEnv* ev, mdb_column inColumn)
|
||||
{
|
||||
mork_pos pos = -1;
|
||||
morkCell* cell = this->GetCell(ev, inColumn, &pos);
|
||||
if ( cell )
|
||||
{
|
||||
morkStore* store = this->GetRowSpaceStore(ev);
|
||||
if ( store )
|
||||
{
|
||||
morkPool* pool = store->StorePool();
|
||||
cell->SetAtom(ev, (morkAtom*) 0, pool);
|
||||
|
||||
mork_fill fill = mRow_Length; // should not be zero
|
||||
MORK_ASSERT(fill);
|
||||
if ( fill ) // index < fill for last cell exists?
|
||||
{
|
||||
mork_fill last = fill - 1; // index of last cell in row
|
||||
|
||||
if ( pos < last ) // need to move cells following cut cell?
|
||||
{
|
||||
morkCell* lastCell = mRow_Cells + last;
|
||||
mork_count after = last - pos; // cell count after cut cell
|
||||
morkCell* next = cell + 1; // next cell after cut cell
|
||||
MORK_MEMMOVE(cell, next, after * sizeof(morkCell));
|
||||
lastCell->SetColumnAndChange(0, 0);
|
||||
lastCell->mCell_Atom = 0;
|
||||
}
|
||||
|
||||
if ( ev->Good() )
|
||||
pool->CutRowCells(ev, this, fill - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void morkRow::AddColumn(morkEnv* ev, mdb_column inColumn,
|
||||
const mdbYarn* inYarn, morkStore* ioStore)
|
||||
{
|
||||
@ -475,7 +578,7 @@ morkRow::NewRowCellCursor(morkEnv* ev, mdb_pos inPos)
|
||||
morkStore* store = this->GetRowSpaceStore(ev);
|
||||
if ( store )
|
||||
{
|
||||
morkRowObject* rowObj = this->GetRowObject(ev, store);
|
||||
morkRowObject* rowObj = this->AcquireRowObject(ev, store);
|
||||
if ( rowObj )
|
||||
{
|
||||
nsIMdbHeap* heap = store->mPort_Heap;
|
||||
@ -492,6 +595,7 @@ morkRow::NewRowCellCursor(morkEnv* ev, mdb_pos inPos)
|
||||
else
|
||||
cursor->CutStrongRef(ev);
|
||||
}
|
||||
rowObj->CutStrongRef(ev); // always cut ref (cursor has its own)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ public: // other row methods
|
||||
mork_size inLength, morkPool* ioPool);
|
||||
// if inLength is nonzero, cells will be allocated from ioPool
|
||||
|
||||
morkRowObject* GetRowObject(morkEnv* ev, morkStore* ioStore);
|
||||
morkRowObject* AcquireRowObject(morkEnv* ev, morkStore* ioStore);
|
||||
nsIMdbRow* AcquireRowHandle(morkEnv* ev, morkStore* ioStore);
|
||||
nsIMdbCell* AcquireCellHandle(morkEnv* ev, morkCell* ioCell,
|
||||
mdb_column inColumn, mork_pos inPos);
|
||||
@ -109,10 +109,14 @@ public: // external row methods
|
||||
void AddColumn(morkEnv* ev, mdb_column inColumn,
|
||||
const mdbYarn* inYarn, morkStore* ioStore);
|
||||
|
||||
void CutColumn(morkEnv* ev, mdb_column inColumn);
|
||||
|
||||
morkRowCellCursor* NewRowCellCursor(morkEnv* ev, mdb_pos inPos);
|
||||
|
||||
void EmptyAllCells(morkEnv* ev);
|
||||
void AddRow(morkEnv* ev, const morkRow* inSourceRow);
|
||||
void SetRow(morkEnv* ev, const morkRow* inSourceRow);
|
||||
void CutAllColumns(morkEnv* ev);
|
||||
|
||||
void OnZeroTableUse(morkEnv* ev);
|
||||
// OnZeroTableUse() is called when CutTableUse() returns zero.
|
||||
|
@ -103,15 +103,16 @@ morkRowObject::CloseRowObject(morkEnv* ev) // called by CloseMorkNode();
|
||||
|
||||
if ( row )
|
||||
{
|
||||
MORK_ASSERT(row->mRow_Object == this);
|
||||
if ( row->mRow_Object == this )
|
||||
{
|
||||
morkRowObject::SlotWeakRowObject((morkRowObject*) 0, ev,
|
||||
&row->mRow_Object);
|
||||
row->mRow_Object = 0; // just nil this slot -- cut ref down below
|
||||
|
||||
morkStore::SlotWeakStore((morkStore*) 0, ev,
|
||||
&mRowObject_Store);
|
||||
|
||||
this->CutWeakRef(ev); // do last, because it might self destroy
|
||||
}
|
||||
else
|
||||
MORK_ASSERT(morkBool_kFalse);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -232,7 +232,8 @@ morkRowSpace::FindTableByKind(morkEnv* ev, mork_kind inTableKind)
|
||||
|
||||
morkTable*
|
||||
morkRowSpace::NewTableWithTid(morkEnv* ev, mork_tid inTid,
|
||||
mork_kind inTableKind)
|
||||
mork_kind inTableKind,
|
||||
const mdbOid* inOptionalMetaRowOid) // can be nil to avoid specifying
|
||||
{
|
||||
morkTable* outTable = 0;
|
||||
|
||||
@ -242,7 +243,7 @@ morkRowSpace::NewTableWithTid(morkEnv* ev, mork_tid inTid,
|
||||
nsIMdbHeap* heap = mSpace_Store->mPort_Heap;
|
||||
morkTable* table = new(*heap, ev)
|
||||
morkTable(ev, morkUsage::kHeap, heap, mSpace_Store, heap, this,
|
||||
inTid, inTableKind, mustBeUnique);
|
||||
inOptionalMetaRowOid, inTid, inTableKind, mustBeUnique);
|
||||
if ( table )
|
||||
{
|
||||
if ( mRowSpace_Tables.AddTable(ev, table) )
|
||||
@ -263,7 +264,8 @@ morkRowSpace::NewTableWithTid(morkEnv* ev, mork_tid inTid,
|
||||
|
||||
morkTable*
|
||||
morkRowSpace::NewTable(morkEnv* ev, mork_kind inTableKind,
|
||||
mdb_bool inMustBeUnique)
|
||||
mdb_bool inMustBeUnique,
|
||||
const mdbOid* inOptionalMetaRowOid) // can be nil to avoid specifying
|
||||
{
|
||||
morkTable* outTable = 0;
|
||||
|
||||
@ -280,7 +282,7 @@ morkRowSpace::NewTable(morkEnv* ev, mork_kind inTableKind,
|
||||
nsIMdbHeap* heap = mSpace_Store->mPort_Heap;
|
||||
morkTable* table = new(*heap, ev)
|
||||
morkTable(ev, morkUsage::kHeap, heap, mSpace_Store, heap, this,
|
||||
id, inTableKind, inMustBeUnique);
|
||||
inOptionalMetaRowOid, id, inTableKind, inMustBeUnique);
|
||||
if ( table )
|
||||
{
|
||||
if ( mRowSpace_Tables.AddTable(ev, table) )
|
||||
|
@ -113,10 +113,10 @@ public: // other space methods
|
||||
// CutAllRows() puts all rows and cells back into the pool.
|
||||
|
||||
morkTable* NewTable(morkEnv* ev, mork_kind inTableKind,
|
||||
mdb_bool inMustBeUnique);
|
||||
mdb_bool inMustBeUnique, const mdbOid* inOptionalMetaRowOid);
|
||||
|
||||
morkTable* NewTableWithTid(morkEnv* ev, mork_tid inTid,
|
||||
mork_kind inTableKind);
|
||||
mork_kind inTableKind, const mdbOid* inOptionalMetaRowOid);
|
||||
|
||||
morkTable* FindTableByKind(morkEnv* ev, mork_kind inTableKind);
|
||||
morkTable* FindTableByTid(morkEnv* ev, mork_tid inTid)
|
||||
|
@ -217,14 +217,6 @@ morkStore::morkStore(morkEnv* ev, const morkUsage& inUsage,
|
||||
, mStore_GroundAtomSpace( 0 )
|
||||
, mStore_GroundColumnSpace( 0 )
|
||||
|
||||
, mStore_MorkNoneToken( 0 )
|
||||
, mStore_CharsetToken( 0 )
|
||||
, mStore_AtomScopeToken( 0 )
|
||||
, mStore_RowScopeToken( 0 )
|
||||
, mStore_TableScopeToken( 0 )
|
||||
, mStore_ColumnScopeToken( 0 )
|
||||
, mStore_TableKindToken( 0 )
|
||||
|
||||
, mStore_RowSpaces(ev, morkUsage::kMember, (nsIMdbHeap*) 0, ioPortHeap)
|
||||
, mStore_AtomSpaces(ev, morkUsage::kMember, (nsIMdbHeap*) 0, ioPortHeap)
|
||||
, mStore_Pool(ev, morkUsage::kMember, (nsIMdbHeap*) 0, ioPortHeap)
|
||||
@ -233,26 +225,6 @@ morkStore::morkStore(morkEnv* ev, const morkUsage& inUsage,
|
||||
{
|
||||
mNode_Derived = morkDerived_kStore;
|
||||
|
||||
if ( ev->Good() )
|
||||
mStore_MorkNoneToken = this->StringToToken(ev, "mork:none");
|
||||
|
||||
if ( ev->Good() )
|
||||
mStore_CharsetToken = this->StringToToken(ev, "charset");
|
||||
|
||||
if ( ev->Good() )
|
||||
mStore_AtomScopeToken = this->StringToToken(ev, "atomScope");
|
||||
|
||||
if ( ev->Good() )
|
||||
mStore_RowScopeToken = this->StringToToken(ev, "rowScope");
|
||||
|
||||
if ( ev->Good() )
|
||||
mStore_TableScopeToken = this->StringToToken(ev, "tableScope");
|
||||
|
||||
if ( ev->Good() )
|
||||
mStore_ColumnScopeToken = this->StringToToken(ev, "columnScope");
|
||||
|
||||
if ( ev->Good() )
|
||||
mStore_TableKindToken = this->StringToToken(ev, "tableKind");
|
||||
}
|
||||
}
|
||||
|
||||
@ -603,6 +575,20 @@ morkStore::CreateStoreFile(morkEnv* ev,
|
||||
}
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
morkAtom*
|
||||
morkStore::CopyAtom(morkEnv* ev, const morkAtom* inAtom)
|
||||
// copy inAtom (from some other store) over to this store
|
||||
{
|
||||
morkAtom* outAtom = 0;
|
||||
if ( inAtom )
|
||||
{
|
||||
mdbYarn yarn;
|
||||
if ( inAtom->AliasYarn(&yarn) )
|
||||
outAtom = this->YarnToAtom(ev, &yarn);
|
||||
}
|
||||
return outAtom;
|
||||
}
|
||||
|
||||
morkAtom*
|
||||
morkStore::YarnToAtom(morkEnv* ev, const mdbYarn* inYarn)
|
||||
@ -691,7 +677,7 @@ morkStore::MidToTable(morkEnv* ev, const morkMid& inMid)
|
||||
{
|
||||
mdbOid tempOid;
|
||||
this->MidToOid(ev, inMid, &tempOid);
|
||||
return this->OidToTable(ev, &tempOid);
|
||||
return this->OidToTable(ev, &tempOid, /*metarow*/ (mdbOid*) 0);
|
||||
}
|
||||
|
||||
mork_bool
|
||||
@ -769,10 +755,10 @@ morkStore::TokenToString(morkEnv* ev, mdb_token inToken, mdbYarn* outTokenName)
|
||||
this->SmallTokenToOneByteYarn(ev, inToken, outTokenName);
|
||||
}
|
||||
|
||||
void
|
||||
morkStore::SyncTokenIdChange(morkEnv* ev, const morkBookAtom* inAtom,
|
||||
const mdbOid* inOid)
|
||||
{
|
||||
// void
|
||||
// morkStore::SyncTokenIdChange(morkEnv* ev, const morkBookAtom* inAtom,
|
||||
// const mdbOid* inOid)
|
||||
// {
|
||||
// mork_token mStore_MorkNoneToken; // token for "mork:none" // fill=9
|
||||
// mork_column mStore_CharsetToken; // token for "charset" // fill=7
|
||||
// mork_column mStore_AtomScopeToken; // token for "atomScope" // fill=9
|
||||
@ -781,55 +767,55 @@ morkStore::SyncTokenIdChange(morkEnv* ev, const morkBookAtom* inAtom,
|
||||
// mork_column mStore_ColumnScopeToken; // token for "columnScope" // fill=11
|
||||
// mork_kind mStore_TableKindToken; // token for "tableKind" // fill=9
|
||||
// ---------------------ruler-for-token-length-above---123456789012
|
||||
|
||||
if ( inOid->mOid_Scope == morkStore_kColumnSpaceScope && inAtom->IsWeeBook() )
|
||||
{
|
||||
const mork_u1* body = ((const morkWeeBookAtom*) inAtom)->mWeeBookAtom_Body;
|
||||
mork_size size = inAtom->mAtom_Size;
|
||||
|
||||
if ( size >= 7 && size <= 11 )
|
||||
{
|
||||
if ( size == 9 )
|
||||
{
|
||||
if ( *body == 'm' )
|
||||
{
|
||||
if ( MORK_MEMCMP(body, "mork:none", 9) == 0 )
|
||||
mStore_MorkNoneToken = inAtom->mBookAtom_Id;
|
||||
}
|
||||
else if ( *body == 'a' )
|
||||
{
|
||||
if ( MORK_MEMCMP(body, "atomScope", 9) == 0 )
|
||||
mStore_AtomScopeToken = inAtom->mBookAtom_Id;
|
||||
}
|
||||
else if ( *body == 't' )
|
||||
{
|
||||
if ( MORK_MEMCMP(body, "tableKind", 9) == 0 )
|
||||
mStore_TableKindToken = inAtom->mBookAtom_Id;
|
||||
}
|
||||
}
|
||||
else if ( size == 7 && *body == 'c' )
|
||||
{
|
||||
if ( MORK_MEMCMP(body, "charset", 7) == 0 )
|
||||
mStore_CharsetToken = inAtom->mBookAtom_Id;
|
||||
}
|
||||
else if ( size == 8 && *body == 'r' )
|
||||
{
|
||||
if ( MORK_MEMCMP(body, "rowScope", 8) == 0 )
|
||||
mStore_RowScopeToken = inAtom->mBookAtom_Id;
|
||||
}
|
||||
else if ( size == 10 && *body == 't' )
|
||||
{
|
||||
if ( MORK_MEMCMP(body, "tableScope", 10) == 0 )
|
||||
mStore_TableScopeToken = inAtom->mBookAtom_Id;
|
||||
}
|
||||
else if ( size == 11 && *body == 'c' )
|
||||
{
|
||||
if ( MORK_MEMCMP(body, "columnScope", 11) == 0 )
|
||||
mStore_ColumnScopeToken = inAtom->mBookAtom_Id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// if ( inOid->mOid_Scope == morkStore_kColumnSpaceScope && inAtom->IsWeeBook() )
|
||||
// {
|
||||
// const mork_u1* body = ((const morkWeeBookAtom*) inAtom)->mWeeBookAtom_Body;
|
||||
// mork_size size = inAtom->mAtom_Size;
|
||||
//
|
||||
// if ( size >= 7 && size <= 11 )
|
||||
// {
|
||||
// if ( size == 9 )
|
||||
// {
|
||||
// if ( *body == 'm' )
|
||||
// {
|
||||
// if ( MORK_MEMCMP(body, "mork:none", 9) == 0 )
|
||||
// mStore_MorkNoneToken = inAtom->mBookAtom_Id;
|
||||
// }
|
||||
// else if ( *body == 'a' )
|
||||
// {
|
||||
// if ( MORK_MEMCMP(body, "atomScope", 9) == 0 )
|
||||
// mStore_AtomScopeToken = inAtom->mBookAtom_Id;
|
||||
// }
|
||||
// else if ( *body == 't' )
|
||||
// {
|
||||
// if ( MORK_MEMCMP(body, "tableKind", 9) == 0 )
|
||||
// mStore_TableKindToken = inAtom->mBookAtom_Id;
|
||||
// }
|
||||
// }
|
||||
// else if ( size == 7 && *body == 'c' )
|
||||
// {
|
||||
// if ( MORK_MEMCMP(body, "charset", 7) == 0 )
|
||||
// mStore_CharsetToken = inAtom->mBookAtom_Id;
|
||||
// }
|
||||
// else if ( size == 8 && *body == 'r' )
|
||||
// {
|
||||
// if ( MORK_MEMCMP(body, "rowScope", 8) == 0 )
|
||||
// mStore_RowScopeToken = inAtom->mBookAtom_Id;
|
||||
// }
|
||||
// else if ( size == 10 && *body == 't' )
|
||||
// {
|
||||
// if ( MORK_MEMCMP(body, "tableScope", 10) == 0 )
|
||||
// mStore_TableScopeToken = inAtom->mBookAtom_Id;
|
||||
// }
|
||||
// else if ( size == 11 && *body == 'c' )
|
||||
// {
|
||||
// if ( MORK_MEMCMP(body, "columnScope", 11) == 0 )
|
||||
// mStore_ColumnScopeToken = inAtom->mBookAtom_Id;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
morkAtom*
|
||||
morkStore::AddAlias(morkEnv* ev, const morkMid& inMid, mork_cscode inForm)
|
||||
@ -858,15 +844,15 @@ morkStore::AddAlias(morkEnv* ev, const morkMid& inMid, mork_cscode inForm)
|
||||
outAtom = atomSpace->MakeBookAtomCopyWithAid(ev,
|
||||
*keyAtom, (mork_aid) oid->mOid_Id);
|
||||
|
||||
if ( outAtom && outAtom->IsWeeBook() )
|
||||
{
|
||||
if ( oid->mOid_Scope == morkStore_kColumnSpaceScope )
|
||||
{
|
||||
mork_size size = outAtom->mAtom_Size;
|
||||
if ( size >= 7 && size <= 11 )
|
||||
this->SyncTokenIdChange(ev, outAtom, oid);
|
||||
}
|
||||
}
|
||||
// if ( outAtom && outAtom->IsWeeBook() )
|
||||
// {
|
||||
// if ( oid->mOid_Scope == morkStore_kColumnSpaceScope )
|
||||
// {
|
||||
// mork_size size = outAtom->mAtom_Size;
|
||||
// if ( size >= 7 && size <= 11 )
|
||||
// this->SyncTokenIdChange(ev, outAtom, oid);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -874,6 +860,36 @@ morkStore::AddAlias(morkEnv* ev, const morkMid& inMid, mork_cscode inForm)
|
||||
return outAtom;
|
||||
}
|
||||
|
||||
#define morkStore_kMaxCopyTokenSize 512 /* if larger, cannot be copied */
|
||||
|
||||
mork_token
|
||||
morkStore::CopyToken(morkEnv* ev, mdb_token inToken, morkStore* inStore)
|
||||
// copy inToken from inStore over to this store
|
||||
{
|
||||
mork_token outToken = 0;
|
||||
if ( inStore == this ) // same store?
|
||||
outToken = inToken; // just return token unchanged
|
||||
else
|
||||
{
|
||||
char yarnBuf[ morkStore_kMaxCopyTokenSize ];
|
||||
mdbYarn yarn;
|
||||
yarn.mYarn_Buf = yarnBuf;
|
||||
yarn.mYarn_Fill = 0;
|
||||
yarn.mYarn_Size = morkStore_kMaxCopyTokenSize;
|
||||
yarn.mYarn_More = 0;
|
||||
yarn.mYarn_Form = 0;
|
||||
yarn.mYarn_Grow = 0;
|
||||
|
||||
inStore->TokenToString(ev, inToken, &yarn);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
morkBuf buf(yarn.mYarn_Buf, yarn.mYarn_Fill);
|
||||
outToken = this->BufToToken(ev, &buf);
|
||||
}
|
||||
}
|
||||
return outToken;
|
||||
}
|
||||
|
||||
mork_token
|
||||
morkStore::BufToToken(morkEnv* ev, const morkBuf* inBuf)
|
||||
{
|
||||
@ -1064,14 +1080,16 @@ morkStore::GetTable(morkEnv* ev, const mdbOid* inOid)
|
||||
|
||||
morkTable*
|
||||
morkStore::NewTable(morkEnv* ev, mdb_scope inRowScope,
|
||||
mdb_kind inTableKind, mdb_bool inMustBeUnique)
|
||||
mdb_kind inTableKind, mdb_bool inMustBeUnique,
|
||||
const mdbOid* inOptionalMetaRowOid) // can be nil to avoid specifying
|
||||
{
|
||||
morkTable* outTable = 0;
|
||||
if ( ev->Good() )
|
||||
{
|
||||
morkRowSpace* rowSpace = this->LazyGetRowSpace(ev, inRowScope);
|
||||
if ( rowSpace )
|
||||
outTable = rowSpace->NewTable(ev, inTableKind, inMustBeUnique);
|
||||
outTable = rowSpace->NewTable(ev, inTableKind, inMustBeUnique,
|
||||
inOptionalMetaRowOid);
|
||||
}
|
||||
return outTable;
|
||||
}
|
||||
@ -1136,7 +1154,8 @@ morkStore::OidToRow(morkEnv* ev, const mdbOid* inOid)
|
||||
}
|
||||
|
||||
morkTable*
|
||||
morkStore::OidToTable(morkEnv* ev, const mdbOid* inOid)
|
||||
morkStore::OidToTable(morkEnv* ev, const mdbOid* inOid,
|
||||
const mdbOid* inOptionalMetaRowOid) // can be nil to avoid specifying
|
||||
// OidToTable() finds old table with oid, or makes new one if not found.
|
||||
{
|
||||
morkTable* outTable = 0;
|
||||
@ -1148,8 +1167,9 @@ morkStore::OidToTable(morkEnv* ev, const mdbOid* inOid)
|
||||
outTable = rowSpace->mRowSpace_Tables.GetTable(ev, inOid->mOid_Id);
|
||||
if ( !outTable && ev->Good() )
|
||||
{
|
||||
mork_kind tableKind = mStore_MorkNoneToken;
|
||||
outTable = rowSpace->NewTableWithTid(ev, inOid->mOid_Id, tableKind);
|
||||
mork_kind tableKind = morkStore_kNoneToken;
|
||||
outTable = rowSpace->NewTableWithTid(ev, inOid->mOid_Id, tableKind,
|
||||
inOptionalMetaRowOid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -119,6 +119,15 @@ public: // typesafe refcounting inlines calling inherited morkNode methods
|
||||
#define morkStore_kGroundAtomSpace 'a' /* for mStore_GroundAtomSpace*/
|
||||
#define morkStore_kStreamBufSize (8 * 1024) /* okay buffer size */
|
||||
|
||||
#define morkStore_kReservedColumnCount 0x20 /* for well-known columns */
|
||||
|
||||
#define morkStore_kNoneToken ((mork_token) 'n')
|
||||
#define morkStore_kFormColumn ((mork_column) 'f')
|
||||
#define morkStore_kAtomScopeColumn ((mork_column) 'a')
|
||||
#define morkStore_kRowScopeColumn ((mork_column) 'r')
|
||||
#define morkStore_kMetaScope ((mork_scope) 'm')
|
||||
#define morkStore_kKindColumn ((mork_column) 'k')
|
||||
|
||||
/*| morkStore:
|
||||
|*/
|
||||
class morkStore : public morkPort {
|
||||
@ -151,14 +160,6 @@ public: // state is public because the entire Mork system is private
|
||||
|
||||
morkStream* mStore_OutStream; // stream using file used by the writer
|
||||
|
||||
mork_token mStore_MorkNoneToken; // token for "mork:none"
|
||||
mork_column mStore_CharsetToken; // token for "charset"
|
||||
mork_column mStore_AtomScopeToken; // token for "atomScope"
|
||||
mork_column mStore_RowScopeToken; // token for "rowScope"
|
||||
mork_column mStore_TableScopeToken; // token for "tableScope"
|
||||
mork_column mStore_ColumnScopeToken; // token for "columnScope"
|
||||
mork_kind mStore_TableKindToken; // token for "tableKind"
|
||||
|
||||
morkRowSpaceMap mStore_RowSpaces; // maps mork_scope -> morkSpace
|
||||
morkAtomSpaceMap mStore_AtomSpaces; // maps mork_scope -> morkSpace
|
||||
|
||||
@ -169,8 +170,8 @@ public: // state is public because the entire Mork system is private
|
||||
|
||||
public: // coping with any changes to store token slots above:
|
||||
|
||||
void SyncTokenIdChange(morkEnv* ev, const morkBookAtom* inAtom,
|
||||
const mdbOid* inOid);
|
||||
// void SyncTokenIdChange(morkEnv* ev, const morkBookAtom* inAtom,
|
||||
// const mdbOid* inOid);
|
||||
|
||||
public: // building an atom inside mStore_BookAtom from a char* string
|
||||
|
||||
@ -252,6 +253,12 @@ public: // other store methods
|
||||
const char* inFilePath,
|
||||
const mdbOpenPolicy* inOpenPolicy);
|
||||
|
||||
morkAtom* CopyAtom(morkEnv* ev, const morkAtom* inAtom);
|
||||
// copy inAtom (from some other store) over to this store
|
||||
|
||||
mork_token CopyToken(morkEnv* ev, mdb_token inToken, morkStore* inStore);
|
||||
// copy inToken from inStore over to this store
|
||||
|
||||
mork_token BufToToken(morkEnv* ev, const morkBuf* inBuf);
|
||||
mork_token StringToToken(morkEnv* ev, const char* inTokenName);
|
||||
mork_token QueryToken(morkEnv* ev, const char* inTokenName);
|
||||
@ -270,7 +277,8 @@ public: // other store methods
|
||||
morkRow* OidToRow(morkEnv* ev, const mdbOid* inOid);
|
||||
// OidToRow() finds old row with oid, or makes new one if not found.
|
||||
|
||||
morkTable* OidToTable(morkEnv* ev, const mdbOid* inOid);
|
||||
morkTable* OidToTable(morkEnv* ev, const mdbOid* inOid,
|
||||
const mdbOid* inOptionalMetaRowOid);
|
||||
// OidToTable() finds old table with oid, or makes new one if not found.
|
||||
|
||||
static void SmallTokenToOneByteYarn(morkEnv* ev, mdb_token inToken,
|
||||
@ -287,7 +295,8 @@ public: // other store methods
|
||||
morkTable* GetTable(morkEnv* ev, const mdbOid* inOid);
|
||||
|
||||
morkTable* NewTable(morkEnv* ev, mdb_scope inRowScope,
|
||||
mdb_kind inTableKind, mdb_bool inMustBeUnique);
|
||||
mdb_kind inTableKind, mdb_bool inMustBeUnique,
|
||||
const mdbOid* inOptionalMetaRowOid);
|
||||
|
||||
morkPortTableCursor* GetPortTableCursor(morkEnv* ev, mdb_scope inRowScope,
|
||||
mdb_kind inTableKind) ;
|
||||
|
@ -92,10 +92,12 @@ morkTable::~morkTable() /*i*/ // assert CloseTable() executed earlier
|
||||
morkTable::morkTable(morkEnv* ev, /*i*/
|
||||
const morkUsage& inUsage, nsIMdbHeap* ioHeap,
|
||||
morkStore* ioStore, nsIMdbHeap* ioSlotHeap, morkRowSpace* ioRowSpace,
|
||||
const mdbOid* inOptionalMetaRowOid, // can be nil to avoid specifying
|
||||
mork_tid inTid, mork_kind inKind, mork_bool inMustBeUnique)
|
||||
: morkObject(ev, inUsage, ioHeap, (morkHandle*) 0)
|
||||
, mTable_Store( 0 )
|
||||
, mTable_RowSpace( 0 )
|
||||
, mTable_MetaRow( 0 )
|
||||
, mTable_Id( inTid )
|
||||
, mTable_RowMap(ev, morkUsage::kMember, (nsIMdbHeap*) 0, ioSlotHeap,
|
||||
morkTable_kStartRowMapSlotCount)
|
||||
@ -112,6 +114,13 @@ morkTable::morkTable(morkEnv* ev, /*i*/
|
||||
{
|
||||
morkStore::SlotWeakStore(ioStore, ev, &mTable_Store);
|
||||
morkRowSpace::SlotWeakRowSpace(ioRowSpace, ev, &mTable_RowSpace);
|
||||
if ( inOptionalMetaRowOid )
|
||||
mTable_MetaRowOid = *inOptionalMetaRowOid;
|
||||
else
|
||||
{
|
||||
mTable_MetaRowOid.mOid_Scope = 0;
|
||||
mTable_MetaRowOid.mOid_Id = morkRow_kMinusOneRid;
|
||||
}
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kTable;
|
||||
}
|
||||
@ -194,6 +203,33 @@ morkTable::NilRowSpaceError(morkEnv* ev)
|
||||
ev->NewError("nil mTable_RowSpace");
|
||||
}
|
||||
|
||||
morkRow*
|
||||
morkTable::GetMetaRow(morkEnv* ev, const mdbOid* inOptionalMetaRowOid)
|
||||
{
|
||||
morkRow* outRow = mTable_MetaRow;
|
||||
if ( !outRow )
|
||||
{
|
||||
morkStore* store = mTable_Store;
|
||||
mdbOid* oid = &mTable_MetaRowOid;
|
||||
if ( inOptionalMetaRowOid && !oid->mOid_Scope )
|
||||
*oid = *inOptionalMetaRowOid;
|
||||
|
||||
if ( oid->mOid_Scope ) // oid already recorded in table?
|
||||
outRow = store->OidToRow(ev, oid);
|
||||
else
|
||||
{
|
||||
outRow = store->NewRow(ev, morkStore_kMetaScope);
|
||||
if ( outRow ) // need to record new oid in table?
|
||||
*oid = outRow->mRow_Oid;
|
||||
}
|
||||
mTable_MetaRow = outRow;
|
||||
if ( outRow ) // need to note another use of this row?
|
||||
outRow->AddTableUse(ev);
|
||||
}
|
||||
|
||||
return outRow;
|
||||
}
|
||||
|
||||
void
|
||||
morkTable::GetTableOid(morkEnv* ev, mdbOid* outOid)
|
||||
{
|
||||
@ -241,14 +277,10 @@ morkTable::ArrayHasOid(morkEnv* ev, const mdbOid* inOid)
|
||||
return -1;
|
||||
}
|
||||
|
||||
mork_pos
|
||||
mork_bool
|
||||
morkTable::MapHasOid(morkEnv* ev, const mdbOid* inOid)
|
||||
{
|
||||
morkRow* row = mTable_RowMap.GetOid(ev, inOid);
|
||||
if ( row )
|
||||
return 1;
|
||||
|
||||
return -1;
|
||||
return ( mTable_RowMap.GetOid(ev, inOid) != 0 );
|
||||
}
|
||||
|
||||
mork_bool
|
||||
|
@ -78,6 +78,9 @@ public: // state is public because the entire Mork system is private
|
||||
|
||||
// mTable_RowSpace->mSpace_Scope is row scope
|
||||
morkRowSpace* mTable_RowSpace; // weak ref to containing space
|
||||
|
||||
morkRow* mTable_MetaRow; // table's actual meta row
|
||||
mdbOid mTable_MetaRowOid; // oid for meta row
|
||||
|
||||
morkRowMap mTable_RowMap; // hash table of all members
|
||||
morkArray mTable_RowArray; // array of morkRow pointers
|
||||
@ -98,6 +101,7 @@ public: // morkTable construction & destruction
|
||||
morkTable(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioNodeHeap, morkStore* ioStore,
|
||||
nsIMdbHeap* ioSlotHeap, morkRowSpace* ioRowSpace,
|
||||
const mdbOid* inOptionalMetaRowOid, // can be nil to avoid specifying
|
||||
mork_tid inTableId,
|
||||
mork_kind inKind, mork_bool inMustBeUnique);
|
||||
void CloseTable(morkEnv* ev); // called by CloseMorkNode();
|
||||
@ -120,6 +124,8 @@ public: // warnings
|
||||
static void CellUsesUnderflowWarning(morkEnv* ev);
|
||||
|
||||
public: // other table methods
|
||||
|
||||
morkRow* GetMetaRow(morkEnv* ev, const mdbOid* inOptionalMetaRowOid);
|
||||
|
||||
mork_u2 AddCellUse(morkEnv* ev);
|
||||
mork_u2 CutCellUse(morkEnv* ev);
|
||||
@ -134,7 +140,7 @@ public: // other table methods
|
||||
|
||||
void GetTableOid(morkEnv* ev, mdbOid* outOid);
|
||||
mork_pos ArrayHasOid(morkEnv* ev, const mdbOid* inOid);
|
||||
mork_pos MapHasOid(morkEnv* ev, const mdbOid* inOid);
|
||||
mork_bool MapHasOid(morkEnv* ev, const mdbOid* inOid);
|
||||
mork_bool AddRow(morkEnv* ev, morkRow* ioRow); // returns ev->Good()
|
||||
mork_bool CutRow(morkEnv* ev, morkRow* ioRow); // returns ev->Good()
|
||||
|
||||
|
@ -129,18 +129,16 @@ morkWriter::morkWriter(morkEnv* ev, const morkUsage& inUsage,
|
||||
, mWriter_MaxIndent( morkWriter_kMaxIndent )
|
||||
, mWriter_MaxLine( morkWriter_kMaxLine )
|
||||
|
||||
, mWriter_TableCharset( 0 )
|
||||
, mWriter_TableForm( 0 )
|
||||
, mWriter_TableAtomScope( 0 )
|
||||
, mWriter_TableRowScope( 0 )
|
||||
, mWriter_TableTableScope( 0 )
|
||||
, mWriter_TableColumnScope( 0 )
|
||||
, mWriter_TableKind( 0 )
|
||||
|
||||
, mWriter_RowCharset( 0 )
|
||||
, mWriter_RowForm( 0 )
|
||||
, mWriter_RowAtomScope( 0 )
|
||||
, mWriter_RowScope( 0 )
|
||||
|
||||
, mWriter_DictCharset( 0 )
|
||||
, mWriter_DictForm( 0 )
|
||||
, mWriter_DictAtomScope( 0 )
|
||||
|
||||
, mWriter_NeedDirtyAll( morkBool_kFalse )
|
||||
@ -372,7 +370,7 @@ morkWriter::WriteYarn(morkEnv* ev, const mdbYarn* inYarn)
|
||||
stream->Putc(ev, c);
|
||||
++outSize; // c
|
||||
}
|
||||
else if ( c == ')' && c == '$' && c == '\\' )
|
||||
else if ( c == ')' || c == '$' || c == '\\' )
|
||||
{
|
||||
stream->Putc(ev, '\\');
|
||||
stream->Putc(ev, c);
|
||||
@ -403,8 +401,8 @@ morkWriter::WriteAtom(morkEnv* ev, const morkAtom* inAtom)
|
||||
|
||||
if ( inAtom->AliasYarn(&yarn) )
|
||||
{
|
||||
if ( mWriter_DidStartDict && yarn.mYarn_Form != mWriter_DictCharset )
|
||||
this->ChangeDictCharset(ev, yarn.mYarn_Form);
|
||||
if ( mWriter_DidStartDict && yarn.mYarn_Form != mWriter_DictForm )
|
||||
this->ChangeDictForm(ev, yarn.mYarn_Form);
|
||||
|
||||
outSize = this->WriteYarn(ev, &yarn);
|
||||
// mWriter_LineSize += stream->Write(ev, inYarn->mYarn_Buf, outSize);
|
||||
@ -424,10 +422,10 @@ morkWriter::WriteAtomSpaceAsDict(morkEnv* ev, morkAtomSpace* ioSpace)
|
||||
{
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
stream->PutString(ev, "< <(atomScope=");
|
||||
stream->PutString(ev, "< <(a=");
|
||||
stream->Putc(ev, (int) scope);
|
||||
++mWriter_LineSize;
|
||||
stream->PutString(ev, ")> // (charset=iso-8859-1)");
|
||||
stream->PutString(ev, ")> // (f=iso-8859-1)");
|
||||
mWriter_LineSize = stream->PutIndent(ev, morkWriter_kDictAliasDepth);
|
||||
}
|
||||
else
|
||||
@ -457,8 +455,8 @@ morkWriter::WriteAtomSpaceAsDict(morkEnv* ev, morkAtomSpace* ioSpace)
|
||||
atom->AliasYarn(&yarn);
|
||||
mork_size size = ev->TokenAsHex(idBuf, atom->mBookAtom_Id);
|
||||
|
||||
if ( yarn.mYarn_Form != mWriter_DictCharset )
|
||||
this->ChangeDictCharset(ev, yarn.mYarn_Form);
|
||||
if ( yarn.mYarn_Form != mWriter_DictForm )
|
||||
this->ChangeDictForm(ev, yarn.mYarn_Form);
|
||||
|
||||
mork_size pending = yarn.mYarn_Fill + size +
|
||||
morkWriter_kYarnEscapeSlop + 4;
|
||||
@ -648,7 +646,7 @@ morkWriter::OnDirtyAllDone(morkEnv* ev)
|
||||
stream->Seek(ev, 0); // beginning of stream
|
||||
if ( ev->Good() )
|
||||
{
|
||||
stream->PutStringThenNewline(ev, "// <!-- <mdb:mork:z v=\"1.1\"/> -->");
|
||||
stream->PutStringThenNewline(ev, morkWriter_kFileHeader);
|
||||
mWriter_LineSize = 0;
|
||||
}
|
||||
|
||||
@ -968,17 +966,15 @@ morkWriter::PutTableDict(morkEnv* ev, morkTable* ioTable)
|
||||
{
|
||||
morkRowSpace* space = ioTable->mTable_RowSpace;
|
||||
mWriter_TableRowScope = space->mSpace_Scope;
|
||||
mWriter_TableCharset = 0; // (charset=iso-8859-1)
|
||||
mWriter_TableAtomScope = 'a'; // (atomScope=a)
|
||||
mWriter_TableTableScope = 't'; // (tableScope=t)
|
||||
mWriter_TableColumnScope = 'c'; // (columnScope=c)
|
||||
mWriter_TableForm = 0; // (f=iso-8859-1)
|
||||
mWriter_TableAtomScope = 'v'; // (a=v)
|
||||
mWriter_TableKind = ioTable->mTable_Kind;
|
||||
|
||||
mWriter_RowCharset = mWriter_TableCharset;
|
||||
mWriter_RowForm = mWriter_TableForm;
|
||||
mWriter_RowAtomScope = mWriter_TableAtomScope;
|
||||
mWriter_RowScope = mWriter_TableRowScope;
|
||||
|
||||
mWriter_DictCharset = mWriter_TableCharset;
|
||||
mWriter_DictForm = mWriter_TableForm;
|
||||
mWriter_DictAtomScope = mWriter_TableAtomScope;
|
||||
|
||||
if ( ev->Good() )
|
||||
@ -986,6 +982,14 @@ morkWriter::PutTableDict(morkEnv* ev, morkTable* ioTable)
|
||||
|
||||
if ( ev->Good() )
|
||||
{
|
||||
morkRow* r = ioTable->mTable_MetaRow;
|
||||
if ( r )
|
||||
{
|
||||
if ( r->IsRow() )
|
||||
this->PutRowDict(ev, r);
|
||||
else
|
||||
r->NonRowTypeError(ev);
|
||||
}
|
||||
morkArray* array = &ioTable->mTable_RowArray; // vector of rows
|
||||
mork_fill fill = array->mArray_Fill; // count of rows
|
||||
morkRow** rows = (morkRow**) array->mArray_Slots;
|
||||
@ -994,7 +998,7 @@ morkWriter::PutTableDict(morkEnv* ev, morkTable* ioTable)
|
||||
morkRow** end = rows + fill;
|
||||
while ( rows < end && ev->Good() )
|
||||
{
|
||||
morkRow* r = *rows++; // next row to consider
|
||||
r = *rows++; // next row to consider
|
||||
if ( r && r->IsRow() )
|
||||
this->PutRowDict(ev, r);
|
||||
else
|
||||
@ -1013,15 +1017,25 @@ morkWriter::WriteTokenToTokenMetaCell(morkEnv* ev,
|
||||
mork_token inCol, mork_token inValue)
|
||||
{
|
||||
morkStream* stream = mWriter_Stream;
|
||||
char buf[ 128 ]; // buffer for staging the two hex IDs
|
||||
char* p = buf;
|
||||
*p++ = '('; // we always start with open paren
|
||||
*p++ = '^'; // indicates col is hex ID
|
||||
|
||||
mork_size colSize = ev->TokenAsHex(p, inCol);
|
||||
p += colSize;
|
||||
*p++ = '='; // we always start with open paren
|
||||
mWriter_LineSize += stream->Write(ev, buf, colSize + 3);
|
||||
if ( inCol < 0x80 )
|
||||
{
|
||||
stream->Putc(ev, '(');
|
||||
stream->Putc(ev, (char) inCol);
|
||||
stream->Putc(ev, '=');
|
||||
}
|
||||
else
|
||||
{
|
||||
char buf[ 128 ]; // buffer for staging the two hex IDs
|
||||
char* p = buf;
|
||||
*p++ = '('; // we always start with open paren
|
||||
|
||||
*p++ = '^'; // indicates col is hex ID
|
||||
mork_size colSize = ev->TokenAsHex(p, inCol);
|
||||
p += colSize;
|
||||
*p++ = '=';
|
||||
mWriter_LineSize += stream->Write(ev, buf, colSize + 3);
|
||||
}
|
||||
|
||||
this->IndentAsNeeded(ev, morkWriter_kTableMetaCellValueDepth);
|
||||
mdbYarn* yarn = &mWriter_ColYarn;
|
||||
@ -1058,21 +1072,34 @@ morkWriter::WriteStringToTokenDictCell(morkEnv* ev,
|
||||
}
|
||||
|
||||
void
|
||||
morkWriter::ChangeDictCharset(morkEnv* ev, mork_cscode inNewForm)
|
||||
morkWriter::ChangeDictForm(morkEnv* ev, mork_cscode inNewForm)
|
||||
{
|
||||
if ( inNewForm != mWriter_DictCharset )
|
||||
if ( inNewForm != mWriter_DictForm )
|
||||
{
|
||||
morkStream* stream = mWriter_Stream;
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
mWriter_LineSize = 0;
|
||||
|
||||
stream->Putc(ev, '<');
|
||||
this->WriteStringToTokenDictCell(ev, "(charset=", mWriter_DictCharset);
|
||||
stream->Putc(ev, '>');
|
||||
++mWriter_LineSize;
|
||||
char buf[ 128 ]; // buffer for staging the two hex IDs
|
||||
char* p = buf;
|
||||
*p++ = '<'; // we always start with open paren
|
||||
*p++ = '('; // we always start with open paren
|
||||
*p++ = (char) morkStore_kFormColumn;
|
||||
*p++ = '^'; // indicates col is hex ID
|
||||
|
||||
mork_size formSize = ev->TokenAsHex(p, inNewForm);
|
||||
p += formSize;
|
||||
*p++ = ')';
|
||||
*p++ = '>';
|
||||
*p = 0;
|
||||
|
||||
mork_size pending = formSize + 6;
|
||||
this->IndentOverMaxLine(ev, pending, morkWriter_kDictAliasDepth);
|
||||
|
||||
mWriter_LineSize += stream->Write(ev, buf, pending);
|
||||
|
||||
mWriter_DictCharset = inNewForm;
|
||||
mWriter_DictForm = inNewForm;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1091,16 +1118,16 @@ morkWriter::StartDict(morkEnv* ev)
|
||||
stream->PutLineBreak(ev);
|
||||
mWriter_LineSize = 0;
|
||||
stream->PutLineBreak(ev);
|
||||
if ( mWriter_DictCharset || mWriter_DictAtomScope != 'a' )
|
||||
if ( mWriter_DictForm || mWriter_DictAtomScope != 'v' )
|
||||
{
|
||||
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);
|
||||
if ( mWriter_DictForm )
|
||||
this->WriteStringToTokenDictCell(ev, "(f=", mWriter_DictForm);
|
||||
if ( mWriter_DictAtomScope != 'v' )
|
||||
this->WriteStringToTokenDictCell(ev, "(a=", mWriter_DictAtomScope);
|
||||
|
||||
stream->Putc(ev, '>');
|
||||
++mWriter_LineSize;
|
||||
@ -1149,19 +1176,28 @@ morkWriter::StartTable(morkEnv* ev, morkTable* ioTable)
|
||||
*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_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);
|
||||
this->WriteTokenToTokenMetaCell(ev, morkStore_kKindColumn, tk);
|
||||
}
|
||||
|
||||
morkRow* r = ioTable->mTable_MetaRow;
|
||||
if ( r )
|
||||
{
|
||||
if ( r->IsRow() )
|
||||
this->PutRow(ev, r);
|
||||
else
|
||||
r->NonRowTypeError(ev);
|
||||
}
|
||||
|
||||
stream->Putc(ev, '}'); // end meta
|
||||
mWriter_LineSize = stream->PutIndent(ev, morkWriter_kRowCellDepth);
|
||||
}
|
||||
@ -1218,6 +1254,22 @@ morkWriter::PutRowDict(morkEnv* ev, morkRow* ioRow)
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkWriter::IsYarnAllValue(const mdbYarn* inYarn)
|
||||
{
|
||||
mork_fill fill = inYarn->mYarn_Fill;
|
||||
const mork_u1* buf = (const mork_u1*) inYarn->mYarn_Buf;
|
||||
const mork_u1* end = buf + fill;
|
||||
--buf; // prepare for preincrement
|
||||
while ( ++buf < end )
|
||||
{
|
||||
mork_ch c = *buf;
|
||||
if ( !morkCh_IsValue(c) )
|
||||
return morkBool_kFalse;
|
||||
}
|
||||
return morkBool_kTrue;
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkWriter::PutRowCells(morkEnv* ev, morkRow* ioRow)
|
||||
{
|
||||
@ -1243,17 +1295,39 @@ morkWriter::PutRowCells(morkEnv* ev, morkRow* ioRow)
|
||||
char* p = idBuf;
|
||||
colSize = ev->TokenAsHex(p, col);
|
||||
p += colSize;
|
||||
|
||||
mdbYarn yarn; // to ref content inside atom
|
||||
atom->AliasYarn(&yarn);
|
||||
|
||||
if ( atom->IsBook() ) // is it possible to write atom ID?
|
||||
{
|
||||
this->IndentAsNeeded(ev, morkWriter_kRowCellDepth);
|
||||
*p++ = '^';
|
||||
morkBookAtom* ba = (morkBookAtom*) atom;
|
||||
mork_size valSize = ev->TokenAsHex(p, ba->mBookAtom_Id);
|
||||
p += valSize;
|
||||
*p = ')';
|
||||
|
||||
mWriter_LineSize += stream->Write(ev, buf, colSize + valSize + 4);
|
||||
mork_size valSize = ev->TokenAsHex(p, ba->mBookAtom_Id);
|
||||
mork_fill yarnFill = yarn.mYarn_Fill;
|
||||
mork_bool putImmYarn = ( yarnFill <= valSize );
|
||||
if ( putImmYarn )
|
||||
putImmYarn = this->IsYarnAllValue(&yarn);
|
||||
|
||||
if ( putImmYarn ) // value no bigger than id?
|
||||
{
|
||||
p[ -1 ] = '='; // go back and clobber '^' with '=' instead
|
||||
if ( yarnFill )
|
||||
{
|
||||
MORK_MEMCPY(p, yarn.mYarn_Buf, yarnFill);
|
||||
p += yarnFill;
|
||||
}
|
||||
*p++ = ')';
|
||||
mWriter_LineSize += stream->Write(ev, buf, p - buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
p += valSize;
|
||||
*p = ')';
|
||||
mWriter_LineSize += stream->Write(ev, buf, colSize + valSize + 4);
|
||||
}
|
||||
|
||||
if ( atom->mAtom_Change == morkChange_kAdd )
|
||||
{
|
||||
@ -1263,11 +1337,8 @@ morkWriter::PutRowCells(morkEnv* ev, morkRow* ioRow)
|
||||
}
|
||||
else // must write an anonymous atom
|
||||
{
|
||||
mdbYarn yarn; // to ref content inside atom
|
||||
atom->AliasYarn(&yarn);
|
||||
|
||||
if ( yarn.mYarn_Form != mWriter_DictCharset )
|
||||
this->ChangeDictCharset(ev, yarn.mYarn_Form);
|
||||
if ( yarn.mYarn_Form != mWriter_DictForm )
|
||||
this->ChangeDictForm(ev, yarn.mYarn_Form);
|
||||
|
||||
mork_size pending = yarn.mYarn_Fill + colSize +
|
||||
morkWriter_kYarnEscapeSlop + 2;
|
||||
@ -1299,11 +1370,10 @@ morkWriter::PutRow(morkEnv* ev, morkRow* ioRow)
|
||||
mdbOid* roid = &ioRow->mRow_Oid;
|
||||
mork_size ridSize = 0;
|
||||
|
||||
this->IndentAsNeeded(ev, morkWriter_kRowDepth);
|
||||
|
||||
//if ( morkBool_kTrue )
|
||||
if ( ioRow->IsRowDirty() )
|
||||
{
|
||||
stream->PutIndent(ev, morkWriter_kRowDepth);
|
||||
|
||||
ioRow->SetRowClean();
|
||||
mork_rid rid = roid->mOid_Id;
|
||||
*p++ = '[';
|
||||
@ -1322,6 +1392,8 @@ morkWriter::PutRow(morkEnv* ev, morkRow* ioRow)
|
||||
}
|
||||
else
|
||||
{
|
||||
this->IndentAsNeeded(ev, morkWriter_kRowDepth);
|
||||
|
||||
if ( roid->mOid_Scope == mWriter_TableRowScope )
|
||||
ridSize = ev->TokenAsHex(p, roid->mOid_Id);
|
||||
else
|
||||
|
@ -103,6 +103,9 @@
|
||||
#define morkWriter_kRowCellDepth 4 /* */
|
||||
#define morkWriter_kRowCellValueDepth 6 /* */
|
||||
|
||||
// v=1.1 retired on 23-Mar-98
|
||||
#define morkWriter_kFileHeader "// <!-- <mdb:mork:z v=\"1.2\"/> -->"
|
||||
|
||||
class morkWriter : public morkNode { // row iterator
|
||||
|
||||
// public: // slots inherited from morkObject (meant to inform only)
|
||||
@ -131,18 +134,16 @@ public: // state is public because the entire Mork system is private
|
||||
mork_size mWriter_MaxIndent; // line size forcing a line break
|
||||
mork_size mWriter_MaxLine; // line size forcing a value continuation
|
||||
|
||||
mork_cscode mWriter_TableCharset; // current charset metainfo
|
||||
mork_cscode mWriter_TableForm; // current charset metainfo
|
||||
mork_scope mWriter_TableAtomScope; // current atom scope
|
||||
mork_scope mWriter_TableRowScope; // current row scope
|
||||
mork_scope mWriter_TableTableScope; // current table scope
|
||||
mork_scope mWriter_TableColumnScope; // current column scope
|
||||
mork_kind mWriter_TableKind; // current table kind
|
||||
|
||||
mork_cscode mWriter_RowCharset; // current charset metainfo
|
||||
mork_cscode mWriter_RowForm; // current charset metainfo
|
||||
mork_scope mWriter_RowAtomScope; // current atom scope
|
||||
mork_scope mWriter_RowScope; // current row scope
|
||||
|
||||
mork_cscode mWriter_DictCharset; // current charset metainfo
|
||||
mork_cscode mWriter_DictForm; // current charset metainfo
|
||||
mork_scope mWriter_DictAtomScope; // current atom scope
|
||||
|
||||
mork_bool mWriter_NeedDirtyAll; // need to call DirtyAll()
|
||||
@ -199,7 +200,7 @@ public: // typing & errors
|
||||
static void UnsupportedPhaseError(morkEnv* ev);
|
||||
|
||||
public: // inlines
|
||||
void ChangeDictCharset(morkEnv* ev, mork_cscode inNewForm);
|
||||
void ChangeDictForm(morkEnv* ev, mork_cscode inNewForm);
|
||||
mork_bool DidStartDict() const { return mWriter_DidStartDict; }
|
||||
mork_bool DidEndDict() const { return mWriter_DidEndDict; }
|
||||
|
||||
@ -269,6 +270,8 @@ public: // writing node content second pass
|
||||
|
||||
public: // other writer methods
|
||||
|
||||
mork_bool IsYarnAllValue(const mdbYarn* inYarn);
|
||||
|
||||
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
|
||||
|
@ -60,6 +60,10 @@
|
||||
#include "morkFile.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKWRITER_
|
||||
#include "morkWriter.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKSTORE_
|
||||
#include "morkStore.h"
|
||||
#endif
|
||||
@ -371,6 +375,7 @@ orkinFactory::CanOpenFilePort(
|
||||
{
|
||||
if ( inFilePath && inFirst512Bytes && outCanOpen )
|
||||
{
|
||||
canOpenAsPort = this->CanOpenMorkTextFile(ev, inFirst512Bytes);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
@ -448,6 +453,21 @@ orkinFactory::ThumbToOpenPort( // redeeming a completed thumb from OpenFilePort(
|
||||
}
|
||||
// } ----- end port methods -----
|
||||
|
||||
mork_bool
|
||||
orkinFactory::CanOpenMorkTextFile(morkEnv* ev,
|
||||
const mdbYarn* inFirst512Bytes)
|
||||
{
|
||||
mork_bool outBool = morkBool_kFalse;
|
||||
mork_size headSize = MORK_STRLEN(morkWriter_kFileHeader);
|
||||
const mdbYarn* y = inFirst512Bytes;
|
||||
if ( y && y->mYarn_Buf && y->mYarn_Fill >= headSize )
|
||||
{
|
||||
mork_u1* buf = (mork_u1*) y->mYarn_Buf;
|
||||
outBool = ( MORK_MEMCMP(morkWriter_kFileHeader, buf, headSize) == 0 );
|
||||
}
|
||||
return outBool;
|
||||
}
|
||||
|
||||
// { ----- begin store methods -----
|
||||
/*virtual*/ mdb_err
|
||||
orkinFactory::CanOpenFileStore(
|
||||
@ -468,8 +488,8 @@ orkinFactory::CanOpenFileStore(
|
||||
if ( inFilePath && inFirst512Bytes && outCanOpenAsStore )
|
||||
{
|
||||
// right now always say true; later we should look for magic patterns
|
||||
canOpenAsStore = morkBool_kTrue; // don't bother checking
|
||||
canOpenAsPort = morkBool_kTrue;
|
||||
canOpenAsStore = this->CanOpenMorkTextFile(ev, inFirst512Bytes);
|
||||
canOpenAsPort = canOpenAsStore;
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
|
@ -92,6 +92,8 @@ public: // utilities:
|
||||
mdb_err* outErr) const;
|
||||
|
||||
morkEnv* GetInternalFactoryEnv(mdb_err* outErr);
|
||||
|
||||
mork_bool CanOpenMorkTextFile(morkEnv* ev, const mdbYarn* inFirst512Bytes);
|
||||
|
||||
public: // type identification
|
||||
mork_bool IsOrkinFactory() const
|
||||
|
@ -48,6 +48,10 @@
|
||||
#include "morkRowObject.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKCELLOBJECT_
|
||||
#include "morkCellObject.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKSTORE_
|
||||
#include "morkStore.h"
|
||||
#endif
|
||||
@ -68,6 +72,10 @@
|
||||
#include "orkinRowCellCursor.h"
|
||||
#endif
|
||||
|
||||
#ifndef _ORKINCELL_
|
||||
#include "orkinCell.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
/* public virtual*/
|
||||
@ -463,7 +471,7 @@ orkinRow::CutColumn( // make sure a column is absent from the row
|
||||
&outErr, &row);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
row->CutColumn(ev, inColumn);
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
return outErr;
|
||||
@ -479,7 +487,7 @@ orkinRow::CutAllColumns( // remove all columns from the row
|
||||
&outErr, &row);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
row->CutAllColumns(ev);
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
return outErr;
|
||||
@ -539,7 +547,39 @@ orkinRow::AddCell( // copy a cell from another row to this row
|
||||
&outErr, &row);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
morkCell* cell = 0;
|
||||
orkinCell* ocell = (orkinCell*) inCell; // must verify this cast:
|
||||
if ( ocell->CanUseCell(mev, morkBool_kFalse, &outErr, &cell) )
|
||||
{
|
||||
morkCellObject* cellObj = (morkCellObject*) ocell->mHandle_Object;
|
||||
|
||||
morkRow* cellRow = cellObj->mCellObject_Row;
|
||||
if ( cellRow )
|
||||
{
|
||||
if ( row != cellRow )
|
||||
{
|
||||
morkStore* store = row->GetRowSpaceStore(ev);
|
||||
morkStore* cellStore = cellRow->GetRowSpaceStore(ev);
|
||||
if ( store && cellStore )
|
||||
{
|
||||
mork_column col = cell->GetColumn();
|
||||
morkAtom* atom = cell->mCell_Atom;
|
||||
mdbYarn yarn;
|
||||
atom->AliasYarn(&yarn); // works even when atom is nil
|
||||
|
||||
if ( store != cellStore )
|
||||
col = store->CopyToken(ev, col, cellStore);
|
||||
if ( ev->Good() )
|
||||
row->AddColumn(ev, col, &yarn, store);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
return outErr;
|
||||
@ -627,7 +667,11 @@ orkinRow::SetRow( // make exact duplicate of another row
|
||||
&outErr, &row);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
morkRow* source = 0;
|
||||
if ( this->CanUseRow(mev, morkBool_kFalse, &outErr, &source) )
|
||||
{
|
||||
row->SetRow(ev, source);
|
||||
}
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
return outErr;
|
||||
|
@ -677,6 +677,7 @@ orkinStore::NewTable( // make one new table of specific type
|
||||
mdb_scope inRowScope, // row scope for row ids
|
||||
mdb_kind inTableKind, // the type of table to access
|
||||
mdb_bool inMustBeUnique, // whether store can hold only one of these
|
||||
const mdbOid* inOptionalMetaRowOid, // can be nil to avoid specifying
|
||||
nsIMdbTable** acqTable) // acquire scoped collection of rows
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
@ -686,7 +687,7 @@ orkinStore::NewTable( // make one new table of specific type
|
||||
{
|
||||
morkTable* table =
|
||||
((morkStore*) mHandle_Object)->NewTable(ev, inRowScope,
|
||||
inTableKind, inMustBeUnique);
|
||||
inTableKind, inMustBeUnique, inOptionalMetaRowOid);
|
||||
if ( table && ev->Good() )
|
||||
outTable = table->AcquireTableHandle(ev);
|
||||
outErr = ev->AsErr();
|
||||
@ -695,6 +696,36 @@ orkinStore::NewTable( // make one new table of specific type
|
||||
*acqTable = outTable;
|
||||
return outErr;
|
||||
}
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinStore::NewTableWithOid( // make one new table of specific type
|
||||
nsIMdbEnv* mev, // context
|
||||
const mdbOid* inOid, // caller assigned oid
|
||||
mdb_kind inTableKind, // the type of table to access
|
||||
mdb_bool inMustBeUnique, // whether store can hold only one of these
|
||||
const mdbOid* inOptionalMetaRowOid, // can be nil to avoid specifying
|
||||
nsIMdbTable** acqTable) // acquire scoped collection of rows
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
nsIMdbTable* outTable = 0;
|
||||
morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
morkTable* table = ((morkStore*) mHandle_Object)->OidToTable(ev, inOid,
|
||||
inOptionalMetaRowOid);
|
||||
if ( table && ev->Good() )
|
||||
{
|
||||
table->mTable_Kind = inTableKind;
|
||||
if ( inMustBeUnique )
|
||||
table->mTable_MustBeUnique = inMustBeUnique;
|
||||
outTable = table->AcquireTableHandle(ev);
|
||||
}
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( acqTable )
|
||||
*acqTable = outTable;
|
||||
return outErr;
|
||||
}
|
||||
// } ----- end table methods -----
|
||||
|
||||
// { ----- begin row scope methods -----
|
||||
|
@ -274,6 +274,15 @@ public: // type identification
|
||||
mdb_scope inRowScope, // row scope for row ids
|
||||
mdb_kind inTableKind, // the type of table to access
|
||||
mdb_bool inMustBeUnique, // whether store can hold only one of these
|
||||
const mdbOid* inOptionalMetaRowOid, // can be nil to avoid specifying
|
||||
nsIMdbTable** acqTable); // acquire scoped collection of rows
|
||||
|
||||
virtual mdb_err NewTableWithOid( // make one new table of specific type
|
||||
nsIMdbEnv* ev, // context
|
||||
const mdbOid* inOid, // caller assigned oid
|
||||
mdb_kind inTableKind, // the type of table to access
|
||||
mdb_bool inMustBeUnique, // whether store can hold only one of these
|
||||
const mdbOid* inOptionalMetaRowOid, // can be nil to avoid specifying
|
||||
nsIMdbTable** acqTable); // acquire scoped collection of rows
|
||||
// } ----- end table methods -----
|
||||
|
||||
|
@ -383,6 +383,61 @@ orkinTable::GetRowScope(nsIMdbEnv* mev, mdb_scope* outRowScope)
|
||||
return outErr;
|
||||
}
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinTable::GetMetaRow( nsIMdbEnv* mev,
|
||||
const mdbOid* inOptionalMetaRowOid, // can be nil to avoid specifying
|
||||
mdbOid* outOid, // output meta row oid, can be nil to suppress output
|
||||
nsIMdbRow** acqRow) // acquire table's unique singleton meta row
|
||||
// The purpose of a meta row is to support the persistent recording of
|
||||
// meta info about a table as cells put into the distinguished meta row.
|
||||
// Each table has exactly one meta row, which is not considered a member
|
||||
// of the collection of rows inside the table. The only way to tell
|
||||
// whether a row is a meta row is by the fact that it is returned by this
|
||||
// GetMetaRow() method from some table. Otherwise nothing distinguishes
|
||||
// a meta row from any other row. A meta row can be used anyplace that
|
||||
// any other row can be used, and can even be put into other tables (or
|
||||
// the same table) as a table member, if this is useful for some reason.
|
||||
// The first attempt to access a table's meta row using GetMetaRow() will
|
||||
// cause the meta row to be created if it did not already exist. When the
|
||||
// meta row is created, it will have the row oid that was previously
|
||||
// requested for this table's meta row; or if no oid was ever explicitly
|
||||
// specified for this meta row, then a unique oid will be generated in
|
||||
// the row scope named "metaScope" (so obviously MDB clients should not
|
||||
// manually allocate any row IDs from that special meta scope namespace).
|
||||
// The meta row oid can be specified either when the table is created, or
|
||||
// else the first time that GetMetaRow() is called, by passing a non-nil
|
||||
// pointer to an oid for parameter inOptionalMetaRowOid. The meta row's
|
||||
// actual oid is returned in outOid (if this is a non-nil pointer), and
|
||||
// it will be different from inOptionalMetaRowOid when the meta row was
|
||||
// already given a different oid earlier.
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
nsIMdbRow* outRow = 0;
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
morkTable* table = (morkTable*) mHandle_Object;
|
||||
morkRow* row = table->GetMetaRow(ev, inOptionalMetaRowOid);
|
||||
if ( row && ev->Good() )
|
||||
{
|
||||
if ( outOid )
|
||||
*outOid = row->mRow_Oid;
|
||||
|
||||
outRow = row->AcquireRowHandle(ev, table->mTable_Store);
|
||||
}
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( acqRow )
|
||||
*acqRow = outRow;
|
||||
|
||||
if ( ev->Bad() && outOid )
|
||||
{
|
||||
outOid->mOid_Scope = 0;
|
||||
outOid->mOid_Id = morkRow_kMinusOneRid;
|
||||
}
|
||||
return outErr;
|
||||
}
|
||||
|
||||
// } ----- end attribute methods -----
|
||||
|
||||
// { ----- begin cursor methods -----
|
||||
@ -456,6 +511,23 @@ orkinTable::AddOid( // make sure the row with inOid is a table member
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinTable::HasOid( // test for the table position of a row member
|
||||
nsIMdbEnv* mev, // context
|
||||
const mdbOid* inOid, // row to find in table
|
||||
mdb_bool* outHasOid) // whether inOid is a member row
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
if ( outHasOid )
|
||||
*outHasOid = ((morkTable*) mHandle_Object)->MapHasOid(ev, inOid);
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
return outErr;
|
||||
}
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinTable::OidToPos( // test for the table position of a row member
|
||||
nsIMdbEnv* mev, // context
|
||||
const mdbOid* inOid, // row to find in table
|
||||
mdb_pos* outPos) // zero-based ordinal position of row in table
|
||||
@ -481,7 +553,17 @@ orkinTable::CutOid( // make sure the row with inOid is not a member
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
morkTable* table = (morkTable*) mHandle_Object;
|
||||
morkStore* store = table->mTable_Store;
|
||||
if ( inOid && store )
|
||||
{
|
||||
morkRow* row = store->GetRow(ev, inOid);
|
||||
if ( row )
|
||||
table->CutRow(ev, row);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
return outErr;
|
||||
@ -496,12 +578,30 @@ orkinTable::NewRow( // create a new row instance in table
|
||||
nsIMdbRow** acqRow) // create new row
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
nsIMdbRow* outRow = 0;
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
morkTable* table = (morkTable*) mHandle_Object;
|
||||
morkStore* store = table->mTable_Store;
|
||||
if ( ioOid && store )
|
||||
{
|
||||
morkRow* row = 0;
|
||||
if ( ioOid->mOid_Id == morkRow_kMinusOneRid )
|
||||
row = store->NewRow(ev, ioOid->mOid_Scope);
|
||||
else
|
||||
row = store->NewRowWithOid(ev, ioOid);
|
||||
|
||||
if ( row && table->AddRow(ev, row) )
|
||||
outRow = row->AcquireRowHandle(ev, store);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( acqRow )
|
||||
*acqRow = outRow;
|
||||
return outErr;
|
||||
}
|
||||
|
||||
@ -527,6 +627,30 @@ orkinTable::AddRow( // make sure the row with inOid is a table member
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinTable::HasRow( // test for the table position of a row member
|
||||
nsIMdbEnv* mev, // context
|
||||
nsIMdbRow* ioRow, // row to find in table
|
||||
mdb_bool* outBool) // zero-based ordinal position of row in table
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
morkRow* row = 0;
|
||||
orkinRow* orow = (orkinRow*) ioRow;
|
||||
if ( orow->CanUseRow(mev, /*inMutable*/ morkBool_kFalse, &outErr, &row) )
|
||||
{
|
||||
morkTable* table = (morkTable*) mHandle_Object;
|
||||
if ( outBool )
|
||||
*outBool = table->MapHasOid(ev, &row->mRow_Oid);
|
||||
}
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
return outErr;
|
||||
}
|
||||
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinTable::RowToPos( // test for the table position of a row member
|
||||
nsIMdbEnv* mev, // context
|
||||
nsIMdbRow* ioRow, // row to find in table
|
||||
mdb_pos* outPos) // zero-based ordinal position of row in table
|
||||
@ -535,7 +659,15 @@ orkinTable::HasRow( // test for the table position of a row member
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
morkRow* row = 0;
|
||||
orkinRow* orow = (orkinRow*) ioRow;
|
||||
if ( orow->CanUseRow(mev, /*inMutable*/ morkBool_kFalse, &outErr, &row) )
|
||||
{
|
||||
morkTable* table = (morkTable*) mHandle_Object;
|
||||
mork_pos pos = table->ArrayHasOid(ev, &row->mRow_Oid);
|
||||
if ( outPos )
|
||||
*outPos = pos;
|
||||
}
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
return outErr;
|
||||
@ -611,7 +743,7 @@ orkinTable::SearchColumnsHint( // advise re future expected search cols
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// ev->StubMethodOnlyError(); // legal to do nothing
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
return outErr;
|
||||
@ -626,7 +758,7 @@ orkinTable::SortColumnsHint( // advise re future expected sort columns
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// ev->StubMethodOnlyError(); // legal to do nothing
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
return outErr;
|
||||
@ -644,7 +776,7 @@ orkinTable::StartBatchChangeHint( // advise before many adds and cuts
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// ev->StubMethodOnlyError(); // legal to do nothing
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
return outErr;
|
||||
@ -668,7 +800,7 @@ orkinTable::EndBatchChangeHint( // advise before many adds and cuts
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// ev->StubMethodOnlyError(); // legal to do nothing
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
return outErr;
|
||||
@ -689,7 +821,9 @@ orkinTable::CanSortColumn( // query which col is currently used for sorting
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
if ( outCanSort )
|
||||
*outCanSort = morkBool_kFalse;
|
||||
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
return outErr;
|
||||
@ -703,12 +837,15 @@ orkinTable::NewSortColumn( // change col used for sorting in the table
|
||||
nsIMdbThumb** acqThumb) // acquire thumb for incremental table resort
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
nsIMdbThumb* outThumb = 0;
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( acqThumb )
|
||||
*acqThumb = outThumb;
|
||||
return outErr;
|
||||
}
|
||||
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
|
||||
@ -723,12 +860,15 @@ orkinTable::NewSortColumnWithCompare( // change sort col w/ explicit compare
|
||||
nsIMdbThumb** acqThumb) // acquire thumb for incremental table resort
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
nsIMdbThumb* outThumb = 0;
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( acqThumb )
|
||||
*acqThumb = outThumb;
|
||||
return outErr;
|
||||
}
|
||||
// Note the table will hold a reference to inCompare if this object is used
|
||||
@ -743,12 +883,15 @@ orkinTable::GetSortColumn( // query which col is currently sorted
|
||||
mdb_column* outColumn) // col the table uses for sorting (or zero)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
mdb_column col = 0;
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( outColumn )
|
||||
*outColumn = col;
|
||||
return outErr;
|
||||
}
|
||||
|
||||
@ -760,12 +903,15 @@ orkinTable::CloneSortColumn( // view same table with a different sort
|
||||
nsIMdbThumb** acqThumb) // acquire thumb for incremental table clone
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
nsIMdbThumb* outThumb = 0;
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( acqThumb )
|
||||
*acqThumb = outThumb;
|
||||
return outErr;
|
||||
}
|
||||
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
|
||||
@ -778,12 +924,15 @@ orkinTable::ThumbToCloneSortTable( // redeem complete CloneSortColumn() thumb
|
||||
nsIMdbTable** acqTable) // new table instance (or old if sort unchanged)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
nsIMdbTable* outTable = 0;
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( acqTable )
|
||||
*acqTable = outTable;
|
||||
return outErr;
|
||||
}
|
||||
// } ----- end sorting methods -----
|
||||
@ -841,7 +990,8 @@ orkinTable::AddIndex( // create a sorting index for column if possible
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// ev->StubMethodOnlyError(); // legal to do nothing
|
||||
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
return outErr;
|
||||
@ -859,7 +1009,8 @@ orkinTable::CutIndex( // stop supporting a specific column index
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// ev->StubMethodOnlyError(); // legal to do nothing
|
||||
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
return outErr;
|
||||
@ -875,7 +1026,9 @@ orkinTable::HasIndex( // query for current presence of a column index
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
if ( outHasIndex )
|
||||
*outHasIndex = morkBool_kFalse;
|
||||
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
return outErr;
|
||||
@ -890,7 +1043,7 @@ orkinTable::EnableIndexOnSort( // create an index for col on first sort
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// ev->StubMethodOnlyError(); // legal to do nothing
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
return outErr;
|
||||
@ -906,7 +1059,9 @@ orkinTable::QueryIndexOnSort( // check whether index on sort is enabled
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
if ( outIndexOnSort )
|
||||
*outIndexOnSort = morkBool_kFalse;
|
||||
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
return outErr;
|
||||
@ -921,7 +1076,7 @@ orkinTable::DisableIndexOnSort( // prevent future index creation on sort
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// ev->StubMethodOnlyError(); // legal to do nothing
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
return outErr;
|
||||
|
@ -35,7 +35,7 @@
|
||||
#include "morkHandle.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKTable_
|
||||
#ifndef _MORKTABLE_
|
||||
#include "morkTable.h"
|
||||
#endif
|
||||
|
||||
@ -164,11 +164,38 @@ public: // type identification
|
||||
|
||||
// { ===== begin nsIMdbTable methods =====
|
||||
|
||||
// { ----- begin attribute methods -----
|
||||
// { ----- begin meta attribute methods -----
|
||||
virtual mdb_err GetTableKind(nsIMdbEnv* ev, mdb_kind* outTableKind);
|
||||
virtual mdb_err GetRowScope(nsIMdbEnv* ev, mdb_scope* outRowScope);
|
||||
|
||||
// } ----- end attribute methods -----
|
||||
virtual mdb_err GetMetaRow(
|
||||
nsIMdbEnv* ev, // context
|
||||
const mdbOid* inOptionalMetaRowOid, // can be nil to avoid specifying
|
||||
mdbOid* outOid, // output meta row oid, can be nil to suppress output
|
||||
nsIMdbRow** acqRow); // acquire table's unique singleton meta row
|
||||
// The purpose of a meta row is to support the persistent recording of
|
||||
// meta info about a table as cells put into the distinguished meta row.
|
||||
// Each table has exactly one meta row, which is not considered a member
|
||||
// of the collection of rows inside the table. The only way to tell
|
||||
// whether a row is a meta row is by the fact that it is returned by this
|
||||
// GetMetaRow() method from some table. Otherwise nothing distinguishes
|
||||
// a meta row from any other row. A meta row can be used anyplace that
|
||||
// any other row can be used, and can even be put into other tables (or
|
||||
// the same table) as a table member, if this is useful for some reason.
|
||||
// The first attempt to access a table's meta row using GetMetaRow() will
|
||||
// cause the meta row to be created if it did not already exist. When the
|
||||
// meta row is created, it will have the row oid that was previously
|
||||
// requested for this table's meta row; or if no oid was ever explicitly
|
||||
// specified for this meta row, then a unique oid will be generated in
|
||||
// the row scope named "metaScope" (so obviously MDB clients should not
|
||||
// manually allocate any row IDs from that special meta scope namespace).
|
||||
// The meta row oid can be specified either when the table is created, or
|
||||
// else the first time that GetMetaRow() is called, by passing a non-nil
|
||||
// pointer to an oid for parameter inOptionalMetaRowOid. The meta row's
|
||||
// actual oid is returned in outOid (if this is a non-nil pointer), and
|
||||
// it will be different from inOptionalMetaRowOid when the meta row was
|
||||
// already given a different oid earlier.
|
||||
// } ----- end meta attribute methods -----
|
||||
|
||||
// { ----- begin cursor methods -----
|
||||
virtual mdb_err GetTableRowCursor( // make a cursor, starting iteration at inRowPos
|
||||
@ -183,7 +210,11 @@ public: // type identification
|
||||
mdb_pos inRowPos, // zero-based ordinal position of row in table
|
||||
mdbOid* outOid); // row oid at the specified position
|
||||
|
||||
// Note that HasRow() performs the inverse oid->pos mapping
|
||||
virtual mdb_err RowToPos( // test for the table position of a row member
|
||||
nsIMdbEnv* ev, // context
|
||||
nsIMdbRow* ioRow, // row to find in table
|
||||
mdb_pos* outPos); // zero-based ordinal position of row in table
|
||||
|
||||
// } ----- end row position methods -----
|
||||
|
||||
// { ----- begin oid set methods -----
|
||||
@ -192,6 +223,11 @@ public: // type identification
|
||||
const mdbOid* inOid); // row to ensure membership in table
|
||||
|
||||
virtual mdb_err HasOid( // test for the table position of a row member
|
||||
nsIMdbEnv* ev, // context
|
||||
const mdbOid* inOid, // row to find in table
|
||||
mdb_bool* outHasOid); // whether inOid is a member row
|
||||
|
||||
virtual mdb_err OidToPos( // test for the table position of a row member
|
||||
nsIMdbEnv* ev, // context
|
||||
const mdbOid* inOid, // row to find in table
|
||||
mdb_pos* outPos); // zero-based ordinal position of row in table
|
||||
@ -214,7 +250,7 @@ public: // type identification
|
||||
virtual mdb_err HasRow( // test for the table position of a row member
|
||||
nsIMdbEnv* ev, // context
|
||||
nsIMdbRow* ioRow, // row to find in table
|
||||
mdb_pos* outPos); // zero-based ordinal position of row in table
|
||||
mdb_bool* outHasRow); // whether row is a table member
|
||||
|
||||
virtual mdb_err CutRow( // make sure the row with inOid is not a member
|
||||
nsIMdbEnv* ev, // context
|
||||
|
@ -690,6 +690,88 @@ public:
|
||||
|
||||
extern "C" nsIMdbFactory* MakeMdbFactory();
|
||||
|
||||
/*| nsIMdbFile: abstract file interface resembling the original morkFile
|
||||
**| abstract interface (which was in turn modeled on the file interface
|
||||
**| from public domain IronDoc). The design of this file interface is
|
||||
**| complicated by the fact that some DB's will not find this interface
|
||||
**| adequate for all runtime requirements (even though this file API is
|
||||
**| enough to implement text-based DB's like Mork). For this reason,
|
||||
**| more methods have been added to let a DB library force the file to
|
||||
**| become closed so the DB can reopen the file in some other manner.
|
||||
**| Folks are encouraged to suggest ways to tune this interface to suit
|
||||
**| DB's that cannot manage to pull their maneuvers even given this API.
|
||||
**|
|
||||
**|| Tell: get the current i/o position in file
|
||||
**|
|
||||
**|| Seek: change the current i/o position in file
|
||||
**|
|
||||
**|| Eof: return file's total length in bytes
|
||||
**|
|
||||
**|| Read: input inSize bytes into outBuf, returning actual transfer size
|
||||
**|
|
||||
**|| Get: read starting at specific file offset (e.g. Seek(); Read();)
|
||||
**|
|
||||
**|| Write: output inSize bytes from inBuf, returning actual transfer size
|
||||
**|
|
||||
**|| Put: write starting at specific file offset (e.g. Seek(); Write();)
|
||||
**|
|
||||
**|| Flush: if written bytes are buffered, push them to final destination
|
||||
**|
|
||||
**|| Path: get file path in some string representation. This is intended
|
||||
**| either to support the display of file name in a user presentation, or
|
||||
**| to support the closing and reopening of the file when the DB needs more
|
||||
**| exotic file access than is presented by the nsIMdbFile interface.
|
||||
**|
|
||||
**|| Steal: tell this file to close any associated i/o stream in the file
|
||||
**| system, because the file ioThief intends to reopen the file in order
|
||||
**| to provide the MDB implementation with more exotic file access than is
|
||||
**| offered by the nsIMdbFile alone. Presumably the thief knows enough
|
||||
**| from Path() in order to know which file to reopen. If Steal() is
|
||||
**| successful, this file should probably delegate all future calls to
|
||||
**| the nsIMdbFile interface down to the thief files, so that even after
|
||||
**| the file has been stolen, it can still be read, written, or forcibly
|
||||
**| closed (by a call to CloseMdbObject()).
|
||||
**|
|
||||
**|| Thief: acquire and return thief passed to an earlier call to Steal().
|
||||
|*/
|
||||
class nsIMdbFile : public nsIMdbObject { // minimal file interface
|
||||
public:
|
||||
|
||||
// { ===== begin nsIMdbFile methods =====
|
||||
|
||||
// { ----- begin pos methods -----
|
||||
virtual mdb_err Tell(nsIMdbEnv* ev, mdb_pos* outPos) const = 0;
|
||||
virtual mdb_err Seek(nsIMdbEnv* ev, mdb_pos inPos) = 0;
|
||||
virtual mdb_err Eof(nsIMdbEnv* ev, mdb_pos* outPos) const = 0;
|
||||
// } ----- end pos methods -----
|
||||
|
||||
// { ----- begin read methods -----
|
||||
virtual mdb_err Read(nsIMdbEnv* ev, void* outBuf, mdb_size inSize,
|
||||
mdb_size* outActualSize) = 0;
|
||||
virtual mdb_err Get(nsIMdbEnv* ev, void* outBuf, mdb_size inSize,
|
||||
mdb_pos inPos, mdb_size* outActualSize) = 0;
|
||||
// } ----- end read methods -----
|
||||
|
||||
// { ----- begin write methods -----
|
||||
virtual mdb_err Write(nsIMdbEnv* ev, const void* inBuf, mdb_size inSize,
|
||||
mdb_size* outActualSize) = 0;
|
||||
virtual mdb_err Put(nsIMdbEnv* ev, const void* inBuf, mdb_size inSize,
|
||||
mdb_pos inPos, mdb_size* outActualSize) = 0;
|
||||
virtual mdb_err Flush(nsIMdbEnv* ev) = 0;
|
||||
// } ----- end attribute methods -----
|
||||
|
||||
// { ----- begin path methods -----
|
||||
virtual mdb_err Path(nsIMdbEnv* ev, mdbYarn* outFilePath) = 0;
|
||||
// } ----- end path methods -----
|
||||
|
||||
// { ----- begin replacement methods -----
|
||||
virtual mdb_err Steal(nsIMdbEnv* ev, nsIMdbFile* ioThief) = 0;
|
||||
virtual mdb_err Thief(nsIMdbEnv* ev, nsIMdbFile** acqThief) = 0;
|
||||
// } ----- end replacement methods -----
|
||||
|
||||
// } ===== end nsIMdbFile methods =====
|
||||
};
|
||||
|
||||
/*| nsIMdbPort: a readonly interface to a specific database file. The mutable
|
||||
**| nsIMdbStore interface is a subclass that includes writing behavior, but
|
||||
**| most of the needed db methods appear in the readonly nsIMdbPort interface.
|
||||
@ -995,6 +1077,15 @@ public:
|
||||
mdb_scope inRowScope, // row scope for row ids
|
||||
mdb_kind inTableKind, // the type of table to access
|
||||
mdb_bool inMustBeUnique, // whether store can hold only one of these
|
||||
const mdbOid* inOptionalMetaRowOid, // can be nil to avoid specifying
|
||||
nsIMdbTable** acqTable) = 0; // acquire scoped collection of rows
|
||||
|
||||
virtual mdb_err NewTableWithOid( // make one new table of specific type
|
||||
nsIMdbEnv* ev, // context
|
||||
const mdbOid* inOid, // caller assigned oid
|
||||
mdb_kind inTableKind, // the type of table to access
|
||||
mdb_bool inMustBeUnique, // whether store can hold only one of these
|
||||
const mdbOid* inOptionalMetaRowOid, // can be nil to avoid specifying
|
||||
nsIMdbTable** acqTable) = 0; // acquire scoped collection of rows
|
||||
// } ----- end table methods -----
|
||||
|
||||
@ -1333,7 +1424,7 @@ public:
|
||||
**| complain not at all. Cutting a row from a table only does something when
|
||||
**| the row was actually a member, and otherwise does nothing silently.
|
||||
**|
|
||||
**|| row ref count: one can query the number of tables (and or cells)
|
||||
**|| row ref count: one can query the number of tables (and/or cells)
|
||||
**| containing a row as a member or a child.
|
||||
**|
|
||||
**|| row content: one can access or modify the cell content in a table's row
|
||||
@ -1355,11 +1446,38 @@ public:
|
||||
|
||||
// { ===== begin nsIMdbTable methods =====
|
||||
|
||||
// { ----- begin attribute methods -----
|
||||
// { ----- begin meta attribute methods -----
|
||||
virtual mdb_err GetTableKind(nsIMdbEnv* ev, mdb_kind* outTableKind) = 0;
|
||||
virtual mdb_err GetRowScope(nsIMdbEnv* ev, mdb_scope* outRowScope) = 0;
|
||||
|
||||
// } ----- end attribute methods -----
|
||||
virtual mdb_err GetMetaRow(
|
||||
nsIMdbEnv* ev, // context
|
||||
const mdbOid* inOptionalMetaRowOid, // can be nil to avoid specifying
|
||||
mdbOid* outOid, // output meta row oid, can be nil to suppress output
|
||||
nsIMdbRow** acqRow) = 0; // acquire table's unique singleton meta row
|
||||
// The purpose of a meta row is to support the persistent recording of
|
||||
// meta info about a table as cells put into the distinguished meta row.
|
||||
// Each table has exactly one meta row, which is not considered a member
|
||||
// of the collection of rows inside the table. The only way to tell
|
||||
// whether a row is a meta row is by the fact that it is returned by this
|
||||
// GetMetaRow() method from some table. Otherwise nothing distinguishes
|
||||
// a meta row from any other row. A meta row can be used anyplace that
|
||||
// any other row can be used, and can even be put into other tables (or
|
||||
// the same table) as a table member, if this is useful for some reason.
|
||||
// The first attempt to access a table's meta row using GetMetaRow() will
|
||||
// cause the meta row to be created if it did not already exist. When the
|
||||
// meta row is created, it will have the row oid that was previously
|
||||
// requested for this table's meta row; or if no oid was ever explicitly
|
||||
// specified for this meta row, then a unique oid will be generated in
|
||||
// the row scope named "metaScope" (so obviously MDB clients should not
|
||||
// manually allocate any row IDs from that special meta scope namespace).
|
||||
// The meta row oid can be specified either when the table is created, or
|
||||
// else the first time that GetMetaRow() is called, by passing a non-nil
|
||||
// pointer to an oid for parameter inOptionalMetaRowOid. The meta row's
|
||||
// actual oid is returned in outOid (if this is a non-nil pointer), and
|
||||
// it will be different from inOptionalMetaRowOid when the meta row was
|
||||
// already given a different oid earlier.
|
||||
// } ----- end meta attribute methods -----
|
||||
|
||||
// { ----- begin cursor methods -----
|
||||
virtual mdb_err GetTableRowCursor( // make a cursor, starting iteration at inRowPos
|
||||
@ -1374,7 +1492,10 @@ public:
|
||||
mdb_pos inRowPos, // zero-based ordinal position of row in table
|
||||
mdbOid* outOid) = 0; // row oid at the specified position
|
||||
|
||||
// Note that HasRow() performs the inverse oid->pos mapping
|
||||
virtual mdb_err RowToPos( // test for the table position of a row member
|
||||
nsIMdbEnv* ev, // context
|
||||
nsIMdbRow* ioRow, // row to find in table
|
||||
mdb_pos* outPos) = 0; // zero-based ordinal position of row in table
|
||||
// } ----- end row position methods -----
|
||||
|
||||
// { ----- begin oid set methods -----
|
||||
@ -1383,6 +1504,11 @@ public:
|
||||
const mdbOid* inOid) = 0; // row to ensure membership in table
|
||||
|
||||
virtual mdb_err HasOid( // test for the table position of a row member
|
||||
nsIMdbEnv* ev, // context
|
||||
const mdbOid* inOid, // row to find in table
|
||||
mdb_bool* outHasOid) = 0; // whether inOid is a member row
|
||||
|
||||
virtual mdb_err OidToPos( // test for the table position of a row member
|
||||
nsIMdbEnv* ev, // context
|
||||
const mdbOid* inOid, // row to find in table
|
||||
mdb_pos* outPos) = 0; // zero-based ordinal position of row in table
|
||||
@ -1395,7 +1521,7 @@ public:
|
||||
// { ----- begin row set methods -----
|
||||
virtual mdb_err NewRow( // create a new row instance in table
|
||||
nsIMdbEnv* ev, // context
|
||||
mdbOid* ioOid, // please use zero (unbound) rowId for db-assigned IDs
|
||||
mdbOid* ioOid, // please use minus one (unbound) rowId for db-assigned IDs
|
||||
nsIMdbRow** acqRow) = 0; // create new row
|
||||
|
||||
virtual mdb_err AddRow( // make sure the row with inOid is a table member
|
||||
@ -1405,7 +1531,7 @@ public:
|
||||
virtual mdb_err HasRow( // test for the table position of a row member
|
||||
nsIMdbEnv* ev, // context
|
||||
nsIMdbRow* ioRow, // row to find in table
|
||||
mdb_pos* outPos) = 0; // zero-based ordinal position of row in table
|
||||
mdb_bool* outHasRow) = 0; // whether row is a table member
|
||||
|
||||
virtual mdb_err CutRow( // make sure the row with inOid is not a member
|
||||
nsIMdbEnv* ev, // context
|
||||
|
@ -131,6 +131,12 @@ public: // setup
|
||||
|
||||
public: // other space methods
|
||||
|
||||
// void ReserveColumnAidCount(mork_count inCount)
|
||||
// {
|
||||
// mAtomSpace_HighUnderId = morkAtomSpace_kMinUnderId + inCount;
|
||||
// mAtomSpace_HighOverId = morkAtomSpace_kMinOverId + inCount;
|
||||
// }
|
||||
|
||||
mork_num CutAllAtoms(morkEnv* ev, morkPool* ioPool);
|
||||
// CutAllAtoms() puts all the atoms back in the pool.
|
||||
|
||||
|
@ -123,32 +123,25 @@ morkBuilder::morkBuilder(morkEnv* ev,
|
||||
|
||||
, mBuilder_OidAtomSpace( 0 )
|
||||
, mBuilder_ScopeAtomSpace( 0 )
|
||||
|
||||
, mBuilder_iso_8859_1( 0 )
|
||||
, mBuilder_r( (mork_scope) 'r' )
|
||||
, mBuilder_a( (mork_scope) 'a' )
|
||||
, mBuilder_t( (mork_scope) 't' )
|
||||
|
||||
, mBuilder_MorkNoneToken( 0 )
|
||||
|
||||
, mBuilder_PortForm( 0 )
|
||||
, mBuilder_PortRowScope( (mork_scope) 'r' )
|
||||
, mBuilder_PortAtomScope( (mork_scope) 'a' )
|
||||
, mBuilder_PortAtomScope( (mork_scope) 'v' )
|
||||
|
||||
, mBuilder_TableForm( 0 )
|
||||
, mBuilder_TableRowScope( (mork_scope) 'r' )
|
||||
, mBuilder_TableAtomScope( (mork_scope) 'a' )
|
||||
, mBuilder_TableAtomScope( (mork_scope) 'v' )
|
||||
, mBuilder_TableKind( 0 )
|
||||
|
||||
, mBuilder_RowForm( 0 )
|
||||
, mBuilder_RowRowScope( (mork_scope) 'r' )
|
||||
, mBuilder_RowAtomScope( (mork_scope) 'a' )
|
||||
, mBuilder_RowAtomScope( (mork_scope) 'v' )
|
||||
|
||||
, mBuilder_CellForm( 0 )
|
||||
, mBuilder_CellAtomScope( (mork_scope) 'a' )
|
||||
, mBuilder_CellAtomScope( (mork_scope) 'v' )
|
||||
|
||||
, mBuilder_DictForm( 0 )
|
||||
, mBuilder_DictAtomScope( (mork_scope) 'a' )
|
||||
, mBuilder_DictAtomScope( (mork_scope) 'v' )
|
||||
|
||||
, mBuilder_MetaTokenSlot( 0 )
|
||||
|
||||
@ -160,7 +153,6 @@ morkBuilder::morkBuilder(morkEnv* ev,
|
||||
{
|
||||
if ( ioStore )
|
||||
{
|
||||
mBuilder_MorkNoneToken = ioStore->mStore_MorkNoneToken;
|
||||
morkStore::SlotWeakStore(ioStore, ev, &mBuilder_Store);
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kBuilder;
|
||||
@ -267,7 +259,7 @@ morkBuilder::OnNewPort(morkEnv* ev, const morkPlace& inPlace)
|
||||
// mParser_InPort = morkBool_kTrue;
|
||||
mBuilder_PortForm = 0;
|
||||
mBuilder_PortRowScope = (mork_scope) 'r';
|
||||
mBuilder_PortAtomScope = (mork_scope) 'a';
|
||||
mBuilder_PortAtomScope = (mork_scope) 'v';
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
@ -337,7 +329,8 @@ morkBuilder::OnPortRowEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
morkBuilder::OnNewTable(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkMid& inMid, mork_change inChange)
|
||||
// mp:Table ::= OnNewTable mp:TableItem* OnTableEnd
|
||||
// mp:TableItem ::= mp:Row | mp:Meta | OnTableGlitch
|
||||
// mp:TableItem ::= mp:Row | mp:MetaTable | OnTableGlitch
|
||||
// mp:MetaTable ::= OnNewMeta mp:MetaItem* mp:Row OnMetaEnd
|
||||
// mp:Meta ::= OnNewMeta mp:MetaItem* OnMetaEnd
|
||||
// mp:MetaItem ::= mp:Cell | OnMetaGlitch
|
||||
{
|
||||
@ -345,7 +338,7 @@ morkBuilder::OnNewTable(morkEnv* ev, const morkPlace& inPlace,
|
||||
mBuilder_TableForm = mBuilder_PortForm;
|
||||
mBuilder_TableRowScope = mBuilder_PortRowScope;
|
||||
mBuilder_TableAtomScope = mBuilder_PortAtomScope;
|
||||
mBuilder_TableKind = mBuilder_MorkNoneToken;
|
||||
mBuilder_TableKind = morkStore_kNoneToken;
|
||||
|
||||
morkTable* table = mBuilder_Store->MidToTable(ev, inMid);
|
||||
morkTable::SlotStrongTable(table, ev, &mBuilder_Table);
|
||||
@ -372,7 +365,7 @@ morkBuilder::OnTableEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
mBuilder_Row = 0;
|
||||
mBuilder_Cell = 0;
|
||||
|
||||
if ( mBuilder_TableKind == mBuilder_MorkNoneToken )
|
||||
if ( mBuilder_TableKind == morkStore_kNoneToken )
|
||||
ev->NewError("missing table kind");
|
||||
|
||||
mBuilder_CellAtomScope = mBuilder_RowAtomScope =
|
||||
@ -407,6 +400,9 @@ morkBuilder::OnMetaEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnNewRow(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkMid& inMid, mork_change inChange)
|
||||
// mp:Table ::= OnNewTable mp:TableItem* OnTableEnd
|
||||
// mp:TableItem ::= mp:Row | mp:MetaTable | OnTableGlitch
|
||||
// mp:MetaTable ::= OnNewMeta mp:MetaItem* mp:Row OnMetaEnd
|
||||
// mp:Row ::= OnNewRow mp:RowItem* OnRowEnd
|
||||
// mp:RowItem ::= mp:Cell | mp:Meta | OnRowGlitch
|
||||
// mp:Cell ::= OnNewCell mp:CellItem? OnCellEnd
|
||||
@ -432,8 +428,24 @@ morkBuilder::OnNewRow(morkEnv* ev, const morkPlace& inPlace,
|
||||
mBuilder_Row = store->MidToRow(ev, inMid);
|
||||
}
|
||||
|
||||
if ( mBuilder_Row )
|
||||
mBuilder_Table->AddRow(ev, mBuilder_Row);
|
||||
morkRow* row = mBuilder_Row;
|
||||
if ( row )
|
||||
{
|
||||
morkTable* table = mBuilder_Table;
|
||||
if ( mParser_InMeta )
|
||||
{
|
||||
if ( !table->mTable_MetaRow )
|
||||
{
|
||||
table->mTable_MetaRow = row;
|
||||
table->mTable_MetaRowOid = row->mRow_Oid;
|
||||
row->AddTableUse(ev);
|
||||
}
|
||||
else
|
||||
ev->NewError("duplicate table meta row");
|
||||
}
|
||||
else
|
||||
table->AddRow(ev, row);
|
||||
}
|
||||
}
|
||||
else
|
||||
this->NilBuilderTableError(ev);
|
||||
@ -612,29 +624,29 @@ morkBuilder::OnNewCell(morkEnv* ev, const morkPlace& inPlace,
|
||||
{
|
||||
if ( mParser_InTable ) // metainfo for table?
|
||||
{
|
||||
if ( column == store->mStore_TableKindToken )
|
||||
if ( column == morkStore_kKindColumn )
|
||||
mBuilder_MetaTokenSlot = &mBuilder_TableKind;
|
||||
else if ( column == store->mStore_RowScopeToken )
|
||||
else if ( column == morkStore_kRowScopeColumn )
|
||||
mBuilder_MetaTokenSlot = &mBuilder_TableRowScope;
|
||||
else if ( column == store->mStore_AtomScopeToken )
|
||||
else if ( column == morkStore_kAtomScopeColumn )
|
||||
mBuilder_MetaTokenSlot = &mBuilder_TableAtomScope;
|
||||
else if ( column == store->mStore_CharsetToken )
|
||||
else if ( column == morkStore_kFormColumn )
|
||||
mBuilder_MetaTokenSlot = &mBuilder_TableForm;
|
||||
}
|
||||
else if ( mParser_InDict ) // metainfo for dict?
|
||||
{
|
||||
if ( column == store->mStore_AtomScopeToken )
|
||||
if ( column == morkStore_kAtomScopeColumn )
|
||||
mBuilder_MetaTokenSlot = &mBuilder_DictAtomScope;
|
||||
else if ( column == store->mStore_CharsetToken )
|
||||
else if ( column == morkStore_kFormColumn )
|
||||
mBuilder_MetaTokenSlot = &mBuilder_DictForm;
|
||||
}
|
||||
else if ( mParser_InRow ) // metainfo for row?
|
||||
{
|
||||
if ( column == store->mStore_AtomScopeToken )
|
||||
if ( column == morkStore_kAtomScopeColumn )
|
||||
mBuilder_MetaTokenSlot = &mBuilder_RowAtomScope;
|
||||
else if ( column == store->mStore_RowScopeToken )
|
||||
else if ( column == morkStore_kRowScopeColumn )
|
||||
mBuilder_MetaTokenSlot = &mBuilder_RowRowScope;
|
||||
else if ( column == store->mStore_CharsetToken )
|
||||
else if ( column == morkStore_kFormColumn )
|
||||
mBuilder_MetaTokenSlot = &mBuilder_RowForm;
|
||||
}
|
||||
}
|
||||
@ -856,7 +868,8 @@ morkBuilder::OnTableMid(morkEnv* ev, const morkSpan& inSpan,
|
||||
if ( atom )
|
||||
{
|
||||
cell->SetAtom(ev, atom, pool);
|
||||
morkTable* table = store->OidToTable(ev, &tableOid);
|
||||
morkTable* table = store->OidToTable(ev, &tableOid,
|
||||
/*optionalMetaRowOid*/ (mdbOid*) 0);
|
||||
if ( table ) // found or created such a table?
|
||||
table->AddCellUse(ev);
|
||||
}
|
||||
|
@ -127,15 +127,7 @@ protected: // protected morkBuilder members
|
||||
// scoped object ids for current objects under construction:
|
||||
mdbOid mBuilder_TableOid; // full oid for current table
|
||||
mdbOid mBuilder_RowOid; // full oid for current row
|
||||
|
||||
// standard tokens that we want to know about for this port:
|
||||
mork_cscode mBuilder_iso_8859_1; // token for "iso-8859-1"
|
||||
mork_cscode mBuilder_r; // token for "r"
|
||||
mork_cscode mBuilder_a; // token for "a"
|
||||
mork_cscode mBuilder_t; // token for "t"
|
||||
|
||||
mork_token mBuilder_MorkNoneToken; // token for "mork:none"
|
||||
|
||||
|
||||
// tokens that become set as the result of meta cells in port rows:
|
||||
mork_cscode mBuilder_PortForm; // default port charset format
|
||||
mork_scope mBuilder_PortRowScope; // port row scope
|
||||
|
@ -99,14 +99,17 @@ morkCellObject::morkCellObject(morkEnv* ev, const morkUsage& inUsage,
|
||||
morkStore* store = ioRow->GetRowSpaceStore(ev);
|
||||
if ( store )
|
||||
{
|
||||
morkRowObject* rowObj = ioRow->GetRowObject(ev, store);
|
||||
morkRowObject* rowObj = ioRow->AcquireRowObject(ev, store);
|
||||
if ( rowObj )
|
||||
{
|
||||
mCellObject_Row = ioRow;
|
||||
mCellObject_Cell = ioCell;
|
||||
mCellObject_RowSeed = ioRow->mRow_Seed;
|
||||
morkRowObject::SlotStrongRowObject(rowObj, ev,
|
||||
&mCellObject_RowObject);
|
||||
|
||||
// morkRowObject::SlotStrongRowObject(rowObj, ev,
|
||||
// &mCellObject_RowObject);
|
||||
|
||||
mCellObject_RowObject = rowObj; // assume control of strong ref
|
||||
}
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kCellObject;
|
||||
|
@ -87,7 +87,7 @@ const mork_u1 morkCh_Type[] = /* derives from public domain Mithril ch table */
|
||||
0, /* 0x29 ) cannot be kV because needs escape */
|
||||
morkCh_kV, /* 0x2A * */
|
||||
morkCh_kV|morkCh_kM, /* 0x2B + */
|
||||
0, /* 0x2C , */
|
||||
morkCh_kV, /* 0x2C , */
|
||||
morkCh_kV|morkCh_kM, /* 0x2D - */
|
||||
morkCh_kV, /* 0x2E . */
|
||||
morkCh_kV, /* 0x2F / */
|
||||
|
@ -31,8 +31,8 @@
|
||||
|
||||
// { %%%%% begin platform defs peculiar to Mork %%%%%
|
||||
#ifdef XP_MAC
|
||||
#define MORK_MAC 1
|
||||
#define MORK_OBSOLETE 1
|
||||
#define MORK_MAC 1
|
||||
#endif
|
||||
|
||||
#ifdef XP_OS2
|
||||
|
@ -113,7 +113,7 @@ morkHandle::CloseHandle(morkEnv* ev) // called by CloseMorkNode();
|
||||
this->MarkShut();
|
||||
|
||||
if ( objDidRefSelf )
|
||||
this->CutWeakRef(ev);
|
||||
this->CutWeakRef(ev); // do last, because it might self destroy
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
|
@ -917,8 +917,18 @@ void morkParser::ReadMeta(morkEnv* ev, int inEndMeta)
|
||||
this->UnexpectedByteInMetaWarning(ev);
|
||||
break;
|
||||
|
||||
case '[': // maybe table meta row?
|
||||
if ( mParser_InTable )
|
||||
this->ReadRow(ev, '[');
|
||||
else
|
||||
this->UnexpectedByteInMetaWarning(ev);
|
||||
break;
|
||||
|
||||
default:
|
||||
this->UnexpectedByteInMetaWarning(ev);
|
||||
if ( mParser_InTable && morkCh_IsHex(c) )
|
||||
this->ReadRow(ev, c);
|
||||
else
|
||||
this->UnexpectedByteInMetaWarning(ev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -379,7 +379,8 @@ public: // out virtual morkParser methods, data flow parser to subclass
|
||||
// mp:Dict ::= OnNewDict mp:DictItem* OnDictEnd
|
||||
// mp:DictItem ::= OnAlias | OnAliasGlitch | mp:Meta | OnDictGlitch
|
||||
// mp:Table ::= OnNewTable mp:TableItem* OnTableEnd
|
||||
// mp:TableItem ::= mp:Row | mp:Meta | OnTableGlitch
|
||||
// mp:TableItem ::= mp:Row | mp:MetaTable | OnTableGlitch
|
||||
// mp:MetaTable ::= OnNewMeta mp:MetaItem* mp:Row OnMetaEnd
|
||||
// mp:Meta ::= OnNewMeta mp:MetaItem* OnMetaEnd
|
||||
// mp:MetaItem ::= mp:Cell | OnMetaGlitch
|
||||
// mp:Row ::= OnNewRow mp:RowItem* OnRowEnd
|
||||
|
@ -217,7 +217,8 @@ morkPool::AddRowCells(morkEnv* ev, morkRow* ioRow, mork_size inNewSize)
|
||||
ioRow->mRow_Length = inNewSize;
|
||||
++ioRow->mRow_Seed;
|
||||
|
||||
this->ZapCells(ev, oldCells, fill);
|
||||
if ( oldCells )
|
||||
this->ZapCells(ev, oldCells, fill);
|
||||
}
|
||||
}
|
||||
return ( ev->Good() && ioRow->mRow_Length >= inNewSize );
|
||||
@ -230,28 +231,42 @@ morkPool::CutRowCells(morkEnv* ev, morkRow* ioRow,
|
||||
mork_fill fill = ioRow->mRow_Length;
|
||||
if ( ev->Good() && fill > inNewSize ) // need fewer cells?
|
||||
{
|
||||
morkCell* newCells = this->NewCells(ev, inNewSize);
|
||||
if ( newCells )
|
||||
if ( inNewSize ) // want any row cells at all?
|
||||
{
|
||||
morkCell* newCells = this->NewCells(ev, inNewSize);
|
||||
if ( newCells )
|
||||
{
|
||||
morkCell* oldCells = ioRow->mRow_Cells;
|
||||
morkCell* oldEnd = oldCells + fill; // one past all old cells
|
||||
morkCell* newEnd = oldCells + inNewSize; // copy only kept old cells
|
||||
while ( oldCells < newEnd )
|
||||
{
|
||||
*newCells++ = *oldCells++; // bitwise copy each old cell struct
|
||||
}
|
||||
while ( oldCells < oldEnd )
|
||||
{
|
||||
if ( oldCells->mCell_Atom ) // need to unref old cell atom?
|
||||
oldCells->SetAtom(ev, (morkAtom*) 0, this); // unref cell atom
|
||||
++oldCells;
|
||||
}
|
||||
oldCells = ioRow->mRow_Cells;
|
||||
ioRow->mRow_Cells = newCells;
|
||||
ioRow->mRow_Length = inNewSize;
|
||||
++ioRow->mRow_Seed;
|
||||
|
||||
if ( oldCells )
|
||||
this->ZapCells(ev, oldCells, fill);
|
||||
}
|
||||
}
|
||||
else // get rid of all row cells
|
||||
{
|
||||
morkCell* oldCells = ioRow->mRow_Cells;
|
||||
morkCell* oldEnd = oldCells + fill; // one past all old cells
|
||||
morkCell* newEnd = oldCells + inNewSize; // copy only kept old cells
|
||||
while ( oldCells < newEnd )
|
||||
{
|
||||
*newCells++ = *oldCells++; // bitwise copy each old cell struct
|
||||
}
|
||||
while ( oldCells < oldEnd )
|
||||
{
|
||||
if ( oldCells->mCell_Atom ) // need to unref old cell atom?
|
||||
oldCells->SetAtom(ev, (morkAtom*) 0, this); // unref cell atom
|
||||
++oldCells;
|
||||
}
|
||||
oldCells = ioRow->mRow_Cells;
|
||||
ioRow->mRow_Cells = newCells;
|
||||
ioRow->mRow_Length = inNewSize;
|
||||
ioRow->mRow_Cells = 0;
|
||||
ioRow->mRow_Length = 0;
|
||||
++ioRow->mRow_Seed;
|
||||
|
||||
this->ZapCells(ev, oldCells, fill);
|
||||
if ( oldCells )
|
||||
this->ZapCells(ev, oldCells, fill);
|
||||
}
|
||||
}
|
||||
return ( ev->Good() && ioRow->mRow_Length <= inNewSize );
|
||||
|
@ -163,15 +163,18 @@ morkRow::InitRow(morkEnv* ev, const mdbOid* inOid, morkRowSpace* ioSpace,
|
||||
}
|
||||
|
||||
morkRowObject*
|
||||
morkRow::GetRowObject(morkEnv* ev, morkStore* ioStore)
|
||||
morkRow::AcquireRowObject(morkEnv* ev, morkStore* ioStore)
|
||||
{
|
||||
morkRowObject* ro = mRow_Object;
|
||||
if ( !ro ) // need new row object?
|
||||
if ( ro ) // need new row object?
|
||||
ro->AddStrongRef(ev);
|
||||
else
|
||||
{
|
||||
nsIMdbHeap* heap = ioStore->mPort_Heap;
|
||||
ro = new (*heap, ev)
|
||||
morkRowObject(ev, morkUsage::kHeap, heap, this, ioStore);
|
||||
mRow_Object = ro;
|
||||
|
||||
morkRowObject::SlotWeakRowObject(ro, ev, &mRow_Object);
|
||||
}
|
||||
return ro;
|
||||
}
|
||||
@ -179,10 +182,13 @@ morkRow::GetRowObject(morkEnv* ev, morkStore* ioStore)
|
||||
nsIMdbRow*
|
||||
morkRow::AcquireRowHandle(morkEnv* ev, morkStore* ioStore)
|
||||
{
|
||||
morkRowObject* object = this->GetRowObject(ev, ioStore);
|
||||
morkRowObject* object = this->AcquireRowObject(ev, ioStore);
|
||||
if ( object )
|
||||
return object->AcquireRowHandle(ev);
|
||||
|
||||
{
|
||||
nsIMdbRow* rowHandle = object->AcquireRowHandle(ev);
|
||||
object->CutStrongRef(ev);
|
||||
return rowHandle;
|
||||
}
|
||||
return (nsIMdbRow*) 0;
|
||||
}
|
||||
|
||||
@ -387,12 +393,74 @@ morkRow::EmptyAllCells(morkEnv* ev)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
morkRow::CutAllColumns(morkEnv* ev)
|
||||
{
|
||||
morkStore* store = this->GetRowSpaceStore(ev);
|
||||
if ( store )
|
||||
{
|
||||
morkPool* pool = store->StorePool();
|
||||
pool->CutRowCells(ev, this, /*newSize*/ 0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
morkRow::SetRow(morkEnv* ev, const morkRow* inSourceRow)
|
||||
{
|
||||
// note inSourceRow might be in another DB, with a different store...
|
||||
morkStore* store = this->GetRowSpaceStore(ev);
|
||||
morkStore* srcStore = inSourceRow->GetRowSpaceStore(ev);
|
||||
if ( store && srcStore )
|
||||
{
|
||||
mork_bool sameStore = ( store == srcStore ); // identical stores?
|
||||
morkPool* pool = store->StorePool();
|
||||
if ( pool->CutRowCells(ev, this, /*newSize*/ 0) )
|
||||
{
|
||||
mork_fill fill = inSourceRow->mRow_Length;
|
||||
if ( pool->AddRowCells(ev, this, fill) )
|
||||
{
|
||||
morkCell* dst = mRow_Cells;
|
||||
morkCell* dstEnd = dst + mRow_Length;
|
||||
|
||||
const morkCell* src = inSourceRow->mRow_Cells;
|
||||
const morkCell* srcEnd = src + fill;
|
||||
--dst; --src; // prepare both for preincrement:
|
||||
|
||||
while ( ++dst < dstEnd && ++src < srcEnd && ev->Good() )
|
||||
{
|
||||
morkAtom* atom = src->mCell_Atom;
|
||||
mork_column col = src->GetColumn();
|
||||
if ( sameStore ) // source and dest in same store?
|
||||
{
|
||||
dst->SetColumnAndChange(col, morkChange_kAdd);
|
||||
dst->mCell_Atom = atom;
|
||||
if ( atom ) // another ref to non-nil atom?
|
||||
atom->AddCellUse(ev);
|
||||
}
|
||||
else // need to dup items from src store in a dest store
|
||||
{
|
||||
mork_column dstCol = store->CopyToken(ev, col, srcStore);
|
||||
if ( dstCol )
|
||||
{
|
||||
dst->SetColumnAndChange(dstCol, morkChange_kAdd);
|
||||
dst->mCell_Atom = store->CopyAtom(ev, atom);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
morkRow::AddRow(morkEnv* ev, const morkRow* inSourceRow)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// $$$$$ need to iterate over inSourceRow cells adding them to this row.
|
||||
// When the atoms are book atoms, we can just incr the use count.
|
||||
if ( mRow_Length ) // any existing cells we might need to keep?
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
else
|
||||
this->SetRow(ev, inSourceRow); // just exactly duplicate inSourceRow
|
||||
}
|
||||
|
||||
void
|
||||
@ -444,6 +512,41 @@ morkRow::GetRowSpaceStore(morkEnv* ev) const
|
||||
return (morkStore*) 0;
|
||||
}
|
||||
|
||||
void morkRow::CutColumn(morkEnv* ev, mdb_column inColumn)
|
||||
{
|
||||
mork_pos pos = -1;
|
||||
morkCell* cell = this->GetCell(ev, inColumn, &pos);
|
||||
if ( cell )
|
||||
{
|
||||
morkStore* store = this->GetRowSpaceStore(ev);
|
||||
if ( store )
|
||||
{
|
||||
morkPool* pool = store->StorePool();
|
||||
cell->SetAtom(ev, (morkAtom*) 0, pool);
|
||||
|
||||
mork_fill fill = mRow_Length; // should not be zero
|
||||
MORK_ASSERT(fill);
|
||||
if ( fill ) // index < fill for last cell exists?
|
||||
{
|
||||
mork_fill last = fill - 1; // index of last cell in row
|
||||
|
||||
if ( pos < last ) // need to move cells following cut cell?
|
||||
{
|
||||
morkCell* lastCell = mRow_Cells + last;
|
||||
mork_count after = last - pos; // cell count after cut cell
|
||||
morkCell* next = cell + 1; // next cell after cut cell
|
||||
MORK_MEMMOVE(cell, next, after * sizeof(morkCell));
|
||||
lastCell->SetColumnAndChange(0, 0);
|
||||
lastCell->mCell_Atom = 0;
|
||||
}
|
||||
|
||||
if ( ev->Good() )
|
||||
pool->CutRowCells(ev, this, fill - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void morkRow::AddColumn(morkEnv* ev, mdb_column inColumn,
|
||||
const mdbYarn* inYarn, morkStore* ioStore)
|
||||
{
|
||||
@ -475,7 +578,7 @@ morkRow::NewRowCellCursor(morkEnv* ev, mdb_pos inPos)
|
||||
morkStore* store = this->GetRowSpaceStore(ev);
|
||||
if ( store )
|
||||
{
|
||||
morkRowObject* rowObj = this->GetRowObject(ev, store);
|
||||
morkRowObject* rowObj = this->AcquireRowObject(ev, store);
|
||||
if ( rowObj )
|
||||
{
|
||||
nsIMdbHeap* heap = store->mPort_Heap;
|
||||
@ -492,6 +595,7 @@ morkRow::NewRowCellCursor(morkEnv* ev, mdb_pos inPos)
|
||||
else
|
||||
cursor->CutStrongRef(ev);
|
||||
}
|
||||
rowObj->CutStrongRef(ev); // always cut ref (cursor has its own)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ public: // other row methods
|
||||
mork_size inLength, morkPool* ioPool);
|
||||
// if inLength is nonzero, cells will be allocated from ioPool
|
||||
|
||||
morkRowObject* GetRowObject(morkEnv* ev, morkStore* ioStore);
|
||||
morkRowObject* AcquireRowObject(morkEnv* ev, morkStore* ioStore);
|
||||
nsIMdbRow* AcquireRowHandle(morkEnv* ev, morkStore* ioStore);
|
||||
nsIMdbCell* AcquireCellHandle(morkEnv* ev, morkCell* ioCell,
|
||||
mdb_column inColumn, mork_pos inPos);
|
||||
@ -109,10 +109,14 @@ public: // external row methods
|
||||
void AddColumn(morkEnv* ev, mdb_column inColumn,
|
||||
const mdbYarn* inYarn, morkStore* ioStore);
|
||||
|
||||
void CutColumn(morkEnv* ev, mdb_column inColumn);
|
||||
|
||||
morkRowCellCursor* NewRowCellCursor(morkEnv* ev, mdb_pos inPos);
|
||||
|
||||
void EmptyAllCells(morkEnv* ev);
|
||||
void AddRow(morkEnv* ev, const morkRow* inSourceRow);
|
||||
void SetRow(morkEnv* ev, const morkRow* inSourceRow);
|
||||
void CutAllColumns(morkEnv* ev);
|
||||
|
||||
void OnZeroTableUse(morkEnv* ev);
|
||||
// OnZeroTableUse() is called when CutTableUse() returns zero.
|
||||
|
@ -103,15 +103,16 @@ morkRowObject::CloseRowObject(morkEnv* ev) // called by CloseMorkNode();
|
||||
|
||||
if ( row )
|
||||
{
|
||||
MORK_ASSERT(row->mRow_Object == this);
|
||||
if ( row->mRow_Object == this )
|
||||
{
|
||||
morkRowObject::SlotWeakRowObject((morkRowObject*) 0, ev,
|
||||
&row->mRow_Object);
|
||||
row->mRow_Object = 0; // just nil this slot -- cut ref down below
|
||||
|
||||
morkStore::SlotWeakStore((morkStore*) 0, ev,
|
||||
&mRowObject_Store);
|
||||
|
||||
this->CutWeakRef(ev); // do last, because it might self destroy
|
||||
}
|
||||
else
|
||||
MORK_ASSERT(morkBool_kFalse);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -232,7 +232,8 @@ morkRowSpace::FindTableByKind(morkEnv* ev, mork_kind inTableKind)
|
||||
|
||||
morkTable*
|
||||
morkRowSpace::NewTableWithTid(morkEnv* ev, mork_tid inTid,
|
||||
mork_kind inTableKind)
|
||||
mork_kind inTableKind,
|
||||
const mdbOid* inOptionalMetaRowOid) // can be nil to avoid specifying
|
||||
{
|
||||
morkTable* outTable = 0;
|
||||
|
||||
@ -242,7 +243,7 @@ morkRowSpace::NewTableWithTid(morkEnv* ev, mork_tid inTid,
|
||||
nsIMdbHeap* heap = mSpace_Store->mPort_Heap;
|
||||
morkTable* table = new(*heap, ev)
|
||||
morkTable(ev, morkUsage::kHeap, heap, mSpace_Store, heap, this,
|
||||
inTid, inTableKind, mustBeUnique);
|
||||
inOptionalMetaRowOid, inTid, inTableKind, mustBeUnique);
|
||||
if ( table )
|
||||
{
|
||||
if ( mRowSpace_Tables.AddTable(ev, table) )
|
||||
@ -263,7 +264,8 @@ morkRowSpace::NewTableWithTid(morkEnv* ev, mork_tid inTid,
|
||||
|
||||
morkTable*
|
||||
morkRowSpace::NewTable(morkEnv* ev, mork_kind inTableKind,
|
||||
mdb_bool inMustBeUnique)
|
||||
mdb_bool inMustBeUnique,
|
||||
const mdbOid* inOptionalMetaRowOid) // can be nil to avoid specifying
|
||||
{
|
||||
morkTable* outTable = 0;
|
||||
|
||||
@ -280,7 +282,7 @@ morkRowSpace::NewTable(morkEnv* ev, mork_kind inTableKind,
|
||||
nsIMdbHeap* heap = mSpace_Store->mPort_Heap;
|
||||
morkTable* table = new(*heap, ev)
|
||||
morkTable(ev, morkUsage::kHeap, heap, mSpace_Store, heap, this,
|
||||
id, inTableKind, inMustBeUnique);
|
||||
inOptionalMetaRowOid, id, inTableKind, inMustBeUnique);
|
||||
if ( table )
|
||||
{
|
||||
if ( mRowSpace_Tables.AddTable(ev, table) )
|
||||
|
@ -113,10 +113,10 @@ public: // other space methods
|
||||
// CutAllRows() puts all rows and cells back into the pool.
|
||||
|
||||
morkTable* NewTable(morkEnv* ev, mork_kind inTableKind,
|
||||
mdb_bool inMustBeUnique);
|
||||
mdb_bool inMustBeUnique, const mdbOid* inOptionalMetaRowOid);
|
||||
|
||||
morkTable* NewTableWithTid(morkEnv* ev, mork_tid inTid,
|
||||
mork_kind inTableKind);
|
||||
mork_kind inTableKind, const mdbOid* inOptionalMetaRowOid);
|
||||
|
||||
morkTable* FindTableByKind(morkEnv* ev, mork_kind inTableKind);
|
||||
morkTable* FindTableByTid(morkEnv* ev, mork_tid inTid)
|
||||
|
@ -217,14 +217,6 @@ morkStore::morkStore(morkEnv* ev, const morkUsage& inUsage,
|
||||
, mStore_GroundAtomSpace( 0 )
|
||||
, mStore_GroundColumnSpace( 0 )
|
||||
|
||||
, mStore_MorkNoneToken( 0 )
|
||||
, mStore_CharsetToken( 0 )
|
||||
, mStore_AtomScopeToken( 0 )
|
||||
, mStore_RowScopeToken( 0 )
|
||||
, mStore_TableScopeToken( 0 )
|
||||
, mStore_ColumnScopeToken( 0 )
|
||||
, mStore_TableKindToken( 0 )
|
||||
|
||||
, mStore_RowSpaces(ev, morkUsage::kMember, (nsIMdbHeap*) 0, ioPortHeap)
|
||||
, mStore_AtomSpaces(ev, morkUsage::kMember, (nsIMdbHeap*) 0, ioPortHeap)
|
||||
, mStore_Pool(ev, morkUsage::kMember, (nsIMdbHeap*) 0, ioPortHeap)
|
||||
@ -233,26 +225,6 @@ morkStore::morkStore(morkEnv* ev, const morkUsage& inUsage,
|
||||
{
|
||||
mNode_Derived = morkDerived_kStore;
|
||||
|
||||
if ( ev->Good() )
|
||||
mStore_MorkNoneToken = this->StringToToken(ev, "mork:none");
|
||||
|
||||
if ( ev->Good() )
|
||||
mStore_CharsetToken = this->StringToToken(ev, "charset");
|
||||
|
||||
if ( ev->Good() )
|
||||
mStore_AtomScopeToken = this->StringToToken(ev, "atomScope");
|
||||
|
||||
if ( ev->Good() )
|
||||
mStore_RowScopeToken = this->StringToToken(ev, "rowScope");
|
||||
|
||||
if ( ev->Good() )
|
||||
mStore_TableScopeToken = this->StringToToken(ev, "tableScope");
|
||||
|
||||
if ( ev->Good() )
|
||||
mStore_ColumnScopeToken = this->StringToToken(ev, "columnScope");
|
||||
|
||||
if ( ev->Good() )
|
||||
mStore_TableKindToken = this->StringToToken(ev, "tableKind");
|
||||
}
|
||||
}
|
||||
|
||||
@ -603,6 +575,20 @@ morkStore::CreateStoreFile(morkEnv* ev,
|
||||
}
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
morkAtom*
|
||||
morkStore::CopyAtom(morkEnv* ev, const morkAtom* inAtom)
|
||||
// copy inAtom (from some other store) over to this store
|
||||
{
|
||||
morkAtom* outAtom = 0;
|
||||
if ( inAtom )
|
||||
{
|
||||
mdbYarn yarn;
|
||||
if ( inAtom->AliasYarn(&yarn) )
|
||||
outAtom = this->YarnToAtom(ev, &yarn);
|
||||
}
|
||||
return outAtom;
|
||||
}
|
||||
|
||||
morkAtom*
|
||||
morkStore::YarnToAtom(morkEnv* ev, const mdbYarn* inYarn)
|
||||
@ -691,7 +677,7 @@ morkStore::MidToTable(morkEnv* ev, const morkMid& inMid)
|
||||
{
|
||||
mdbOid tempOid;
|
||||
this->MidToOid(ev, inMid, &tempOid);
|
||||
return this->OidToTable(ev, &tempOid);
|
||||
return this->OidToTable(ev, &tempOid, /*metarow*/ (mdbOid*) 0);
|
||||
}
|
||||
|
||||
mork_bool
|
||||
@ -769,10 +755,10 @@ morkStore::TokenToString(morkEnv* ev, mdb_token inToken, mdbYarn* outTokenName)
|
||||
this->SmallTokenToOneByteYarn(ev, inToken, outTokenName);
|
||||
}
|
||||
|
||||
void
|
||||
morkStore::SyncTokenIdChange(morkEnv* ev, const morkBookAtom* inAtom,
|
||||
const mdbOid* inOid)
|
||||
{
|
||||
// void
|
||||
// morkStore::SyncTokenIdChange(morkEnv* ev, const morkBookAtom* inAtom,
|
||||
// const mdbOid* inOid)
|
||||
// {
|
||||
// mork_token mStore_MorkNoneToken; // token for "mork:none" // fill=9
|
||||
// mork_column mStore_CharsetToken; // token for "charset" // fill=7
|
||||
// mork_column mStore_AtomScopeToken; // token for "atomScope" // fill=9
|
||||
@ -781,55 +767,55 @@ morkStore::SyncTokenIdChange(morkEnv* ev, const morkBookAtom* inAtom,
|
||||
// mork_column mStore_ColumnScopeToken; // token for "columnScope" // fill=11
|
||||
// mork_kind mStore_TableKindToken; // token for "tableKind" // fill=9
|
||||
// ---------------------ruler-for-token-length-above---123456789012
|
||||
|
||||
if ( inOid->mOid_Scope == morkStore_kColumnSpaceScope && inAtom->IsWeeBook() )
|
||||
{
|
||||
const mork_u1* body = ((const morkWeeBookAtom*) inAtom)->mWeeBookAtom_Body;
|
||||
mork_size size = inAtom->mAtom_Size;
|
||||
|
||||
if ( size >= 7 && size <= 11 )
|
||||
{
|
||||
if ( size == 9 )
|
||||
{
|
||||
if ( *body == 'm' )
|
||||
{
|
||||
if ( MORK_MEMCMP(body, "mork:none", 9) == 0 )
|
||||
mStore_MorkNoneToken = inAtom->mBookAtom_Id;
|
||||
}
|
||||
else if ( *body == 'a' )
|
||||
{
|
||||
if ( MORK_MEMCMP(body, "atomScope", 9) == 0 )
|
||||
mStore_AtomScopeToken = inAtom->mBookAtom_Id;
|
||||
}
|
||||
else if ( *body == 't' )
|
||||
{
|
||||
if ( MORK_MEMCMP(body, "tableKind", 9) == 0 )
|
||||
mStore_TableKindToken = inAtom->mBookAtom_Id;
|
||||
}
|
||||
}
|
||||
else if ( size == 7 && *body == 'c' )
|
||||
{
|
||||
if ( MORK_MEMCMP(body, "charset", 7) == 0 )
|
||||
mStore_CharsetToken = inAtom->mBookAtom_Id;
|
||||
}
|
||||
else if ( size == 8 && *body == 'r' )
|
||||
{
|
||||
if ( MORK_MEMCMP(body, "rowScope", 8) == 0 )
|
||||
mStore_RowScopeToken = inAtom->mBookAtom_Id;
|
||||
}
|
||||
else if ( size == 10 && *body == 't' )
|
||||
{
|
||||
if ( MORK_MEMCMP(body, "tableScope", 10) == 0 )
|
||||
mStore_TableScopeToken = inAtom->mBookAtom_Id;
|
||||
}
|
||||
else if ( size == 11 && *body == 'c' )
|
||||
{
|
||||
if ( MORK_MEMCMP(body, "columnScope", 11) == 0 )
|
||||
mStore_ColumnScopeToken = inAtom->mBookAtom_Id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// if ( inOid->mOid_Scope == morkStore_kColumnSpaceScope && inAtom->IsWeeBook() )
|
||||
// {
|
||||
// const mork_u1* body = ((const morkWeeBookAtom*) inAtom)->mWeeBookAtom_Body;
|
||||
// mork_size size = inAtom->mAtom_Size;
|
||||
//
|
||||
// if ( size >= 7 && size <= 11 )
|
||||
// {
|
||||
// if ( size == 9 )
|
||||
// {
|
||||
// if ( *body == 'm' )
|
||||
// {
|
||||
// if ( MORK_MEMCMP(body, "mork:none", 9) == 0 )
|
||||
// mStore_MorkNoneToken = inAtom->mBookAtom_Id;
|
||||
// }
|
||||
// else if ( *body == 'a' )
|
||||
// {
|
||||
// if ( MORK_MEMCMP(body, "atomScope", 9) == 0 )
|
||||
// mStore_AtomScopeToken = inAtom->mBookAtom_Id;
|
||||
// }
|
||||
// else if ( *body == 't' )
|
||||
// {
|
||||
// if ( MORK_MEMCMP(body, "tableKind", 9) == 0 )
|
||||
// mStore_TableKindToken = inAtom->mBookAtom_Id;
|
||||
// }
|
||||
// }
|
||||
// else if ( size == 7 && *body == 'c' )
|
||||
// {
|
||||
// if ( MORK_MEMCMP(body, "charset", 7) == 0 )
|
||||
// mStore_CharsetToken = inAtom->mBookAtom_Id;
|
||||
// }
|
||||
// else if ( size == 8 && *body == 'r' )
|
||||
// {
|
||||
// if ( MORK_MEMCMP(body, "rowScope", 8) == 0 )
|
||||
// mStore_RowScopeToken = inAtom->mBookAtom_Id;
|
||||
// }
|
||||
// else if ( size == 10 && *body == 't' )
|
||||
// {
|
||||
// if ( MORK_MEMCMP(body, "tableScope", 10) == 0 )
|
||||
// mStore_TableScopeToken = inAtom->mBookAtom_Id;
|
||||
// }
|
||||
// else if ( size == 11 && *body == 'c' )
|
||||
// {
|
||||
// if ( MORK_MEMCMP(body, "columnScope", 11) == 0 )
|
||||
// mStore_ColumnScopeToken = inAtom->mBookAtom_Id;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
morkAtom*
|
||||
morkStore::AddAlias(morkEnv* ev, const morkMid& inMid, mork_cscode inForm)
|
||||
@ -858,15 +844,15 @@ morkStore::AddAlias(morkEnv* ev, const morkMid& inMid, mork_cscode inForm)
|
||||
outAtom = atomSpace->MakeBookAtomCopyWithAid(ev,
|
||||
*keyAtom, (mork_aid) oid->mOid_Id);
|
||||
|
||||
if ( outAtom && outAtom->IsWeeBook() )
|
||||
{
|
||||
if ( oid->mOid_Scope == morkStore_kColumnSpaceScope )
|
||||
{
|
||||
mork_size size = outAtom->mAtom_Size;
|
||||
if ( size >= 7 && size <= 11 )
|
||||
this->SyncTokenIdChange(ev, outAtom, oid);
|
||||
}
|
||||
}
|
||||
// if ( outAtom && outAtom->IsWeeBook() )
|
||||
// {
|
||||
// if ( oid->mOid_Scope == morkStore_kColumnSpaceScope )
|
||||
// {
|
||||
// mork_size size = outAtom->mAtom_Size;
|
||||
// if ( size >= 7 && size <= 11 )
|
||||
// this->SyncTokenIdChange(ev, outAtom, oid);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -874,6 +860,36 @@ morkStore::AddAlias(morkEnv* ev, const morkMid& inMid, mork_cscode inForm)
|
||||
return outAtom;
|
||||
}
|
||||
|
||||
#define morkStore_kMaxCopyTokenSize 512 /* if larger, cannot be copied */
|
||||
|
||||
mork_token
|
||||
morkStore::CopyToken(morkEnv* ev, mdb_token inToken, morkStore* inStore)
|
||||
// copy inToken from inStore over to this store
|
||||
{
|
||||
mork_token outToken = 0;
|
||||
if ( inStore == this ) // same store?
|
||||
outToken = inToken; // just return token unchanged
|
||||
else
|
||||
{
|
||||
char yarnBuf[ morkStore_kMaxCopyTokenSize ];
|
||||
mdbYarn yarn;
|
||||
yarn.mYarn_Buf = yarnBuf;
|
||||
yarn.mYarn_Fill = 0;
|
||||
yarn.mYarn_Size = morkStore_kMaxCopyTokenSize;
|
||||
yarn.mYarn_More = 0;
|
||||
yarn.mYarn_Form = 0;
|
||||
yarn.mYarn_Grow = 0;
|
||||
|
||||
inStore->TokenToString(ev, inToken, &yarn);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
morkBuf buf(yarn.mYarn_Buf, yarn.mYarn_Fill);
|
||||
outToken = this->BufToToken(ev, &buf);
|
||||
}
|
||||
}
|
||||
return outToken;
|
||||
}
|
||||
|
||||
mork_token
|
||||
morkStore::BufToToken(morkEnv* ev, const morkBuf* inBuf)
|
||||
{
|
||||
@ -1064,14 +1080,16 @@ morkStore::GetTable(morkEnv* ev, const mdbOid* inOid)
|
||||
|
||||
morkTable*
|
||||
morkStore::NewTable(morkEnv* ev, mdb_scope inRowScope,
|
||||
mdb_kind inTableKind, mdb_bool inMustBeUnique)
|
||||
mdb_kind inTableKind, mdb_bool inMustBeUnique,
|
||||
const mdbOid* inOptionalMetaRowOid) // can be nil to avoid specifying
|
||||
{
|
||||
morkTable* outTable = 0;
|
||||
if ( ev->Good() )
|
||||
{
|
||||
morkRowSpace* rowSpace = this->LazyGetRowSpace(ev, inRowScope);
|
||||
if ( rowSpace )
|
||||
outTable = rowSpace->NewTable(ev, inTableKind, inMustBeUnique);
|
||||
outTable = rowSpace->NewTable(ev, inTableKind, inMustBeUnique,
|
||||
inOptionalMetaRowOid);
|
||||
}
|
||||
return outTable;
|
||||
}
|
||||
@ -1136,7 +1154,8 @@ morkStore::OidToRow(morkEnv* ev, const mdbOid* inOid)
|
||||
}
|
||||
|
||||
morkTable*
|
||||
morkStore::OidToTable(morkEnv* ev, const mdbOid* inOid)
|
||||
morkStore::OidToTable(morkEnv* ev, const mdbOid* inOid,
|
||||
const mdbOid* inOptionalMetaRowOid) // can be nil to avoid specifying
|
||||
// OidToTable() finds old table with oid, or makes new one if not found.
|
||||
{
|
||||
morkTable* outTable = 0;
|
||||
@ -1148,8 +1167,9 @@ morkStore::OidToTable(morkEnv* ev, const mdbOid* inOid)
|
||||
outTable = rowSpace->mRowSpace_Tables.GetTable(ev, inOid->mOid_Id);
|
||||
if ( !outTable && ev->Good() )
|
||||
{
|
||||
mork_kind tableKind = mStore_MorkNoneToken;
|
||||
outTable = rowSpace->NewTableWithTid(ev, inOid->mOid_Id, tableKind);
|
||||
mork_kind tableKind = morkStore_kNoneToken;
|
||||
outTable = rowSpace->NewTableWithTid(ev, inOid->mOid_Id, tableKind,
|
||||
inOptionalMetaRowOid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -119,6 +119,15 @@ public: // typesafe refcounting inlines calling inherited morkNode methods
|
||||
#define morkStore_kGroundAtomSpace 'a' /* for mStore_GroundAtomSpace*/
|
||||
#define morkStore_kStreamBufSize (8 * 1024) /* okay buffer size */
|
||||
|
||||
#define morkStore_kReservedColumnCount 0x20 /* for well-known columns */
|
||||
|
||||
#define morkStore_kNoneToken ((mork_token) 'n')
|
||||
#define morkStore_kFormColumn ((mork_column) 'f')
|
||||
#define morkStore_kAtomScopeColumn ((mork_column) 'a')
|
||||
#define morkStore_kRowScopeColumn ((mork_column) 'r')
|
||||
#define morkStore_kMetaScope ((mork_scope) 'm')
|
||||
#define morkStore_kKindColumn ((mork_column) 'k')
|
||||
|
||||
/*| morkStore:
|
||||
|*/
|
||||
class morkStore : public morkPort {
|
||||
@ -151,14 +160,6 @@ public: // state is public because the entire Mork system is private
|
||||
|
||||
morkStream* mStore_OutStream; // stream using file used by the writer
|
||||
|
||||
mork_token mStore_MorkNoneToken; // token for "mork:none"
|
||||
mork_column mStore_CharsetToken; // token for "charset"
|
||||
mork_column mStore_AtomScopeToken; // token for "atomScope"
|
||||
mork_column mStore_RowScopeToken; // token for "rowScope"
|
||||
mork_column mStore_TableScopeToken; // token for "tableScope"
|
||||
mork_column mStore_ColumnScopeToken; // token for "columnScope"
|
||||
mork_kind mStore_TableKindToken; // token for "tableKind"
|
||||
|
||||
morkRowSpaceMap mStore_RowSpaces; // maps mork_scope -> morkSpace
|
||||
morkAtomSpaceMap mStore_AtomSpaces; // maps mork_scope -> morkSpace
|
||||
|
||||
@ -169,8 +170,8 @@ public: // state is public because the entire Mork system is private
|
||||
|
||||
public: // coping with any changes to store token slots above:
|
||||
|
||||
void SyncTokenIdChange(morkEnv* ev, const morkBookAtom* inAtom,
|
||||
const mdbOid* inOid);
|
||||
// void SyncTokenIdChange(morkEnv* ev, const morkBookAtom* inAtom,
|
||||
// const mdbOid* inOid);
|
||||
|
||||
public: // building an atom inside mStore_BookAtom from a char* string
|
||||
|
||||
@ -252,6 +253,12 @@ public: // other store methods
|
||||
const char* inFilePath,
|
||||
const mdbOpenPolicy* inOpenPolicy);
|
||||
|
||||
morkAtom* CopyAtom(morkEnv* ev, const morkAtom* inAtom);
|
||||
// copy inAtom (from some other store) over to this store
|
||||
|
||||
mork_token CopyToken(morkEnv* ev, mdb_token inToken, morkStore* inStore);
|
||||
// copy inToken from inStore over to this store
|
||||
|
||||
mork_token BufToToken(morkEnv* ev, const morkBuf* inBuf);
|
||||
mork_token StringToToken(morkEnv* ev, const char* inTokenName);
|
||||
mork_token QueryToken(morkEnv* ev, const char* inTokenName);
|
||||
@ -270,7 +277,8 @@ public: // other store methods
|
||||
morkRow* OidToRow(morkEnv* ev, const mdbOid* inOid);
|
||||
// OidToRow() finds old row with oid, or makes new one if not found.
|
||||
|
||||
morkTable* OidToTable(morkEnv* ev, const mdbOid* inOid);
|
||||
morkTable* OidToTable(morkEnv* ev, const mdbOid* inOid,
|
||||
const mdbOid* inOptionalMetaRowOid);
|
||||
// OidToTable() finds old table with oid, or makes new one if not found.
|
||||
|
||||
static void SmallTokenToOneByteYarn(morkEnv* ev, mdb_token inToken,
|
||||
@ -287,7 +295,8 @@ public: // other store methods
|
||||
morkTable* GetTable(morkEnv* ev, const mdbOid* inOid);
|
||||
|
||||
morkTable* NewTable(morkEnv* ev, mdb_scope inRowScope,
|
||||
mdb_kind inTableKind, mdb_bool inMustBeUnique);
|
||||
mdb_kind inTableKind, mdb_bool inMustBeUnique,
|
||||
const mdbOid* inOptionalMetaRowOid);
|
||||
|
||||
morkPortTableCursor* GetPortTableCursor(morkEnv* ev, mdb_scope inRowScope,
|
||||
mdb_kind inTableKind) ;
|
||||
|
@ -92,10 +92,12 @@ morkTable::~morkTable() /*i*/ // assert CloseTable() executed earlier
|
||||
morkTable::morkTable(morkEnv* ev, /*i*/
|
||||
const morkUsage& inUsage, nsIMdbHeap* ioHeap,
|
||||
morkStore* ioStore, nsIMdbHeap* ioSlotHeap, morkRowSpace* ioRowSpace,
|
||||
const mdbOid* inOptionalMetaRowOid, // can be nil to avoid specifying
|
||||
mork_tid inTid, mork_kind inKind, mork_bool inMustBeUnique)
|
||||
: morkObject(ev, inUsage, ioHeap, (morkHandle*) 0)
|
||||
, mTable_Store( 0 )
|
||||
, mTable_RowSpace( 0 )
|
||||
, mTable_MetaRow( 0 )
|
||||
, mTable_Id( inTid )
|
||||
, mTable_RowMap(ev, morkUsage::kMember, (nsIMdbHeap*) 0, ioSlotHeap,
|
||||
morkTable_kStartRowMapSlotCount)
|
||||
@ -112,6 +114,13 @@ morkTable::morkTable(morkEnv* ev, /*i*/
|
||||
{
|
||||
morkStore::SlotWeakStore(ioStore, ev, &mTable_Store);
|
||||
morkRowSpace::SlotWeakRowSpace(ioRowSpace, ev, &mTable_RowSpace);
|
||||
if ( inOptionalMetaRowOid )
|
||||
mTable_MetaRowOid = *inOptionalMetaRowOid;
|
||||
else
|
||||
{
|
||||
mTable_MetaRowOid.mOid_Scope = 0;
|
||||
mTable_MetaRowOid.mOid_Id = morkRow_kMinusOneRid;
|
||||
}
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kTable;
|
||||
}
|
||||
@ -194,6 +203,33 @@ morkTable::NilRowSpaceError(morkEnv* ev)
|
||||
ev->NewError("nil mTable_RowSpace");
|
||||
}
|
||||
|
||||
morkRow*
|
||||
morkTable::GetMetaRow(morkEnv* ev, const mdbOid* inOptionalMetaRowOid)
|
||||
{
|
||||
morkRow* outRow = mTable_MetaRow;
|
||||
if ( !outRow )
|
||||
{
|
||||
morkStore* store = mTable_Store;
|
||||
mdbOid* oid = &mTable_MetaRowOid;
|
||||
if ( inOptionalMetaRowOid && !oid->mOid_Scope )
|
||||
*oid = *inOptionalMetaRowOid;
|
||||
|
||||
if ( oid->mOid_Scope ) // oid already recorded in table?
|
||||
outRow = store->OidToRow(ev, oid);
|
||||
else
|
||||
{
|
||||
outRow = store->NewRow(ev, morkStore_kMetaScope);
|
||||
if ( outRow ) // need to record new oid in table?
|
||||
*oid = outRow->mRow_Oid;
|
||||
}
|
||||
mTable_MetaRow = outRow;
|
||||
if ( outRow ) // need to note another use of this row?
|
||||
outRow->AddTableUse(ev);
|
||||
}
|
||||
|
||||
return outRow;
|
||||
}
|
||||
|
||||
void
|
||||
morkTable::GetTableOid(morkEnv* ev, mdbOid* outOid)
|
||||
{
|
||||
@ -241,14 +277,10 @@ morkTable::ArrayHasOid(morkEnv* ev, const mdbOid* inOid)
|
||||
return -1;
|
||||
}
|
||||
|
||||
mork_pos
|
||||
mork_bool
|
||||
morkTable::MapHasOid(morkEnv* ev, const mdbOid* inOid)
|
||||
{
|
||||
morkRow* row = mTable_RowMap.GetOid(ev, inOid);
|
||||
if ( row )
|
||||
return 1;
|
||||
|
||||
return -1;
|
||||
return ( mTable_RowMap.GetOid(ev, inOid) != 0 );
|
||||
}
|
||||
|
||||
mork_bool
|
||||
|
@ -78,6 +78,9 @@ public: // state is public because the entire Mork system is private
|
||||
|
||||
// mTable_RowSpace->mSpace_Scope is row scope
|
||||
morkRowSpace* mTable_RowSpace; // weak ref to containing space
|
||||
|
||||
morkRow* mTable_MetaRow; // table's actual meta row
|
||||
mdbOid mTable_MetaRowOid; // oid for meta row
|
||||
|
||||
morkRowMap mTable_RowMap; // hash table of all members
|
||||
morkArray mTable_RowArray; // array of morkRow pointers
|
||||
@ -98,6 +101,7 @@ public: // morkTable construction & destruction
|
||||
morkTable(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioNodeHeap, morkStore* ioStore,
|
||||
nsIMdbHeap* ioSlotHeap, morkRowSpace* ioRowSpace,
|
||||
const mdbOid* inOptionalMetaRowOid, // can be nil to avoid specifying
|
||||
mork_tid inTableId,
|
||||
mork_kind inKind, mork_bool inMustBeUnique);
|
||||
void CloseTable(morkEnv* ev); // called by CloseMorkNode();
|
||||
@ -120,6 +124,8 @@ public: // warnings
|
||||
static void CellUsesUnderflowWarning(morkEnv* ev);
|
||||
|
||||
public: // other table methods
|
||||
|
||||
morkRow* GetMetaRow(morkEnv* ev, const mdbOid* inOptionalMetaRowOid);
|
||||
|
||||
mork_u2 AddCellUse(morkEnv* ev);
|
||||
mork_u2 CutCellUse(morkEnv* ev);
|
||||
@ -134,7 +140,7 @@ public: // other table methods
|
||||
|
||||
void GetTableOid(morkEnv* ev, mdbOid* outOid);
|
||||
mork_pos ArrayHasOid(morkEnv* ev, const mdbOid* inOid);
|
||||
mork_pos MapHasOid(morkEnv* ev, const mdbOid* inOid);
|
||||
mork_bool MapHasOid(morkEnv* ev, const mdbOid* inOid);
|
||||
mork_bool AddRow(morkEnv* ev, morkRow* ioRow); // returns ev->Good()
|
||||
mork_bool CutRow(morkEnv* ev, morkRow* ioRow); // returns ev->Good()
|
||||
|
||||
|
@ -129,18 +129,16 @@ morkWriter::morkWriter(morkEnv* ev, const morkUsage& inUsage,
|
||||
, mWriter_MaxIndent( morkWriter_kMaxIndent )
|
||||
, mWriter_MaxLine( morkWriter_kMaxLine )
|
||||
|
||||
, mWriter_TableCharset( 0 )
|
||||
, mWriter_TableForm( 0 )
|
||||
, mWriter_TableAtomScope( 0 )
|
||||
, mWriter_TableRowScope( 0 )
|
||||
, mWriter_TableTableScope( 0 )
|
||||
, mWriter_TableColumnScope( 0 )
|
||||
, mWriter_TableKind( 0 )
|
||||
|
||||
, mWriter_RowCharset( 0 )
|
||||
, mWriter_RowForm( 0 )
|
||||
, mWriter_RowAtomScope( 0 )
|
||||
, mWriter_RowScope( 0 )
|
||||
|
||||
, mWriter_DictCharset( 0 )
|
||||
, mWriter_DictForm( 0 )
|
||||
, mWriter_DictAtomScope( 0 )
|
||||
|
||||
, mWriter_NeedDirtyAll( morkBool_kFalse )
|
||||
@ -372,7 +370,7 @@ morkWriter::WriteYarn(morkEnv* ev, const mdbYarn* inYarn)
|
||||
stream->Putc(ev, c);
|
||||
++outSize; // c
|
||||
}
|
||||
else if ( c == ')' && c == '$' && c == '\\' )
|
||||
else if ( c == ')' || c == '$' || c == '\\' )
|
||||
{
|
||||
stream->Putc(ev, '\\');
|
||||
stream->Putc(ev, c);
|
||||
@ -403,8 +401,8 @@ morkWriter::WriteAtom(morkEnv* ev, const morkAtom* inAtom)
|
||||
|
||||
if ( inAtom->AliasYarn(&yarn) )
|
||||
{
|
||||
if ( mWriter_DidStartDict && yarn.mYarn_Form != mWriter_DictCharset )
|
||||
this->ChangeDictCharset(ev, yarn.mYarn_Form);
|
||||
if ( mWriter_DidStartDict && yarn.mYarn_Form != mWriter_DictForm )
|
||||
this->ChangeDictForm(ev, yarn.mYarn_Form);
|
||||
|
||||
outSize = this->WriteYarn(ev, &yarn);
|
||||
// mWriter_LineSize += stream->Write(ev, inYarn->mYarn_Buf, outSize);
|
||||
@ -424,10 +422,10 @@ morkWriter::WriteAtomSpaceAsDict(morkEnv* ev, morkAtomSpace* ioSpace)
|
||||
{
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
stream->PutString(ev, "< <(atomScope=");
|
||||
stream->PutString(ev, "< <(a=");
|
||||
stream->Putc(ev, (int) scope);
|
||||
++mWriter_LineSize;
|
||||
stream->PutString(ev, ")> // (charset=iso-8859-1)");
|
||||
stream->PutString(ev, ")> // (f=iso-8859-1)");
|
||||
mWriter_LineSize = stream->PutIndent(ev, morkWriter_kDictAliasDepth);
|
||||
}
|
||||
else
|
||||
@ -457,8 +455,8 @@ morkWriter::WriteAtomSpaceAsDict(morkEnv* ev, morkAtomSpace* ioSpace)
|
||||
atom->AliasYarn(&yarn);
|
||||
mork_size size = ev->TokenAsHex(idBuf, atom->mBookAtom_Id);
|
||||
|
||||
if ( yarn.mYarn_Form != mWriter_DictCharset )
|
||||
this->ChangeDictCharset(ev, yarn.mYarn_Form);
|
||||
if ( yarn.mYarn_Form != mWriter_DictForm )
|
||||
this->ChangeDictForm(ev, yarn.mYarn_Form);
|
||||
|
||||
mork_size pending = yarn.mYarn_Fill + size +
|
||||
morkWriter_kYarnEscapeSlop + 4;
|
||||
@ -648,7 +646,7 @@ morkWriter::OnDirtyAllDone(morkEnv* ev)
|
||||
stream->Seek(ev, 0); // beginning of stream
|
||||
if ( ev->Good() )
|
||||
{
|
||||
stream->PutStringThenNewline(ev, "// <!-- <mdb:mork:z v=\"1.1\"/> -->");
|
||||
stream->PutStringThenNewline(ev, morkWriter_kFileHeader);
|
||||
mWriter_LineSize = 0;
|
||||
}
|
||||
|
||||
@ -968,17 +966,15 @@ morkWriter::PutTableDict(morkEnv* ev, morkTable* ioTable)
|
||||
{
|
||||
morkRowSpace* space = ioTable->mTable_RowSpace;
|
||||
mWriter_TableRowScope = space->mSpace_Scope;
|
||||
mWriter_TableCharset = 0; // (charset=iso-8859-1)
|
||||
mWriter_TableAtomScope = 'a'; // (atomScope=a)
|
||||
mWriter_TableTableScope = 't'; // (tableScope=t)
|
||||
mWriter_TableColumnScope = 'c'; // (columnScope=c)
|
||||
mWriter_TableForm = 0; // (f=iso-8859-1)
|
||||
mWriter_TableAtomScope = 'v'; // (a=v)
|
||||
mWriter_TableKind = ioTable->mTable_Kind;
|
||||
|
||||
mWriter_RowCharset = mWriter_TableCharset;
|
||||
mWriter_RowForm = mWriter_TableForm;
|
||||
mWriter_RowAtomScope = mWriter_TableAtomScope;
|
||||
mWriter_RowScope = mWriter_TableRowScope;
|
||||
|
||||
mWriter_DictCharset = mWriter_TableCharset;
|
||||
mWriter_DictForm = mWriter_TableForm;
|
||||
mWriter_DictAtomScope = mWriter_TableAtomScope;
|
||||
|
||||
if ( ev->Good() )
|
||||
@ -986,6 +982,14 @@ morkWriter::PutTableDict(morkEnv* ev, morkTable* ioTable)
|
||||
|
||||
if ( ev->Good() )
|
||||
{
|
||||
morkRow* r = ioTable->mTable_MetaRow;
|
||||
if ( r )
|
||||
{
|
||||
if ( r->IsRow() )
|
||||
this->PutRowDict(ev, r);
|
||||
else
|
||||
r->NonRowTypeError(ev);
|
||||
}
|
||||
morkArray* array = &ioTable->mTable_RowArray; // vector of rows
|
||||
mork_fill fill = array->mArray_Fill; // count of rows
|
||||
morkRow** rows = (morkRow**) array->mArray_Slots;
|
||||
@ -994,7 +998,7 @@ morkWriter::PutTableDict(morkEnv* ev, morkTable* ioTable)
|
||||
morkRow** end = rows + fill;
|
||||
while ( rows < end && ev->Good() )
|
||||
{
|
||||
morkRow* r = *rows++; // next row to consider
|
||||
r = *rows++; // next row to consider
|
||||
if ( r && r->IsRow() )
|
||||
this->PutRowDict(ev, r);
|
||||
else
|
||||
@ -1013,15 +1017,25 @@ morkWriter::WriteTokenToTokenMetaCell(morkEnv* ev,
|
||||
mork_token inCol, mork_token inValue)
|
||||
{
|
||||
morkStream* stream = mWriter_Stream;
|
||||
char buf[ 128 ]; // buffer for staging the two hex IDs
|
||||
char* p = buf;
|
||||
*p++ = '('; // we always start with open paren
|
||||
*p++ = '^'; // indicates col is hex ID
|
||||
|
||||
mork_size colSize = ev->TokenAsHex(p, inCol);
|
||||
p += colSize;
|
||||
*p++ = '='; // we always start with open paren
|
||||
mWriter_LineSize += stream->Write(ev, buf, colSize + 3);
|
||||
if ( inCol < 0x80 )
|
||||
{
|
||||
stream->Putc(ev, '(');
|
||||
stream->Putc(ev, (char) inCol);
|
||||
stream->Putc(ev, '=');
|
||||
}
|
||||
else
|
||||
{
|
||||
char buf[ 128 ]; // buffer for staging the two hex IDs
|
||||
char* p = buf;
|
||||
*p++ = '('; // we always start with open paren
|
||||
|
||||
*p++ = '^'; // indicates col is hex ID
|
||||
mork_size colSize = ev->TokenAsHex(p, inCol);
|
||||
p += colSize;
|
||||
*p++ = '=';
|
||||
mWriter_LineSize += stream->Write(ev, buf, colSize + 3);
|
||||
}
|
||||
|
||||
this->IndentAsNeeded(ev, morkWriter_kTableMetaCellValueDepth);
|
||||
mdbYarn* yarn = &mWriter_ColYarn;
|
||||
@ -1058,21 +1072,34 @@ morkWriter::WriteStringToTokenDictCell(morkEnv* ev,
|
||||
}
|
||||
|
||||
void
|
||||
morkWriter::ChangeDictCharset(morkEnv* ev, mork_cscode inNewForm)
|
||||
morkWriter::ChangeDictForm(morkEnv* ev, mork_cscode inNewForm)
|
||||
{
|
||||
if ( inNewForm != mWriter_DictCharset )
|
||||
if ( inNewForm != mWriter_DictForm )
|
||||
{
|
||||
morkStream* stream = mWriter_Stream;
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
mWriter_LineSize = 0;
|
||||
|
||||
stream->Putc(ev, '<');
|
||||
this->WriteStringToTokenDictCell(ev, "(charset=", mWriter_DictCharset);
|
||||
stream->Putc(ev, '>');
|
||||
++mWriter_LineSize;
|
||||
char buf[ 128 ]; // buffer for staging the two hex IDs
|
||||
char* p = buf;
|
||||
*p++ = '<'; // we always start with open paren
|
||||
*p++ = '('; // we always start with open paren
|
||||
*p++ = (char) morkStore_kFormColumn;
|
||||
*p++ = '^'; // indicates col is hex ID
|
||||
|
||||
mork_size formSize = ev->TokenAsHex(p, inNewForm);
|
||||
p += formSize;
|
||||
*p++ = ')';
|
||||
*p++ = '>';
|
||||
*p = 0;
|
||||
|
||||
mork_size pending = formSize + 6;
|
||||
this->IndentOverMaxLine(ev, pending, morkWriter_kDictAliasDepth);
|
||||
|
||||
mWriter_LineSize += stream->Write(ev, buf, pending);
|
||||
|
||||
mWriter_DictCharset = inNewForm;
|
||||
mWriter_DictForm = inNewForm;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1091,16 +1118,16 @@ morkWriter::StartDict(morkEnv* ev)
|
||||
stream->PutLineBreak(ev);
|
||||
mWriter_LineSize = 0;
|
||||
stream->PutLineBreak(ev);
|
||||
if ( mWriter_DictCharset || mWriter_DictAtomScope != 'a' )
|
||||
if ( mWriter_DictForm || mWriter_DictAtomScope != 'v' )
|
||||
{
|
||||
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);
|
||||
if ( mWriter_DictForm )
|
||||
this->WriteStringToTokenDictCell(ev, "(f=", mWriter_DictForm);
|
||||
if ( mWriter_DictAtomScope != 'v' )
|
||||
this->WriteStringToTokenDictCell(ev, "(a=", mWriter_DictAtomScope);
|
||||
|
||||
stream->Putc(ev, '>');
|
||||
++mWriter_LineSize;
|
||||
@ -1149,19 +1176,28 @@ morkWriter::StartTable(morkEnv* ev, morkTable* ioTable)
|
||||
*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_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);
|
||||
this->WriteTokenToTokenMetaCell(ev, morkStore_kKindColumn, tk);
|
||||
}
|
||||
|
||||
morkRow* r = ioTable->mTable_MetaRow;
|
||||
if ( r )
|
||||
{
|
||||
if ( r->IsRow() )
|
||||
this->PutRow(ev, r);
|
||||
else
|
||||
r->NonRowTypeError(ev);
|
||||
}
|
||||
|
||||
stream->Putc(ev, '}'); // end meta
|
||||
mWriter_LineSize = stream->PutIndent(ev, morkWriter_kRowCellDepth);
|
||||
}
|
||||
@ -1218,6 +1254,22 @@ morkWriter::PutRowDict(morkEnv* ev, morkRow* ioRow)
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkWriter::IsYarnAllValue(const mdbYarn* inYarn)
|
||||
{
|
||||
mork_fill fill = inYarn->mYarn_Fill;
|
||||
const mork_u1* buf = (const mork_u1*) inYarn->mYarn_Buf;
|
||||
const mork_u1* end = buf + fill;
|
||||
--buf; // prepare for preincrement
|
||||
while ( ++buf < end )
|
||||
{
|
||||
mork_ch c = *buf;
|
||||
if ( !morkCh_IsValue(c) )
|
||||
return morkBool_kFalse;
|
||||
}
|
||||
return morkBool_kTrue;
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkWriter::PutRowCells(morkEnv* ev, morkRow* ioRow)
|
||||
{
|
||||
@ -1243,17 +1295,39 @@ morkWriter::PutRowCells(morkEnv* ev, morkRow* ioRow)
|
||||
char* p = idBuf;
|
||||
colSize = ev->TokenAsHex(p, col);
|
||||
p += colSize;
|
||||
|
||||
mdbYarn yarn; // to ref content inside atom
|
||||
atom->AliasYarn(&yarn);
|
||||
|
||||
if ( atom->IsBook() ) // is it possible to write atom ID?
|
||||
{
|
||||
this->IndentAsNeeded(ev, morkWriter_kRowCellDepth);
|
||||
*p++ = '^';
|
||||
morkBookAtom* ba = (morkBookAtom*) atom;
|
||||
mork_size valSize = ev->TokenAsHex(p, ba->mBookAtom_Id);
|
||||
p += valSize;
|
||||
*p = ')';
|
||||
|
||||
mWriter_LineSize += stream->Write(ev, buf, colSize + valSize + 4);
|
||||
mork_size valSize = ev->TokenAsHex(p, ba->mBookAtom_Id);
|
||||
mork_fill yarnFill = yarn.mYarn_Fill;
|
||||
mork_bool putImmYarn = ( yarnFill <= valSize );
|
||||
if ( putImmYarn )
|
||||
putImmYarn = this->IsYarnAllValue(&yarn);
|
||||
|
||||
if ( putImmYarn ) // value no bigger than id?
|
||||
{
|
||||
p[ -1 ] = '='; // go back and clobber '^' with '=' instead
|
||||
if ( yarnFill )
|
||||
{
|
||||
MORK_MEMCPY(p, yarn.mYarn_Buf, yarnFill);
|
||||
p += yarnFill;
|
||||
}
|
||||
*p++ = ')';
|
||||
mWriter_LineSize += stream->Write(ev, buf, p - buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
p += valSize;
|
||||
*p = ')';
|
||||
mWriter_LineSize += stream->Write(ev, buf, colSize + valSize + 4);
|
||||
}
|
||||
|
||||
if ( atom->mAtom_Change == morkChange_kAdd )
|
||||
{
|
||||
@ -1263,11 +1337,8 @@ morkWriter::PutRowCells(morkEnv* ev, morkRow* ioRow)
|
||||
}
|
||||
else // must write an anonymous atom
|
||||
{
|
||||
mdbYarn yarn; // to ref content inside atom
|
||||
atom->AliasYarn(&yarn);
|
||||
|
||||
if ( yarn.mYarn_Form != mWriter_DictCharset )
|
||||
this->ChangeDictCharset(ev, yarn.mYarn_Form);
|
||||
if ( yarn.mYarn_Form != mWriter_DictForm )
|
||||
this->ChangeDictForm(ev, yarn.mYarn_Form);
|
||||
|
||||
mork_size pending = yarn.mYarn_Fill + colSize +
|
||||
morkWriter_kYarnEscapeSlop + 2;
|
||||
@ -1299,11 +1370,10 @@ morkWriter::PutRow(morkEnv* ev, morkRow* ioRow)
|
||||
mdbOid* roid = &ioRow->mRow_Oid;
|
||||
mork_size ridSize = 0;
|
||||
|
||||
this->IndentAsNeeded(ev, morkWriter_kRowDepth);
|
||||
|
||||
//if ( morkBool_kTrue )
|
||||
if ( ioRow->IsRowDirty() )
|
||||
{
|
||||
stream->PutIndent(ev, morkWriter_kRowDepth);
|
||||
|
||||
ioRow->SetRowClean();
|
||||
mork_rid rid = roid->mOid_Id;
|
||||
*p++ = '[';
|
||||
@ -1322,6 +1392,8 @@ morkWriter::PutRow(morkEnv* ev, morkRow* ioRow)
|
||||
}
|
||||
else
|
||||
{
|
||||
this->IndentAsNeeded(ev, morkWriter_kRowDepth);
|
||||
|
||||
if ( roid->mOid_Scope == mWriter_TableRowScope )
|
||||
ridSize = ev->TokenAsHex(p, roid->mOid_Id);
|
||||
else
|
||||
|
@ -103,6 +103,9 @@
|
||||
#define morkWriter_kRowCellDepth 4 /* */
|
||||
#define morkWriter_kRowCellValueDepth 6 /* */
|
||||
|
||||
// v=1.1 retired on 23-Mar-98
|
||||
#define morkWriter_kFileHeader "// <!-- <mdb:mork:z v=\"1.2\"/> -->"
|
||||
|
||||
class morkWriter : public morkNode { // row iterator
|
||||
|
||||
// public: // slots inherited from morkObject (meant to inform only)
|
||||
@ -131,18 +134,16 @@ public: // state is public because the entire Mork system is private
|
||||
mork_size mWriter_MaxIndent; // line size forcing a line break
|
||||
mork_size mWriter_MaxLine; // line size forcing a value continuation
|
||||
|
||||
mork_cscode mWriter_TableCharset; // current charset metainfo
|
||||
mork_cscode mWriter_TableForm; // current charset metainfo
|
||||
mork_scope mWriter_TableAtomScope; // current atom scope
|
||||
mork_scope mWriter_TableRowScope; // current row scope
|
||||
mork_scope mWriter_TableTableScope; // current table scope
|
||||
mork_scope mWriter_TableColumnScope; // current column scope
|
||||
mork_kind mWriter_TableKind; // current table kind
|
||||
|
||||
mork_cscode mWriter_RowCharset; // current charset metainfo
|
||||
mork_cscode mWriter_RowForm; // current charset metainfo
|
||||
mork_scope mWriter_RowAtomScope; // current atom scope
|
||||
mork_scope mWriter_RowScope; // current row scope
|
||||
|
||||
mork_cscode mWriter_DictCharset; // current charset metainfo
|
||||
mork_cscode mWriter_DictForm; // current charset metainfo
|
||||
mork_scope mWriter_DictAtomScope; // current atom scope
|
||||
|
||||
mork_bool mWriter_NeedDirtyAll; // need to call DirtyAll()
|
||||
@ -199,7 +200,7 @@ public: // typing & errors
|
||||
static void UnsupportedPhaseError(morkEnv* ev);
|
||||
|
||||
public: // inlines
|
||||
void ChangeDictCharset(morkEnv* ev, mork_cscode inNewForm);
|
||||
void ChangeDictForm(morkEnv* ev, mork_cscode inNewForm);
|
||||
mork_bool DidStartDict() const { return mWriter_DidStartDict; }
|
||||
mork_bool DidEndDict() const { return mWriter_DidEndDict; }
|
||||
|
||||
@ -269,6 +270,8 @@ public: // writing node content second pass
|
||||
|
||||
public: // other writer methods
|
||||
|
||||
mork_bool IsYarnAllValue(const mdbYarn* inYarn);
|
||||
|
||||
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
|
||||
|
@ -60,6 +60,10 @@
|
||||
#include "morkFile.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKWRITER_
|
||||
#include "morkWriter.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKSTORE_
|
||||
#include "morkStore.h"
|
||||
#endif
|
||||
@ -371,6 +375,7 @@ orkinFactory::CanOpenFilePort(
|
||||
{
|
||||
if ( inFilePath && inFirst512Bytes && outCanOpen )
|
||||
{
|
||||
canOpenAsPort = this->CanOpenMorkTextFile(ev, inFirst512Bytes);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
@ -448,6 +453,21 @@ orkinFactory::ThumbToOpenPort( // redeeming a completed thumb from OpenFilePort(
|
||||
}
|
||||
// } ----- end port methods -----
|
||||
|
||||
mork_bool
|
||||
orkinFactory::CanOpenMorkTextFile(morkEnv* ev,
|
||||
const mdbYarn* inFirst512Bytes)
|
||||
{
|
||||
mork_bool outBool = morkBool_kFalse;
|
||||
mork_size headSize = MORK_STRLEN(morkWriter_kFileHeader);
|
||||
const mdbYarn* y = inFirst512Bytes;
|
||||
if ( y && y->mYarn_Buf && y->mYarn_Fill >= headSize )
|
||||
{
|
||||
mork_u1* buf = (mork_u1*) y->mYarn_Buf;
|
||||
outBool = ( MORK_MEMCMP(morkWriter_kFileHeader, buf, headSize) == 0 );
|
||||
}
|
||||
return outBool;
|
||||
}
|
||||
|
||||
// { ----- begin store methods -----
|
||||
/*virtual*/ mdb_err
|
||||
orkinFactory::CanOpenFileStore(
|
||||
@ -468,8 +488,8 @@ orkinFactory::CanOpenFileStore(
|
||||
if ( inFilePath && inFirst512Bytes && outCanOpenAsStore )
|
||||
{
|
||||
// right now always say true; later we should look for magic patterns
|
||||
canOpenAsStore = morkBool_kTrue; // don't bother checking
|
||||
canOpenAsPort = morkBool_kTrue;
|
||||
canOpenAsStore = this->CanOpenMorkTextFile(ev, inFirst512Bytes);
|
||||
canOpenAsPort = canOpenAsStore;
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
|
@ -92,6 +92,8 @@ public: // utilities:
|
||||
mdb_err* outErr) const;
|
||||
|
||||
morkEnv* GetInternalFactoryEnv(mdb_err* outErr);
|
||||
|
||||
mork_bool CanOpenMorkTextFile(morkEnv* ev, const mdbYarn* inFirst512Bytes);
|
||||
|
||||
public: // type identification
|
||||
mork_bool IsOrkinFactory() const
|
||||
|
@ -48,6 +48,10 @@
|
||||
#include "morkRowObject.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKCELLOBJECT_
|
||||
#include "morkCellObject.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKSTORE_
|
||||
#include "morkStore.h"
|
||||
#endif
|
||||
@ -68,6 +72,10 @@
|
||||
#include "orkinRowCellCursor.h"
|
||||
#endif
|
||||
|
||||
#ifndef _ORKINCELL_
|
||||
#include "orkinCell.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
/* public virtual*/
|
||||
@ -463,7 +471,7 @@ orkinRow::CutColumn( // make sure a column is absent from the row
|
||||
&outErr, &row);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
row->CutColumn(ev, inColumn);
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
return outErr;
|
||||
@ -479,7 +487,7 @@ orkinRow::CutAllColumns( // remove all columns from the row
|
||||
&outErr, &row);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
row->CutAllColumns(ev);
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
return outErr;
|
||||
@ -539,7 +547,39 @@ orkinRow::AddCell( // copy a cell from another row to this row
|
||||
&outErr, &row);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
morkCell* cell = 0;
|
||||
orkinCell* ocell = (orkinCell*) inCell; // must verify this cast:
|
||||
if ( ocell->CanUseCell(mev, morkBool_kFalse, &outErr, &cell) )
|
||||
{
|
||||
morkCellObject* cellObj = (morkCellObject*) ocell->mHandle_Object;
|
||||
|
||||
morkRow* cellRow = cellObj->mCellObject_Row;
|
||||
if ( cellRow )
|
||||
{
|
||||
if ( row != cellRow )
|
||||
{
|
||||
morkStore* store = row->GetRowSpaceStore(ev);
|
||||
morkStore* cellStore = cellRow->GetRowSpaceStore(ev);
|
||||
if ( store && cellStore )
|
||||
{
|
||||
mork_column col = cell->GetColumn();
|
||||
morkAtom* atom = cell->mCell_Atom;
|
||||
mdbYarn yarn;
|
||||
atom->AliasYarn(&yarn); // works even when atom is nil
|
||||
|
||||
if ( store != cellStore )
|
||||
col = store->CopyToken(ev, col, cellStore);
|
||||
if ( ev->Good() )
|
||||
row->AddColumn(ev, col, &yarn, store);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
return outErr;
|
||||
@ -627,7 +667,11 @@ orkinRow::SetRow( // make exact duplicate of another row
|
||||
&outErr, &row);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
morkRow* source = 0;
|
||||
if ( this->CanUseRow(mev, morkBool_kFalse, &outErr, &source) )
|
||||
{
|
||||
row->SetRow(ev, source);
|
||||
}
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
return outErr;
|
||||
|
@ -677,6 +677,7 @@ orkinStore::NewTable( // make one new table of specific type
|
||||
mdb_scope inRowScope, // row scope for row ids
|
||||
mdb_kind inTableKind, // the type of table to access
|
||||
mdb_bool inMustBeUnique, // whether store can hold only one of these
|
||||
const mdbOid* inOptionalMetaRowOid, // can be nil to avoid specifying
|
||||
nsIMdbTable** acqTable) // acquire scoped collection of rows
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
@ -686,7 +687,7 @@ orkinStore::NewTable( // make one new table of specific type
|
||||
{
|
||||
morkTable* table =
|
||||
((morkStore*) mHandle_Object)->NewTable(ev, inRowScope,
|
||||
inTableKind, inMustBeUnique);
|
||||
inTableKind, inMustBeUnique, inOptionalMetaRowOid);
|
||||
if ( table && ev->Good() )
|
||||
outTable = table->AcquireTableHandle(ev);
|
||||
outErr = ev->AsErr();
|
||||
@ -695,6 +696,36 @@ orkinStore::NewTable( // make one new table of specific type
|
||||
*acqTable = outTable;
|
||||
return outErr;
|
||||
}
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinStore::NewTableWithOid( // make one new table of specific type
|
||||
nsIMdbEnv* mev, // context
|
||||
const mdbOid* inOid, // caller assigned oid
|
||||
mdb_kind inTableKind, // the type of table to access
|
||||
mdb_bool inMustBeUnique, // whether store can hold only one of these
|
||||
const mdbOid* inOptionalMetaRowOid, // can be nil to avoid specifying
|
||||
nsIMdbTable** acqTable) // acquire scoped collection of rows
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
nsIMdbTable* outTable = 0;
|
||||
morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
morkTable* table = ((morkStore*) mHandle_Object)->OidToTable(ev, inOid,
|
||||
inOptionalMetaRowOid);
|
||||
if ( table && ev->Good() )
|
||||
{
|
||||
table->mTable_Kind = inTableKind;
|
||||
if ( inMustBeUnique )
|
||||
table->mTable_MustBeUnique = inMustBeUnique;
|
||||
outTable = table->AcquireTableHandle(ev);
|
||||
}
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( acqTable )
|
||||
*acqTable = outTable;
|
||||
return outErr;
|
||||
}
|
||||
// } ----- end table methods -----
|
||||
|
||||
// { ----- begin row scope methods -----
|
||||
|
@ -274,6 +274,15 @@ public: // type identification
|
||||
mdb_scope inRowScope, // row scope for row ids
|
||||
mdb_kind inTableKind, // the type of table to access
|
||||
mdb_bool inMustBeUnique, // whether store can hold only one of these
|
||||
const mdbOid* inOptionalMetaRowOid, // can be nil to avoid specifying
|
||||
nsIMdbTable** acqTable); // acquire scoped collection of rows
|
||||
|
||||
virtual mdb_err NewTableWithOid( // make one new table of specific type
|
||||
nsIMdbEnv* ev, // context
|
||||
const mdbOid* inOid, // caller assigned oid
|
||||
mdb_kind inTableKind, // the type of table to access
|
||||
mdb_bool inMustBeUnique, // whether store can hold only one of these
|
||||
const mdbOid* inOptionalMetaRowOid, // can be nil to avoid specifying
|
||||
nsIMdbTable** acqTable); // acquire scoped collection of rows
|
||||
// } ----- end table methods -----
|
||||
|
||||
|
@ -383,6 +383,61 @@ orkinTable::GetRowScope(nsIMdbEnv* mev, mdb_scope* outRowScope)
|
||||
return outErr;
|
||||
}
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinTable::GetMetaRow( nsIMdbEnv* mev,
|
||||
const mdbOid* inOptionalMetaRowOid, // can be nil to avoid specifying
|
||||
mdbOid* outOid, // output meta row oid, can be nil to suppress output
|
||||
nsIMdbRow** acqRow) // acquire table's unique singleton meta row
|
||||
// The purpose of a meta row is to support the persistent recording of
|
||||
// meta info about a table as cells put into the distinguished meta row.
|
||||
// Each table has exactly one meta row, which is not considered a member
|
||||
// of the collection of rows inside the table. The only way to tell
|
||||
// whether a row is a meta row is by the fact that it is returned by this
|
||||
// GetMetaRow() method from some table. Otherwise nothing distinguishes
|
||||
// a meta row from any other row. A meta row can be used anyplace that
|
||||
// any other row can be used, and can even be put into other tables (or
|
||||
// the same table) as a table member, if this is useful for some reason.
|
||||
// The first attempt to access a table's meta row using GetMetaRow() will
|
||||
// cause the meta row to be created if it did not already exist. When the
|
||||
// meta row is created, it will have the row oid that was previously
|
||||
// requested for this table's meta row; or if no oid was ever explicitly
|
||||
// specified for this meta row, then a unique oid will be generated in
|
||||
// the row scope named "metaScope" (so obviously MDB clients should not
|
||||
// manually allocate any row IDs from that special meta scope namespace).
|
||||
// The meta row oid can be specified either when the table is created, or
|
||||
// else the first time that GetMetaRow() is called, by passing a non-nil
|
||||
// pointer to an oid for parameter inOptionalMetaRowOid. The meta row's
|
||||
// actual oid is returned in outOid (if this is a non-nil pointer), and
|
||||
// it will be different from inOptionalMetaRowOid when the meta row was
|
||||
// already given a different oid earlier.
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
nsIMdbRow* outRow = 0;
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
morkTable* table = (morkTable*) mHandle_Object;
|
||||
morkRow* row = table->GetMetaRow(ev, inOptionalMetaRowOid);
|
||||
if ( row && ev->Good() )
|
||||
{
|
||||
if ( outOid )
|
||||
*outOid = row->mRow_Oid;
|
||||
|
||||
outRow = row->AcquireRowHandle(ev, table->mTable_Store);
|
||||
}
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( acqRow )
|
||||
*acqRow = outRow;
|
||||
|
||||
if ( ev->Bad() && outOid )
|
||||
{
|
||||
outOid->mOid_Scope = 0;
|
||||
outOid->mOid_Id = morkRow_kMinusOneRid;
|
||||
}
|
||||
return outErr;
|
||||
}
|
||||
|
||||
// } ----- end attribute methods -----
|
||||
|
||||
// { ----- begin cursor methods -----
|
||||
@ -456,6 +511,23 @@ orkinTable::AddOid( // make sure the row with inOid is a table member
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinTable::HasOid( // test for the table position of a row member
|
||||
nsIMdbEnv* mev, // context
|
||||
const mdbOid* inOid, // row to find in table
|
||||
mdb_bool* outHasOid) // whether inOid is a member row
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
if ( outHasOid )
|
||||
*outHasOid = ((morkTable*) mHandle_Object)->MapHasOid(ev, inOid);
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
return outErr;
|
||||
}
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinTable::OidToPos( // test for the table position of a row member
|
||||
nsIMdbEnv* mev, // context
|
||||
const mdbOid* inOid, // row to find in table
|
||||
mdb_pos* outPos) // zero-based ordinal position of row in table
|
||||
@ -481,7 +553,17 @@ orkinTable::CutOid( // make sure the row with inOid is not a member
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
morkTable* table = (morkTable*) mHandle_Object;
|
||||
morkStore* store = table->mTable_Store;
|
||||
if ( inOid && store )
|
||||
{
|
||||
morkRow* row = store->GetRow(ev, inOid);
|
||||
if ( row )
|
||||
table->CutRow(ev, row);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
return outErr;
|
||||
@ -496,12 +578,30 @@ orkinTable::NewRow( // create a new row instance in table
|
||||
nsIMdbRow** acqRow) // create new row
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
nsIMdbRow* outRow = 0;
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
morkTable* table = (morkTable*) mHandle_Object;
|
||||
morkStore* store = table->mTable_Store;
|
||||
if ( ioOid && store )
|
||||
{
|
||||
morkRow* row = 0;
|
||||
if ( ioOid->mOid_Id == morkRow_kMinusOneRid )
|
||||
row = store->NewRow(ev, ioOid->mOid_Scope);
|
||||
else
|
||||
row = store->NewRowWithOid(ev, ioOid);
|
||||
|
||||
if ( row && table->AddRow(ev, row) )
|
||||
outRow = row->AcquireRowHandle(ev, store);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( acqRow )
|
||||
*acqRow = outRow;
|
||||
return outErr;
|
||||
}
|
||||
|
||||
@ -527,6 +627,30 @@ orkinTable::AddRow( // make sure the row with inOid is a table member
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinTable::HasRow( // test for the table position of a row member
|
||||
nsIMdbEnv* mev, // context
|
||||
nsIMdbRow* ioRow, // row to find in table
|
||||
mdb_bool* outBool) // zero-based ordinal position of row in table
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
morkRow* row = 0;
|
||||
orkinRow* orow = (orkinRow*) ioRow;
|
||||
if ( orow->CanUseRow(mev, /*inMutable*/ morkBool_kFalse, &outErr, &row) )
|
||||
{
|
||||
morkTable* table = (morkTable*) mHandle_Object;
|
||||
if ( outBool )
|
||||
*outBool = table->MapHasOid(ev, &row->mRow_Oid);
|
||||
}
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
return outErr;
|
||||
}
|
||||
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinTable::RowToPos( // test for the table position of a row member
|
||||
nsIMdbEnv* mev, // context
|
||||
nsIMdbRow* ioRow, // row to find in table
|
||||
mdb_pos* outPos) // zero-based ordinal position of row in table
|
||||
@ -535,7 +659,15 @@ orkinTable::HasRow( // test for the table position of a row member
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
morkRow* row = 0;
|
||||
orkinRow* orow = (orkinRow*) ioRow;
|
||||
if ( orow->CanUseRow(mev, /*inMutable*/ morkBool_kFalse, &outErr, &row) )
|
||||
{
|
||||
morkTable* table = (morkTable*) mHandle_Object;
|
||||
mork_pos pos = table->ArrayHasOid(ev, &row->mRow_Oid);
|
||||
if ( outPos )
|
||||
*outPos = pos;
|
||||
}
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
return outErr;
|
||||
@ -611,7 +743,7 @@ orkinTable::SearchColumnsHint( // advise re future expected search cols
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// ev->StubMethodOnlyError(); // legal to do nothing
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
return outErr;
|
||||
@ -626,7 +758,7 @@ orkinTable::SortColumnsHint( // advise re future expected sort columns
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// ev->StubMethodOnlyError(); // legal to do nothing
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
return outErr;
|
||||
@ -644,7 +776,7 @@ orkinTable::StartBatchChangeHint( // advise before many adds and cuts
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// ev->StubMethodOnlyError(); // legal to do nothing
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
return outErr;
|
||||
@ -668,7 +800,7 @@ orkinTable::EndBatchChangeHint( // advise before many adds and cuts
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// ev->StubMethodOnlyError(); // legal to do nothing
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
return outErr;
|
||||
@ -689,7 +821,9 @@ orkinTable::CanSortColumn( // query which col is currently used for sorting
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
if ( outCanSort )
|
||||
*outCanSort = morkBool_kFalse;
|
||||
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
return outErr;
|
||||
@ -703,12 +837,15 @@ orkinTable::NewSortColumn( // change col used for sorting in the table
|
||||
nsIMdbThumb** acqThumb) // acquire thumb for incremental table resort
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
nsIMdbThumb* outThumb = 0;
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( acqThumb )
|
||||
*acqThumb = outThumb;
|
||||
return outErr;
|
||||
}
|
||||
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
|
||||
@ -723,12 +860,15 @@ orkinTable::NewSortColumnWithCompare( // change sort col w/ explicit compare
|
||||
nsIMdbThumb** acqThumb) // acquire thumb for incremental table resort
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
nsIMdbThumb* outThumb = 0;
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( acqThumb )
|
||||
*acqThumb = outThumb;
|
||||
return outErr;
|
||||
}
|
||||
// Note the table will hold a reference to inCompare if this object is used
|
||||
@ -743,12 +883,15 @@ orkinTable::GetSortColumn( // query which col is currently sorted
|
||||
mdb_column* outColumn) // col the table uses for sorting (or zero)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
mdb_column col = 0;
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( outColumn )
|
||||
*outColumn = col;
|
||||
return outErr;
|
||||
}
|
||||
|
||||
@ -760,12 +903,15 @@ orkinTable::CloneSortColumn( // view same table with a different sort
|
||||
nsIMdbThumb** acqThumb) // acquire thumb for incremental table clone
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
nsIMdbThumb* outThumb = 0;
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( acqThumb )
|
||||
*acqThumb = outThumb;
|
||||
return outErr;
|
||||
}
|
||||
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
|
||||
@ -778,12 +924,15 @@ orkinTable::ThumbToCloneSortTable( // redeem complete CloneSortColumn() thumb
|
||||
nsIMdbTable** acqTable) // new table instance (or old if sort unchanged)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
nsIMdbTable* outTable = 0;
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( acqTable )
|
||||
*acqTable = outTable;
|
||||
return outErr;
|
||||
}
|
||||
// } ----- end sorting methods -----
|
||||
@ -841,7 +990,8 @@ orkinTable::AddIndex( // create a sorting index for column if possible
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// ev->StubMethodOnlyError(); // legal to do nothing
|
||||
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
return outErr;
|
||||
@ -859,7 +1009,8 @@ orkinTable::CutIndex( // stop supporting a specific column index
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// ev->StubMethodOnlyError(); // legal to do nothing
|
||||
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
return outErr;
|
||||
@ -875,7 +1026,9 @@ orkinTable::HasIndex( // query for current presence of a column index
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
if ( outHasIndex )
|
||||
*outHasIndex = morkBool_kFalse;
|
||||
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
return outErr;
|
||||
@ -890,7 +1043,7 @@ orkinTable::EnableIndexOnSort( // create an index for col on first sort
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// ev->StubMethodOnlyError(); // legal to do nothing
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
return outErr;
|
||||
@ -906,7 +1059,9 @@ orkinTable::QueryIndexOnSort( // check whether index on sort is enabled
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
if ( outIndexOnSort )
|
||||
*outIndexOnSort = morkBool_kFalse;
|
||||
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
return outErr;
|
||||
@ -921,7 +1076,7 @@ orkinTable::DisableIndexOnSort( // prevent future index creation on sort
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// ev->StubMethodOnlyError(); // legal to do nothing
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
return outErr;
|
||||
|
@ -35,7 +35,7 @@
|
||||
#include "morkHandle.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKTable_
|
||||
#ifndef _MORKTABLE_
|
||||
#include "morkTable.h"
|
||||
#endif
|
||||
|
||||
@ -164,11 +164,38 @@ public: // type identification
|
||||
|
||||
// { ===== begin nsIMdbTable methods =====
|
||||
|
||||
// { ----- begin attribute methods -----
|
||||
// { ----- begin meta attribute methods -----
|
||||
virtual mdb_err GetTableKind(nsIMdbEnv* ev, mdb_kind* outTableKind);
|
||||
virtual mdb_err GetRowScope(nsIMdbEnv* ev, mdb_scope* outRowScope);
|
||||
|
||||
// } ----- end attribute methods -----
|
||||
virtual mdb_err GetMetaRow(
|
||||
nsIMdbEnv* ev, // context
|
||||
const mdbOid* inOptionalMetaRowOid, // can be nil to avoid specifying
|
||||
mdbOid* outOid, // output meta row oid, can be nil to suppress output
|
||||
nsIMdbRow** acqRow); // acquire table's unique singleton meta row
|
||||
// The purpose of a meta row is to support the persistent recording of
|
||||
// meta info about a table as cells put into the distinguished meta row.
|
||||
// Each table has exactly one meta row, which is not considered a member
|
||||
// of the collection of rows inside the table. The only way to tell
|
||||
// whether a row is a meta row is by the fact that it is returned by this
|
||||
// GetMetaRow() method from some table. Otherwise nothing distinguishes
|
||||
// a meta row from any other row. A meta row can be used anyplace that
|
||||
// any other row can be used, and can even be put into other tables (or
|
||||
// the same table) as a table member, if this is useful for some reason.
|
||||
// The first attempt to access a table's meta row using GetMetaRow() will
|
||||
// cause the meta row to be created if it did not already exist. When the
|
||||
// meta row is created, it will have the row oid that was previously
|
||||
// requested for this table's meta row; or if no oid was ever explicitly
|
||||
// specified for this meta row, then a unique oid will be generated in
|
||||
// the row scope named "metaScope" (so obviously MDB clients should not
|
||||
// manually allocate any row IDs from that special meta scope namespace).
|
||||
// The meta row oid can be specified either when the table is created, or
|
||||
// else the first time that GetMetaRow() is called, by passing a non-nil
|
||||
// pointer to an oid for parameter inOptionalMetaRowOid. The meta row's
|
||||
// actual oid is returned in outOid (if this is a non-nil pointer), and
|
||||
// it will be different from inOptionalMetaRowOid when the meta row was
|
||||
// already given a different oid earlier.
|
||||
// } ----- end meta attribute methods -----
|
||||
|
||||
// { ----- begin cursor methods -----
|
||||
virtual mdb_err GetTableRowCursor( // make a cursor, starting iteration at inRowPos
|
||||
@ -183,7 +210,11 @@ public: // type identification
|
||||
mdb_pos inRowPos, // zero-based ordinal position of row in table
|
||||
mdbOid* outOid); // row oid at the specified position
|
||||
|
||||
// Note that HasRow() performs the inverse oid->pos mapping
|
||||
virtual mdb_err RowToPos( // test for the table position of a row member
|
||||
nsIMdbEnv* ev, // context
|
||||
nsIMdbRow* ioRow, // row to find in table
|
||||
mdb_pos* outPos); // zero-based ordinal position of row in table
|
||||
|
||||
// } ----- end row position methods -----
|
||||
|
||||
// { ----- begin oid set methods -----
|
||||
@ -192,6 +223,11 @@ public: // type identification
|
||||
const mdbOid* inOid); // row to ensure membership in table
|
||||
|
||||
virtual mdb_err HasOid( // test for the table position of a row member
|
||||
nsIMdbEnv* ev, // context
|
||||
const mdbOid* inOid, // row to find in table
|
||||
mdb_bool* outHasOid); // whether inOid is a member row
|
||||
|
||||
virtual mdb_err OidToPos( // test for the table position of a row member
|
||||
nsIMdbEnv* ev, // context
|
||||
const mdbOid* inOid, // row to find in table
|
||||
mdb_pos* outPos); // zero-based ordinal position of row in table
|
||||
@ -214,7 +250,7 @@ public: // type identification
|
||||
virtual mdb_err HasRow( // test for the table position of a row member
|
||||
nsIMdbEnv* ev, // context
|
||||
nsIMdbRow* ioRow, // row to find in table
|
||||
mdb_pos* outPos); // zero-based ordinal position of row in table
|
||||
mdb_bool* outHasRow); // whether row is a table member
|
||||
|
||||
virtual mdb_err CutRow( // make sure the row with inOid is not a member
|
||||
nsIMdbEnv* ev, // context
|
||||
|
@ -144,7 +144,7 @@ nsresult nsDBFolderInfo::AddToNewMDB()
|
||||
nsIMdbStore *store = m_mdb->GetStore();
|
||||
// create the unique table for the dbFolderInfo.
|
||||
mdb_err err = store->NewTable(m_mdb->GetEnv(), m_rowScopeToken,
|
||||
m_tableKindToken, PR_TRUE, &m_mdbTable);
|
||||
m_tableKindToken, PR_TRUE, nsnull, &m_mdbTable);
|
||||
|
||||
// make sure the oid of the table is 1.
|
||||
struct mdbOid folderInfoTableOID;
|
||||
@ -179,6 +179,7 @@ nsresult nsDBFolderInfo::InitFromExistingDB()
|
||||
mdb_pos rowPos;
|
||||
mdb_count outTableCount; // current number of such tables
|
||||
mdb_bool mustBeUnique; // whether port can hold only one of these
|
||||
mdb_bool hasOid;
|
||||
ret = store->GetTableKind(m_mdb->GetEnv(), m_rowScopeToken, m_tableKindToken, &outTableCount,
|
||||
&mustBeUnique, &m_mdbTable);
|
||||
// NS_ASSERTION(mustBeUnique && outTableCount == 1, "only one global db info allowed");
|
||||
@ -186,7 +187,7 @@ nsresult nsDBFolderInfo::InitFromExistingDB()
|
||||
if (m_mdbTable)
|
||||
{
|
||||
// find singleton row for global info.
|
||||
ret = m_mdbTable->HasOid(m_mdb->GetEnv(), &gDBFolderInfoOID, &rowPos);
|
||||
ret = m_mdbTable->HasOid(m_mdb->GetEnv(), &gDBFolderInfoOID, &hasOid);
|
||||
if (ret == NS_OK)
|
||||
{
|
||||
nsIMdbTableRowCursor *rowCursor;
|
||||
|
@ -27,6 +27,8 @@
|
||||
#include "nsRDFCID.h"
|
||||
#include "nsIRDFResource.h"
|
||||
|
||||
#include "nsFileStream.h"
|
||||
|
||||
#include "nsIMimeHeaderConverter.h"
|
||||
//#include "nsMimeHeaderConverter.h"
|
||||
|
||||
@ -37,6 +39,7 @@
|
||||
#include "nsCollationCID.h"
|
||||
#include "nsIPref.h"
|
||||
|
||||
|
||||
static NS_DEFINE_IID(kIPrefIID, NS_IPREF_IID);
|
||||
static NS_DEFINE_CID(kPrefCID, NS_PREF_CID);
|
||||
|
||||
@ -448,13 +451,37 @@ NS_IMETHODIMP nsMsgDatabase::OpenMDB(const char *dbName, PRBool create)
|
||||
else
|
||||
{
|
||||
mdbOpenPolicy inOpenPolicy;
|
||||
mdb_bool canOpen;
|
||||
mdbYarn outFormatVersion;
|
||||
char bufFirst512Bytes[512];
|
||||
mdbYarn first512Bytes;
|
||||
|
||||
inOpenPolicy.mOpenPolicy_ScopePlan.mScopeStringSet_Count = 0;
|
||||
inOpenPolicy.mOpenPolicy_MinMemory = 0;
|
||||
inOpenPolicy.mOpenPolicy_MaxLazy = 0;
|
||||
first512Bytes.mYarn_Buf = bufFirst512Bytes;
|
||||
first512Bytes.mYarn_Size = 512;
|
||||
first512Bytes.mYarn_Fill = 512;
|
||||
first512Bytes.mYarn_Form = 0; // what to do with this? we're storing csid in the msg hdr...
|
||||
|
||||
ret = myMDBFactory->OpenFileStore(m_mdbEnv, NULL, nativeFileName, &inOpenPolicy,
|
||||
&thumb);
|
||||
{
|
||||
nsIOFileStream *dbStream = new nsIOFileStream(nsFileSpec(dbName));
|
||||
PRInt32 bytesRead = dbStream->read(bufFirst512Bytes, sizeof(bufFirst512Bytes));
|
||||
first512Bytes.mYarn_Fill = bytesRead;
|
||||
dbStream->close();
|
||||
delete dbStream;
|
||||
}
|
||||
ret = myMDBFactory->CanOpenFilePort(m_mdbEnv, nativeFileName, // the file to investigate
|
||||
&first512Bytes, &canOpen, &outFormatVersion);
|
||||
if (ret == 0 && canOpen)
|
||||
{
|
||||
|
||||
inOpenPolicy.mOpenPolicy_ScopePlan.mScopeStringSet_Count = 0;
|
||||
inOpenPolicy.mOpenPolicy_MinMemory = 0;
|
||||
inOpenPolicy.mOpenPolicy_MaxLazy = 0;
|
||||
|
||||
ret = myMDBFactory->OpenFileStore(m_mdbEnv, NULL, nativeFileName, &inOpenPolicy,
|
||||
&thumb);
|
||||
}
|
||||
else
|
||||
ret = NS_MSG_ERROR_FOLDER_SUMMARY_OUT_OF_DATE;
|
||||
}
|
||||
if (NS_SUCCEEDED(ret) && thumb)
|
||||
{
|
||||
@ -627,7 +654,7 @@ nsresult nsMsgDatabase::InitNewDB()
|
||||
nsIMdbStore *store = GetStore();
|
||||
// create the unique table for the dbFolderInfo.
|
||||
mdb_err err = store->NewTable(GetEnv(), m_hdrRowScopeToken,
|
||||
m_hdrTableKindToken, PR_FALSE, &m_mdbAllMsgHeadersTable);
|
||||
m_hdrTableKindToken, PR_FALSE, nsnull, &m_mdbAllMsgHeadersTable);
|
||||
// m_mdbAllMsgHeadersTable->BecomeContent(GetEnv(), &gAllMsgHdrsTableOID);
|
||||
m_dbFolderInfo = dbFolderInfo;
|
||||
|
||||
@ -701,8 +728,7 @@ nsresult nsMsgDatabase::InitMDBInfo()
|
||||
NS_IMETHODIMP nsMsgDatabase::GetMsgHdrForKey(nsMsgKey key, nsIMessage **pmsgHdr)
|
||||
{
|
||||
nsresult err = NS_OK;
|
||||
mdb_pos rowPos;
|
||||
mdb_pos desiredRowPos;
|
||||
mdb_bool hasOid;
|
||||
mdbOid rowObjectId;
|
||||
|
||||
|
||||
@ -712,29 +738,15 @@ NS_IMETHODIMP nsMsgDatabase::GetMsgHdrForKey(nsMsgKey key, nsIMessage **pmsgHdr)
|
||||
*pmsgHdr = NULL;
|
||||
rowObjectId.mOid_Id = key;
|
||||
rowObjectId.mOid_Scope = m_hdrRowScopeToken;
|
||||
err = m_mdbAllMsgHeadersTable->HasOid(GetEnv(), &rowObjectId, &desiredRowPos);
|
||||
if (err == NS_OK)
|
||||
err = m_mdbAllMsgHeadersTable->HasOid(GetEnv(), &rowObjectId, &hasOid);
|
||||
if (err == NS_OK && m_mdbStore)
|
||||
{
|
||||
nsIMdbTableRowCursor* rowCursor;
|
||||
rowPos = -1;
|
||||
err = m_mdbAllMsgHeadersTable->GetTableRowCursor(GetEnv(), rowPos, &rowCursor);
|
||||
if (err == NS_OK && rowCursor /*rowPos >= 0*/) // ### is rowPos > 0 the right thing to check?
|
||||
{
|
||||
do
|
||||
{
|
||||
nsIMdbRow *hdrRow;
|
||||
err = rowCursor->NextRow(GetEnv(), &hdrRow, &rowPos);
|
||||
if (!NS_SUCCEEDED(err) || rowPos < 0 || !hdrRow)
|
||||
break;
|
||||
if (rowPos == desiredRowPos)
|
||||
{
|
||||
err = CreateMsgHdr(hdrRow, m_dbName, key, pmsgHdr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (TRUE);
|
||||
nsIMdbRow *hdrRow;
|
||||
|
||||
NS_RELEASE(rowCursor);
|
||||
err = m_mdbStore->GetRow(GetEnv(), &rowObjectId, &hdrRow);
|
||||
if (err == NS_OK && hdrRow)
|
||||
{
|
||||
err = CreateMsgHdr(hdrRow, m_dbName, key, pmsgHdr);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user