add FindRow api, fix lots of warnings, speed up msg threading
This commit is contained in:
Родитель
10dc94a5a3
Коммит
9f481ea375
|
@ -939,16 +939,54 @@ public:
|
|||
nsIMdbEnv* ev, // context
|
||||
const mdbOid* inOid, // hypothetical row oid
|
||||
mdb_bool* outHasRow) = 0; // whether GetRow() might succeed
|
||||
|
||||
virtual mdb_err GetRowRefCount( // get number of tables that contain a row
|
||||
nsIMdbEnv* ev, // context
|
||||
const mdbOid* inOid, // hypothetical row oid
|
||||
mdb_count* outRefCount) = 0; // number of tables containing inRowKey
|
||||
|
||||
virtual mdb_err GetRow( // access one row with specific oid
|
||||
nsIMdbEnv* ev, // context
|
||||
const mdbOid* inOid, // hypothetical row oid
|
||||
nsIMdbRow** acqRow) = 0; // acquire specific row (or null)
|
||||
|
||||
virtual mdb_err GetRowRefCount( // get number of tables that contain a row
|
||||
nsIMdbEnv* ev, // context
|
||||
const mdbOid* inOid, // hypothetical row oid
|
||||
mdb_count* outRefCount) = 0; // number of tables containing inRowKey
|
||||
virtual mdb_err FindRow(nsIMdbEnv* ev, // search for row with matching cell
|
||||
mdb_scope inRowScope, // row scope for row ids
|
||||
mdb_column inColumn, // the column to search (and maintain an index)
|
||||
const mdbYarn* inTargetCellValue, // cell value for which to search
|
||||
mdbOid* outRowOid, // out row oid on match (or {0,-1} for no match)
|
||||
nsIMdbRow** acqRow) = 0; // acquire matching row (or nil for no match)
|
||||
// FindRow() searches for one row that has a cell in column inColumn with
|
||||
// a contained value with the same form (i.e. charset) and is byte-wise
|
||||
// identical to the blob described by yarn inTargetCellValue. Both content
|
||||
// and form of the yarn must be an exact match to find a matching row.
|
||||
//
|
||||
// (In other words, both a yarn's blob bytes and form are significant. The
|
||||
// form is not expected to vary in columns used for identity anyway. This
|
||||
// is intended to make the cost of FindRow() cheaper for MDB implementors,
|
||||
// since any cell value atomization performed internally must necessarily
|
||||
// make yarn form significant in order to avoid data loss in atomization.)
|
||||
//
|
||||
// FindRow() can lazily create an index on attribute inColumn for all rows
|
||||
// with that attribute in row space scope inRowScope, so that subsequent
|
||||
// calls to FindRow() will perform faster. Such an index might or might
|
||||
// not be persistent (but this seems desirable if it is cheap to do so).
|
||||
// Note that lazy index creation in readonly DBs is not very feasible.
|
||||
//
|
||||
// This FindRow() interface assumes that attribute inColumn is effectively
|
||||
// an alternative means of unique identification for a row in a rowspace,
|
||||
// so correct behavior is only guaranteed when no duplicates for this col
|
||||
// appear in the given set of rows. (If more than one row has the same cell
|
||||
// value in this column, no more than one will be found; and cutting one of
|
||||
// two duplicate rows can cause the index to assume no other such row lives
|
||||
// in the row space, so future calls return nil for negative search results
|
||||
// even though some duplicate row might still live within the rowspace.)
|
||||
//
|
||||
// In other words, the FindRow() implementation is allowed to assume simple
|
||||
// hash tables mapping unqiue column keys to associated row values will be
|
||||
// sufficient, where any duplication is not recorded because only one copy
|
||||
// of a given key need be remembered. Implementors are not required to sort
|
||||
// all rows by the specified column.
|
||||
// } ----- end row methods -----
|
||||
|
||||
// { ----- begin table methods -----
|
||||
|
@ -1116,6 +1154,7 @@ public:
|
|||
nsIMdbRow** acqRow) = 0; // create new row
|
||||
// Note this row must be added to some table or cell child before the
|
||||
// store is closed in order to make this row persist across sesssions.
|
||||
|
||||
// } ----- end row methods -----
|
||||
|
||||
// { ----- begin inport/export methods -----
|
||||
|
|
|
@ -230,7 +230,7 @@ morkArray::AppendSlot(morkEnv* ev, void* ioSlot)
|
|||
mork_fill fill = mArray_Fill;
|
||||
if ( this->Grow(ev, fill+1) )
|
||||
{
|
||||
outPos = fill;
|
||||
outPos = (mork_pos) fill;
|
||||
mArray_Slots[ fill ] = ioSlot;
|
||||
mArray_Fill = fill + 1;
|
||||
// note Grow() increments mArray_Seed
|
||||
|
@ -269,6 +269,7 @@ morkArray::AddSlot(morkEnv* ev, mork_pos inPos, void* ioSlot)
|
|||
void
|
||||
morkArray::CutSlot(morkEnv* ev, mork_pos inPos)
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
mork_fill fill = mArray_Fill;
|
||||
if ( inPos >= 0 && inPos < (mork_pos) fill ) // cutting slot in used array portion?
|
||||
{
|
||||
|
|
|
@ -204,15 +204,40 @@ morkAtom::AliasYarn(mdbYarn* outYarn) const
|
|||
return ( atom != 0 );
|
||||
}
|
||||
|
||||
mork_aid
|
||||
morkAtom::GetBookAtomAid() const // zero or book atom's ID
|
||||
{
|
||||
return ( this->IsBook() )? ((morkBookAtom*) this)->mBookAtom_Id : 0;
|
||||
}
|
||||
|
||||
mork_scope
|
||||
morkAtom::GetBookAtomSpaceScope(morkEnv* ev) const // zero or book's space's scope
|
||||
{
|
||||
mork_scope outScope = 0;
|
||||
if ( this->IsBook() )
|
||||
{
|
||||
const morkBookAtom* bookAtom = (const morkBookAtom*) this;
|
||||
morkAtomSpace* space = bookAtom->mBookAtom_Space;
|
||||
if ( space->IsAtomSpace() )
|
||||
outScope = space->mSpace_Scope;
|
||||
else
|
||||
space->NonAtomSpaceTypeError(ev);
|
||||
}
|
||||
|
||||
return outScope;
|
||||
}
|
||||
|
||||
void
|
||||
morkAtom::MakeCellUseForever(morkEnv* ev)
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
mAtom_CellUses = morkAtom_kForeverCellUses;
|
||||
}
|
||||
|
||||
mork_u1
|
||||
morkAtom::AddCellUse(morkEnv* ev)
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
if ( mAtom_CellUses < morkAtom_kMaxCellUses ) // not already maxed out?
|
||||
++mAtom_CellUses;
|
||||
|
||||
|
@ -260,6 +285,7 @@ morkAtom::AtomSizeOverflowError(morkEnv* ev)
|
|||
void
|
||||
morkOidAtom::InitRowOidAtom(morkEnv* ev, const mdbOid& inOid)
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
mAtom_CellUses = 0;
|
||||
mAtom_Kind = morkAtom_kKindRowOid;
|
||||
mAtom_Change = morkChange_kNil;
|
||||
|
@ -270,6 +296,7 @@ morkOidAtom::InitRowOidAtom(morkEnv* ev, const mdbOid& inOid)
|
|||
void
|
||||
morkOidAtom::InitTableOidAtom(morkEnv* ev, const mdbOid& inOid)
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
mAtom_CellUses = 0;
|
||||
mAtom_Kind = morkAtom_kKindTableOid;
|
||||
mAtom_Change = morkChange_kNil;
|
||||
|
@ -301,6 +328,7 @@ void
|
|||
morkBigAnonAtom::InitBigAnonAtom(morkEnv* ev, const morkBuf& inBuf,
|
||||
mork_cscode inForm)
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
mAtom_CellUses = 0;
|
||||
mAtom_Kind = morkAtom_kKindBigAnon;
|
||||
mAtom_Change = morkChange_kNil;
|
||||
|
|
|
@ -60,6 +60,14 @@ public:
|
|||
|
||||
mork_bool IsBook() const { return this->IsWeeBook() || this->IsBigBook(); }
|
||||
|
||||
public: // atom space scope if IsBook() is true, or else zero:
|
||||
|
||||
mork_scope GetBookAtomSpaceScope(morkEnv* ev) const;
|
||||
// zero or book's space's scope
|
||||
|
||||
mork_aid GetBookAtomAid() const;
|
||||
// zero or book atom's ID
|
||||
|
||||
public: // empty construction does nothing
|
||||
morkAtom() { }
|
||||
|
||||
|
|
|
@ -44,6 +44,14 @@
|
|||
#include "morkAtom.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKINTMAP_
|
||||
#include "morkIntMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKROW_
|
||||
#include "morkRow.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
|
@ -103,6 +111,7 @@ morkAtomAidMap::CloseAtomAidMap(morkEnv* ev) // called by CloseMorkNode();
|
|||
morkAtomAidMap::Equal(morkEnv* ev, const void* inKeyA,
|
||||
const void* inKeyB) const
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
return (*(const morkBookAtom**) inKeyA)->EqualAid(
|
||||
*(const morkBookAtom**) inKeyB);
|
||||
}
|
||||
|
@ -110,6 +119,7 @@ morkAtomAidMap::Equal(morkEnv* ev, const void* inKeyA,
|
|||
/*virtual*/ mork_u4 //
|
||||
morkAtomAidMap::Hash(morkEnv* ev, const void* inKey) const
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
return (*(const morkBookAtom**) inKey)->HashAid();
|
||||
}
|
||||
// } ===== end morkMap poly interface =====
|
||||
|
@ -261,3 +271,35 @@ morkAtomBodyMap::GetAtom(morkEnv* ev, const morkBookAtom* inAtom)
|
|||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
morkAtomRowMap::~morkAtomRowMap()
|
||||
{
|
||||
}
|
||||
|
||||
morkAtomRowMap::morkAtomRowMap(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap, mork_column inIndexColumn)
|
||||
: morkIntMap(ev, inUsage, sizeof(mork_aid), ioHeap, ioSlotHeap,
|
||||
/*inHoldChanges*/ morkBool_kFalse)
|
||||
, mAtomRowMap_IndexColumn( inIndexColumn )
|
||||
{
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kAtomRowMap;
|
||||
}
|
||||
|
||||
void morkAtomRowMap::AddRow(morkEnv* ev, morkRow* ioRow)
|
||||
// add ioRow only if it contains a cell in mAtomRowMap_IndexColumn.
|
||||
{
|
||||
mork_aid aid = ioRow->GetCellAtomAid(ev, mAtomRowMap_IndexColumn);
|
||||
if ( aid )
|
||||
this->AddAid(ev, aid, ioRow);
|
||||
}
|
||||
|
||||
void morkAtomRowMap::CutRow(morkEnv* ev, morkRow* ioRow)
|
||||
// cut ioRow only if it contains a cell in mAtomRowMap_IndexColumn.
|
||||
{
|
||||
mork_aid aid = ioRow->GetCellAtomAid(ev, mAtomRowMap_IndexColumn);
|
||||
if ( aid )
|
||||
this->CutAid(ev, aid);
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
#include "morkMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKINTMAP_
|
||||
#include "morkIntMap.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#define morkDerived_kAtomAidMap /*i*/ 0x6141 /* ascii 'aA' */
|
||||
|
@ -81,6 +85,15 @@ public: // other map methods
|
|||
// GetAid() returns the atom equal to inAid, or else nil
|
||||
|
||||
// note the atoms are owned elsewhere, usuall by morkAtomSpace
|
||||
|
||||
public: // typesafe refcounting inlines calling inherited morkNode methods
|
||||
static void SlotWeakAtomAidMap(morkAtomAidMap* me,
|
||||
morkEnv* ev, morkAtomAidMap** ioSlot)
|
||||
{ morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
|
||||
static void SlotStrongAtomAidMap(morkAtomAidMap* me,
|
||||
morkEnv* ev, morkAtomAidMap** ioSlot)
|
||||
{ morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -157,6 +170,15 @@ public: // other map methods
|
|||
// GetAtom() returns the atom equal to inAtom, or else nil
|
||||
|
||||
// note the atoms are owned elsewhere, usuall by morkAtomSpace
|
||||
|
||||
public: // typesafe refcounting inlines calling inherited morkNode methods
|
||||
static void SlotWeakAtomBodyMap(morkAtomBodyMap* me,
|
||||
morkEnv* ev, morkAtomBodyMap** ioSlot)
|
||||
{ morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
|
||||
static void SlotStrongAtomBodyMap(morkAtomBodyMap* me,
|
||||
morkEnv* ev, morkAtomBodyMap** ioSlot)
|
||||
{ morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
};
|
||||
|
||||
class morkAtomBodyMapIter: public morkMapIter{ // typesafe wrapper class
|
||||
|
@ -182,6 +204,88 @@ public:
|
|||
{ return this->CutHere(ev, outAtomPtr, /*val*/ (void*) 0); }
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#define morkDerived_kAtomRowMap /*i*/ 0x6152 /* ascii 'aR' */
|
||||
|
||||
/*| morkAtomRowMap: maps morkAtom* -> morkRow*
|
||||
|*/
|
||||
class morkAtomRowMap : public morkIntMap { // for mapping atoms to rows
|
||||
|
||||
public:
|
||||
mork_column mAtomRowMap_IndexColumn; // row column being indexed
|
||||
|
||||
public:
|
||||
|
||||
virtual ~morkAtomRowMap();
|
||||
morkAtomRowMap(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap, mork_column inIndexColumn);
|
||||
|
||||
public: // adding and cutting from morkRow instance candidate
|
||||
|
||||
void AddRow(morkEnv* ev, morkRow* ioRow);
|
||||
// add ioRow only if it contains a cell in mAtomRowMap_IndexColumn.
|
||||
|
||||
void CutRow(morkEnv* ev, morkRow* ioRow);
|
||||
// cut ioRow only if it contains a cell in mAtomRowMap_IndexColumn.
|
||||
|
||||
public: // other map methods
|
||||
|
||||
mork_bool AddAid(morkEnv* ev, mork_aid inAid, morkRow* ioRow)
|
||||
{ return this->AddInt(ev, inAid, ioRow); }
|
||||
// the AddAid() boolean return equals ev->Good().
|
||||
|
||||
mork_bool CutAid(morkEnv* ev, mork_aid inAid)
|
||||
{ return this->CutInt(ev, inAid); }
|
||||
// The CutAid() boolean return indicates whether removal happened.
|
||||
|
||||
morkRow* GetAid(morkEnv* ev, mork_aid inAid)
|
||||
{ return (morkRow*) this->GetInt(ev, inAid); }
|
||||
// Note the returned space does NOT have an increase in refcount for this.
|
||||
|
||||
public: // dynamic type identification
|
||||
mork_bool IsAtomRowMap() const
|
||||
{ return IsNode() && mNode_Derived == morkDerived_kAtomRowMap; }
|
||||
|
||||
public: // typesafe refcounting inlines calling inherited morkNode methods
|
||||
static void SlotWeakAtomRowMap(morkAtomRowMap* me,
|
||||
morkEnv* ev, morkAtomRowMap** ioSlot)
|
||||
{ morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
|
||||
static void SlotStrongAtomRowMap(morkAtomRowMap* me,
|
||||
morkEnv* ev, morkAtomRowMap** ioSlot)
|
||||
{ morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
|
||||
};
|
||||
|
||||
class morkAtomRowMapIter: public morkMapIter{ // typesafe wrapper class
|
||||
|
||||
public:
|
||||
morkAtomRowMapIter(morkEnv* ev, morkAtomRowMap* ioMap)
|
||||
: morkMapIter(ev, ioMap) { }
|
||||
|
||||
morkAtomRowMapIter( ) : morkMapIter() { }
|
||||
void InitAtomRowMapIter(morkEnv* ev, morkAtomRowMap* ioMap)
|
||||
{ this->InitMapIter(ev, ioMap); }
|
||||
|
||||
mork_change*
|
||||
FirstAtomAndRow(morkEnv* ev, morkAtom** outAtom, morkRow** outRow)
|
||||
{ return this->First(ev, outAtom, outRow); }
|
||||
|
||||
mork_change*
|
||||
NextAtomAndRow(morkEnv* ev, morkAtom** outAtom, morkRow** outRow)
|
||||
{ return this->Next(ev, outAtom, outRow); }
|
||||
|
||||
mork_change*
|
||||
HereAtomAndRow(morkEnv* ev, morkAtom** outAtom, morkRow** outRow)
|
||||
{ return this->Here(ev, outAtom, outRow); }
|
||||
|
||||
mork_change*
|
||||
CutHereAtomAndRow(morkEnv* ev, morkAtom** outAtom, morkRow** outRow)
|
||||
{ return this->CutHere(ev, outAtom, outRow); }
|
||||
};
|
||||
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKATOMMAP_ */
|
||||
|
|
|
@ -186,28 +186,28 @@ morkAtomSpace::MakeBookAtomCopy(morkEnv* ev, const morkBigBookAtom& inAtom)
|
|||
morkBookAtom* outAtom = 0;
|
||||
if ( ev->Good() )
|
||||
{
|
||||
if ( mSpace_Store->mStore_CanAutoAssignAtomIdentity )
|
||||
{
|
||||
morkPool* pool = this->GetSpaceStorePool();
|
||||
morkBookAtom* atom = pool->NewBookAtomCopy(ev, inAtom);
|
||||
if ( atom )
|
||||
{
|
||||
mork_aid id = this->MakeNewAtomId(ev, atom);
|
||||
if ( id )
|
||||
{
|
||||
outAtom = atom;
|
||||
atom->mBookAtom_Space = this;
|
||||
mAtomSpace_AtomAids.AddAtom(ev, atom);
|
||||
mAtomSpace_AtomBodies.AddAtom(ev, atom);
|
||||
if ( mSpace_Scope == morkAtomSpace_kColumnScope )
|
||||
outAtom->MakeCellUseForever(ev);
|
||||
}
|
||||
else
|
||||
pool->ZapAtom(ev, atom);
|
||||
}
|
||||
}
|
||||
else
|
||||
mSpace_Store->CannotAutoAssignAtomIdentityError(ev);
|
||||
if ( mSpace_Store->mStore_CanAutoAssignAtomIdentity )
|
||||
{
|
||||
morkPool* pool = this->GetSpaceStorePool();
|
||||
morkBookAtom* atom = pool->NewBookAtomCopy(ev, inAtom);
|
||||
if ( atom )
|
||||
{
|
||||
mork_aid id = this->MakeNewAtomId(ev, atom);
|
||||
if ( id )
|
||||
{
|
||||
outAtom = atom;
|
||||
atom->mBookAtom_Space = this;
|
||||
mAtomSpace_AtomAids.AddAtom(ev, atom);
|
||||
mAtomSpace_AtomBodies.AddAtom(ev, atom);
|
||||
if ( mSpace_Scope == morkAtomSpace_kColumnScope )
|
||||
outAtom->MakeCellUseForever(ev);
|
||||
}
|
||||
else
|
||||
pool->ZapAtom(ev, atom);
|
||||
}
|
||||
}
|
||||
else
|
||||
mSpace_Store->CannotAutoAssignAtomIdentityError(ev);
|
||||
}
|
||||
return outAtom;
|
||||
}
|
||||
|
|
|
@ -235,6 +235,7 @@ void
|
|||
morkBuilder::LogGlitch(morkEnv* ev, const morkGlitch& inGlitch,
|
||||
const char* inKind)
|
||||
{
|
||||
MORK_USED_2(inGlitch,inKind);
|
||||
ev->NewWarning("parsing glitch");
|
||||
}
|
||||
|
||||
|
@ -256,6 +257,7 @@ morkBuilder::OnNewPort(morkEnv* ev, const morkPlace& inPlace)
|
|||
// mp:PortItem ::= mp:Content | mp:Group | OnPortGlitch
|
||||
// mp:Content ::= mp:PortRow | mp:Dict | mp:Table | mp:Row
|
||||
{
|
||||
MORK_USED_2(ev,inPlace);
|
||||
// mParser_InPort = morkBool_kTrue;
|
||||
mBuilder_PortForm = 0;
|
||||
mBuilder_PortRowScope = (mork_scope) 'r';
|
||||
|
@ -272,6 +274,7 @@ morkBuilder::OnPortGlitch(morkEnv* ev, const morkGlitch& inGlitch)
|
|||
morkBuilder::OnPortEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
// mp:Start ::= OnNewPort mp:PortItem* OnPortEnd
|
||||
{
|
||||
MORK_USED_2(ev,inSpan);
|
||||
// ev->StubMethodOnlyError();
|
||||
// nothing to do?
|
||||
// mParser_InPort = morkBool_kFalse;
|
||||
|
@ -280,6 +283,7 @@ morkBuilder::OnPortEnd(morkEnv* ev, const morkSpan& inSpan)
|
|||
/*virtual*/ void
|
||||
morkBuilder::OnNewGroup(morkEnv* ev, const morkPlace& inPlace, mork_gid inGid)
|
||||
{
|
||||
MORK_USED_2(inPlace,inGid);
|
||||
// mParser_InGroup = morkBool_kTrue;
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
@ -293,6 +297,7 @@ morkBuilder::OnGroupGlitch(morkEnv* ev, const morkGlitch& inGlitch)
|
|||
/*virtual*/ void
|
||||
morkBuilder::OnGroupCommitEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
{
|
||||
MORK_USED_1(inSpan);
|
||||
// mParser_InGroup = morkBool_kFalse;
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
@ -300,6 +305,7 @@ morkBuilder::OnGroupCommitEnd(morkEnv* ev, const morkSpan& inSpan)
|
|||
/*virtual*/ void
|
||||
morkBuilder::OnGroupAbortEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
{
|
||||
MORK_USED_1(inSpan);
|
||||
// mParser_InGroup = morkBool_kFalse;
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
@ -308,6 +314,7 @@ morkBuilder::OnGroupAbortEnd(morkEnv* ev, const morkSpan& inSpan)
|
|||
morkBuilder::OnNewPortRow(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkMid& inMid, mork_change inChange)
|
||||
{
|
||||
MORK_USED_3(inMid,inPlace,inChange);
|
||||
// mParser_InPortRow = morkBool_kTrue;
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
@ -321,6 +328,7 @@ morkBuilder::OnPortRowGlitch(morkEnv* ev, const morkGlitch& inGlitch)
|
|||
/*virtual*/ void
|
||||
morkBuilder::OnPortRowEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
{
|
||||
MORK_USED_1(inSpan);
|
||||
// mParser_InPortRow = morkBool_kFalse;
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
@ -334,6 +342,7 @@ morkBuilder::OnNewTable(morkEnv* ev, const morkPlace& inPlace,
|
|||
// mp:Meta ::= OnNewMeta mp:MetaItem* OnMetaEnd
|
||||
// mp:MetaItem ::= mp:Cell | OnMetaGlitch
|
||||
{
|
||||
MORK_USED_2(inPlace,inChange);
|
||||
// mParser_InTable = morkBool_kTrue;
|
||||
mBuilder_TableForm = mBuilder_PortForm;
|
||||
mBuilder_TableRowScope = mBuilder_PortRowScope;
|
||||
|
@ -355,6 +364,7 @@ morkBuilder::OnTableGlitch(morkEnv* ev, const morkGlitch& inGlitch)
|
|||
morkBuilder::OnTableEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
// mp:Table ::= OnNewTable mp:TableItem* OnTableEnd
|
||||
{
|
||||
MORK_USED_1(inSpan);
|
||||
// mParser_InTable = morkBool_kFalse;
|
||||
if ( mBuilder_Table )
|
||||
{
|
||||
|
@ -381,6 +391,7 @@ morkBuilder::OnNewMeta(morkEnv* ev, const morkPlace& inPlace)
|
|||
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
|
||||
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
|
||||
{
|
||||
MORK_USED_2(ev,inPlace);
|
||||
// mParser_InMeta = morkBool_kTrue;
|
||||
|
||||
}
|
||||
|
@ -395,6 +406,7 @@ morkBuilder::OnMetaGlitch(morkEnv* ev, const morkGlitch& inGlitch)
|
|||
morkBuilder::OnMetaEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
// mp:Meta ::= OnNewMeta mp:MetaItem* OnMetaEnd
|
||||
{
|
||||
MORK_USED_2(ev,inSpan);
|
||||
// mParser_InMeta = morkBool_kFalse;
|
||||
}
|
||||
|
||||
|
@ -410,6 +422,7 @@ morkBuilder::OnNewRow(morkEnv* ev, const morkPlace& inPlace,
|
|||
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
|
||||
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
|
||||
{
|
||||
MORK_USED_2(inPlace,inChange);
|
||||
// mParser_InRow = morkBool_kTrue;
|
||||
if ( mBuilder_Table )
|
||||
{
|
||||
|
@ -485,6 +498,7 @@ morkBuilder::FlushBuilderCells(morkEnv* ev)
|
|||
morkBuilder::OnRowEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
// mp:Row ::= OnNewRow mp:RowItem* OnRowEnd
|
||||
{
|
||||
MORK_USED_1(inSpan);
|
||||
// mParser_InRow = morkBool_kFalse;
|
||||
if ( mBuilder_Row )
|
||||
{
|
||||
|
@ -502,6 +516,7 @@ morkBuilder::OnNewDict(morkEnv* ev, const morkPlace& inPlace)
|
|||
// mp:Dict ::= OnNewDict mp:DictItem* OnDictEnd
|
||||
// mp:DictItem ::= OnAlias | OnAliasGlitch | mp:Meta | OnDictGlitch
|
||||
{
|
||||
MORK_USED_2(ev,inPlace);
|
||||
// mParser_InDict = morkBool_kTrue;
|
||||
|
||||
mBuilder_CellForm = mBuilder_DictForm = mBuilder_PortForm;
|
||||
|
@ -518,6 +533,7 @@ morkBuilder::OnDictGlitch(morkEnv* ev, const morkGlitch& inGlitch)
|
|||
morkBuilder::OnDictEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
// mp:Dict ::= OnNewDict mp:DictItem* OnDictEnd
|
||||
{
|
||||
MORK_USED_2(ev,inSpan);
|
||||
// mParser_InDict = morkBool_kFalse;
|
||||
|
||||
mBuilder_DictForm = 0;
|
||||
|
@ -528,6 +544,7 @@ morkBuilder::OnDictEnd(morkEnv* ev, const morkSpan& inSpan)
|
|||
morkBuilder::OnAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkMid& inMid)
|
||||
{
|
||||
MORK_USED_1(inSpan);
|
||||
if ( mParser_InDict )
|
||||
{
|
||||
morkMid mid = inMid; // local copy for modification
|
||||
|
@ -583,6 +600,7 @@ morkBuilder::OnNewCell(morkEnv* ev, const morkPlace& inPlace,
|
|||
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
|
||||
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
|
||||
{
|
||||
MORK_USED_1(inPlace);
|
||||
// mParser_InCell = morkBool_kTrue;
|
||||
|
||||
mBuilder_CellAtomScope = mBuilder_RowAtomScope;
|
||||
|
@ -699,6 +717,7 @@ morkBuilder::OnCellForm(morkEnv* ev, mork_cscode inCharsetFormat)
|
|||
morkBuilder::OnCellEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
// mp:Cell ::= OnNewCell mp:CellItem? OnCellEnd
|
||||
{
|
||||
MORK_USED_2(ev,inSpan);
|
||||
// mParser_InCell = morkBool_kFalse;
|
||||
|
||||
mBuilder_MetaTokenSlot = 0;
|
||||
|
@ -711,6 +730,7 @@ morkBuilder::OnValue(morkEnv* ev, const morkSpan& inSpan,
|
|||
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
|
||||
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
|
||||
{
|
||||
MORK_USED_1(inSpan);
|
||||
morkStore* store = mBuilder_Store;
|
||||
morkCell* cell = mBuilder_Cell;
|
||||
if ( cell )
|
||||
|
@ -751,6 +771,7 @@ morkBuilder::OnValueMid(morkEnv* ev, const morkSpan& inSpan,
|
|||
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
|
||||
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
|
||||
{
|
||||
MORK_USED_1(inSpan);
|
||||
morkStore* store = mBuilder_Store;
|
||||
morkCell* cell = mBuilder_Cell;
|
||||
|
||||
|
@ -779,7 +800,7 @@ morkBuilder::OnValueMid(morkEnv* ev, const morkSpan& inSpan,
|
|||
mork_token* metaSlot = mBuilder_MetaTokenSlot;
|
||||
if ( metaSlot )
|
||||
{
|
||||
mork_scope valScope = valOid->mOid_Scope;
|
||||
mork_scope valScope = valOid->mOid_Scope;
|
||||
if ( !valScope || valScope == morkStore_kColumnSpaceScope )
|
||||
{
|
||||
if ( ev->Good() && valMid.HasSomeId() )
|
||||
|
@ -810,6 +831,7 @@ morkBuilder::OnRowMid(morkEnv* ev, const morkSpan& inSpan,
|
|||
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
|
||||
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
|
||||
{
|
||||
MORK_USED_1(inSpan);
|
||||
morkStore* store = mBuilder_Store;
|
||||
morkCell* cell = mBuilder_Cell;
|
||||
if ( cell )
|
||||
|
@ -846,6 +868,7 @@ morkBuilder::OnTableMid(morkEnv* ev, const morkSpan& inSpan,
|
|||
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
|
||||
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
|
||||
{
|
||||
MORK_USED_1(inSpan);
|
||||
morkStore* store = mBuilder_Store;
|
||||
morkCell* cell = mBuilder_Cell;
|
||||
if ( cell )
|
||||
|
|
|
@ -57,12 +57,14 @@ morkCell::SetYarn(morkEnv* ev, const mdbYarn* inYarn, morkStore* ioStore)
|
|||
void
|
||||
morkCell::GetYarn(morkEnv* ev, mdbYarn* outYarn) const
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
mCell_Atom->GetYarn(outYarn);
|
||||
}
|
||||
|
||||
void
|
||||
morkCell::AliasYarn(morkEnv* ev, mdbYarn* outYarn) const
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
mCell_Atom->AliasYarn(outYarn);
|
||||
}
|
||||
|
||||
|
|
|
@ -156,7 +156,7 @@ morkCellObject::ResyncWithRow(morkEnv* ev)
|
|||
morkCell* cell = row->GetCell(ev, mCellObject_Col, &pos);
|
||||
if ( cell )
|
||||
{
|
||||
mCellObject_Pos = pos;
|
||||
mCellObject_Pos = (mork_u2) pos;
|
||||
mCellObject_Cell = cell;
|
||||
mCellObject_RowSeed = row->mRow_Seed;
|
||||
}
|
||||
|
|
|
@ -31,19 +31,19 @@
|
|||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
/* ----- ----- ----- ----- MORK_OBSOLETE ----- ----- ----- ----- */
|
||||
#ifdef MORK_OBSOLETE
|
||||
#if defined(MORK_OBSOLETE) || defined(MORK_ALONE)
|
||||
|
||||
#include <Types.h>
|
||||
#include "plstr.h"
|
||||
//#include "plstr.h"
|
||||
|
||||
static void // copied almost verbatim from the IronDoc debugger sources:
|
||||
mork_mac_break_string(register const char* inMessage) /*i*/
|
||||
{
|
||||
Str255 pascalStr; // to hold Pascal string version of inMessage
|
||||
mork_u4 length = PL_strlen(inMessage);
|
||||
mork_u4 length = MORK_STRLEN(inMessage);
|
||||
|
||||
// if longer than maximum 255 bytes, just copy 255 bytes worth
|
||||
pascalStr[ 0 ] = (length > 255)? 255 : length;
|
||||
pascalStr[ 0 ] = (mork_u1) ((length > 255)? 255 : length);
|
||||
if ( length ) // anything to copy? */
|
||||
{
|
||||
register mork_u1* p = ((mork_u1*) &pascalStr) + 1; // after length byte
|
||||
|
@ -64,13 +64,15 @@
|
|||
|
||||
void mork_assertion_signal(const char* inMessage)
|
||||
{
|
||||
#ifdef MORK_OBSOLETE
|
||||
#if defined(MORK_OBSOLETE) || defined(MORK_ALONE)
|
||||
mork_mac_break_string(inMessage);
|
||||
#endif /*MORK_OBSOLETE*/
|
||||
|
||||
#if defined(MORK_WIN) || defined(MORK_MAC)
|
||||
// asm { int 3 }
|
||||
#ifndef MORK_ALONE
|
||||
NS_ASSERTION(0, inMessage);
|
||||
#endif /*MORK_ALONE*/
|
||||
#endif /*MORK_WIN*/
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,10 @@
|
|||
#endif
|
||||
|
||||
// { %%%%% begin platform defs peculiar to Mork %%%%%
|
||||
|
||||
//#define XP_MAC 1
|
||||
//#define MORK_ALONE 1
|
||||
|
||||
#ifdef XP_MAC
|
||||
#define MORK_MAC 1
|
||||
#endif
|
||||
|
@ -59,7 +63,10 @@
|
|||
#include "errno.h"
|
||||
#include "string.h"
|
||||
#include "memory.h"
|
||||
|
||||
#ifndef MORK_ALONE
|
||||
#include "nsDebug.h"
|
||||
#endif /*MORK_ALONE*/
|
||||
|
||||
#define MORK_ISPRINT(c) isprint(c)
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ morkDeque::IndexOf(const morkLink* member) const /*i*/
|
|||
{
|
||||
++count;
|
||||
if ( member == link )
|
||||
return count;
|
||||
return (mork_pos) count;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -185,15 +185,15 @@ morkEnv::OidAsHex(void* outBuf, const mdbOid& inOid)
|
|||
mork_scope scope = inOid.mOid_Scope;
|
||||
if ( scope < 0x80 && morkCh_IsName((mork_ch) scope) )
|
||||
{
|
||||
*p++ = (mork_u1) scope;
|
||||
*p = 0; // null termination
|
||||
outSize += 2;
|
||||
*p++ = (mork_u1) scope;
|
||||
*p = 0; // null termination
|
||||
outSize += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
*p++ = '^';
|
||||
mork_size scopeSize = this->TokenAsHex(p, scope);
|
||||
outSize += scopeSize + 2;
|
||||
*p++ = '^';
|
||||
mork_size scopeSize = this->TokenAsHex(p, scope);
|
||||
outSize += scopeSize + 2;
|
||||
}
|
||||
return outSize;
|
||||
}
|
||||
|
@ -205,20 +205,20 @@ morkEnv::HexToByte(mork_ch inFirstHex, mork_ch inSecondHex)
|
|||
mork_u1 hi = 0; // high four hex bits
|
||||
mork_flags f = morkCh_GetFlags(inFirstHex);
|
||||
if ( morkFlags_IsDigit(f) )
|
||||
hi = inFirstHex - '0';
|
||||
hi = (mork_u1) (inFirstHex - (mork_ch) '0');
|
||||
else if ( morkFlags_IsUpper(f) )
|
||||
hi = (inFirstHex - 'A') + 10;
|
||||
hi = (mork_u1) ((inFirstHex - (mork_ch) 'A') + 10);
|
||||
else if ( morkFlags_IsLower(f) )
|
||||
hi = (inFirstHex - 'a') + 10;
|
||||
hi = (mork_u1) ((inFirstHex - (mork_ch) 'a') + 10);
|
||||
|
||||
mork_u1 lo = 0; // low four hex bits
|
||||
f = morkCh_GetFlags(inSecondHex);
|
||||
if ( morkFlags_IsDigit(f) )
|
||||
lo = inSecondHex - '0';
|
||||
lo = (mork_u1) (inSecondHex - (mork_ch) '0');
|
||||
else if ( morkFlags_IsUpper(f) )
|
||||
lo = (inSecondHex - 'A') + 10;
|
||||
lo = (mork_u1) ((inSecondHex - (mork_ch) 'A') + 10);
|
||||
else if ( morkFlags_IsLower(f) )
|
||||
lo = (inSecondHex - 'a') + 10;
|
||||
lo = (mork_u1) ((inSecondHex - (mork_ch) 'a') + 10);
|
||||
|
||||
return (mork_u1) ((hi << 4) | lo);
|
||||
}
|
||||
|
@ -240,7 +240,7 @@ morkEnv::TokenAsHex(void* outBuf, mork_token inToken)
|
|||
}
|
||||
*p = 0; // end the string with a null byte
|
||||
char* s = (char*) outBuf; // first byte in string
|
||||
mork_size size = p - s; // distance from start
|
||||
mork_size size = (mork_size) (p - s); // distance from start
|
||||
|
||||
// now reverse the string in place:
|
||||
// note that p starts on the null byte, so we need predecrement:
|
||||
|
@ -311,7 +311,7 @@ morkEnv::NewErrorAndCode(const char* inString, mork_u2 inCode)
|
|||
MORK_ASSERT(morkBool_kFalse); // get developer's attention
|
||||
|
||||
++mEnv_ErrorCount;
|
||||
mEnv_ErrorCode = (inCode)? inCode: morkEnv_kGenericError;
|
||||
mEnv_ErrorCode = (mork_u4) ((inCode)? inCode: morkEnv_kGenericError);
|
||||
|
||||
if ( mEnv_ErrorHook )
|
||||
mEnv_ErrorHook->OnErrorString(this->AsMdbEnv(), inString);
|
||||
|
|
|
@ -373,6 +373,7 @@ morkStdioFile::AcquireBud(morkEnv* ev, nsIMdbHeap* ioHeap)
|
|||
// behavior is exhibited by the file, so crashes protect old files.
|
||||
// Note that AcquireBud() is an illegal operation on readonly files.
|
||||
{
|
||||
MORK_USED_1(ioHeap);
|
||||
morkFile* outFile = 0;
|
||||
if ( this->IsOpenAndActiveFile() )
|
||||
{
|
||||
|
@ -491,7 +492,7 @@ morkStdioFile::Read(morkEnv* ev, void* outBuf, mork_size inSize)
|
|||
FILE* file = (FILE*) mStdioFile_File;
|
||||
if ( file )
|
||||
{
|
||||
long count = MORK_FILEREAD(outBuf, inSize, file);
|
||||
long count = (long) MORK_FILEREAD(outBuf, inSize, file);
|
||||
if ( count >= 0 )
|
||||
{
|
||||
outCount = (mork_num) count;
|
||||
|
|
|
@ -132,10 +132,10 @@ public: // non-poly morkFile methods
|
|||
mork_bool FileIoOpen() const { return mFile_IoOpen == 'O'; }
|
||||
mork_bool FileActive() const { return mFile_Active == 'A'; }
|
||||
|
||||
void SetFileFrozen(mork_bool b) { mFile_Frozen = (b)? 'F' : 0; }
|
||||
void SetFileDoTrace(mork_bool b) { mFile_DoTrace = (b)? 'T' : 0; }
|
||||
void SetFileIoOpen(mork_bool b) { mFile_IoOpen = (b)? 'O' : 0; }
|
||||
void SetFileActive(mork_bool b) { mFile_Active = (b)? 'A' : 0; }
|
||||
void SetFileFrozen(mork_bool b) { mFile_Frozen = (mork_u1) ((b)? 'F' : 0); }
|
||||
void SetFileDoTrace(mork_bool b) { mFile_DoTrace = (mork_u1) ((b)? 'T' : 0); }
|
||||
void SetFileIoOpen(mork_bool b) { mFile_IoOpen = (mork_u1) ((b)? 'O' : 0); }
|
||||
void SetFileActive(mork_bool b) { mFile_Active = (mork_u1) ((b)? 'A' : 0); }
|
||||
|
||||
|
||||
mork_bool IsOpenActiveAndMutableFile() const
|
||||
|
|
|
@ -147,6 +147,7 @@ void morkHandle::NonOpenObjectError(morkEnv* ev) const
|
|||
|
||||
void morkHandle::NewBadMagicHandleError(morkEnv* ev, mork_magic inMagic) const
|
||||
{
|
||||
MORK_USED_1(inMagic);
|
||||
ev->NewError("wrong mHandle_Magic");
|
||||
}
|
||||
|
||||
|
@ -393,6 +394,7 @@ morkHandle::Handle_CloseMdbObject(nsIMdbEnv* mev)
|
|||
/*virtual*/ mdb_err
|
||||
morkHandle::Handle_IsOpenMdbObject(nsIMdbEnv* mev, mdb_bool* outOpen)
|
||||
{
|
||||
MORK_USED_1(mev);
|
||||
mdb_err outErr = 0;
|
||||
|
||||
MORK_ASSERT(outOpen);
|
||||
|
|
|
@ -100,7 +100,7 @@ public: // morkHandle memory management operators
|
|||
{ return ioPool.NewHandle(ev, inSize); }
|
||||
|
||||
void* operator new(size_t inSize, morkHandleFace* ioFace)
|
||||
{ return ioFace; }
|
||||
{ MORK_USED_1(inSize); return ioFace; }
|
||||
|
||||
void operator delete(void* ioAddress)
|
||||
{ morkNode::OnDeleteAssert(ioAddress); }
|
||||
|
|
|
@ -97,12 +97,14 @@ morkIntMap::CloseIntMap(morkEnv* ev) // called by CloseMorkNode();
|
|||
/*virtual*/ mork_bool // *((mork_u4*) inKeyA) == *((mork_u4*) inKeyB)
|
||||
morkIntMap::Equal(morkEnv* ev, const void* inKeyA, const void* inKeyB) const
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
return *((const mork_u4*) inKeyA) == *((const mork_u4*) inKeyB);
|
||||
}
|
||||
|
||||
/*virtual*/ mork_u4 // some integer function of *((mork_u4*) inKey)
|
||||
morkIntMap::Hash(morkEnv* ev, const void* inKey) const
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
return *((const mork_u4*) inKey);
|
||||
}
|
||||
// } ===== end morkMap poly interface =====
|
||||
|
@ -145,4 +147,115 @@ morkIntMap::HasInt(morkEnv* ev, mork_u4 inKey)
|
|||
(mork_change**) 0);
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#ifdef MORK_POINTER_MAP_IMPL
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkPointerMap::CloseMorkNode(morkEnv* ev) // ClosePointerMap() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->ClosePointerMap(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkPointerMap::~morkPointerMap() // assert ClosePointerMap() executed earlier
|
||||
{
|
||||
MORK_ASSERT(this->IsShutNode());
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkPointerMap::morkPointerMap(morkEnv* ev,
|
||||
const morkUsage& inUsage, nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap)
|
||||
: morkMap(ev, inUsage, ioHeap, sizeof(void*), sizeof(void*),
|
||||
morkPointerMap_kStartSlotCount, ioSlotHeap,
|
||||
/*inHoldChanges*/ morkBool_kFalse)
|
||||
{
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kPointerMap;
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkPointerMap::ClosePointerMap(morkEnv* ev) // called by CloseMorkNode();
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
this->CloseMap(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
// { ===== begin morkMap poly interface =====
|
||||
/*virtual*/ mork_bool // *((void**) inKeyA) == *((void**) inKeyB)
|
||||
morkPointerMap::Equal(morkEnv* ev, const void* inKeyA, const void* inKeyB) const
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
return *((const void**) inKeyA) == *((const void**) inKeyB);
|
||||
}
|
||||
|
||||
/*virtual*/ mork_u4 // some integer function of *((mork_u4*) inKey)
|
||||
morkPointerMap::Hash(morkEnv* ev, const void* inKey) const
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
return *((const mork_u4*) inKey);
|
||||
}
|
||||
// } ===== end morkMap poly interface =====
|
||||
|
||||
mork_bool
|
||||
morkPointerMap::AddPointer(morkEnv* ev, void* inKey, void* ioAddress)
|
||||
// the AddPointer() method return value equals ev->Good().
|
||||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
this->Put(ev, &inKey, &ioAddress,
|
||||
/*key*/ (void*) 0, /*val*/ (void*) 0, (mork_change**) 0);
|
||||
}
|
||||
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkPointerMap::CutPointer(morkEnv* ev, void* inKey)
|
||||
{
|
||||
return this->Cut(ev, &inKey, /*key*/ (void*) 0, /*val*/ (void*) 0,
|
||||
(mork_change**) 0);
|
||||
}
|
||||
|
||||
void*
|
||||
morkPointerMap::GetPointer(morkEnv* ev, void* inKey)
|
||||
// Note the returned val does NOT have an increase in refcount for this.
|
||||
{
|
||||
void* val = 0; // old val in the map
|
||||
this->Get(ev, &inKey, /*key*/ (void*) 0, &val, (mork_change**) 0);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkPointerMap::HasPointer(morkEnv* ev, void* inKey)
|
||||
// Note the returned val does NOT have an increase in refcount for this.
|
||||
{
|
||||
return this->Get(ev, &inKey, /*key*/ (void*) 0, /*val*/ (void*) 0,
|
||||
(mork_change**) 0);
|
||||
}
|
||||
#endif /*MORK_POINTER_MAP_IMPL*/
|
||||
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
|
||||
#define morkDerived_kIntMap /*i*/ 0x694D /* ascii 'iM' */
|
||||
|
||||
#define morkIntMap_kStartSlotCount 512
|
||||
#define morkIntMap_kStartSlotCount 256
|
||||
|
||||
/*| morkIntMap: maps mork_token -> morkNode
|
||||
|*/
|
||||
|
@ -71,10 +71,10 @@ public: // other map methods
|
|||
mork_bool AddInt(morkEnv* ev, mork_u4 inKey, void* ioAddress);
|
||||
// the AddInt() boolean return equals ev->Good().
|
||||
|
||||
mork_bool CutInt(morkEnv* ev, mork_token inKey);
|
||||
mork_bool CutInt(morkEnv* ev, mork_u4 inKey);
|
||||
// The CutInt() boolean return indicates whether removal happened.
|
||||
|
||||
void* GetInt(morkEnv* ev, mork_token inKey);
|
||||
void* GetInt(morkEnv* ev, mork_u4 inKey);
|
||||
// Note the returned node does NOT have an increase in refcount for this.
|
||||
|
||||
mork_bool HasInt(morkEnv* ev, mork_u4 inKey);
|
||||
|
@ -82,6 +82,77 @@ public: // other map methods
|
|||
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#ifdef MORK_POINTER_MAP_IMPL
|
||||
|
||||
#define morkDerived_kPointerMap /*i*/ 0x704D /* ascii 'pM' */
|
||||
|
||||
#define morkPointerMap_kStartSlotCount 256
|
||||
|
||||
/*| morkPointerMap: maps void* -> void*
|
||||
**|
|
||||
**| This pointer map class is equivalent to morkIntMap when sizeof(mork_u4)
|
||||
**| equals sizeof(void*). However, when these two sizes are different,
|
||||
**| then we cannot use the same hash table structure very easily without
|
||||
**| being very careful about the size and usage assumptions of those
|
||||
**| clients using the smaller data type. So we just go ahead and use
|
||||
**| morkPointerMap for hash tables using pointer key types.
|
||||
|*/
|
||||
class morkPointerMap : public morkMap { // for mapping tokens to maps
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
virtual void CloseMorkNode(morkEnv* ev); // ClosePointerMap() only if open
|
||||
virtual ~morkPointerMap(); // assert that ClosePointerMap() executed earlier
|
||||
|
||||
public: // morkMap construction & destruction
|
||||
|
||||
// keySize for morkPointerMap equals sizeof(mork_u4)
|
||||
morkPointerMap(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap);
|
||||
void ClosePointerMap(morkEnv* ev); // called by CloseMorkNode();
|
||||
|
||||
public: // dynamic type identification
|
||||
mork_bool IsPointerMap() const
|
||||
{ return IsNode() && mNode_Derived == morkDerived_kPointerMap; }
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
// { ===== begin morkMap poly interface =====
|
||||
virtual mork_bool // *((void**) inKeyA) == *((void**) inKeyB)
|
||||
Equal(morkEnv* ev, const void* inKeyA, const void* inKeyB) const;
|
||||
|
||||
virtual mork_u4 // some integer function of *((mork_u4*) inKey)
|
||||
Hash(morkEnv* ev, const void* inKey) const;
|
||||
// } ===== end morkMap poly interface =====
|
||||
|
||||
public: // other map methods
|
||||
|
||||
mork_bool AddPointer(morkEnv* ev, void* inKey, void* ioAddress);
|
||||
// the AddPointer() boolean return equals ev->Good().
|
||||
|
||||
mork_bool CutPointer(morkEnv* ev, void* inKey);
|
||||
// The CutPointer() boolean return indicates whether removal happened.
|
||||
|
||||
void* GetPointer(morkEnv* ev, void* inKey);
|
||||
// Note the returned node does NOT have an increase in refcount for this.
|
||||
|
||||
mork_bool HasPointer(morkEnv* ev, void* inKey);
|
||||
// Note the returned node does NOT have an increase in refcount for this.
|
||||
|
||||
public: // typesafe refcounting inlines calling inherited morkNode methods
|
||||
static void SlotWeakIntMap(morkIntMap* me,
|
||||
morkEnv* ev, morkIntMap** ioSlot)
|
||||
{ morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
|
||||
static void SlotStrongIntMap(morkIntMap* me,
|
||||
morkEnv* ev, morkIntMap** ioSlot)
|
||||
{ morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
|
||||
};
|
||||
#endif /*MORK_POINTER_MAP_IMPL*/
|
||||
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKINTMAP_ */
|
||||
|
|
|
@ -636,6 +636,9 @@ morkMap::Cut(morkEnv* ev, const void* inKey,
|
|||
outCut = morkBool_kTrue;
|
||||
morkAssoc* assoc = *ref;
|
||||
mork_pos i = assoc - mMap_Assocs; /* index of assoc */
|
||||
if ( outKey || outVal )
|
||||
this->get_assoc(outKey, outVal, i);
|
||||
|
||||
*ref = assoc->mAssoc_Next; /* unlink the found assoc */
|
||||
this->push_free_assoc(assoc); /* and put it in free list */
|
||||
|
||||
|
@ -747,6 +750,7 @@ morkMapIter::morkMapIter(morkEnv* ev, morkMap* ioMap)
|
|||
void
|
||||
morkMapIter::CloseMapIter(morkEnv* ev)
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
mMapIter_Map = 0;
|
||||
mMapIter_Seed = 0;
|
||||
|
||||
|
|
|
@ -368,13 +368,16 @@ morkNode::SlotStrongNode(morkNode* me, morkEnv* ev, morkNode** ioSlot)
|
|||
// expression 'morkNode::SlotStrongNode((morkNode*) 0, ev, &slot)'.
|
||||
{
|
||||
morkNode* node = *ioSlot;
|
||||
if ( node )
|
||||
if ( me != node )
|
||||
{
|
||||
*ioSlot = 0;
|
||||
node->CutStrongRef(ev);
|
||||
if ( node )
|
||||
{
|
||||
*ioSlot = 0;
|
||||
node->CutStrongRef(ev);
|
||||
}
|
||||
if ( me && me->AddStrongRef(ev) )
|
||||
*ioSlot = me;
|
||||
}
|
||||
if ( me && me->AddStrongRef(ev) )
|
||||
*ioSlot = me;
|
||||
}
|
||||
|
||||
/*public static*/ void
|
||||
|
@ -386,13 +389,16 @@ morkNode::SlotWeakNode(morkNode* me, morkEnv* ev, morkNode** ioSlot)
|
|||
// expression 'morkNode::SlotWeakNode((morkNode*) 0, ev, &slot)'.
|
||||
{
|
||||
morkNode* node = *ioSlot;
|
||||
if ( node )
|
||||
if ( me != node )
|
||||
{
|
||||
*ioSlot = 0;
|
||||
node->CutWeakRef(ev);
|
||||
if ( node )
|
||||
{
|
||||
*ioSlot = 0;
|
||||
node->CutWeakRef(ev);
|
||||
}
|
||||
if ( me && me->AddWeakRef(ev) )
|
||||
*ioSlot = me;
|
||||
}
|
||||
if ( me && me->AddWeakRef(ev) )
|
||||
*ioSlot = me;
|
||||
}
|
||||
|
||||
/*public non-poly*/ mork_uses
|
||||
|
|
|
@ -198,7 +198,7 @@ public: // other morkNode methods
|
|||
mork_bool BadRefs() const { return mNode_Refs < mNode_Uses; }
|
||||
|
||||
mork_uses StrongRefsOnly() const { return mNode_Uses; }
|
||||
mork_refs WeakRefsOnly() const { return ( mNode_Refs - mNode_Uses ); }
|
||||
mork_refs WeakRefsOnly() const { return (mork_refs) ( mNode_Refs - mNode_Uses ); }
|
||||
|
||||
// (this refcounting derives from public domain IronDoc node refcounts)
|
||||
mork_refs AddStrongRef(morkEnv* ev);
|
||||
|
|
|
@ -211,6 +211,7 @@ morkParser::NonUsableParserError(morkEnv* ev) //
|
|||
/*protected non-poly*/ void
|
||||
morkParser::StartParse(morkEnv* ev)
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
mParser_InCell = morkBool_kFalse;
|
||||
mParser_InMeta = morkBool_kFalse;
|
||||
mParser_InDict = morkBool_kFalse;
|
||||
|
@ -792,6 +793,7 @@ morkParser::EofInsteadOfHexError(morkEnv* ev)
|
|||
/*static*/ void
|
||||
morkParser::ExpectedHexDigitError(morkEnv* ev, int c)
|
||||
{
|
||||
MORK_USED_1(c);
|
||||
ev->NewWarning("expected hex digit");
|
||||
}
|
||||
|
||||
|
@ -969,6 +971,45 @@ morkParser::NonParserTypeError(morkEnv* ev)
|
|||
ev->NewError("non morkParser");
|
||||
}
|
||||
|
||||
mork_bool morkParser::MatchPattern(morkEnv* ev, const char* inPattern)
|
||||
{
|
||||
// if an error occurs, we want original inPattern in the debugger:
|
||||
const char* pattern = inPattern; // mutable copy
|
||||
morkStream* s = mParser_Stream;
|
||||
register int c;
|
||||
while ( *inPattern && ev->Good() )
|
||||
{
|
||||
char byte = *pattern++;
|
||||
if ( (c = s->Getc(ev)) != byte )
|
||||
{
|
||||
ev->NewError("byte not in expected pattern");
|
||||
}
|
||||
}
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
void morkParser::ReadGroup(morkEnv* ev)
|
||||
/* groups must be ignored until properly terminated */
|
||||
// zm:Group ::= zm:GroupStart zm:Content zm:GroupEnd /* transaction */
|
||||
// zm:GroupStart ::= zm:S? '@$${' zm:Id '{@' /* transaction id has own space */
|
||||
// zm:GroupEnd ::= zm:GroupCommit | zm:GroupAbort
|
||||
// zm:GroupCommit ::= zm:S? '@$$}' zm:Id '}@' /* id matches start id */
|
||||
// zm:GroupAbort ::= zm:S? '@$$}~~' zm:Id '}@' /* id matches start id */
|
||||
/* We must allow started transactions to be aborted in summary files. */
|
||||
/* Note '$$' will never occur unescaped in values we will see in Mork. */
|
||||
{
|
||||
if ( this->MatchPattern(ev, "$${") )
|
||||
{
|
||||
//morkMid cellMid = &mParser_CellMid;
|
||||
//if ( this->ReadMid(ev, cellMid) )
|
||||
//{
|
||||
// if ( this->MatchPattern(ev, "}@") )
|
||||
// {
|
||||
// }
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
void morkParser::ReadDict(morkEnv* ev)
|
||||
// zm:Dict ::= zm:S? '<' zm:DictItem* zm:S? '>'
|
||||
// zm:DictItem ::= zm:MetaDict | zm:Alias
|
||||
|
@ -1060,6 +1101,10 @@ morkParser::OnPortState(morkEnv* ev)
|
|||
this->ReadDict(ev);
|
||||
break;
|
||||
|
||||
case '@': // group
|
||||
this->ReadGroup(ev);
|
||||
break;
|
||||
|
||||
case '+': // plus
|
||||
mParser_Change = morkChange_kAdd;
|
||||
break;
|
||||
|
@ -1181,7 +1226,7 @@ morkParser::ParseMore( // return count of bytes consumed now
|
|||
*outPos = endPos;
|
||||
|
||||
if ( endPos > startPos )
|
||||
outCount = endPos - startPos;
|
||||
outCount = (mdb_count) (endPos - startPos);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -476,6 +476,7 @@ protected: // protected parser helper methods
|
|||
void ReadTable(morkEnv* ev);
|
||||
void ReadTableMeta(morkEnv* ev);
|
||||
void ReadDict(morkEnv* ev);
|
||||
void ReadGroup(morkEnv* ev);
|
||||
void ReadMeta(morkEnv* ev, int inEndMeta);
|
||||
void ReadAlias(morkEnv* ev);
|
||||
mork_id ReadHex(morkEnv* ev, int* outNextChar);
|
||||
|
@ -483,6 +484,8 @@ protected: // protected parser helper methods
|
|||
morkBuf* ReadName(morkEnv* ev, int c);
|
||||
mork_bool ReadMid(morkEnv* ev, morkMid* outMid);
|
||||
|
||||
mork_bool MatchPattern(morkEnv* ev, const char* inPattern);
|
||||
|
||||
void EndSpanOnThisByte(morkEnv* ev, morkSpan* ioSpan);
|
||||
void StartSpanOnLastByte(morkEnv* ev, morkSpan* ioSpan);
|
||||
|
||||
|
|
|
@ -189,6 +189,7 @@ morkPool::NewCells(morkEnv* ev, mork_size inSize)
|
|||
void
|
||||
morkPool::ZapCells(morkEnv* ev, morkCell* ioVector, mork_size inSize)
|
||||
{
|
||||
MORK_USED_1(inSize);
|
||||
if ( ioVector )
|
||||
mPool_Heap->Free(ev->AsMdbEnv(), ioVector);
|
||||
}
|
||||
|
@ -214,7 +215,7 @@ morkPool::AddRowCells(morkEnv* ev, morkRow* ioRow, mork_size inNewSize)
|
|||
}
|
||||
oldCells = ioRow->mRow_Cells;
|
||||
ioRow->mRow_Cells = newCells;
|
||||
ioRow->mRow_Length = inNewSize;
|
||||
ioRow->mRow_Length = (mork_u2) inNewSize;
|
||||
++ioRow->mRow_Seed;
|
||||
|
||||
if ( oldCells )
|
||||
|
@ -251,7 +252,7 @@ morkPool::CutRowCells(morkEnv* ev, morkRow* ioRow,
|
|||
}
|
||||
oldCells = ioRow->mRow_Cells;
|
||||
ioRow->mRow_Cells = newCells;
|
||||
ioRow->mRow_Length = inNewSize;
|
||||
ioRow->mRow_Length = (mork_u2) inNewSize;
|
||||
++ioRow->mRow_Seed;
|
||||
|
||||
if ( oldCells )
|
||||
|
|
|
@ -86,7 +86,7 @@ morkPortTableCursor::morkPortTableCursor(morkEnv* ev,
|
|||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
if ( ioStore )
|
||||
if ( ioStore && ioSlotHeap )
|
||||
{
|
||||
mCursor_Pos = -1;
|
||||
mCursor_Seed = 0; // let the iterator do it's own seed handling
|
||||
|
|
|
@ -69,8 +69,13 @@
|
|||
mork_u2
|
||||
morkRow::AddTableUse(morkEnv* ev)
|
||||
{
|
||||
if ( mRow_TableUses < morkRow_kMaxTableUses ) // not already maxed out?
|
||||
++mRow_TableUses;
|
||||
if ( this->IsRow() )
|
||||
{
|
||||
if ( mRow_TableUses < morkRow_kMaxTableUses ) // not already maxed out?
|
||||
++mRow_TableUses;
|
||||
}
|
||||
else
|
||||
this->NonRowTypeError(ev);
|
||||
|
||||
return mRow_TableUses;
|
||||
}
|
||||
|
@ -78,13 +83,18 @@ morkRow::AddTableUse(morkEnv* ev)
|
|||
mork_u2
|
||||
morkRow::CutTableUse(morkEnv* ev)
|
||||
{
|
||||
if ( mRow_TableUses ) // any outstanding uses to cut?
|
||||
if ( this->IsRow() )
|
||||
{
|
||||
if ( mRow_TableUses < morkRow_kMaxTableUses ) // not frozen at max?
|
||||
--mRow_TableUses;
|
||||
if ( mRow_TableUses ) // any outstanding uses to cut?
|
||||
{
|
||||
if ( mRow_TableUses < morkRow_kMaxTableUses ) // not frozen at max?
|
||||
--mRow_TableUses;
|
||||
}
|
||||
else
|
||||
this->TableUsesUnderflowWarning(ev);
|
||||
}
|
||||
else
|
||||
this->TableUsesUnderflowWarning(ev);
|
||||
this->NonRowTypeError(ev);
|
||||
|
||||
return mRow_TableUses;
|
||||
}
|
||||
|
@ -142,7 +152,7 @@ morkRow::InitRow(morkEnv* ev, const mdbOid* inOid, morkRowSpace* ioSpace,
|
|||
mRow_Cells = 0;
|
||||
mRow_Oid = *inOid;
|
||||
|
||||
mRow_Length = inLength;
|
||||
mRow_Length = (mork_u2) inLength;
|
||||
mRow_Seed = (mork_u2) this; // "random" assignment
|
||||
|
||||
mRow_TableUses = 0;
|
||||
|
@ -300,7 +310,7 @@ morkRow::TakeCells(morkEnv* ev, morkCell* ioVector, mork_fill inVecLength,
|
|||
if ( ioVector && inVecLength && ev->Good() )
|
||||
{
|
||||
++mRow_Seed; // intend to change structure of mRow_Cells
|
||||
mork_pos length = (mork_pos) mRow_Length;
|
||||
mork_size length = (mork_size) mRow_Length;
|
||||
|
||||
mork_count overlap = this->CountOverlap(ev, ioVector, inVecLength);
|
||||
|
||||
|
@ -328,8 +338,8 @@ morkRow::NewCell(morkEnv* ev, mdb_column inColumn,
|
|||
mork_pos* outPos, morkStore* ioStore)
|
||||
{
|
||||
++mRow_Seed; // intend to change structure of mRow_Cells
|
||||
mork_pos length = (mork_pos) mRow_Length;
|
||||
*outPos = length;
|
||||
mork_size length = (mork_size) mRow_Length;
|
||||
*outPos = (mork_pos) length;
|
||||
morkPool* pool = ioStore->StorePool();
|
||||
if ( pool->AddRowCells(ev, this, length + 1) )
|
||||
{
|
||||
|
@ -344,6 +354,7 @@ morkRow::NewCell(morkEnv* ev, mdb_column inColumn,
|
|||
morkCell*
|
||||
morkRow::CellAt(morkEnv* ev, mork_pos inPos) const
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
morkCell* cells = mRow_Cells;
|
||||
if ( cells && inPos < mRow_Length && inPos >= 0 )
|
||||
{
|
||||
|
@ -355,6 +366,7 @@ morkRow::CellAt(morkEnv* ev, mork_pos inPos) const
|
|||
morkCell*
|
||||
morkRow::GetCell(morkEnv* ev, mdb_column inColumn, mork_pos* outPos) const
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
morkCell* cells = mRow_Cells;
|
||||
if ( cells )
|
||||
{
|
||||
|
@ -375,6 +387,42 @@ morkRow::GetCell(morkEnv* ev, mdb_column inColumn, mork_pos* outPos) const
|
|||
return (morkCell*) 0;
|
||||
}
|
||||
|
||||
mork_aid
|
||||
morkRow::GetCellAtomAid(morkEnv* ev, mdb_column inColumn) const
|
||||
// GetCellAtomAid() finds the cell with column inColumn, and sees if the
|
||||
// atom has a token ID, and returns the atom's ID if there is one. Or
|
||||
// else zero is returned if there is no such column, or no atom, or if
|
||||
// the atom has no ID to return. This method is intended to support
|
||||
// efficient updating of column indexes for rows in a row space.
|
||||
{
|
||||
if ( this && this->IsRow() )
|
||||
{
|
||||
morkCell* cells = mRow_Cells;
|
||||
if ( cells )
|
||||
{
|
||||
morkCell* end = cells + mRow_Length;
|
||||
while ( cells < end )
|
||||
{
|
||||
mork_column col = cells->GetColumn();
|
||||
if ( col == inColumn ) // found desired column?
|
||||
{
|
||||
morkAtom* atom = cells->mCell_Atom;
|
||||
if ( atom && atom->IsBook() )
|
||||
return ((morkBookAtom*) atom)->mBookAtom_Id;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
++cells;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
this->NonRowTypeError(ev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
morkRow::EmptyAllCells(morkEnv* ev)
|
||||
{
|
||||
|
@ -396,12 +444,46 @@ morkRow::EmptyAllCells(morkEnv* ev)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
morkRow::cut_all_index_entries(morkEnv* ev)
|
||||
{
|
||||
morkRowSpace* rowSpace = mRow_Space;
|
||||
if ( rowSpace->mRowSpace_IndexCount ) // any indexes?
|
||||
{
|
||||
morkCell* cells = mRow_Cells;
|
||||
if ( cells )
|
||||
{
|
||||
morkCell* end = cells + mRow_Length;
|
||||
--cells; // prepare for preincrement:
|
||||
while ( ++cells < end )
|
||||
{
|
||||
morkAtom* atom = cells->mCell_Atom;
|
||||
if ( atom )
|
||||
{
|
||||
mork_aid atomAid = atom->GetBookAtomAid();
|
||||
if ( atomAid )
|
||||
{
|
||||
mork_column col = cells->GetColumn();
|
||||
morkAtomRowMap* map = rowSpace->FindMap(ev, col);
|
||||
if ( map ) // cut row from index for this column?
|
||||
map->CutAid(ev, atomAid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
morkRow::CutAllColumns(morkEnv* ev)
|
||||
{
|
||||
morkStore* store = this->GetRowSpaceStore(ev);
|
||||
if ( store )
|
||||
{
|
||||
morkRowSpace* rowSpace = mRow_Space;
|
||||
if ( rowSpace->mRowSpace_IndexCount ) // any indexes?
|
||||
this->cut_all_index_entries(ev);
|
||||
|
||||
morkPool* pool = store->StorePool();
|
||||
pool->CutRowCells(ev, this, /*newSize*/ 0);
|
||||
}
|
||||
|
@ -415,6 +497,9 @@ morkRow::SetRow(morkEnv* ev, const morkRow* inSourceRow)
|
|||
morkStore* srcStore = inSourceRow->GetRowSpaceStore(ev);
|
||||
if ( store && srcStore )
|
||||
{
|
||||
morkRowSpace* rowSpace = mRow_Space;
|
||||
mork_count indexes = rowSpace->mRowSpace_IndexCount; // any indexes?
|
||||
|
||||
mork_bool sameStore = ( store == srcStore ); // identical stores?
|
||||
morkPool* pool = store->StorePool();
|
||||
if ( pool->CutRowCells(ev, this, /*newSize*/ 0) )
|
||||
|
@ -432,17 +517,17 @@ morkRow::SetRow(morkEnv* ev, const morkRow* inSourceRow)
|
|||
while ( ++dst < dstEnd && ++src < srcEnd && ev->Good() )
|
||||
{
|
||||
morkAtom* atom = src->mCell_Atom;
|
||||
mork_column col = src->GetColumn();
|
||||
mork_column dstCol = src->GetColumn();
|
||||
if ( sameStore ) // source and dest in same store?
|
||||
{
|
||||
dst->SetColumnAndChange(col, morkChange_kAdd);
|
||||
dst->SetColumnAndChange(dstCol, 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);
|
||||
dstCol = store->CopyToken(ev, dstCol, srcStore);
|
||||
if ( dstCol )
|
||||
{
|
||||
dst->SetColumnAndChange(dstCol, morkChange_kAdd);
|
||||
|
@ -452,6 +537,16 @@ morkRow::SetRow(morkEnv* ev, const morkRow* inSourceRow)
|
|||
atom->AddCellUse(ev);
|
||||
}
|
||||
}
|
||||
if ( indexes && atom )
|
||||
{
|
||||
mork_aid atomAid = atom->GetBookAtomAid();
|
||||
if ( atomAid )
|
||||
{
|
||||
morkAtomRowMap* map = rowSpace->FindMap(ev, dstCol);
|
||||
if ( map )
|
||||
map->AddAid(ev, atomAid, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -473,12 +568,14 @@ void
|
|||
morkRow::OnZeroTableUse(morkEnv* ev)
|
||||
// OnZeroTableUse() is called when CutTableUse() returns zero.
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
// ev->NewWarning("need to implement OnZeroTableUse");
|
||||
}
|
||||
|
||||
void
|
||||
morkRow::DirtyAllRowContent(morkEnv* ev)
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
this->SetRowDirty();
|
||||
|
||||
morkCell* cells = mRow_Cells;
|
||||
|
@ -527,6 +624,20 @@ void morkRow::CutColumn(morkEnv* ev, mdb_column inColumn)
|
|||
morkStore* store = this->GetRowSpaceStore(ev);
|
||||
if ( store )
|
||||
{
|
||||
morkRowSpace* rowSpace = mRow_Space;
|
||||
morkAtomRowMap* map = ( rowSpace->mRowSpace_IndexCount )?
|
||||
rowSpace->FindMap(ev, inColumn) : (morkAtomRowMap*) 0;
|
||||
if ( map ) // this row attribute is indexed by row space?
|
||||
{
|
||||
morkAtom* oldAtom = cell->mCell_Atom;
|
||||
if ( oldAtom ) // need to cut an entry from the index?
|
||||
{
|
||||
mork_aid oldAid = oldAtom->GetBookAtomAid();
|
||||
if ( oldAid ) // cut old row attribute from row index in space?
|
||||
map->CutAid(ev, oldAid);
|
||||
}
|
||||
}
|
||||
|
||||
morkPool* pool = store->StorePool();
|
||||
cell->SetAtom(ev, (morkAtom*) 0, pool);
|
||||
|
||||
|
@ -553,6 +664,25 @@ void morkRow::CutColumn(morkEnv* ev, mdb_column inColumn)
|
|||
}
|
||||
}
|
||||
|
||||
// void morkRow::cut_cell_from_space_index(morkEnv* ev, morkCell* ioCell)
|
||||
// {
|
||||
// morkAtom* oldAtom = ioCell->mCell_Atom;
|
||||
// if ( oldAtom )
|
||||
// {
|
||||
// mork_column col = ioCell->GetColumn();
|
||||
// morkRowSpace* rowSpace = mRow_Space;
|
||||
// morkAtomRowMap* map = ( rowSpace->mRowSpace_IndexCount )?
|
||||
// rowSpace->FindMap(ev, col) : (morkAtomRowMap*) 0;
|
||||
//
|
||||
// if ( map ) // col is indexed by row space?
|
||||
// {
|
||||
// mork_aid oldAid = oldAtom->GetBookAtomAid();
|
||||
// if ( oldAid ) // cut old row attribute from row index in space?
|
||||
// map->CutAid(ev, oldAid);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
void morkRow::AddColumn(morkEnv* ev, mdb_column inColumn,
|
||||
const mdbYarn* inYarn, morkStore* ioStore)
|
||||
{
|
||||
|
@ -570,7 +700,31 @@ void morkRow::AddColumn(morkEnv* ev, mdb_column inColumn,
|
|||
// cell->SetYarn(ev, inYarn, ioStore);
|
||||
morkAtom* atom = ioStore->YarnToAtom(ev, inYarn);
|
||||
if ( atom )
|
||||
{
|
||||
morkRowSpace* rowSpace = mRow_Space;
|
||||
morkAtomRowMap* map = ( rowSpace->mRowSpace_IndexCount )?
|
||||
rowSpace->FindMap(ev, inColumn) : (morkAtomRowMap*) 0;
|
||||
|
||||
if ( map ) // inColumn is indexed by row space?
|
||||
{
|
||||
morkAtom* oldAtom = cell->mCell_Atom;
|
||||
if ( oldAtom && oldAtom != atom ) // cut old cell from index?
|
||||
{
|
||||
mork_aid oldAid = oldAtom->GetBookAtomAid();
|
||||
if ( oldAid ) // cut old row attribute from row index in space?
|
||||
map->CutAid(ev, oldAid);
|
||||
}
|
||||
}
|
||||
|
||||
cell->SetAtom(ev, atom, ioStore->StorePool()); // refcounts atom
|
||||
|
||||
if ( map ) // inColumn is indexed by row space?
|
||||
{
|
||||
mork_aid newAid = atom->GetBookAtomAid();
|
||||
if ( newAid ) // add new row attribute to row index in space?
|
||||
map->AddAid(ev, newAid, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,6 +74,10 @@ public: // other row methods
|
|||
|
||||
public: // internal row methods
|
||||
|
||||
void cut_all_index_entries(morkEnv* ev);
|
||||
|
||||
// void cut_cell_from_space_index(morkEnv* ev, morkCell* ioCell);
|
||||
|
||||
mork_count CountOverlap(morkEnv* ev, morkCell* ioVector, mork_fill inFill);
|
||||
// Count cells in ioVector that change existing cells in this row when
|
||||
// ioVector is added to the row (as in TakeCells()). This is the set
|
||||
|
@ -100,6 +104,13 @@ public: // internal row methods
|
|||
morkCell* GetCell(morkEnv* ev, mdb_column inColumn, mork_pos* outPos) const;
|
||||
morkCell* CellAt(morkEnv* ev, mork_pos inPos) const;
|
||||
|
||||
mork_aid GetCellAtomAid(morkEnv* ev, mdb_column inColumn) const;
|
||||
// GetCellAtomAid() finds the cell with column inColumn, and sees if the
|
||||
// atom has a token ID, and returns the atom's ID if there is one. Or
|
||||
// else zero is returned if there is no such column, or no atom, or if
|
||||
// the atom has no ID to return. This method is intended to support
|
||||
// efficient updating of column indexes for rows in a row space.
|
||||
|
||||
public: // external row methods
|
||||
|
||||
void DirtyAllRowContent(morkEnv* ev);
|
||||
|
@ -132,7 +143,7 @@ public: // hash and equal
|
|||
return (mRow_Oid.mOid_Scope << 16) ^ mRow_Oid.mOid_Id;
|
||||
}
|
||||
|
||||
mork_u4 EqualRow(const morkRow* ioRow) const
|
||||
mork_bool EqualRow(const morkRow* ioRow) const
|
||||
{
|
||||
return
|
||||
(
|
||||
|
@ -141,7 +152,7 @@ public: // hash and equal
|
|||
);
|
||||
}
|
||||
|
||||
mork_u4 EqualOid(const mdbOid* ioOid) const
|
||||
mork_bool EqualOid(const mdbOid* ioOid) const
|
||||
{
|
||||
return
|
||||
(
|
||||
|
|
|
@ -103,12 +103,14 @@ morkRowMap::CloseRowMap(morkEnv* ev) // called by CloseMorkNode();
|
|||
morkRowMap::Equal(morkEnv* ev, const void* inKeyA,
|
||||
const void* inKeyB) const
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
return (*(const morkRow**) inKeyA)->EqualRow(*(const morkRow**) inKeyB);
|
||||
}
|
||||
|
||||
/*virtual*/ mork_u4 //
|
||||
morkRowMap::Hash(morkEnv* ev, const void* inKey) const
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
return (*(const morkRow**) inKey)->HashRow();
|
||||
}
|
||||
// } ===== end morkMap poly interface =====
|
||||
|
|
|
@ -68,6 +68,10 @@
|
|||
#include "morkRow.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKATOMMAP_
|
||||
#include "morkAtomMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKROWOBJECT_
|
||||
#include "morkRowObject.h"
|
||||
#endif
|
||||
|
@ -99,14 +103,29 @@ morkRowSpace::morkRowSpace(morkEnv* ev,
|
|||
const morkUsage& inUsage, mork_scope inScope, morkStore* ioStore,
|
||||
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap)
|
||||
: morkSpace(ev, inUsage, inScope, ioStore, ioHeap, ioSlotHeap)
|
||||
, mRowSpace_SlotHeap( ioSlotHeap )
|
||||
, mRowSpace_Rows(ev, morkUsage::kMember, (nsIMdbHeap*) 0, ioSlotHeap,
|
||||
morkRowSpace_kStartRowMapSlotCount)
|
||||
, mRowSpace_Tables(ev, morkUsage::kMember, (nsIMdbHeap*) 0, ioSlotHeap)
|
||||
, mRowSpace_NextTableId( 1 )
|
||||
, mRowSpace_NextRowId( 1 )
|
||||
|
||||
, mRowSpace_IndexCount( 0 )
|
||||
{
|
||||
morkAtomRowMap** cache = mRowSpace_IndexCache;
|
||||
morkAtomRowMap** cacheEnd = cache + morkRowSpace_kPrimeCacheSize;
|
||||
while ( cache < cacheEnd )
|
||||
*cache++ = 0; // put nil into every slot of cache table
|
||||
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kRowSpace;
|
||||
{
|
||||
if ( ioSlotHeap )
|
||||
{
|
||||
mNode_Derived = morkDerived_kRowSpace;
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
|
@ -116,11 +135,20 @@ morkRowSpace::CloseRowSpace(morkEnv* ev) // called by CloseMorkNode();
|
|||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
morkAtomRowMap** cache = mRowSpace_IndexCache;
|
||||
morkAtomRowMap** cacheEnd = cache + morkRowSpace_kPrimeCacheSize;
|
||||
--cache; // prepare for preincrement:
|
||||
while ( ++cache < cacheEnd )
|
||||
{
|
||||
if ( *cache )
|
||||
morkAtomRowMap::SlotStrongAtomRowMap(0, ev, cache);
|
||||
}
|
||||
|
||||
mRowSpace_Tables.CloseMorkNode(ev);
|
||||
|
||||
morkStore* store = mSpace_Store;
|
||||
if ( store )
|
||||
this->CutAllRows(ev, &store->mStore_Pool);
|
||||
this->CutAllRows(ev, &store->mStore_Pool);
|
||||
|
||||
mRowSpace_Rows.CloseMorkNode(ev);
|
||||
this->CloseSpace(ev);
|
||||
|
@ -187,18 +215,22 @@ morkRowSpace::CutAllRows(morkEnv* ev, morkPool* ioPool)
|
|||
for ( c = i.FirstRow(ev, &r); c && ev->Good();
|
||||
c = i.NextRow(ev, &r) )
|
||||
{
|
||||
if ( r->IsRow() )
|
||||
if ( r )
|
||||
{
|
||||
if ( r->mRow_Object )
|
||||
if ( r->IsRow() )
|
||||
{
|
||||
morkRowObject::SlotWeakRowObject((morkRowObject*) 0, ev,
|
||||
&r->mRow_Object);
|
||||
}
|
||||
if ( r )
|
||||
if ( r->mRow_Object )
|
||||
{
|
||||
morkRowObject::SlotWeakRowObject((morkRowObject*) 0, ev,
|
||||
&r->mRow_Object);
|
||||
}
|
||||
ioPool->ZapRow(ev, r);
|
||||
}
|
||||
else
|
||||
r->NonRowTypeWarning(ev);
|
||||
}
|
||||
else
|
||||
r->NonRowTypeWarning(ev);
|
||||
ev->NilPointerError();
|
||||
|
||||
i.CutHereRow(ev, /*key*/ (morkRow**) 0);
|
||||
}
|
||||
|
@ -346,6 +378,136 @@ morkRowSpace::MakeNewRowId(morkEnv* ev)
|
|||
return outRid;
|
||||
}
|
||||
|
||||
morkAtomRowMap*
|
||||
morkRowSpace::make_index(morkEnv* ev, mork_column inCol)
|
||||
{
|
||||
morkAtomRowMap* outMap = 0;
|
||||
nsIMdbHeap* heap = mRowSpace_SlotHeap;
|
||||
if ( heap ) // have expected heap for allocations?
|
||||
{
|
||||
morkAtomRowMap* map = new(*heap, ev)
|
||||
morkAtomRowMap(ev, morkUsage::kHeap, heap, heap, inCol);
|
||||
|
||||
if ( map ) // able to create new map index?
|
||||
{
|
||||
if ( ev->Good() ) // no errors during construction?
|
||||
{
|
||||
morkRowMapIter i(ev, &mRowSpace_Rows);
|
||||
mork_change* c = 0;
|
||||
morkRow* row = 0;
|
||||
mork_aid aidKey = 0;
|
||||
|
||||
for ( c = i.FirstRow(ev, &row); c && ev->Good();
|
||||
c = i.NextRow(ev, &row) ) // another row in space?
|
||||
{
|
||||
aidKey = row->GetCellAtomAid(ev, inCol);
|
||||
if ( aidKey ) // row has indexed attribute?
|
||||
map->AddAid(ev, aidKey, row); // include in map
|
||||
}
|
||||
}
|
||||
if ( ev->Good() ) // no errors constructing index?
|
||||
outMap = map; // return from function
|
||||
else
|
||||
map->CutStrongRef(ev); // discard map on error
|
||||
}
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
|
||||
return outMap;
|
||||
}
|
||||
|
||||
morkAtomRowMap*
|
||||
morkRowSpace::ForceMap(morkEnv* ev, mork_column inCol)
|
||||
{
|
||||
morkAtomRowMap* outMap = this->FindMap(ev, inCol);
|
||||
|
||||
if ( !outMap && ev->Good() ) // no such existing index?
|
||||
{
|
||||
if ( mRowSpace_IndexCount < morkRowSpace_kMaxIndexCount )
|
||||
{
|
||||
morkAtomRowMap* map = this->make_index(ev, inCol);
|
||||
if ( map ) // created a new index for col?
|
||||
{
|
||||
mork_count wrap = 0; // count times wrap-around occurs
|
||||
morkAtomRowMap** slot = mRowSpace_IndexCache; // table
|
||||
morkAtomRowMap** end = slot + morkRowSpace_kPrimeCacheSize;
|
||||
slot += ( inCol % morkRowSpace_kPrimeCacheSize ); // hash
|
||||
while ( *slot ) // empty slot not yet found?
|
||||
{
|
||||
if ( ++slot >= end ) // wrap around?
|
||||
{
|
||||
slot = mRowSpace_IndexCache; // back to table start
|
||||
if ( ++wrap > 1 ) // wrapped more than once?
|
||||
{
|
||||
ev->NewError("no free cache slots"); // disaster
|
||||
break; // end while loop
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( ev->Good() ) // everything went just fine?
|
||||
{
|
||||
++mRowSpace_IndexCount; // note another new map
|
||||
*slot = map; // install map in the hash table
|
||||
outMap = map; // return the new map from function
|
||||
}
|
||||
else
|
||||
map->CutStrongRef(ev); // discard map on error
|
||||
}
|
||||
}
|
||||
else
|
||||
ev->NewError("too many indexes"); // why so many indexes?
|
||||
}
|
||||
return outMap;
|
||||
}
|
||||
|
||||
morkAtomRowMap*
|
||||
morkRowSpace::FindMap(morkEnv* ev, mork_column inCol)
|
||||
{
|
||||
if ( mRowSpace_IndexCount && ev->Good() )
|
||||
{
|
||||
mork_count wrap = 0; // count times wrap-around occurs
|
||||
morkAtomRowMap** slot = mRowSpace_IndexCache; // table
|
||||
morkAtomRowMap** end = slot + morkRowSpace_kPrimeCacheSize;
|
||||
slot += ( inCol % morkRowSpace_kPrimeCacheSize ); // hash
|
||||
morkAtomRowMap* map = *slot;
|
||||
while ( map ) // another used slot to examine?
|
||||
{
|
||||
if ( inCol == map->mAtomRowMap_IndexColumn ) // found col?
|
||||
return map;
|
||||
if ( ++slot >= end ) // wrap around?
|
||||
{
|
||||
slot = mRowSpace_IndexCache;
|
||||
if ( ++wrap > 1 ) // wrapped more than once?
|
||||
return (morkAtomRowMap*) 0; // stop searching
|
||||
}
|
||||
map = *slot;
|
||||
}
|
||||
}
|
||||
return (morkAtomRowMap*) 0;
|
||||
}
|
||||
|
||||
morkRow*
|
||||
morkRowSpace::FindRow(morkEnv* ev, mork_column inCol, const mdbYarn* inYarn)
|
||||
{
|
||||
morkRow* outRow = 0;
|
||||
|
||||
morkAtom* atom = mSpace_Store->YarnToAtom(ev, inYarn);
|
||||
if ( atom ) // have or created an atom corresponding to input yarn?
|
||||
{
|
||||
mork_aid atomAid = atom->GetBookAtomAid();
|
||||
if ( atomAid ) // atom has an identity for use in hash table?
|
||||
{
|
||||
morkAtomRowMap* map = this->ForceMap(ev, inCol);
|
||||
if ( map ) // able to find or create index for col?
|
||||
{
|
||||
outRow = map->GetAid(ev, atomAid); // search for row
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return outRow;
|
||||
}
|
||||
|
||||
morkRow*
|
||||
morkRowSpace::NewRowWithOid(morkEnv* ev, const mdbOid* inOid)
|
||||
|
|
|
@ -43,12 +43,21 @@
|
|||
#include "morkTable.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKARRAY_
|
||||
#include "morkArray.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#define morkDerived_kRowSpace /*i*/ 0x7253 /* ascii 'rS' */
|
||||
|
||||
#define morkRowSpace_kStartRowMapSlotCount 512
|
||||
|
||||
#define morkRowSpace_kMaxIndexCount 8 /* no more indexes than this */
|
||||
#define morkRowSpace_kPrimeCacheSize 17 /* should be prime number */
|
||||
|
||||
class morkAtomRowMap;
|
||||
|
||||
/*| morkRowSpace:
|
||||
|*/
|
||||
class morkRowSpace : public morkSpace { //
|
||||
|
@ -76,11 +85,18 @@ class morkRowSpace : public morkSpace { //
|
|||
|
||||
public: // state is public because the entire Mork system is private
|
||||
|
||||
nsIMdbHeap* mRowSpace_SlotHeap;
|
||||
|
||||
morkRowMap mRowSpace_Rows; // hash table of morkRow instances
|
||||
morkTableMap mRowSpace_Tables; // all the tables in this row scope
|
||||
|
||||
mork_tid mRowSpace_NextTableId; // for auto-assigning table IDs
|
||||
mork_rid mRowSpace_NextRowId; // for auto-assigning row IDs
|
||||
mork_tid mRowSpace_NextTableId; // for auto-assigning table IDs
|
||||
mork_rid mRowSpace_NextRowId; // for auto-assigning row IDs
|
||||
|
||||
mork_count mRowSpace_IndexCount; // if nonzero, row indexes exist
|
||||
|
||||
// every nonzero slot in IndexCache is a strong ref to a morkAtomRowMap:
|
||||
morkAtomRowMap* mRowSpace_IndexCache[ morkRowSpace_kPrimeCacheSize ];
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
|
@ -131,6 +147,14 @@ public: // other space methods
|
|||
morkRow* NewRowWithOid(morkEnv* ev, const mdbOid* inOid);
|
||||
morkRow* NewRow(morkEnv* ev);
|
||||
|
||||
morkRow* FindRow(morkEnv* ev, mork_column inColumn, const mdbYarn* inYarn);
|
||||
|
||||
morkAtomRowMap* ForceMap(morkEnv* ev, mork_column inColumn);
|
||||
morkAtomRowMap* FindMap(morkEnv* ev, mork_column inColumn);
|
||||
|
||||
protected: // internal utilities
|
||||
morkAtomRowMap* make_index(morkEnv* ev, mork_column inColumn);
|
||||
|
||||
public: // typesafe refcounting inlines calling inherited morkNode methods
|
||||
static void SlotWeakRowSpace(morkRowSpace* me,
|
||||
morkEnv* ev, morkRowSpace** ioSlot)
|
||||
|
|
|
@ -57,7 +57,7 @@ morkSpool::FlushSink(morkEnv* ev) // sync mSpool_Coil->mBuf_Fill
|
|||
mork_u1* end = mSink_End;
|
||||
if ( at >= body && at <= end ) // expected cursor order?
|
||||
{
|
||||
mork_fill fill = at - body; // current content size
|
||||
mork_fill fill = (mork_fill) (at - body); // current content size
|
||||
if ( fill <= coil->mBlob_Size )
|
||||
coil->mBuf_Fill = fill;
|
||||
else
|
||||
|
@ -90,7 +90,7 @@ morkSpool::SpillPutc(morkEnv* ev, int c) // grow coil and write byte
|
|||
if ( at >= body && at <= end ) // expected cursor order?
|
||||
{
|
||||
mork_size size = coil->mBlob_Size;
|
||||
mork_fill fill = at - body; // current content size
|
||||
mork_fill fill = (mork_fill) (at - body); // current content size
|
||||
if ( fill <= size ) // less content than medium size?
|
||||
{
|
||||
coil->mBuf_Fill = fill;
|
||||
|
@ -121,7 +121,7 @@ morkSpool::SpillPutc(morkEnv* ev, int c) // grow coil and write byte
|
|||
{
|
||||
if ( at < end ) // morkSink::Putc() would succeed?
|
||||
{
|
||||
*at++ = c;
|
||||
*at++ = (mork_u1) c;
|
||||
mSink_At = at;
|
||||
coil->mBuf_Fill = fill + 1;
|
||||
}
|
||||
|
@ -201,14 +201,14 @@ morkSpool::Seek(morkEnv* ev, mork_pos inPos)
|
|||
morkCoil* coil = mSpool_Coil;
|
||||
if ( coil )
|
||||
{
|
||||
mork_size minSize = inPos + 64;
|
||||
mork_size minSize = (mork_size) (inPos + 64);
|
||||
|
||||
if ( coil->mBlob_Size < minSize )
|
||||
coil->GrowCoil(ev, minSize);
|
||||
|
||||
if ( ev->Good() )
|
||||
{
|
||||
coil->mBuf_Fill = inPos;
|
||||
coil->mBuf_Fill = (mork_fill) inPos;
|
||||
mork_u1* body = (mork_u1*) coil->mBuf_Body;
|
||||
if ( body )
|
||||
{
|
||||
|
@ -246,7 +246,7 @@ morkSpool::Write(morkEnv* ev, const void* inBuf, mork_size inSize)
|
|||
{
|
||||
// note coil->mBuf_Fill can be stale after morkSink::Putc():
|
||||
mork_pos fill = at - body; // current content size
|
||||
mork_num space = end - at; // space left in body
|
||||
mork_num space = (mork_num) (end - at); // space left in body
|
||||
if ( space < inSize ) // not enough to hold write?
|
||||
{
|
||||
mork_size minGrowth = space + 16;
|
||||
|
@ -258,7 +258,7 @@ morkSpool::Write(morkEnv* ev, const void* inBuf, mork_size inSize)
|
|||
{
|
||||
mSink_At = at = body + fill;
|
||||
mSink_End = end = body + coil->mBlob_Size;
|
||||
space = end - at; // space left in body
|
||||
space = (mork_num) (end - at); // space left in body
|
||||
}
|
||||
else
|
||||
coil->NilBufBodyError(ev);
|
||||
|
|
|
@ -94,7 +94,7 @@ morkSpace::morkSpace(morkEnv* ev,
|
|||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
if ( ioStore )
|
||||
if ( ioStore && ioSlotHeap )
|
||||
{
|
||||
morkStore::SlotWeakStore(ioStore, ev, &mSpace_Store);
|
||||
if ( ev->Good() )
|
||||
|
|
|
@ -274,6 +274,7 @@ morkStore::CloseStore(morkEnv* ev) // called by CloseMorkNode();
|
|||
void
|
||||
morkStore::RenumberAllCollectableContent(morkEnv* ev)
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
// do nothing currently
|
||||
}
|
||||
|
||||
|
@ -367,6 +368,7 @@ morkStore::StageStringAsBookAtom(morkEnv* ev, const char* inString,
|
|||
|
||||
morkAtomSpace* morkStore::LazyGetOidAtomSpace(morkEnv* ev)
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
if ( !mStore_OidAtomSpace )
|
||||
{
|
||||
}
|
||||
|
@ -551,6 +553,7 @@ mork_bool
|
|||
morkStore::OpenStoreFile(morkEnv* ev, mork_bool inFrozen,
|
||||
const char* inFilePath, const mdbOpenPolicy* inOpenPolicy)
|
||||
{
|
||||
MORK_USED_1(inOpenPolicy);
|
||||
morkFile::SlotStrongFile((morkFile*) 0, ev, &mStore_File);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
|
@ -571,6 +574,7 @@ mork_bool
|
|||
morkStore::CreateStoreFile(morkEnv* ev,
|
||||
const char* inFilePath, const mdbOpenPolicy* inOpenPolicy)
|
||||
{
|
||||
MORK_USED_1(inOpenPolicy);
|
||||
morkFile::SlotStrongFile((morkFile*) 0, ev, &mStore_File);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
|
@ -736,6 +740,7 @@ morkStore::MidToAtom(morkEnv* ev, const morkMid& inMid)
|
|||
morkStore::SmallTokenToOneByteYarn(morkEnv* ev, mdb_token inToken,
|
||||
mdbYarn* outYarn)
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
if ( outYarn->mYarn_Buf && outYarn->mYarn_Size ) // any space in yarn at all?
|
||||
{
|
||||
mork_u1* buf = (mork_u1*) outYarn->mYarn_Buf; // for byte arithmetic
|
||||
|
@ -1028,10 +1033,14 @@ mork_bool
|
|||
morkStore::HasTableKind(morkEnv* ev, mdb_scope inRowScope,
|
||||
mdb_kind inTableKind, mdb_count* outTableCount)
|
||||
{
|
||||
MORK_USED_2(inRowScope,inTableKind);
|
||||
mork_bool outBool = morkBool_kFalse;
|
||||
mdb_count tableCount = 0;
|
||||
|
||||
ev->StubMethodOnlyError();
|
||||
|
||||
if ( outTableCount )
|
||||
*outTableCount = tableCount;
|
||||
return outBool;
|
||||
}
|
||||
|
||||
|
@ -1059,6 +1068,22 @@ morkStore::GetTableKind(morkEnv* ev, mdb_scope inRowScope,
|
|||
return outTable;
|
||||
}
|
||||
|
||||
morkRow*
|
||||
morkStore::FindRow(morkEnv* ev, mdb_scope inScope, mdb_column inColumn,
|
||||
const mdbYarn* inYarn)
|
||||
{
|
||||
morkRow* outRow = 0;
|
||||
if ( ev->Good() )
|
||||
{
|
||||
morkRowSpace* rowSpace = this->LazyGetRowSpace(ev, inScope);
|
||||
if ( rowSpace )
|
||||
{
|
||||
outRow = rowSpace->FindRow(ev, inColumn, inYarn);
|
||||
}
|
||||
}
|
||||
return outRow;
|
||||
}
|
||||
|
||||
morkRow*
|
||||
morkStore::GetRow(morkEnv* ev, const mdbOid* inOid)
|
||||
{
|
||||
|
|
|
@ -294,6 +294,9 @@ public: // other store methods
|
|||
morkTable* GetTableKind(morkEnv* ev, mdb_scope inRowScope,
|
||||
mdb_kind inTableKind, mdb_count* outTableCount,
|
||||
mdb_bool* outMustBeUnique);
|
||||
|
||||
morkRow* FindRow(morkEnv* ev, mdb_scope inScope, mdb_column inColumn,
|
||||
const mdbYarn* inTargetCellValue);
|
||||
|
||||
morkRow* GetRow(morkEnv* ev, const mdbOid* inOid);
|
||||
morkTable* GetTable(morkEnv* ev, const mdbOid* inOid);
|
||||
|
|
|
@ -381,6 +381,7 @@ morkStream::AcquireBud(morkEnv* ev, nsIMdbHeap* ioHeap)
|
|||
// behavior is exhibited by the file, so crashes protect old files.
|
||||
// Note that AcquireBud() is an illegal operation on readonly files.
|
||||
{
|
||||
MORK_USED_1(ioHeap);
|
||||
morkFile* outFile = 0;
|
||||
morkFile* file = mStream_ContentFile;
|
||||
if ( this->IsOpenAndActiveFile() && file )
|
||||
|
@ -508,7 +509,7 @@ morkStream::Read(morkEnv* ev, void* outBuf, mork_size inSize)
|
|||
mork_u1* buf = mStream_Buf;
|
||||
if ( at >= buf && at <= end ) // expected cursor order?
|
||||
{
|
||||
mork_num remaining = end - at; // bytes left in buffer
|
||||
mork_num remaining = (mork_num) (end - at); // bytes left in buffer
|
||||
|
||||
mork_num quantum = inSize; // number of bytes to copy
|
||||
if ( quantum > remaining ) // more than buffer content?
|
||||
|
@ -534,7 +535,7 @@ morkStream::Read(morkEnv* ev, void* outBuf, mork_size inSize)
|
|||
// exhausted the local buffer, so we need to show
|
||||
// it is now empty, and adjust the current buf pos.
|
||||
|
||||
mork_num posDelta = (at - buf); // old buf content
|
||||
mork_num posDelta = (mork_num) (at - buf); // old buf content
|
||||
mStream_BufPos += posDelta; // past now empty buf
|
||||
|
||||
mStream_At = mStream_ReadEnd = buf; // empty buffer
|
||||
|
@ -569,7 +570,7 @@ morkStream::Read(morkEnv* ev, void* outBuf, mork_size inSize)
|
|||
if ( ev->Bad() )
|
||||
outActual = 0;
|
||||
|
||||
return outActual;
|
||||
return (mork_size) outActual;
|
||||
}
|
||||
|
||||
/*public virtual*/ mork_pos
|
||||
|
@ -658,7 +659,7 @@ morkStream::Write(morkEnv* ev, const void* inBuf, mork_size inSize)
|
|||
mork_u1* buf = mStream_Buf;
|
||||
if ( at >= buf && at <= end ) // expected cursor order?
|
||||
{
|
||||
mork_num space = end - at; // space left in buffer
|
||||
mork_num space = (mork_num) (end - at); // space left in buffer
|
||||
|
||||
mork_num quantum = inSize; // number of bytes to write
|
||||
if ( quantum > space ) // more than buffer size?
|
||||
|
@ -695,7 +696,7 @@ morkStream::Write(morkEnv* ev, const void* inBuf, mork_size inSize)
|
|||
|
||||
if ( ev->Good() ) // no errors?
|
||||
{
|
||||
space = end - at; // space left in buffer
|
||||
space = (mork_num) (end - at); // space left in buffer
|
||||
if ( space > inSize ) // write to buffer?
|
||||
{
|
||||
mStream_Dirty = morkBool_kTrue; // ensure flush
|
||||
|
@ -817,7 +818,7 @@ morkStream::spill_buf(morkEnv* ev) // spill/flush from buffer to file
|
|||
mork_u1* at = mStream_At;
|
||||
if ( at >= buf && at <= mStream_WriteEnd ) // order?
|
||||
{
|
||||
mork_num count = at - buf; // the number of bytes buffered
|
||||
mork_num count = (mork_num) (at - buf); // bytes buffered
|
||||
if ( count ) // anything to write to the string?
|
||||
{
|
||||
if ( count > mStream_BufSize ) // no more than max?
|
||||
|
|
|
@ -210,7 +210,7 @@ public: // public non-poly morkStream methods
|
|||
{ this->PutString(ev, inString); }
|
||||
|
||||
void Ungetc(int c) /*i*/
|
||||
{ if ( mStream_At > mStream_Buf && c > 0 ) *--mStream_At = c; }
|
||||
{ if ( mStream_At > mStream_Buf && c > 0 ) *--mStream_At = (mork_u1) c; }
|
||||
|
||||
// Note Getc() returns EOF consistently after any fill_getc() error occurs.
|
||||
int Getc(morkEnv* ev) /*i*/
|
||||
|
@ -220,7 +220,7 @@ public: // public non-poly morkStream methods
|
|||
{
|
||||
mStream_Dirty = morkBool_kTrue;
|
||||
if ( mStream_At < mStream_WriteEnd )
|
||||
*mStream_At++ = c;
|
||||
*mStream_At++ = (mork_u1) c;
|
||||
else
|
||||
spill_putc(ev, c);
|
||||
}
|
||||
|
|
|
@ -162,6 +162,7 @@ morkTable::CloseTable(morkEnv* ev) /*i*/ // called by CloseMorkNode();
|
|||
mork_u2
|
||||
morkTable::AddCellUse(morkEnv* ev)
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
if ( mTable_CellUses < morkTable_kMaxCellUses ) // not already maxed out?
|
||||
++mTable_CellUses;
|
||||
|
||||
|
@ -266,6 +267,7 @@ morkTable::AcquireTableHandle(morkEnv* ev)
|
|||
mork_pos
|
||||
morkTable::ArrayHasOid(morkEnv* ev, const mdbOid* inOid)
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
mork_count count = mTable_RowArray.mArray_Fill;
|
||||
mork_pos pos = -1;
|
||||
while ( ++pos < count )
|
||||
|
|
|
@ -111,8 +111,13 @@ morkThumb::morkThumb(morkEnv* ev,
|
|||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
mThumb_Magic = inMagic;
|
||||
mNode_Derived = morkDerived_kThumb;
|
||||
if ( ioSlotHeap )
|
||||
{
|
||||
mThumb_Magic = inMagic;
|
||||
mNode_Derived = morkDerived_kThumb;
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -218,7 +223,7 @@ morkThumb::Make_OpenFileStore(morkEnv* ev, nsIMdbHeap* ioHeap,
|
|||
morkBuilder* builder = ioStore->LazyGetBuilder(ev);
|
||||
if ( builder )
|
||||
{
|
||||
outThumb->mThumb_Total = fileEof;
|
||||
outThumb->mThumb_Total = (mork_count) fileEof;
|
||||
morkStore::SlotStrongStore(ioStore, ev, &outThumb->mThumb_Store);
|
||||
morkBuilder::SlotStrongBuilder(builder, ev,
|
||||
&outThumb->mThumb_Builder);
|
||||
|
@ -277,6 +282,7 @@ morkThumb::Make_CompressCommit(morkEnv* ev,
|
|||
void morkThumb::GetProgress(morkEnv* ev, mdb_count* outTotal,
|
||||
mdb_count* outCurrent, mdb_bool* outDone, mdb_bool* outBroken)
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
if ( outTotal )
|
||||
*outTotal = mThumb_Total;
|
||||
if ( outCurrent )
|
||||
|
@ -350,6 +356,7 @@ void morkThumb::DoMore(morkEnv* ev, mdb_count* outTotal,
|
|||
|
||||
void morkThumb::CancelAndBreakThumb(morkEnv* ev)
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
mThumb_Broken = morkBool_kTrue;
|
||||
}
|
||||
|
||||
|
@ -359,6 +366,7 @@ morkStore*
|
|||
morkThumb::ThumbToOpenStore(morkEnv* ev)
|
||||
// for orkinFactory::ThumbToOpenStore() after OpenFileStore()
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
return mThumb_Store;
|
||||
}
|
||||
|
||||
|
@ -376,7 +384,7 @@ void morkThumb::DoMore_OpenFileStore(morkEnv* ev)
|
|||
builder->ParseMore(ev, &pos, &mThumb_Done, &mThumb_Broken);
|
||||
// mThumb_Total = builder->mBuilder_TotalCount;
|
||||
// mThumb_Current = builder->mBuilder_DoneCount;
|
||||
mThumb_Current = pos;
|
||||
mThumb_Current = (mork_count) pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1027,7 +1027,7 @@ morkWriter::WriteTokenToTokenMetaCell(morkEnv* ev,
|
|||
{
|
||||
morkStream* stream = mWriter_Stream;
|
||||
mork_bool isKindCol = ( morkStore_kKindColumn == inCol );
|
||||
mork_u1 valSep = ( isKindCol )? '^' : '=';
|
||||
mork_u1 valSep = (mork_u1) (( isKindCol )? '^' : '=');
|
||||
|
||||
char buf[ 128 ]; // buffer for staging the two hex IDs
|
||||
char* p = buf;
|
||||
|
@ -1096,6 +1096,50 @@ morkWriter::WriteStringToTokenDictCell(morkEnv* ev,
|
|||
// mWriter_LineSize += stream->Write(ev, yarnBuf, fill + 1); // +1 for ')'
|
||||
}
|
||||
|
||||
void
|
||||
morkWriter::ChangeDictAtomScope(morkEnv* ev, mork_scope inScope)
|
||||
{
|
||||
if ( inScope != mWriter_DictAtomScope )
|
||||
{
|
||||
ev->NewWarning("unexpected atom scope change");
|
||||
|
||||
morkStream* stream = mWriter_Stream;
|
||||
if ( mWriter_LineSize )
|
||||
stream->PutLineBreak(ev);
|
||||
mWriter_LineSize = 0;
|
||||
|
||||
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_kAtomScopeColumn;
|
||||
|
||||
mork_size scopeSize = 1; // default to one byte
|
||||
if ( inScope >= 0x80 )
|
||||
{
|
||||
*p++ = '^'; // indicates col is hex ID
|
||||
scopeSize = ev->TokenAsHex(p, inScope);
|
||||
p += scopeSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
*p++ = '='; // indicates col is imm byte
|
||||
*p++ = (char) (mork_u1) inScope;
|
||||
}
|
||||
|
||||
*p++ = ')';
|
||||
*p++ = '>';
|
||||
*p = 0;
|
||||
|
||||
mork_size pending = scopeSize + 6;
|
||||
this->IndentOverMaxLine(ev, pending, morkWriter_kDictAliasDepth);
|
||||
|
||||
mWriter_LineSize += stream->Write(ev, buf, pending);
|
||||
|
||||
mWriter_DictAtomScope = inScope;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
morkWriter::ChangeDictForm(morkEnv* ev, mork_cscode inNewForm)
|
||||
{
|
||||
|
@ -1111,10 +1155,20 @@ morkWriter::ChangeDictForm(morkEnv* ev, mork_cscode inNewForm)
|
|||
*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;
|
||||
mork_size formSize = 1; // default to one byte
|
||||
if ( inNewForm >= 0x80 )
|
||||
{
|
||||
*p++ = '^'; // indicates col is hex ID
|
||||
formSize = ev->TokenAsHex(p, inNewForm);
|
||||
p += formSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
*p++ = '='; // indicates col is imm byte
|
||||
*p++ = (char) (mork_u1) inNewForm;
|
||||
}
|
||||
|
||||
*p++ = ')';
|
||||
*p++ = '>';
|
||||
*p = 0;
|
||||
|
@ -1246,6 +1300,8 @@ morkWriter::EndTable(morkEnv* ev)
|
|||
morkStream* stream = mWriter_Stream;
|
||||
stream->Putc(ev, '}'); // end table
|
||||
++mWriter_LineSize;
|
||||
|
||||
mWriter_TableAtomScope = 'v'; // (a=v)
|
||||
}
|
||||
|
||||
mork_bool
|
||||
|
@ -1284,6 +1340,10 @@ morkWriter::PutRowDict(morkEnv* ev, morkRow* ioRow)
|
|||
|
||||
if ( atom->AliasYarn(&yarn) )
|
||||
{
|
||||
mork_scope atomScope = atom->GetBookAtomSpaceScope(ev);
|
||||
if ( atomScope && atomScope != mWriter_DictAtomScope )
|
||||
this->ChangeDictAtomScope(ev, atomScope);
|
||||
|
||||
if ( mWriter_DidStartDict && yarn.mYarn_Form != mWriter_DictForm )
|
||||
this->ChangeDictForm(ev, yarn.mYarn_Form);
|
||||
|
||||
|
@ -1354,6 +1414,9 @@ morkWriter::PutRowCells(morkEnv* ev, morkRow* ioRow)
|
|||
mdbYarn yarn; // to ref content inside atom
|
||||
atom->AliasYarn(&yarn);
|
||||
|
||||
if ( yarn.mYarn_Form != mWriter_DictForm )
|
||||
this->ChangeDictForm(ev, yarn.mYarn_Form);
|
||||
|
||||
if ( atom->IsBook() ) // is it possible to write atom ID?
|
||||
{
|
||||
this->IndentAsNeeded(ev, morkWriter_kRowCellDepth);
|
||||
|
@ -1375,7 +1438,8 @@ morkWriter::PutRowCells(morkEnv* ev, morkRow* ioRow)
|
|||
p += yarnFill;
|
||||
}
|
||||
*p++ = ')';
|
||||
mWriter_LineSize += stream->Write(ev, buf, p - buf);
|
||||
mork_size distance = (mork_size) (p - buf);
|
||||
mWriter_LineSize += stream->Write(ev, buf, distance);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1392,9 +1456,6 @@ morkWriter::PutRowCells(morkEnv* ev, morkRow* ioRow)
|
|||
}
|
||||
else // must write an anonymous atom
|
||||
{
|
||||
if ( yarn.mYarn_Form != mWriter_DictForm )
|
||||
this->ChangeDictForm(ev, yarn.mYarn_Form);
|
||||
|
||||
mork_size pending = yarn.mYarn_Fill + colSize +
|
||||
morkWriter_kYarnEscapeSlop + 2;
|
||||
this->IndentOverMaxLine(ev, pending, morkWriter_kRowCellDepth);
|
||||
|
|
|
@ -204,8 +204,11 @@ public: // typing & errors
|
|||
static void NilWriterStreamError(morkEnv* ev);
|
||||
static void UnsupportedPhaseError(morkEnv* ev);
|
||||
|
||||
public: // inlines
|
||||
public: // utitlities
|
||||
void ChangeDictForm(morkEnv* ev, mork_cscode inNewForm);
|
||||
void ChangeDictAtomScope(morkEnv* ev, mork_scope inScope);
|
||||
|
||||
public: // inlines
|
||||
mork_bool DidStartDict() const { return mWriter_DidStartDict; }
|
||||
mork_bool DidEndDict() const { return mWriter_DidEndDict; }
|
||||
|
||||
|
@ -225,7 +228,7 @@ public: // inlines
|
|||
mWriter_LineSize = mWriter_Stream->PutIndent(ev, inDepth);
|
||||
}
|
||||
|
||||
public: // iterative/asynchronouse writing
|
||||
public: // iterative/asynchronous writing
|
||||
|
||||
mork_bool WriteMore(morkEnv* ev); // call until IsWritingDone() is true
|
||||
|
||||
|
|
|
@ -292,6 +292,7 @@ orkinCell::IsOpenMdbObject(nsIMdbEnv* mev, mdb_bool* outOpen)
|
|||
orkinCell::SetBlob(nsIMdbEnv* mev,
|
||||
nsIMdbBlob* ioBlob)
|
||||
{
|
||||
MORK_USED_1(ioBlob);
|
||||
mdb_err outErr = 0;
|
||||
morkCell* cell = 0;
|
||||
morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue,
|
||||
|
@ -331,6 +332,7 @@ orkinCell::GetBlobFill(nsIMdbEnv* mev,
|
|||
// with a yarn instance that had mYarn_Buf==nil and mYarn_Size==0.
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
mdb_fill fill = 0;
|
||||
morkCell* cell = 0;
|
||||
morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue,
|
||||
&outErr, &cell);
|
||||
|
@ -339,6 +341,8 @@ orkinCell::GetBlobFill(nsIMdbEnv* mev,
|
|||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( outFill )
|
||||
*outFill = fill;
|
||||
|
||||
return outErr;
|
||||
} // size of blob
|
||||
|
@ -418,6 +422,7 @@ orkinCell::AliasYarn(nsIMdbEnv* mev,
|
|||
/*virtual*/ mdb_err
|
||||
orkinCell::SetColumn(nsIMdbEnv* mev, mdb_column inColumn)
|
||||
{
|
||||
MORK_USED_1(inColumn);
|
||||
mdb_err outErr = 0;
|
||||
morkCell* cell = 0;
|
||||
morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue,
|
||||
|
@ -462,6 +467,12 @@ orkinCell::GetCellInfo( // all cell metainfo except actual content
|
|||
// in to memory when you don't actually want to use the content.
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
mdb_bool isRowChild = morkBool_kFalse;
|
||||
mdbOid childOid;
|
||||
childOid.mOid_Scope = 0;
|
||||
childOid.mOid_Id = 0;
|
||||
mork_fill blobFill = 0;
|
||||
mdb_column column = 0;
|
||||
morkCell* cell = 0;
|
||||
morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue,
|
||||
&outErr, &cell);
|
||||
|
@ -471,6 +482,14 @@ orkinCell::GetCellInfo( // all cell metainfo except actual content
|
|||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( outIsRowChild )
|
||||
*outIsRowChild = isRowChild;
|
||||
if ( outChildOid )
|
||||
*outChildOid = childOid;
|
||||
if ( outBlobFill )
|
||||
*outBlobFill = blobFill;
|
||||
if ( outColumn )
|
||||
*outColumn = column;
|
||||
|
||||
return outErr;
|
||||
}
|
||||
|
@ -594,6 +613,7 @@ orkinCell::SetChildRow( // access table of specific attribute
|
|||
nsIMdbEnv* mev, // context
|
||||
nsIMdbRow* ioRow)
|
||||
{
|
||||
MORK_USED_1(ioRow);
|
||||
mdb_err outErr = 0;
|
||||
morkCell* cell = 0;
|
||||
morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue,
|
||||
|
@ -614,6 +634,7 @@ orkinCell::GetChildRow( // access row of specific attribute
|
|||
nsIMdbRow** acqRow) // acquire child row (or nil if no child)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
nsIMdbRow* outRow = 0;
|
||||
morkCell* cell = 0;
|
||||
morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue,
|
||||
&outErr, &cell);
|
||||
|
@ -623,6 +644,8 @@ orkinCell::GetChildRow( // access row of specific attribute
|
|||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( acqRow )
|
||||
*acqRow = outRow;
|
||||
|
||||
return outErr;
|
||||
}
|
||||
|
@ -633,6 +656,7 @@ orkinCell::SetChildTable( // access table of specific attribute
|
|||
nsIMdbEnv* mev, // context
|
||||
nsIMdbTable* inTable) // table must be bound inside this same db port
|
||||
{
|
||||
MORK_USED_1(inTable);
|
||||
mdb_err outErr = 0;
|
||||
morkCell* cell = 0;
|
||||
morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue,
|
||||
|
@ -653,6 +677,7 @@ orkinCell::GetChildTable( // access table of specific attribute
|
|||
nsIMdbTable** acqTable) // acquire child tabdle (or nil if no chil)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
nsIMdbTable* outTable = 0;
|
||||
morkCell* cell = 0;
|
||||
morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue,
|
||||
&outErr, &cell);
|
||||
|
@ -662,6 +687,8 @@ orkinCell::GetChildTable( // access table of specific attribute
|
|||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( acqTable )
|
||||
*acqTable = outTable;
|
||||
|
||||
return outErr;
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ protected: // morkHandle memory management operators
|
|||
{ return ioPool.NewHandle(ev, inSize); }
|
||||
|
||||
void* operator new(size_t inSize, morkHandleFace* ioFace)
|
||||
{ return ioFace; }
|
||||
{ MORK_USED_1(inSize); return ioFace; }
|
||||
|
||||
void operator delete(void* ioAddress)
|
||||
{ morkNode::OnDeleteAssert(ioAddress); }
|
||||
|
|
|
@ -77,6 +77,7 @@ orkinEnv::MakeEnv(morkEnv* ev, morkEnv* ioObject)
|
|||
morkEnv*
|
||||
orkinEnv::CanUseEnv(mork_bool inMutable, mdb_err* outErr) const
|
||||
{
|
||||
MORK_USED_1(inMutable);
|
||||
morkEnv* outEnv = 0;
|
||||
mdb_err err = morkEnv_kBadEnvError;
|
||||
if ( this->IsHandle() )
|
||||
|
|
|
@ -73,7 +73,7 @@ protected: // morkHandle memory management operators
|
|||
{ return ioPool.NewHandle(ev, inSize); }
|
||||
|
||||
void* operator new(size_t inSize, morkHandleFace* ioFace)
|
||||
{ return ioFace; }
|
||||
{ MORK_USED_1(inSize); return ioFace; }
|
||||
|
||||
void operator delete(void* ioAddress)
|
||||
{ morkNode::OnDeleteAssert(ioAddress); }
|
||||
|
|
|
@ -346,13 +346,19 @@ orkinFactory::MakeHeap(nsIMdbEnv* mev, nsIMdbHeap** acqHeap)
|
|||
orkinFactory::MakeRow(nsIMdbEnv* mev, nsIMdbHeap* ioHeap,
|
||||
nsIMdbRow** acqRow)
|
||||
{
|
||||
MORK_USED_1(ioHeap);
|
||||
mdb_err outErr = 0;
|
||||
nsIMdbRow* outRow = 0;
|
||||
morkEnv* ev = this->CanUseFactory(mev,
|
||||
/*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( acqRow )
|
||||
*acqRow = outRow;
|
||||
|
||||
return outErr;
|
||||
}
|
||||
// ioHeap can be nil, causing the heap associated with ev to be used
|
||||
|
@ -368,6 +374,10 @@ orkinFactory::CanOpenFilePort(
|
|||
mdbYarn* outFormatVersion)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
if ( outFormatVersion )
|
||||
{
|
||||
outFormatVersion->mYarn_Fill = 0;
|
||||
}
|
||||
mdb_bool canOpenAsPort = morkBool_kFalse;
|
||||
morkEnv* ev = this->CanUseFactory(mev,
|
||||
/*inMutable*/ morkBool_kFalse, &outErr);
|
||||
|
@ -385,6 +395,7 @@ orkinFactory::CanOpenFilePort(
|
|||
|
||||
if ( outCanOpen )
|
||||
*outCanOpen = canOpenAsPort;
|
||||
|
||||
return outErr;
|
||||
}
|
||||
|
||||
|
@ -396,6 +407,7 @@ orkinFactory::OpenFilePort(
|
|||
const mdbOpenPolicy* inOpenPolicy, // runtime policies for using db
|
||||
nsIMdbThumb** acqThumb)
|
||||
{
|
||||
MORK_USED_1(ioHeap);
|
||||
mdb_err outErr = 0;
|
||||
nsIMdbThumb* outThumb = 0;
|
||||
morkEnv* ev = this->CanUseFactory(mev,
|
||||
|
@ -438,7 +450,7 @@ orkinFactory::ThumbToOpenPort( // redeeming a completed thumb from OpenFilePort(
|
|||
morkStore* store = thumb->ThumbToOpenStore(ev);
|
||||
if ( store )
|
||||
{
|
||||
store->mStore_CanAutoAssignAtomIdentity = morkBool_kTrue;
|
||||
store->mStore_CanAutoAssignAtomIdentity = morkBool_kTrue;
|
||||
outPort = orkinStore::MakeStore(ev, store);
|
||||
}
|
||||
}
|
||||
|
@ -458,6 +470,7 @@ mork_bool
|
|||
orkinFactory::CanOpenMorkTextFile(morkEnv* ev,
|
||||
const mdbYarn* inFirst512Bytes)
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
mork_bool outBool = morkBool_kFalse;
|
||||
mork_size headSize = MORK_STRLEN(morkWriter_kFileHeader);
|
||||
const mdbYarn* y = inFirst512Bytes;
|
||||
|
@ -481,6 +494,10 @@ orkinFactory::CanOpenFileStore(
|
|||
{
|
||||
mdb_bool canOpenAsStore = morkBool_kFalse;
|
||||
mdb_bool canOpenAsPort = morkBool_kFalse;
|
||||
if ( outFormatVersion )
|
||||
{
|
||||
outFormatVersion->mYarn_Fill = 0;
|
||||
}
|
||||
mdb_err outErr = 0;
|
||||
morkEnv* ev = this->CanUseFactory(mev,
|
||||
/*inMutable*/ morkBool_kFalse, &outErr);
|
||||
|
@ -576,7 +593,7 @@ orkinFactory::ThumbToOpenStore( // redeem completed thumb from OpenFileStore()
|
|||
morkStore* store = thumb->ThumbToOpenStore(ev);
|
||||
if ( store )
|
||||
{
|
||||
store->mStore_CanAutoAssignAtomIdentity = morkBool_kTrue;
|
||||
store->mStore_CanAutoAssignAtomIdentity = morkBool_kTrue;
|
||||
outStore = orkinStore::MakeStore(ev, store);
|
||||
}
|
||||
}
|
||||
|
@ -616,7 +633,7 @@ orkinFactory::CreateNewFileStore( // create a new db with minimal content
|
|||
|
||||
if ( store )
|
||||
{
|
||||
store->mStore_CanAutoAssignAtomIdentity = morkBool_kTrue;
|
||||
store->mStore_CanAutoAssignAtomIdentity = morkBool_kTrue;
|
||||
if ( store->CreateStoreFile(ev, inFilePath, inOpenPolicy) )
|
||||
outStore = orkinStore::MakeStore(ev, store);
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ protected: // morkHandle memory management operators
|
|||
{ return ioPool.NewHandle(ev, inSize); }
|
||||
|
||||
void* operator new(size_t inSize, morkHandleFace* ioFace)
|
||||
{ return ioFace; }
|
||||
{ MORK_USED_1(inSize); return ioFace; }
|
||||
|
||||
void operator delete(void* ioAddress)
|
||||
{ morkNode::OnDeleteAssert(ioAddress); }
|
||||
|
|
|
@ -50,6 +50,7 @@ orkinHeap::Alloc(nsIMdbEnv* ev, // allocate a piece of memory
|
|||
mdb_size inSize, // requested size of new memory block
|
||||
void** outBlock) // memory block of inSize bytes, or nil
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
mdb_err outErr = 0;
|
||||
void* block = new char[ inSize ];
|
||||
if ( !block )
|
||||
|
@ -65,6 +66,7 @@ orkinHeap::Alloc(nsIMdbEnv* ev, // allocate a piece of memory
|
|||
orkinHeap::Free(nsIMdbEnv* ev, // free block allocated earlier by Alloc()
|
||||
void* inBlock)
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
MORK_ASSERT(inBlock);
|
||||
if ( inBlock )
|
||||
delete [] inBlock;
|
||||
|
|
|
@ -211,6 +211,7 @@ orkinPortTableCursor::IsOpenMdbObject(nsIMdbEnv* mev, mdb_bool* outOpen)
|
|||
orkinPortTableCursor::GetCount(nsIMdbEnv* mev, mdb_count* outCount)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
mdb_count count = 0;
|
||||
morkEnv* ev =
|
||||
this->CanUsePortTableCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
|
@ -218,6 +219,8 @@ orkinPortTableCursor::GetCount(nsIMdbEnv* mev, mdb_count* outCount)
|
|||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( outCount )
|
||||
*outCount = count;
|
||||
return outErr;
|
||||
}
|
||||
|
||||
|
@ -225,6 +228,7 @@ orkinPortTableCursor::GetCount(nsIMdbEnv* mev, mdb_count* outCount)
|
|||
orkinPortTableCursor::GetSeed(nsIMdbEnv* mev, mdb_seed* outSeed)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
mdb_seed seed = 0;
|
||||
morkEnv* ev =
|
||||
this->CanUsePortTableCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
|
@ -232,12 +236,15 @@ orkinPortTableCursor::GetSeed(nsIMdbEnv* mev, mdb_seed* outSeed)
|
|||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( outSeed )
|
||||
*outSeed = seed;
|
||||
return outErr;
|
||||
}
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinPortTableCursor::SetPos(nsIMdbEnv* mev, mdb_pos inPos)
|
||||
{
|
||||
MORK_USED_1(inPos);
|
||||
mdb_err outErr = 0;
|
||||
morkEnv* ev =
|
||||
this->CanUsePortTableCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
|
@ -253,6 +260,7 @@ orkinPortTableCursor::SetPos(nsIMdbEnv* mev, mdb_pos inPos)
|
|||
orkinPortTableCursor::GetPos(nsIMdbEnv* mev, mdb_pos* outPos)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
mdb_pos pos = 0;
|
||||
morkEnv* ev =
|
||||
this->CanUsePortTableCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
|
@ -260,12 +268,16 @@ orkinPortTableCursor::GetPos(nsIMdbEnv* mev, mdb_pos* outPos)
|
|||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( outPos )
|
||||
*outPos = pos;
|
||||
|
||||
return outErr;
|
||||
}
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinPortTableCursor::SetDoFailOnSeedOutOfSync(nsIMdbEnv* mev, mdb_bool inFail)
|
||||
{
|
||||
MORK_USED_1(inFail);
|
||||
mdb_err outErr = 0;
|
||||
morkEnv* ev =
|
||||
this->CanUsePortTableCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
|
@ -281,6 +293,7 @@ orkinPortTableCursor::SetDoFailOnSeedOutOfSync(nsIMdbEnv* mev, mdb_bool inFail)
|
|||
orkinPortTableCursor::GetDoFailOnSeedOutOfSync(nsIMdbEnv* mev, mdb_bool* outFail)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
mdb_bool fail = 0;
|
||||
morkEnv* ev =
|
||||
this->CanUsePortTableCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
|
@ -288,6 +301,8 @@ orkinPortTableCursor::GetDoFailOnSeedOutOfSync(nsIMdbEnv* mev, mdb_bool* outFail
|
|||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( outFail )
|
||||
*outFail = fail;
|
||||
return outErr;
|
||||
}
|
||||
// } ----- end attribute methods -----
|
||||
|
@ -300,6 +315,7 @@ orkinPortTableCursor::GetDoFailOnSeedOutOfSync(nsIMdbEnv* mev, mdb_bool* outFail
|
|||
/*virtual*/ mdb_err
|
||||
orkinPortTableCursor::SetPort(nsIMdbEnv* mev, nsIMdbPort* ioPort)
|
||||
{
|
||||
MORK_USED_1(ioPort);
|
||||
mdb_err outErr = 0;
|
||||
morkEnv* ev =
|
||||
this->CanUsePortTableCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
|
|
|
@ -80,7 +80,7 @@ protected: // morkHandle memory management operators
|
|||
{ return ioPool.NewHandle(ev, inSize); }
|
||||
|
||||
void* operator new(size_t inSize, morkHandleFace* ioFace)
|
||||
{ return ioFace; }
|
||||
{ MORK_USED_1(inSize); return ioFace; }
|
||||
|
||||
void operator delete(void* ioAddress)
|
||||
{ morkNode::OnDeleteAssert(ioAddress); }
|
||||
|
|
|
@ -370,6 +370,7 @@ orkinRow::GetOid(nsIMdbEnv* mev,
|
|||
orkinRow::BecomeContent(nsIMdbEnv* mev,
|
||||
const mdbOid* inOid)
|
||||
{
|
||||
MORK_USED_1(inOid);
|
||||
mdb_err outErr = 0;
|
||||
morkRow* row = 0;
|
||||
morkEnv* ev = this->CanUseRow(mev, /*inMutable*/ morkBool_kFalse,
|
||||
|
@ -424,7 +425,7 @@ orkinRow::GetRowCellCursor( // make a cursor starting iteration at inRowPos
|
|||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
cursor->mCursor_Seed = inPos;
|
||||
cursor->mCursor_Seed = (mork_seed) inPos;
|
||||
outCursor = cursor->AcquireRowCellCursorHandle(ev);
|
||||
}
|
||||
else
|
||||
|
@ -678,7 +679,6 @@ orkinRow::SetRow( // make exact duplicate of another row
|
|||
}
|
||||
return outErr;
|
||||
}
|
||||
|
||||
// } ----- end row methods -----
|
||||
|
||||
// } ===== end nsIMdbRow methods =====
|
||||
|
|
|
@ -74,7 +74,7 @@ protected: // morkHandle memory management operators
|
|||
{ return ioPool.NewHandle(ev, inSize); }
|
||||
|
||||
void* operator new(size_t inSize, morkHandleFace* ioFace)
|
||||
{ return ioFace; }
|
||||
{ MORK_USED_1(inSize); return ioFace; }
|
||||
|
||||
void operator delete(void* ioAddress)
|
||||
{ morkNode::OnDeleteAssert(ioAddress); }
|
||||
|
|
|
@ -455,7 +455,9 @@ orkinRowCellCursor::SeekCell( // same as SetRow() followed by MakeCell()
|
|||
mdb_column* outColumn, // column for this particular cell
|
||||
nsIMdbCell** acqCell)
|
||||
{
|
||||
MORK_USED_1(inPos);
|
||||
mdb_err outErr = 0;
|
||||
mdb_column column = 0;
|
||||
nsIMdbCell* outCell = 0;
|
||||
morkRow* row = 0;
|
||||
morkEnv* ev =
|
||||
|
@ -468,6 +470,8 @@ orkinRowCellCursor::SeekCell( // same as SetRow() followed by MakeCell()
|
|||
}
|
||||
if ( acqCell )
|
||||
*acqCell = outCell;
|
||||
if ( outColumn )
|
||||
*outColumn = column;
|
||||
return outErr;
|
||||
}
|
||||
// } ----- end cell seeking methods -----
|
||||
|
@ -480,7 +484,10 @@ orkinRowCellCursor::NextCell( // get next cell in the row
|
|||
mdb_column* outColumn, // column for this particular cell
|
||||
mdb_pos* outPos)
|
||||
{
|
||||
MORK_USED_1(ioCell);
|
||||
mdb_err outErr = 0;
|
||||
mdb_pos pos = -1;
|
||||
mdb_column column = 0;
|
||||
morkRow* row = 0;
|
||||
morkEnv* ev =
|
||||
this->CanUseRowCellCursor(mev, /*mut*/ morkBool_kFalse, &outErr, &row);
|
||||
|
@ -490,6 +497,10 @@ orkinRowCellCursor::NextCell( // get next cell in the row
|
|||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( outColumn )
|
||||
*outColumn = column;
|
||||
if ( outPos )
|
||||
*outPos = pos;
|
||||
return outErr;
|
||||
}
|
||||
|
||||
|
@ -504,6 +515,9 @@ orkinRowCellCursor::PickNextCell( // get next cell in row within filter set
|
|||
// cols, since this might imply a potential excessive consumption of time
|
||||
// over many cursor calls when looking for column and filter intersection.
|
||||
{
|
||||
MORK_USED_2(ioCell,inFilterSet);
|
||||
mdb_pos pos = -1;
|
||||
mdb_column column = 0;
|
||||
mdb_err outErr = 0;
|
||||
morkRow* row = 0;
|
||||
morkEnv* ev =
|
||||
|
@ -514,6 +528,10 @@ orkinRowCellCursor::PickNextCell( // get next cell in row within filter set
|
|||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( outColumn )
|
||||
*outColumn = column;
|
||||
if ( outPos )
|
||||
*outPos = pos;
|
||||
return outErr;
|
||||
}
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ protected: // morkHandle memory management operators
|
|||
{ return ioPool.NewHandle(ev, inSize); }
|
||||
|
||||
void* operator new(size_t inSize, morkHandleFace* ioFace)
|
||||
{ return ioFace; }
|
||||
{ MORK_USED_1(inSize); return ioFace; }
|
||||
|
||||
void operator delete(void* ioAddress)
|
||||
{ morkNode::OnDeleteAssert(ioAddress); }
|
||||
|
|
|
@ -228,19 +228,23 @@ orkinStore::IsOpenMdbObject(nsIMdbEnv* mev, mdb_bool* outOpen)
|
|||
orkinStore::GetIsPortReadonly(nsIMdbEnv* mev, mdb_bool* outBool)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
mdb_bool isReadOnly = morkBool_kFalse;
|
||||
morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( outBool )
|
||||
*outBool = isReadOnly;
|
||||
return outErr;
|
||||
}
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinStore::GetIsStore(nsIMdbEnv* mev, mdb_bool* outBool)
|
||||
{
|
||||
if ( outBool )
|
||||
MORK_USED_1(mev);
|
||||
if ( outBool )
|
||||
*outBool = morkBool_kTrue;
|
||||
return 0;
|
||||
}
|
||||
|
@ -265,6 +269,7 @@ orkinStore::GetIsStoreAndDirty(nsIMdbEnv* mev, mdb_bool* outBool)
|
|||
orkinStore::GetUsagePolicy(nsIMdbEnv* mev,
|
||||
mdbUsagePolicy* ioUsagePolicy)
|
||||
{
|
||||
MORK_USED_1(ioUsagePolicy);
|
||||
mdb_err outErr = 0;
|
||||
morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
|
@ -279,6 +284,7 @@ orkinStore::GetUsagePolicy(nsIMdbEnv* mev,
|
|||
orkinStore::SetUsagePolicy(nsIMdbEnv* mev,
|
||||
const mdbUsagePolicy* inUsagePolicy)
|
||||
{
|
||||
MORK_USED_1(inUsagePolicy);
|
||||
mdb_err outErr = 0;
|
||||
morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
|
@ -315,13 +321,17 @@ orkinStore::SessionMemoryPurge( // request specific footprint decrease
|
|||
mdb_size inDesiredBytesFreed, // approximate number of bytes wanted
|
||||
mdb_size* outEstimatedBytesFreed) // approximate bytes actually freed
|
||||
{
|
||||
MORK_USED_1(inDesiredBytesFreed);
|
||||
mdb_err outErr = 0;
|
||||
mdb_size estimate = 0;
|
||||
morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
// ev->StubMethodOnlyError(); // okay to do nothing?
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( outEstimatedBytesFreed )
|
||||
*outEstimatedBytesFreed = estimate;
|
||||
return outErr;
|
||||
}
|
||||
|
||||
|
@ -331,12 +341,15 @@ orkinStore::PanicMemoryPurge( // desperately free all possible memory
|
|||
mdb_size* outEstimatedBytesFreed) // approximate bytes actually freed
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
mdb_size estimate = 0;
|
||||
morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
// ev->StubMethodOnlyError(); // okay to do nothing?
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( outEstimatedBytesFreed )
|
||||
*outEstimatedBytesFreed = estimate;
|
||||
return outErr;
|
||||
}
|
||||
// } ----- end memory policy methods -----
|
||||
|
@ -349,6 +362,10 @@ orkinStore::GetPortFilePath(
|
|||
mdbYarn* outFormatVersion) // file format description
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
if ( outFormatVersion )
|
||||
outFormatVersion->mYarn_Fill = 0;
|
||||
if ( outFilePath )
|
||||
outFilePath->mYarn_Fill = 0;
|
||||
morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
|
@ -366,6 +383,8 @@ orkinStore::BestExportFormat( // determine preferred export format
|
|||
mdbYarn* outFormatVersion) // file format description
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
if ( outFormatVersion )
|
||||
outFormatVersion->mYarn_Fill = 0;
|
||||
morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
|
@ -381,6 +400,8 @@ orkinStore::CanExportToFormat( // can export content in given specific format?
|
|||
const char* inFormatVersion, // file format description
|
||||
mdb_bool* outCanExport) // whether ExportSource() might succeed
|
||||
{
|
||||
MORK_USED_1(inFormatVersion);
|
||||
mdb_bool canExport = morkBool_kFalse;
|
||||
mdb_err outErr = 0;
|
||||
morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
|
@ -388,6 +409,8 @@ orkinStore::CanExportToFormat( // can export content in given specific format?
|
|||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( outCanExport )
|
||||
*outCanExport = canExport;
|
||||
return outErr;
|
||||
}
|
||||
|
||||
|
@ -400,13 +423,17 @@ orkinStore::ExportToFormat( // export content in given specific format
|
|||
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
|
||||
// then the export will be finished.
|
||||
{
|
||||
MORK_USED_2(inFilePath,inFormatVersion);
|
||||
mdb_err outErr = 0;
|
||||
nsIMdbThumb* outThumb = 0;
|
||||
morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( acqThumb )
|
||||
*acqThumb = outThumb;
|
||||
return outErr;
|
||||
}
|
||||
|
||||
|
@ -547,6 +574,71 @@ orkinStore::GetRowRefCount( // get number of tables that contain a row
|
|||
*outRefCount = count;
|
||||
return outErr;
|
||||
}
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinStore::FindRow(nsIMdbEnv* mev, // search for row with matching cell
|
||||
mdb_scope inRowScope, // row scope for row ids
|
||||
mdb_column inColumn, // the column to search (and maintain an index)
|
||||
const mdbYarn* inTargetCellValue, // cell value for which to search
|
||||
mdbOid* outRowOid, // out row oid on match (or {0,-1} for no match)
|
||||
nsIMdbRow** acqRow) // acquire matching row (or nil for no match)
|
||||
// FindRow() searches for one row that has a cell in column inColumn with
|
||||
// a contained value with the same form (i.e. charset) and is byte-wise
|
||||
// identical to the blob described by yarn inTargetCellValue. Both content
|
||||
// and form of the yarn must be an exact match to find a matching row.
|
||||
//
|
||||
// (In other words, both a yarn's blob bytes and form are significant. The
|
||||
// form is not expected to vary in columns used for identity anyway. This
|
||||
// is intended to make the cost of FindRow() cheaper for MDB implementors,
|
||||
// since any cell value atomization performed internally must necessarily
|
||||
// make yarn form significant in order to avoid data loss in atomization.)
|
||||
//
|
||||
// FindRow() can lazily create an index on attribute inColumn for all rows
|
||||
// with that attribute in row space scope inRowScope, so that subsequent
|
||||
// calls to FindRow() will perform faster. Such an index might or might
|
||||
// not be persistent (but this seems desirable if it is cheap to do so).
|
||||
// Note that lazy index creation in readonly DBs is not very feasible.
|
||||
//
|
||||
// This FindRow() interface assumes that attribute inColumn is effectively
|
||||
// an alternative means of unique identification for a row in a rowspace,
|
||||
// so correct behavior is only guaranteed when no duplicates for this col
|
||||
// appear in the given set of rows. (If more than one row has the same cell
|
||||
// value in this column, no more than one will be found; and cutting one of
|
||||
// two duplicate rows can cause the index to assume no other such row lives
|
||||
// in the row space, so future calls return nil for negative search results
|
||||
// even though some duplicate row might still live within the rowspace.)
|
||||
//
|
||||
// In other words, the FindRow() implementation is allowed to assume simple
|
||||
// hash tables mapping unqiue column keys to associated row values will be
|
||||
// sufficient, where any duplication is not recorded because only one copy
|
||||
// of a given key need be remembered. Implementors are not required to sort
|
||||
// all rows by the specified column.
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
nsIMdbRow* outRow = 0;
|
||||
mdbOid rowOid;
|
||||
rowOid.mOid_Scope = 0;
|
||||
rowOid.mOid_Id = (mdb_id) -1;
|
||||
|
||||
morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
morkStore* store = (morkStore*) mHandle_Object;
|
||||
morkRow* row = store->FindRow(ev, inRowScope, inColumn, inTargetCellValue);
|
||||
if ( row && ev->Good() )
|
||||
{
|
||||
outRow = row->AcquireRowHandle(ev, store);
|
||||
if ( outRow )
|
||||
rowOid = row->mRow_Oid;
|
||||
}
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( acqRow )
|
||||
*acqRow = outRow;
|
||||
|
||||
return outErr;
|
||||
}
|
||||
|
||||
// } ----- end row methods -----
|
||||
|
||||
// { ----- begin table methods -----
|
||||
|
@ -735,6 +827,9 @@ orkinStore::RowScopeHasAssignedIds(nsIMdbEnv* mev,
|
|||
mdb_bool* outCallerAssigned, // nonzero if caller assigned specified
|
||||
mdb_bool* outStoreAssigned) // nonzero if store db assigned specified
|
||||
{
|
||||
MORK_USED_1(inRowScope);
|
||||
mdb_bool storeAssigned = morkBool_kFalse;
|
||||
mdb_bool callerAssigned = morkBool_kFalse;
|
||||
mdb_err outErr = 0;
|
||||
morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
|
@ -742,6 +837,10 @@ orkinStore::RowScopeHasAssignedIds(nsIMdbEnv* mev,
|
|||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( outCallerAssigned )
|
||||
*outCallerAssigned = callerAssigned;
|
||||
if ( outStoreAssigned )
|
||||
*outStoreAssigned = storeAssigned;
|
||||
return outErr;
|
||||
}
|
||||
|
||||
|
@ -751,6 +850,9 @@ orkinStore::SetCallerAssignedIds(nsIMdbEnv* mev,
|
|||
mdb_bool* outCallerAssigned, // nonzero if caller assigned specified
|
||||
mdb_bool* outStoreAssigned) // nonzero if store db assigned specified
|
||||
{
|
||||
MORK_USED_1(inRowScope);
|
||||
mdb_bool storeAssigned = morkBool_kFalse;
|
||||
mdb_bool callerAssigned = morkBool_kFalse;
|
||||
mdb_err outErr = 0;
|
||||
morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
|
@ -758,6 +860,10 @@ orkinStore::SetCallerAssignedIds(nsIMdbEnv* mev,
|
|||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( outCallerAssigned )
|
||||
*outCallerAssigned = callerAssigned;
|
||||
if ( outStoreAssigned )
|
||||
*outStoreAssigned = storeAssigned;
|
||||
return outErr;
|
||||
}
|
||||
|
||||
|
@ -767,13 +873,20 @@ orkinStore::SetStoreAssignedIds(nsIMdbEnv* mev,
|
|||
mdb_bool* outCallerAssigned, // nonzero if caller assigned specified
|
||||
mdb_bool* outStoreAssigned) // nonzero if store db assigned specified
|
||||
{
|
||||
MORK_USED_1(inRowScope);
|
||||
mdb_err outErr = 0;
|
||||
mdb_bool storeAssigned = morkBool_kFalse;
|
||||
mdb_bool callerAssigned = morkBool_kFalse;
|
||||
morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( outCallerAssigned )
|
||||
*outCallerAssigned = callerAssigned;
|
||||
if ( outStoreAssigned )
|
||||
*outStoreAssigned = storeAssigned;
|
||||
return outErr;
|
||||
}
|
||||
// } ----- end row scope methods -----
|
||||
|
@ -836,6 +949,8 @@ orkinStore::ImportContent( // import content from port
|
|||
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
|
||||
// then the import will be finished.
|
||||
{
|
||||
MORK_USED_2(inRowScope,ioPort);
|
||||
nsIMdbThumb* outThumb = 0;
|
||||
mdb_err outErr = 0;
|
||||
morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
|
@ -843,6 +958,8 @@ orkinStore::ImportContent( // import content from port
|
|||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( acqThumb )
|
||||
*acqThumb = outThumb;
|
||||
return outErr;
|
||||
}
|
||||
// } ----- end inport/export methods -----
|
||||
|
@ -854,6 +971,7 @@ orkinStore::ShareAtomColumnsHint( // advise re shared col content atomizing
|
|||
mdb_scope inScopeHint, // zero, or suggested shared namespace
|
||||
const mdbColumnSet* inColumnSet) // cols desired tokenized together
|
||||
{
|
||||
MORK_USED_2(inColumnSet,inScopeHint);
|
||||
mdb_err outErr = 0;
|
||||
morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
|
@ -869,6 +987,7 @@ orkinStore::AvoidAtomColumnsHint( // advise col w/ poor atomizing prospects
|
|||
nsIMdbEnv* mev, // context
|
||||
const mdbColumnSet* inColumnSet) // cols with poor atomizing prospects
|
||||
{
|
||||
MORK_USED_1(inColumnSet);
|
||||
mdb_err outErr = 0;
|
||||
morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
|
|
|
@ -73,7 +73,7 @@ protected: // morkHandle memory management operators
|
|||
{ return ioPool.NewHandle(ev, inSize); }
|
||||
|
||||
void* operator new(size_t inSize, morkHandleFace* ioFace)
|
||||
{ return ioFace; }
|
||||
{ MORK_USED_1(inSize); return ioFace; }
|
||||
|
||||
void operator delete(void* ioAddress)
|
||||
{ morkNode::OnDeleteAssert(ioAddress); }
|
||||
|
@ -218,16 +218,54 @@ public: // type identification
|
|||
nsIMdbEnv* ev, // context
|
||||
const mdbOid* inOid, // hypothetical row oid
|
||||
mdb_bool* outHasRow); // whether GetRow() might succeed
|
||||
|
||||
virtual mdb_err GetRowRefCount( // get number of tables that contain a row
|
||||
nsIMdbEnv* ev, // context
|
||||
const mdbOid* inOid, // hypothetical row oid
|
||||
mdb_count* outRefCount); // number of tables containing inRowKey
|
||||
|
||||
virtual mdb_err GetRow( // access one row with specific oid
|
||||
nsIMdbEnv* ev, // context
|
||||
const mdbOid* inOid, // hypothetical row oid
|
||||
nsIMdbRow** acqRow); // acquire specific row (or null)
|
||||
|
||||
virtual mdb_err GetRowRefCount( // get number of tables that contain a row
|
||||
nsIMdbEnv* ev, // context
|
||||
const mdbOid* inOid, // hypothetical row oid
|
||||
mdb_count* outRefCount); // number of tables containing inRowKey
|
||||
virtual mdb_err FindRow(nsIMdbEnv* ev, // search for row with matching cell
|
||||
mdb_scope inRowScope, // row scope for row ids
|
||||
mdb_column inColumn, // the column to search (and maintain an index)
|
||||
const mdbYarn* inTargetCellValue, // cell value for which to search
|
||||
mdbOid* outRowOid, // out row oid on match (or {0,-1} for no match)
|
||||
nsIMdbRow** acqRow); // acquire matching row (or nil for no match)
|
||||
// FindRow() searches for one row that has a cell in column inColumn with
|
||||
// a contained value with the same form (i.e. charset) and is byte-wise
|
||||
// identical to the blob described by yarn inTargetCellValue. Both content
|
||||
// and form of the yarn must be an exact match to find a matching row.
|
||||
//
|
||||
// (In other words, both a yarn's blob bytes and form are significant. The
|
||||
// form is not expected to vary in columns used for identity anyway. This
|
||||
// is intended to make the cost of FindRow() cheaper for MDB implementors,
|
||||
// since any cell value atomization performed internally must necessarily
|
||||
// make yarn form significant in order to avoid data loss in atomization.)
|
||||
//
|
||||
// FindRow() can lazily create an index on attribute inColumn for all rows
|
||||
// with that attribute in row space scope inRowScope, so that subsequent
|
||||
// calls to FindRow() will perform faster. Such an index might or might
|
||||
// not be persistent (but this seems desirable if it is cheap to do so).
|
||||
// Note that lazy index creation in readonly DBs is not very feasible.
|
||||
//
|
||||
// This FindRow() interface assumes that attribute inColumn is effectively
|
||||
// an alternative means of unique identification for a row in a rowspace,
|
||||
// so correct behavior is only guaranteed when no duplicates for this col
|
||||
// appear in the given set of rows. (If more than one row has the same cell
|
||||
// value in this column, no more than one will be found; and cutting one of
|
||||
// two duplicate rows can cause the index to assume no other such row lives
|
||||
// in the row space, so future calls return nil for negative search results
|
||||
// even though some duplicate row might still live within the rowspace.)
|
||||
//
|
||||
// In other words, the FindRow() implementation is allowed to assume simple
|
||||
// hash tables mapping unqiue column keys to associated row values will be
|
||||
// sufficient, where any duplication is not recorded because only one copy
|
||||
// of a given key need be remembered. Implementors are not required to sort
|
||||
// all rows by the specified column.
|
||||
// } ----- end row methods -----
|
||||
|
||||
// { ----- begin table methods -----
|
||||
|
|
|
@ -310,6 +310,7 @@ orkinTable::GetOid(nsIMdbEnv* mev,
|
|||
orkinTable::BecomeContent(nsIMdbEnv* mev,
|
||||
const mdbOid* inOid) // exchange content
|
||||
{
|
||||
MORK_USED_1(inOid);
|
||||
mdb_err outErr = 0;
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
|
@ -458,7 +459,7 @@ orkinTable::GetTableRowCursor( // make a cursor, starting iteration at inRowPos
|
|||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
cursor->mCursor_Seed = inRowPos;
|
||||
cursor->mCursor_Seed = (mork_seed) inRowPos;
|
||||
outCursor = cursor->AcquireTableRowCursorHandle(ev);
|
||||
}
|
||||
else
|
||||
|
@ -483,7 +484,7 @@ orkinTable::PosToOid( // get row member for a table position
|
|||
mdb_err outErr = 0;
|
||||
mdbOid roid;
|
||||
roid.mOid_Scope = 0;
|
||||
roid.mOid_Id = -1;
|
||||
roid.mOid_Id = (mork_id) -1;
|
||||
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
|
@ -576,6 +577,7 @@ orkinTable::AddOid( // make sure the row with inOid is a table member
|
|||
nsIMdbEnv* mev, // context
|
||||
const mdbOid* inOid) // row to ensure membership in table
|
||||
{
|
||||
MORK_USED_1(inOid);
|
||||
mdb_err outErr = 0;
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
|
@ -736,6 +738,10 @@ orkinTable::SearchOneSortedColumn( // search only currently sorted col
|
|||
const mdbYarn* inPrefix, // content to find as prefix in row's column cell
|
||||
mdbRange* outRange) // range of matching rows
|
||||
{
|
||||
MORK_USED_1(inPrefix);
|
||||
mdbRange range;
|
||||
range.mRange_FirstPos = -1;
|
||||
range.mRange_LastPos = -1;
|
||||
mdb_err outErr = 0;
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
|
@ -743,6 +749,8 @@ orkinTable::SearchOneSortedColumn( // search only currently sorted col
|
|||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( outRange )
|
||||
*outRange = range;
|
||||
return outErr;
|
||||
}
|
||||
|
||||
|
@ -757,13 +765,17 @@ orkinTable::SearchManyColumns( // search variable number of sorted cols
|
|||
// is assumed referenced and used by the thumb; one should not inspect any
|
||||
// output results in ioSearch until after the thumb is finished with it.
|
||||
{
|
||||
MORK_USED_2(inPrefix,ioSearch);
|
||||
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;
|
||||
}
|
||||
// } ----- end searching methods -----
|
||||
|
@ -774,6 +786,7 @@ orkinTable::SearchColumnsHint( // advise re future expected search cols
|
|||
nsIMdbEnv* mev, // context
|
||||
const mdbColumnSet* inColumnSet) // columns likely to be searched
|
||||
{
|
||||
MORK_USED_1(inColumnSet);
|
||||
mdb_err outErr = 0;
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
|
@ -789,6 +802,7 @@ orkinTable::SortColumnsHint( // advise re future expected sort columns
|
|||
nsIMdbEnv* mev, // context
|
||||
const mdbColumnSet* inColumnSet) // columns for likely sort requests
|
||||
{
|
||||
MORK_USED_1(inColumnSet);
|
||||
mdb_err outErr = 0;
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
|
@ -807,6 +821,7 @@ orkinTable::StartBatchChangeHint( // advise before many adds and cuts
|
|||
// the address of a local variable makes a good batch start label that
|
||||
// can be used at batch end time, and such addresses remain unique.
|
||||
{
|
||||
MORK_USED_1(inLabel);
|
||||
mdb_err outErr = 0;
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
|
@ -831,6 +846,7 @@ orkinTable::EndBatchChangeHint( // advise before many adds and cuts
|
|||
// a full sort of all rows at need when the batch changes end, or when
|
||||
// a surprise request occurs for row position during batch changes.
|
||||
{
|
||||
MORK_USED_1(inLabel);
|
||||
mdb_err outErr = 0;
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
|
@ -852,6 +868,8 @@ orkinTable::CanSortColumn( // query which col is currently used for sorting
|
|||
mdb_column inColumn, // column to query sorting potential
|
||||
mdb_bool* outCanSort) // whether the column can be sorted
|
||||
{
|
||||
MORK_USED_1(inColumn);
|
||||
mdb_bool canSort = morkBool_kFalse;
|
||||
mdb_err outErr = 0;
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
|
@ -861,6 +879,8 @@ orkinTable::CanSortColumn( // query which col is currently used for sorting
|
|||
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( outCanSort )
|
||||
*outCanSort = canSort;
|
||||
return outErr;
|
||||
}
|
||||
|
||||
|
@ -871,6 +891,8 @@ orkinTable::NewSortColumn( // change col used for sorting in the table
|
|||
mdb_column* outActualColumn, // column actually used for sorting
|
||||
nsIMdbThumb** acqThumb) // acquire thumb for incremental table resort
|
||||
{
|
||||
MORK_USED_1(inColumn);
|
||||
mdb_column actualColumn = 0;
|
||||
mdb_err outErr = 0;
|
||||
nsIMdbThumb* outThumb = 0;
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
|
@ -879,6 +901,8 @@ orkinTable::NewSortColumn( // change col used for sorting in the table
|
|||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( outActualColumn )
|
||||
*outActualColumn = actualColumn;
|
||||
if ( acqThumb )
|
||||
*acqThumb = outThumb;
|
||||
return outErr;
|
||||
|
@ -894,6 +918,8 @@ orkinTable::NewSortColumnWithCompare( // change sort col w/ explicit compare
|
|||
mdb_column* outActualColumn, // column actually used for sorting
|
||||
nsIMdbThumb** acqThumb) // acquire thumb for incremental table resort
|
||||
{
|
||||
MORK_USED_2(inColumn,ioCompare);
|
||||
mdb_column actualColumn = 0;
|
||||
mdb_err outErr = 0;
|
||||
nsIMdbThumb* outThumb = 0;
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
|
@ -902,6 +928,8 @@ orkinTable::NewSortColumnWithCompare( // change sort col w/ explicit compare
|
|||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( outActualColumn )
|
||||
*outActualColumn = actualColumn;
|
||||
if ( acqThumb )
|
||||
*acqThumb = outThumb;
|
||||
return outErr;
|
||||
|
@ -937,6 +965,7 @@ orkinTable::CloneSortColumn( // view same table with a different sort
|
|||
mdb_column inColumn, // requested new column for sorting table
|
||||
nsIMdbThumb** acqThumb) // acquire thumb for incremental table clone
|
||||
{
|
||||
MORK_USED_1(inColumn);
|
||||
mdb_err outErr = 0;
|
||||
nsIMdbThumb* outThumb = 0;
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
|
@ -958,6 +987,7 @@ orkinTable::ThumbToCloneSortTable( // redeem complete CloneSortColumn() thumb
|
|||
nsIMdbThumb* ioThumb, // thumb from CloneSortColumn() with done status
|
||||
nsIMdbTable** acqTable) // new table instance (or old if sort unchanged)
|
||||
{
|
||||
MORK_USED_1(ioThumb);
|
||||
mdb_err outErr = 0;
|
||||
nsIMdbTable* outTable = 0;
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
|
@ -983,13 +1013,17 @@ orkinTable::MoveOid( // change position of row in unsorted table
|
|||
mdb_pos inToPos, // desired new position for row inRowId
|
||||
mdb_pos* outActualPos) // actual new position of row in table
|
||||
{
|
||||
MORK_USED_3(inHintFromPos,inToPos,inOid);
|
||||
mdb_err outErr = 0;
|
||||
mdb_pos actualPos = 0;
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( outActualPos )
|
||||
*outActualPos = actualPos;
|
||||
return outErr;
|
||||
}
|
||||
|
||||
|
@ -1001,6 +1035,8 @@ orkinTable::MoveRow( // change position of row in unsorted table
|
|||
mdb_pos inToPos, // desired new position for row inRowId
|
||||
mdb_pos* outActualPos) // actual new position of row in table
|
||||
{
|
||||
MORK_USED_3(inHintFromPos,inToPos,ioRow);
|
||||
mdb_pos actualPos = 0;
|
||||
mdb_err outErr = 0;
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
|
@ -1008,6 +1044,8 @@ orkinTable::MoveRow( // change position of row in unsorted table
|
|||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( outActualPos )
|
||||
*outActualPos = actualPos;
|
||||
return outErr;
|
||||
}
|
||||
// } ----- end moving methods -----
|
||||
|
@ -1021,6 +1059,8 @@ orkinTable::AddIndex( // create a sorting index for column if possible
|
|||
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
|
||||
// then the index addition will be finished.
|
||||
{
|
||||
MORK_USED_1(inColumn);
|
||||
nsIMdbThumb* outThumb = 0;
|
||||
mdb_err outErr = 0;
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
|
@ -1029,6 +1069,9 @@ orkinTable::AddIndex( // create a sorting index for column if possible
|
|||
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( acqThumb )
|
||||
*acqThumb = outThumb;
|
||||
|
||||
return outErr;
|
||||
}
|
||||
|
||||
|
@ -1040,7 +1083,9 @@ orkinTable::CutIndex( // stop supporting a specific column index
|
|||
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
|
||||
// then the index removal will be finished.
|
||||
{
|
||||
MORK_USED_1(inColumn);
|
||||
mdb_err outErr = 0;
|
||||
nsIMdbThumb* outThumb = 0;
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
|
@ -1048,6 +1093,9 @@ orkinTable::CutIndex( // stop supporting a specific column index
|
|||
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( acqThumb )
|
||||
*acqThumb = outThumb;
|
||||
|
||||
return outErr;
|
||||
}
|
||||
|
||||
|
@ -1057,15 +1105,17 @@ orkinTable::HasIndex( // query for current presence of a column index
|
|||
mdb_column inColumn, // the column to investigate
|
||||
mdb_bool* outHasIndex) // whether column has index for this column
|
||||
{
|
||||
MORK_USED_1(inColumn);
|
||||
mdb_bool hasIndex = morkBool_kFalse;
|
||||
mdb_err outErr = 0;
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
if ( outHasIndex )
|
||||
*outHasIndex = morkBool_kFalse;
|
||||
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( outHasIndex )
|
||||
*outHasIndex = hasIndex;
|
||||
return outErr;
|
||||
}
|
||||
|
||||
|
@ -1074,6 +1124,7 @@ orkinTable::EnableIndexOnSort( // create an index for col on first sort
|
|||
nsIMdbEnv* mev, // context
|
||||
mdb_column inColumn) // the column to index if ever sorted
|
||||
{
|
||||
MORK_USED_1(inColumn);
|
||||
mdb_err outErr = 0;
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
|
@ -1090,15 +1141,17 @@ orkinTable::QueryIndexOnSort( // check whether index on sort is enabled
|
|||
mdb_column inColumn, // the column to investigate
|
||||
mdb_bool* outIndexOnSort) // whether column has index-on-sort enabled
|
||||
{
|
||||
MORK_USED_1(inColumn);
|
||||
mdb_bool indexOnSort = morkBool_kFalse;
|
||||
mdb_err outErr = 0;
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
if ( outIndexOnSort )
|
||||
*outIndexOnSort = morkBool_kFalse;
|
||||
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( outIndexOnSort )
|
||||
*outIndexOnSort = indexOnSort;
|
||||
return outErr;
|
||||
}
|
||||
|
||||
|
@ -1107,6 +1160,7 @@ orkinTable::DisableIndexOnSort( // prevent future index creation on sort
|
|||
nsIMdbEnv* mev, // context
|
||||
mdb_column inColumn) // the column to index if ever sorted
|
||||
{
|
||||
MORK_USED_1(inColumn);
|
||||
mdb_err outErr = 0;
|
||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
|
|
|
@ -73,7 +73,7 @@ protected: // morkHandle memory management operators
|
|||
{ return ioPool.NewHandle(ev, inSize); }
|
||||
|
||||
void* operator new(size_t inSize, morkHandleFace* ioFace)
|
||||
{ return ioFace; }
|
||||
{ MORK_USED_1(inSize); return ioFace; }
|
||||
|
||||
void operator delete(void* ioAddress)
|
||||
{ morkNode::OnDeleteAssert(ioAddress); }
|
||||
|
|
|
@ -248,6 +248,7 @@ orkinTableRowCursor::GetCount(nsIMdbEnv* mev, mdb_count* outCount)
|
|||
orkinTableRowCursor::GetSeed(nsIMdbEnv* mev, mdb_seed* outSeed)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
mdb_seed seed = 0;
|
||||
morkEnv* ev =
|
||||
this->CanUseTableRowCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
|
@ -255,6 +256,8 @@ orkinTableRowCursor::GetSeed(nsIMdbEnv* mev, mdb_seed* outSeed)
|
|||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( outSeed )
|
||||
*outSeed = seed;
|
||||
return outErr;
|
||||
}
|
||||
|
||||
|
@ -294,6 +297,7 @@ orkinTableRowCursor::GetPos(nsIMdbEnv* mev, mdb_pos* outPos)
|
|||
/*virtual*/ mdb_err
|
||||
orkinTableRowCursor::SetDoFailOnSeedOutOfSync(nsIMdbEnv* mev, mdb_bool inFail)
|
||||
{
|
||||
MORK_USED_1(inFail);
|
||||
mdb_err outErr = 0;
|
||||
morkEnv* ev =
|
||||
this->CanUseTableRowCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
|
@ -308,6 +312,7 @@ orkinTableRowCursor::SetDoFailOnSeedOutOfSync(nsIMdbEnv* mev, mdb_bool inFail)
|
|||
/*virtual*/ mdb_err
|
||||
orkinTableRowCursor::GetDoFailOnSeedOutOfSync(nsIMdbEnv* mev, mdb_bool* outFail)
|
||||
{
|
||||
mdb_bool fail = morkBool_kFalse;
|
||||
mdb_err outErr = 0;
|
||||
morkEnv* ev =
|
||||
this->CanUseTableRowCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
|
@ -316,6 +321,8 @@ orkinTableRowCursor::GetDoFailOnSeedOutOfSync(nsIMdbEnv* mev, mdb_bool* outFail)
|
|||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( outFail )
|
||||
*outFail = fail;
|
||||
return outErr;
|
||||
}
|
||||
// } ----- end attribute methods -----
|
||||
|
@ -329,6 +336,7 @@ orkinTableRowCursor::GetDoFailOnSeedOutOfSync(nsIMdbEnv* mev, mdb_bool* outFail)
|
|||
/*virtual*/ mdb_err
|
||||
orkinTableRowCursor::SetTable(nsIMdbEnv* mev, nsIMdbTable* ioTable)
|
||||
{
|
||||
MORK_USED_1(ioTable);
|
||||
mdb_err outErr = 0;
|
||||
morkEnv* ev =
|
||||
this->CanUseTableRowCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
|
@ -428,6 +436,11 @@ orkinTableRowCursor::NextRowCopy( // put row cells into sink only when already i
|
|||
mdbOid* outOid, // out row oid
|
||||
mdb_pos* outRowPos)
|
||||
{
|
||||
MORK_USED_1(ioSinkRow);
|
||||
mdbOid oid;
|
||||
oid.mOid_Scope = 0;
|
||||
oid.mOid_Id = (mork_id) -1;
|
||||
mdb_pos rowPos = -1;
|
||||
mdb_err outErr = 0;
|
||||
morkEnv* ev =
|
||||
this->CanUseTableRowCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
|
@ -441,6 +454,10 @@ orkinTableRowCursor::NextRowCopy( // put row cells into sink only when already i
|
|||
ev->NilPointerError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( outRowPos )
|
||||
*outRowPos = rowPos;
|
||||
if ( outOid )
|
||||
*outOid = oid;
|
||||
return outErr;
|
||||
}
|
||||
|
||||
|
@ -451,6 +468,11 @@ orkinTableRowCursor::NextRowCopyAll( // put all row cells into sink, adding to s
|
|||
mdbOid* outOid, // out row oid
|
||||
mdb_pos* outRowPos)
|
||||
{
|
||||
MORK_USED_1(ioSinkRow);
|
||||
mdbOid oid;
|
||||
oid.mOid_Scope = 0;
|
||||
oid.mOid_Id = (mork_id) -1;
|
||||
mdb_pos rowPos = -1;
|
||||
mdb_err outErr = 0;
|
||||
morkEnv* ev =
|
||||
this->CanUseTableRowCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
|
@ -459,6 +481,10 @@ orkinTableRowCursor::NextRowCopyAll( // put all row cells into sink, adding to s
|
|||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( outRowPos )
|
||||
*outRowPos = rowPos;
|
||||
if ( outOid )
|
||||
*outOid = oid;
|
||||
return outErr;
|
||||
} // nonzero if child, and a row child
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ protected: // morkHandle memory management operators
|
|||
{ return ioPool.NewHandle(ev, inSize); }
|
||||
|
||||
void* operator new(size_t inSize, morkHandleFace* ioFace)
|
||||
{ return ioFace; }
|
||||
{ MORK_USED_1(inSize); return ioFace; }
|
||||
|
||||
void operator delete(void* ioAddress)
|
||||
{ morkNode::OnDeleteAssert(ioAddress); }
|
||||
|
|
|
@ -73,7 +73,7 @@ protected: // morkHandle memory management operators
|
|||
{ return ioPool.NewHandle(ev, inSize); }
|
||||
|
||||
void* operator new(size_t inSize, morkHandleFace* ioFace)
|
||||
{ return ioFace; }
|
||||
{ MORK_USED_1(inSize); return ioFace; }
|
||||
|
||||
void operator delete(void* ioAddress)
|
||||
{ morkNode::OnDeleteAssert(ioAddress); }
|
||||
|
|
|
@ -939,16 +939,54 @@ public:
|
|||
nsIMdbEnv* ev, // context
|
||||
const mdbOid* inOid, // hypothetical row oid
|
||||
mdb_bool* outHasRow) = 0; // whether GetRow() might succeed
|
||||
|
||||
virtual mdb_err GetRowRefCount( // get number of tables that contain a row
|
||||
nsIMdbEnv* ev, // context
|
||||
const mdbOid* inOid, // hypothetical row oid
|
||||
mdb_count* outRefCount) = 0; // number of tables containing inRowKey
|
||||
|
||||
virtual mdb_err GetRow( // access one row with specific oid
|
||||
nsIMdbEnv* ev, // context
|
||||
const mdbOid* inOid, // hypothetical row oid
|
||||
nsIMdbRow** acqRow) = 0; // acquire specific row (or null)
|
||||
|
||||
virtual mdb_err GetRowRefCount( // get number of tables that contain a row
|
||||
nsIMdbEnv* ev, // context
|
||||
const mdbOid* inOid, // hypothetical row oid
|
||||
mdb_count* outRefCount) = 0; // number of tables containing inRowKey
|
||||
virtual mdb_err FindRow(nsIMdbEnv* ev, // search for row with matching cell
|
||||
mdb_scope inRowScope, // row scope for row ids
|
||||
mdb_column inColumn, // the column to search (and maintain an index)
|
||||
const mdbYarn* inTargetCellValue, // cell value for which to search
|
||||
mdbOid* outRowOid, // out row oid on match (or {0,-1} for no match)
|
||||
nsIMdbRow** acqRow) = 0; // acquire matching row (or nil for no match)
|
||||
// FindRow() searches for one row that has a cell in column inColumn with
|
||||
// a contained value with the same form (i.e. charset) and is byte-wise
|
||||
// identical to the blob described by yarn inTargetCellValue. Both content
|
||||
// and form of the yarn must be an exact match to find a matching row.
|
||||
//
|
||||
// (In other words, both a yarn's blob bytes and form are significant. The
|
||||
// form is not expected to vary in columns used for identity anyway. This
|
||||
// is intended to make the cost of FindRow() cheaper for MDB implementors,
|
||||
// since any cell value atomization performed internally must necessarily
|
||||
// make yarn form significant in order to avoid data loss in atomization.)
|
||||
//
|
||||
// FindRow() can lazily create an index on attribute inColumn for all rows
|
||||
// with that attribute in row space scope inRowScope, so that subsequent
|
||||
// calls to FindRow() will perform faster. Such an index might or might
|
||||
// not be persistent (but this seems desirable if it is cheap to do so).
|
||||
// Note that lazy index creation in readonly DBs is not very feasible.
|
||||
//
|
||||
// This FindRow() interface assumes that attribute inColumn is effectively
|
||||
// an alternative means of unique identification for a row in a rowspace,
|
||||
// so correct behavior is only guaranteed when no duplicates for this col
|
||||
// appear in the given set of rows. (If more than one row has the same cell
|
||||
// value in this column, no more than one will be found; and cutting one of
|
||||
// two duplicate rows can cause the index to assume no other such row lives
|
||||
// in the row space, so future calls return nil for negative search results
|
||||
// even though some duplicate row might still live within the rowspace.)
|
||||
//
|
||||
// In other words, the FindRow() implementation is allowed to assume simple
|
||||
// hash tables mapping unqiue column keys to associated row values will be
|
||||
// sufficient, where any duplication is not recorded because only one copy
|
||||
// of a given key need be remembered. Implementors are not required to sort
|
||||
// all rows by the specified column.
|
||||
// } ----- end row methods -----
|
||||
|
||||
// { ----- begin table methods -----
|
||||
|
@ -1116,6 +1154,7 @@ public:
|
|||
nsIMdbRow** acqRow) = 0; // create new row
|
||||
// Note this row must be added to some table or cell child before the
|
||||
// store is closed in order to make this row persist across sesssions.
|
||||
|
||||
// } ----- end row methods -----
|
||||
|
||||
// { ----- begin inport/export methods -----
|
||||
|
|
|
@ -1,310 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKARRAY_
|
||||
#include "morkArray.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkArray::CloseMorkNode(morkEnv* ev) // CloseTable() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->CloseArray(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkArray::~morkArray() // assert CloseTable() executed earlier
|
||||
{
|
||||
MORK_ASSERT(this->IsShutNode());
|
||||
MORK_ASSERT(mArray_Slots==0);
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkArray::morkArray(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, mork_size inSize, nsIMdbHeap* ioSlotHeap)
|
||||
: morkNode(ev, inUsage, ioHeap)
|
||||
, mArray_Slots( 0 )
|
||||
, mArray_Heap( 0 )
|
||||
, mArray_Fill( 0 )
|
||||
, mArray_Size( 0 )
|
||||
, mArray_Seed( (mork_u4) this ) // "random" integer assignment
|
||||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
if ( ioSlotHeap )
|
||||
{
|
||||
nsIMdbHeap_SlotStrongHeap(ioSlotHeap, ev, &mArray_Heap);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
if ( inSize < 3 )
|
||||
inSize = 3;
|
||||
mdb_size byteSize = inSize * sizeof(void*);
|
||||
void** block = 0;
|
||||
ioSlotHeap->Alloc(ev->AsMdbEnv(), byteSize, (void**) &block);
|
||||
if ( block && ev->Good() )
|
||||
{
|
||||
mArray_Slots = block;
|
||||
mArray_Size = inSize;
|
||||
MORK_MEMSET(mArray_Slots, 0, byteSize);
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kArray;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkArray::CloseArray(morkEnv* ev) // called by CloseMorkNode();
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
if ( mArray_Heap && mArray_Slots )
|
||||
mArray_Heap->Free(ev->AsMdbEnv(), mArray_Slots);
|
||||
|
||||
mArray_Slots = 0;
|
||||
mArray_Size = 0;
|
||||
mArray_Fill = 0;
|
||||
++mArray_Seed;
|
||||
nsIMdbHeap_SlotStrongHeap((nsIMdbHeap*) 0, ev, &mArray_Heap);
|
||||
this->MarkShut();
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
/*static*/ void
|
||||
morkArray::NonArrayTypeError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("non morkArray");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkArray::IndexBeyondEndError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("array index beyond end");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkArray::NilSlotsAddressError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("nil mArray_Slots");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkArray::FillBeyondSizeError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("mArray_Fill > mArray_Size");
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkArray::Grow(morkEnv* ev, mork_size inNewSize)
|
||||
// Grow() returns true if capacity becomes >= inNewSize and ev->Good()
|
||||
{
|
||||
if ( ev->Good() && inNewSize > mArray_Size ) // make array larger?
|
||||
{
|
||||
if ( mArray_Fill <= mArray_Size ) // fill and size fit the invariant?
|
||||
{
|
||||
if ( inNewSize - mArray_Size < 3 ) // actually want a few more slots?
|
||||
inNewSize = mArray_Size + 3;
|
||||
|
||||
mdb_size newByteSize = inNewSize * sizeof(void*);
|
||||
void** newBlock = 0;
|
||||
mArray_Heap->Alloc(ev->AsMdbEnv(), newByteSize, (void**) &newBlock);
|
||||
if ( newBlock && ev->Good() ) // okay new block?
|
||||
{
|
||||
void** oldSlots = mArray_Slots;
|
||||
void** oldEnd = oldSlots + mArray_Fill;
|
||||
|
||||
void** newSlots = newBlock;
|
||||
void** newEnd = newBlock + inNewSize;
|
||||
|
||||
while ( oldSlots < oldEnd )
|
||||
*newSlots++ = *oldSlots++;
|
||||
|
||||
while ( newSlots < newEnd )
|
||||
*newSlots++ = (void*) 0;
|
||||
|
||||
oldSlots = mArray_Slots;
|
||||
mArray_Size = inNewSize;
|
||||
mArray_Slots = newBlock;
|
||||
mArray_Heap->Free(ev->AsMdbEnv(), oldSlots);
|
||||
}
|
||||
}
|
||||
else
|
||||
this->FillBeyondSizeError(ev);
|
||||
}
|
||||
++mArray_Seed; // always modify seed, since caller intends to add slots
|
||||
return ( ev->Good() && mArray_Size >= inNewSize );
|
||||
}
|
||||
|
||||
void*
|
||||
morkArray::SafeAt(morkEnv* ev, mork_pos inPos)
|
||||
{
|
||||
if ( mArray_Slots )
|
||||
{
|
||||
if ( inPos >= 0 && inPos < (mork_pos) mArray_Fill )
|
||||
return mArray_Slots[ inPos ];
|
||||
else
|
||||
this->IndexBeyondEndError(ev);
|
||||
}
|
||||
else
|
||||
this->NilSlotsAddressError(ev);
|
||||
|
||||
return (void*) 0;
|
||||
}
|
||||
|
||||
void
|
||||
morkArray::SafeAtPut(morkEnv* ev, mork_pos inPos, void* ioSlot)
|
||||
{
|
||||
if ( mArray_Slots )
|
||||
{
|
||||
if ( inPos >= 0 && inPos < (mork_pos) mArray_Fill )
|
||||
{
|
||||
mArray_Slots[ inPos ] = ioSlot;
|
||||
++mArray_Seed;
|
||||
}
|
||||
else
|
||||
this->IndexBeyondEndError(ev);
|
||||
}
|
||||
else
|
||||
this->NilSlotsAddressError(ev);
|
||||
}
|
||||
|
||||
mork_pos
|
||||
morkArray::AppendSlot(morkEnv* ev, void* ioSlot)
|
||||
{
|
||||
mork_pos outPos = -1;
|
||||
if ( mArray_Slots )
|
||||
{
|
||||
mork_fill fill = mArray_Fill;
|
||||
if ( this->Grow(ev, fill+1) )
|
||||
{
|
||||
outPos = fill;
|
||||
mArray_Slots[ fill ] = ioSlot;
|
||||
mArray_Fill = fill + 1;
|
||||
// note Grow() increments mArray_Seed
|
||||
}
|
||||
}
|
||||
else
|
||||
this->NilSlotsAddressError(ev);
|
||||
|
||||
return outPos;
|
||||
}
|
||||
|
||||
void
|
||||
morkArray::AddSlot(morkEnv* ev, mork_pos inPos, void* ioSlot)
|
||||
{
|
||||
if ( mArray_Slots )
|
||||
{
|
||||
mork_fill fill = mArray_Fill;
|
||||
if ( this->Grow(ev, fill+1) )
|
||||
{
|
||||
void** slot = mArray_Slots; // the slot vector
|
||||
void** end = slot + fill; // one past the last used array slot
|
||||
slot += inPos; // the slot to be added
|
||||
|
||||
while ( --end >= slot ) // another slot to move upward?
|
||||
end[ 1 ] = *end;
|
||||
|
||||
*slot = ioSlot;
|
||||
mArray_Fill = fill + 1;
|
||||
// note Grow() increments mArray_Seed
|
||||
}
|
||||
}
|
||||
else
|
||||
this->NilSlotsAddressError(ev);
|
||||
}
|
||||
|
||||
void
|
||||
morkArray::CutSlot(morkEnv* ev, mork_pos inPos)
|
||||
{
|
||||
mork_fill fill = mArray_Fill;
|
||||
if ( inPos >= 0 && inPos < (mork_pos) fill ) // cutting slot in used array portion?
|
||||
{
|
||||
void** slot = mArray_Slots; // the slot vector
|
||||
void** end = slot + fill; // one past the last used array slot
|
||||
slot += inPos; // the slot to be cut
|
||||
|
||||
while ( ++slot < end ) // another slot to move downward?
|
||||
slot[ -1 ] = *slot;
|
||||
|
||||
slot[ -1 ] = 0; // clear the last used slot which is now unused
|
||||
|
||||
// note inPos<fill implies fill>0, so fill-1 must be nonnegative:
|
||||
mArray_Fill = fill - 1;
|
||||
++mArray_Seed;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
morkArray::CutAllSlots(morkEnv* ev)
|
||||
{
|
||||
if ( mArray_Slots )
|
||||
{
|
||||
if ( mArray_Fill <= mArray_Size )
|
||||
{
|
||||
mdb_size oldByteSize = mArray_Fill * sizeof(void*);
|
||||
MORK_MEMSET(mArray_Slots, 0, oldByteSize);
|
||||
}
|
||||
else
|
||||
this->FillBeyondSizeError(ev);
|
||||
}
|
||||
else
|
||||
this->NilSlotsAddressError(ev);
|
||||
|
||||
++mArray_Seed;
|
||||
mArray_Fill = 0;
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
|
@ -204,15 +204,40 @@ morkAtom::AliasYarn(mdbYarn* outYarn) const
|
|||
return ( atom != 0 );
|
||||
}
|
||||
|
||||
mork_aid
|
||||
morkAtom::GetBookAtomAid() const // zero or book atom's ID
|
||||
{
|
||||
return ( this->IsBook() )? ((morkBookAtom*) this)->mBookAtom_Id : 0;
|
||||
}
|
||||
|
||||
mork_scope
|
||||
morkAtom::GetBookAtomSpaceScope(morkEnv* ev) const // zero or book's space's scope
|
||||
{
|
||||
mork_scope outScope = 0;
|
||||
if ( this->IsBook() )
|
||||
{
|
||||
const morkBookAtom* bookAtom = (const morkBookAtom*) this;
|
||||
morkAtomSpace* space = bookAtom->mBookAtom_Space;
|
||||
if ( space->IsAtomSpace() )
|
||||
outScope = space->mSpace_Scope;
|
||||
else
|
||||
space->NonAtomSpaceTypeError(ev);
|
||||
}
|
||||
|
||||
return outScope;
|
||||
}
|
||||
|
||||
void
|
||||
morkAtom::MakeCellUseForever(morkEnv* ev)
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
mAtom_CellUses = morkAtom_kForeverCellUses;
|
||||
}
|
||||
|
||||
mork_u1
|
||||
morkAtom::AddCellUse(morkEnv* ev)
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
if ( mAtom_CellUses < morkAtom_kMaxCellUses ) // not already maxed out?
|
||||
++mAtom_CellUses;
|
||||
|
||||
|
@ -260,6 +285,7 @@ morkAtom::AtomSizeOverflowError(morkEnv* ev)
|
|||
void
|
||||
morkOidAtom::InitRowOidAtom(morkEnv* ev, const mdbOid& inOid)
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
mAtom_CellUses = 0;
|
||||
mAtom_Kind = morkAtom_kKindRowOid;
|
||||
mAtom_Change = morkChange_kNil;
|
||||
|
@ -270,6 +296,7 @@ morkOidAtom::InitRowOidAtom(morkEnv* ev, const mdbOid& inOid)
|
|||
void
|
||||
morkOidAtom::InitTableOidAtom(morkEnv* ev, const mdbOid& inOid)
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
mAtom_CellUses = 0;
|
||||
mAtom_Kind = morkAtom_kKindTableOid;
|
||||
mAtom_Change = morkChange_kNil;
|
||||
|
@ -301,6 +328,7 @@ void
|
|||
morkBigAnonAtom::InitBigAnonAtom(morkEnv* ev, const morkBuf& inBuf,
|
||||
mork_cscode inForm)
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
mAtom_CellUses = 0;
|
||||
mAtom_Kind = morkAtom_kKindBigAnon;
|
||||
mAtom_Change = morkChange_kNil;
|
||||
|
|
|
@ -60,6 +60,14 @@ public:
|
|||
|
||||
mork_bool IsBook() const { return this->IsWeeBook() || this->IsBigBook(); }
|
||||
|
||||
public: // atom space scope if IsBook() is true, or else zero:
|
||||
|
||||
mork_scope GetBookAtomSpaceScope(morkEnv* ev) const;
|
||||
// zero or book's space's scope
|
||||
|
||||
mork_aid GetBookAtomAid() const;
|
||||
// zero or book atom's ID
|
||||
|
||||
public: // empty construction does nothing
|
||||
morkAtom() { }
|
||||
|
||||
|
|
|
@ -1,263 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKMAP_
|
||||
#include "morkMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKATOMMAP_
|
||||
#include "morkAtomMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKATOM_
|
||||
#include "morkAtom.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkAtomAidMap::CloseMorkNode(morkEnv* ev) // CloseAtomAidMap() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->CloseAtomAidMap(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkAtomAidMap::~morkAtomAidMap() // assert CloseAtomAidMap() executed earlier
|
||||
{
|
||||
MORK_ASSERT(this->IsShutNode());
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkAtomAidMap::morkAtomAidMap(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap)
|
||||
: morkMap(ev, inUsage, ioHeap,
|
||||
/*inKeySize*/ sizeof(morkBookAtom*), /*inValSize*/ 0,
|
||||
morkAtomAidMap_kStartSlotCount, ioSlotHeap,
|
||||
/*inHoldChanges*/ morkBool_kFalse)
|
||||
{
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kAtomAidMap;
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkAtomAidMap::CloseAtomAidMap(morkEnv* ev) // called by CloseMorkNode();
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
this->CloseMap(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
// { ===== begin morkMap poly interface =====
|
||||
/*virtual*/ mork_bool //
|
||||
morkAtomAidMap::Equal(morkEnv* ev, const void* inKeyA,
|
||||
const void* inKeyB) const
|
||||
{
|
||||
return (*(const morkBookAtom**) inKeyA)->EqualAid(
|
||||
*(const morkBookAtom**) inKeyB);
|
||||
}
|
||||
|
||||
/*virtual*/ mork_u4 //
|
||||
morkAtomAidMap::Hash(morkEnv* ev, const void* inKey) const
|
||||
{
|
||||
return (*(const morkBookAtom**) inKey)->HashAid();
|
||||
}
|
||||
// } ===== end morkMap poly interface =====
|
||||
|
||||
|
||||
mork_bool
|
||||
morkAtomAidMap::AddAtom(morkEnv* ev, morkBookAtom* ioAtom)
|
||||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
this->Put(ev, &ioAtom, /*val*/ (void*) 0,
|
||||
/*key*/ (void*) 0, /*val*/ (void*) 0, (mork_change**) 0);
|
||||
}
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
morkBookAtom*
|
||||
morkAtomAidMap::CutAtom(morkEnv* ev, const morkBookAtom* inAtom)
|
||||
{
|
||||
morkBookAtom* oldKey = 0;
|
||||
this->Cut(ev, &inAtom, &oldKey, /*val*/ (void*) 0,
|
||||
(mork_change**) 0);
|
||||
|
||||
return oldKey;
|
||||
}
|
||||
|
||||
morkBookAtom*
|
||||
morkAtomAidMap::GetAtom(morkEnv* ev, const morkBookAtom* inAtom)
|
||||
{
|
||||
morkBookAtom* key = 0; // old val in the map
|
||||
this->Get(ev, &inAtom, &key, /*val*/ (void*) 0, (mork_change**) 0);
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
morkBookAtom*
|
||||
morkAtomAidMap::GetAid(morkEnv* ev, mork_aid inAid)
|
||||
{
|
||||
morkWeeBookAtom weeAtom(inAid);
|
||||
morkBookAtom* key = &weeAtom; // we need a pointer
|
||||
morkBookAtom* oldKey = 0; // old key in the map
|
||||
this->Get(ev, &key, &oldKey, /*val*/ (void*) 0, (mork_change**) 0);
|
||||
|
||||
return oldKey;
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkAtomBodyMap::CloseMorkNode(morkEnv* ev) // CloseAtomBodyMap() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->CloseAtomBodyMap(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkAtomBodyMap::~morkAtomBodyMap() // assert CloseAtomBodyMap() executed earlier
|
||||
{
|
||||
MORK_ASSERT(this->IsShutNode());
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkAtomBodyMap::morkAtomBodyMap(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap)
|
||||
: morkMap(ev, inUsage, ioHeap,
|
||||
/*inKeySize*/ sizeof(morkBookAtom*), /*inValSize*/ 0,
|
||||
morkAtomBodyMap_kStartSlotCount, ioSlotHeap,
|
||||
/*inHoldChanges*/ morkBool_kFalse)
|
||||
{
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kAtomBodyMap;
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkAtomBodyMap::CloseAtomBodyMap(morkEnv* ev) // called by CloseMorkNode();
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
this->CloseMap(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
// { ===== begin morkMap poly interface =====
|
||||
/*virtual*/ mork_bool //
|
||||
morkAtomBodyMap::Equal(morkEnv* ev, const void* inKeyA,
|
||||
const void* inKeyB) const
|
||||
{
|
||||
return (*(const morkBookAtom**) inKeyA)->EqualFormAndBody(ev,
|
||||
*(const morkBookAtom**) inKeyB);
|
||||
}
|
||||
|
||||
/*virtual*/ mork_u4 //
|
||||
morkAtomBodyMap::Hash(morkEnv* ev, const void* inKey) const
|
||||
{
|
||||
return (*(const morkBookAtom**) inKey)->HashFormAndBody(ev);
|
||||
}
|
||||
// } ===== end morkMap poly interface =====
|
||||
|
||||
|
||||
mork_bool
|
||||
morkAtomBodyMap::AddAtom(morkEnv* ev, morkBookAtom* ioAtom)
|
||||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
this->Put(ev, &ioAtom, /*val*/ (void*) 0,
|
||||
/*key*/ (void*) 0, /*val*/ (void*) 0, (mork_change**) 0);
|
||||
}
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
morkBookAtom*
|
||||
morkAtomBodyMap::CutAtom(morkEnv* ev, const morkBookAtom* inAtom)
|
||||
{
|
||||
morkBookAtom* oldKey = 0;
|
||||
this->Cut(ev, &inAtom, &oldKey, /*val*/ (void*) 0,
|
||||
(mork_change**) 0);
|
||||
|
||||
return oldKey;
|
||||
}
|
||||
|
||||
morkBookAtom*
|
||||
morkAtomBodyMap::GetAtom(morkEnv* ev, const morkBookAtom* inAtom)
|
||||
{
|
||||
morkBookAtom* key = 0; // old val in the map
|
||||
this->Get(ev, &inAtom, &key, /*val*/ (void*) 0, (mork_change**) 0);
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
|
@ -1,187 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MORKATOMMAP_
|
||||
#define _MORKATOMMAP_ 1
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKMAP_
|
||||
#include "morkMap.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#define morkDerived_kAtomAidMap /*i*/ 0x6141 /* ascii 'aA' */
|
||||
|
||||
#define morkAtomAidMap_kStartSlotCount 512
|
||||
|
||||
/*| morkAtomAidMap: keys of morkBookAtom organized by atom ID
|
||||
|*/
|
||||
class morkAtomAidMap : public morkMap { // for mapping tokens to maps
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
virtual void CloseMorkNode(morkEnv* ev); // CloseAtomAidMap() only if open
|
||||
virtual ~morkAtomAidMap(); // assert that CloseAtomAidMap() executed earlier
|
||||
|
||||
public: // morkMap construction & destruction
|
||||
morkAtomAidMap(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap);
|
||||
void CloseAtomAidMap(morkEnv* ev); // called by CloseMorkNode();
|
||||
|
||||
public: // dynamic type identification
|
||||
mork_bool IsAtomAidMap() const
|
||||
{ return IsNode() && mNode_Derived == morkDerived_kAtomAidMap; }
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
// { ===== begin morkMap poly interface =====
|
||||
virtual mork_bool // note: equal(a,b) implies hash(a) == hash(b)
|
||||
Equal(morkEnv* ev, const void* inKeyA, const void* inKeyB) const;
|
||||
// implemented using morkBookAtom::HashAid()
|
||||
|
||||
virtual mork_u4 // note: equal(a,b) implies hash(a) == hash(b)
|
||||
Hash(morkEnv* ev, const void* inKey) const;
|
||||
// implemented using morkBookAtom::EqualAid()
|
||||
// } ===== end morkMap poly interface =====
|
||||
|
||||
public: // other map methods
|
||||
|
||||
mork_bool AddAtom(morkEnv* ev, morkBookAtom* ioAtom);
|
||||
// AddAtom() returns ev->Good()
|
||||
|
||||
morkBookAtom* CutAtom(morkEnv* ev, const morkBookAtom* inAtom);
|
||||
// CutAtom() returns the atom removed equal to inAtom, if there was one
|
||||
|
||||
morkBookAtom* GetAtom(morkEnv* ev, const morkBookAtom* inAtom);
|
||||
// GetAtom() returns the atom equal to inAtom, or else nil
|
||||
|
||||
morkBookAtom* GetAid(morkEnv* ev, mork_aid inAid);
|
||||
// GetAid() returns the atom equal to inAid, or else nil
|
||||
|
||||
// note the atoms are owned elsewhere, usuall by morkAtomSpace
|
||||
};
|
||||
|
||||
|
||||
class morkAtomAidMapIter: public morkMapIter{ // typesafe wrapper class
|
||||
|
||||
public:
|
||||
morkAtomAidMapIter(morkEnv* ev, morkAtomAidMap* ioMap)
|
||||
: morkMapIter(ev, ioMap) { }
|
||||
|
||||
morkAtomAidMapIter( ) : morkMapIter() { }
|
||||
void InitAtomAidMapIter(morkEnv* ev, morkAtomAidMap* ioMap)
|
||||
{ this->InitMapIter(ev, ioMap); }
|
||||
|
||||
mork_change* FirstAtom(morkEnv* ev, morkBookAtom** outAtomPtr)
|
||||
{ return this->First(ev, outAtomPtr, /*val*/ (void*) 0); }
|
||||
|
||||
mork_change* NextAtom(morkEnv* ev, morkBookAtom** outAtomPtr)
|
||||
{ return this->Next(ev, outAtomPtr, /*val*/ (void*) 0); }
|
||||
|
||||
mork_change* HereAtom(morkEnv* ev, morkBookAtom** outAtomPtr)
|
||||
{ return this->Here(ev, outAtomPtr, /*val*/ (void*) 0); }
|
||||
|
||||
mork_change* CutHereAtom(morkEnv* ev, morkBookAtom** outAtomPtr)
|
||||
{ return this->CutHere(ev, outAtomPtr, /*val*/ (void*) 0); }
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#define morkDerived_kAtomBodyMap /*i*/ 0x6142 /* ascii 'aB' */
|
||||
|
||||
#define morkAtomBodyMap_kStartSlotCount 512
|
||||
|
||||
/*| morkAtomBodyMap: keys of morkBookAtom organized by body bytes
|
||||
|*/
|
||||
class morkAtomBodyMap : public morkMap { // for mapping tokens to maps
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
virtual void CloseMorkNode(morkEnv* ev); // CloseAtomBodyMap() only if open
|
||||
virtual ~morkAtomBodyMap(); // assert CloseAtomBodyMap() executed earlier
|
||||
|
||||
public: // morkMap construction & destruction
|
||||
morkAtomBodyMap(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap);
|
||||
void CloseAtomBodyMap(morkEnv* ev); // called by CloseMorkNode();
|
||||
|
||||
public: // dynamic type identification
|
||||
mork_bool IsAtomBodyMap() const
|
||||
{ return IsNode() && mNode_Derived == morkDerived_kAtomBodyMap; }
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
// { ===== begin morkMap poly interface =====
|
||||
virtual mork_bool // note: equal(a,b) implies hash(a) == hash(b)
|
||||
Equal(morkEnv* ev, const void* inKeyA, const void* inKeyB) const;
|
||||
// implemented using morkBookAtom::EqualFormAndBody()
|
||||
|
||||
virtual mork_u4 // note: equal(a,b) implies hash(a) == hash(b)
|
||||
Hash(morkEnv* ev, const void* inKey) const;
|
||||
// implemented using morkBookAtom::HashFormAndBody()
|
||||
// } ===== end morkMap poly interface =====
|
||||
|
||||
public: // other map methods
|
||||
|
||||
mork_bool AddAtom(morkEnv* ev, morkBookAtom* ioAtom);
|
||||
// AddAtom() returns ev->Good()
|
||||
|
||||
morkBookAtom* CutAtom(morkEnv* ev, const morkBookAtom* inAtom);
|
||||
// CutAtom() returns the atom removed equal to inAtom, if there was one
|
||||
|
||||
morkBookAtom* GetAtom(morkEnv* ev, const morkBookAtom* inAtom);
|
||||
// GetAtom() returns the atom equal to inAtom, or else nil
|
||||
|
||||
// note the atoms are owned elsewhere, usuall by morkAtomSpace
|
||||
};
|
||||
|
||||
class morkAtomBodyMapIter: public morkMapIter{ // typesafe wrapper class
|
||||
|
||||
public:
|
||||
morkAtomBodyMapIter(morkEnv* ev, morkAtomBodyMap* ioMap)
|
||||
: morkMapIter(ev, ioMap) { }
|
||||
|
||||
morkAtomBodyMapIter( ) : morkMapIter() { }
|
||||
void InitAtomBodyMapIter(morkEnv* ev, morkAtomBodyMap* ioMap)
|
||||
{ this->InitMapIter(ev, ioMap); }
|
||||
|
||||
mork_change* FirstAtom(morkEnv* ev, morkBookAtom** outAtomPtr)
|
||||
{ return this->First(ev, outAtomPtr, /*val*/ (void*) 0); }
|
||||
|
||||
mork_change* NextAtom(morkEnv* ev, morkBookAtom** outAtomPtr)
|
||||
{ return this->Next(ev, outAtomPtr, /*val*/ (void*) 0); }
|
||||
|
||||
mork_change* HereAtom(morkEnv* ev, morkBookAtom** outAtomPtr)
|
||||
{ return this->Here(ev, outAtomPtr, /*val*/ (void*) 0); }
|
||||
|
||||
mork_change* CutHereAtom(morkEnv* ev, morkBookAtom** outAtomPtr)
|
||||
{ return this->CutHere(ev, outAtomPtr, /*val*/ (void*) 0); }
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKATOMMAP_ */
|
|
@ -186,28 +186,28 @@ morkAtomSpace::MakeBookAtomCopy(morkEnv* ev, const morkBigBookAtom& inAtom)
|
|||
morkBookAtom* outAtom = 0;
|
||||
if ( ev->Good() )
|
||||
{
|
||||
if ( mSpace_Store->mStore_CanAutoAssignAtomIdentity )
|
||||
{
|
||||
morkPool* pool = this->GetSpaceStorePool();
|
||||
morkBookAtom* atom = pool->NewBookAtomCopy(ev, inAtom);
|
||||
if ( atom )
|
||||
{
|
||||
mork_aid id = this->MakeNewAtomId(ev, atom);
|
||||
if ( id )
|
||||
{
|
||||
outAtom = atom;
|
||||
atom->mBookAtom_Space = this;
|
||||
mAtomSpace_AtomAids.AddAtom(ev, atom);
|
||||
mAtomSpace_AtomBodies.AddAtom(ev, atom);
|
||||
if ( mSpace_Scope == morkAtomSpace_kColumnScope )
|
||||
outAtom->MakeCellUseForever(ev);
|
||||
}
|
||||
else
|
||||
pool->ZapAtom(ev, atom);
|
||||
}
|
||||
}
|
||||
else
|
||||
mSpace_Store->CannotAutoAssignAtomIdentityError(ev);
|
||||
if ( mSpace_Store->mStore_CanAutoAssignAtomIdentity )
|
||||
{
|
||||
morkPool* pool = this->GetSpaceStorePool();
|
||||
morkBookAtom* atom = pool->NewBookAtomCopy(ev, inAtom);
|
||||
if ( atom )
|
||||
{
|
||||
mork_aid id = this->MakeNewAtomId(ev, atom);
|
||||
if ( id )
|
||||
{
|
||||
outAtom = atom;
|
||||
atom->mBookAtom_Space = this;
|
||||
mAtomSpace_AtomAids.AddAtom(ev, atom);
|
||||
mAtomSpace_AtomBodies.AddAtom(ev, atom);
|
||||
if ( mSpace_Scope == morkAtomSpace_kColumnScope )
|
||||
outAtom->MakeCellUseForever(ev);
|
||||
}
|
||||
else
|
||||
pool->ZapAtom(ev, atom);
|
||||
}
|
||||
}
|
||||
else
|
||||
mSpace_Store->CannotAutoAssignAtomIdentityError(ev);
|
||||
}
|
||||
return outAtom;
|
||||
}
|
||||
|
|
|
@ -235,6 +235,7 @@ void
|
|||
morkBuilder::LogGlitch(morkEnv* ev, const morkGlitch& inGlitch,
|
||||
const char* inKind)
|
||||
{
|
||||
MORK_USED_2(inGlitch,inKind);
|
||||
ev->NewWarning("parsing glitch");
|
||||
}
|
||||
|
||||
|
@ -256,6 +257,7 @@ morkBuilder::OnNewPort(morkEnv* ev, const morkPlace& inPlace)
|
|||
// mp:PortItem ::= mp:Content | mp:Group | OnPortGlitch
|
||||
// mp:Content ::= mp:PortRow | mp:Dict | mp:Table | mp:Row
|
||||
{
|
||||
MORK_USED_2(ev,inPlace);
|
||||
// mParser_InPort = morkBool_kTrue;
|
||||
mBuilder_PortForm = 0;
|
||||
mBuilder_PortRowScope = (mork_scope) 'r';
|
||||
|
@ -272,6 +274,7 @@ morkBuilder::OnPortGlitch(morkEnv* ev, const morkGlitch& inGlitch)
|
|||
morkBuilder::OnPortEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
// mp:Start ::= OnNewPort mp:PortItem* OnPortEnd
|
||||
{
|
||||
MORK_USED_2(ev,inSpan);
|
||||
// ev->StubMethodOnlyError();
|
||||
// nothing to do?
|
||||
// mParser_InPort = morkBool_kFalse;
|
||||
|
@ -280,6 +283,7 @@ morkBuilder::OnPortEnd(morkEnv* ev, const morkSpan& inSpan)
|
|||
/*virtual*/ void
|
||||
morkBuilder::OnNewGroup(morkEnv* ev, const morkPlace& inPlace, mork_gid inGid)
|
||||
{
|
||||
MORK_USED_2(inPlace,inGid);
|
||||
// mParser_InGroup = morkBool_kTrue;
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
@ -293,6 +297,7 @@ morkBuilder::OnGroupGlitch(morkEnv* ev, const morkGlitch& inGlitch)
|
|||
/*virtual*/ void
|
||||
morkBuilder::OnGroupCommitEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
{
|
||||
MORK_USED_1(inSpan);
|
||||
// mParser_InGroup = morkBool_kFalse;
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
@ -300,6 +305,7 @@ morkBuilder::OnGroupCommitEnd(morkEnv* ev, const morkSpan& inSpan)
|
|||
/*virtual*/ void
|
||||
morkBuilder::OnGroupAbortEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
{
|
||||
MORK_USED_1(inSpan);
|
||||
// mParser_InGroup = morkBool_kFalse;
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
@ -308,6 +314,7 @@ morkBuilder::OnGroupAbortEnd(morkEnv* ev, const morkSpan& inSpan)
|
|||
morkBuilder::OnNewPortRow(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkMid& inMid, mork_change inChange)
|
||||
{
|
||||
MORK_USED_3(inMid,inPlace,inChange);
|
||||
// mParser_InPortRow = morkBool_kTrue;
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
@ -321,6 +328,7 @@ morkBuilder::OnPortRowGlitch(morkEnv* ev, const morkGlitch& inGlitch)
|
|||
/*virtual*/ void
|
||||
morkBuilder::OnPortRowEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
{
|
||||
MORK_USED_1(inSpan);
|
||||
// mParser_InPortRow = morkBool_kFalse;
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
@ -334,6 +342,7 @@ morkBuilder::OnNewTable(morkEnv* ev, const morkPlace& inPlace,
|
|||
// mp:Meta ::= OnNewMeta mp:MetaItem* OnMetaEnd
|
||||
// mp:MetaItem ::= mp:Cell | OnMetaGlitch
|
||||
{
|
||||
MORK_USED_2(inPlace,inChange);
|
||||
// mParser_InTable = morkBool_kTrue;
|
||||
mBuilder_TableForm = mBuilder_PortForm;
|
||||
mBuilder_TableRowScope = mBuilder_PortRowScope;
|
||||
|
@ -355,6 +364,7 @@ morkBuilder::OnTableGlitch(morkEnv* ev, const morkGlitch& inGlitch)
|
|||
morkBuilder::OnTableEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
// mp:Table ::= OnNewTable mp:TableItem* OnTableEnd
|
||||
{
|
||||
MORK_USED_1(inSpan);
|
||||
// mParser_InTable = morkBool_kFalse;
|
||||
if ( mBuilder_Table )
|
||||
{
|
||||
|
@ -381,6 +391,7 @@ morkBuilder::OnNewMeta(morkEnv* ev, const morkPlace& inPlace)
|
|||
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
|
||||
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
|
||||
{
|
||||
MORK_USED_2(ev,inPlace);
|
||||
// mParser_InMeta = morkBool_kTrue;
|
||||
|
||||
}
|
||||
|
@ -395,6 +406,7 @@ morkBuilder::OnMetaGlitch(morkEnv* ev, const morkGlitch& inGlitch)
|
|||
morkBuilder::OnMetaEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
// mp:Meta ::= OnNewMeta mp:MetaItem* OnMetaEnd
|
||||
{
|
||||
MORK_USED_2(ev,inSpan);
|
||||
// mParser_InMeta = morkBool_kFalse;
|
||||
}
|
||||
|
||||
|
@ -410,6 +422,7 @@ morkBuilder::OnNewRow(morkEnv* ev, const morkPlace& inPlace,
|
|||
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
|
||||
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
|
||||
{
|
||||
MORK_USED_2(inPlace,inChange);
|
||||
// mParser_InRow = morkBool_kTrue;
|
||||
if ( mBuilder_Table )
|
||||
{
|
||||
|
@ -485,6 +498,7 @@ morkBuilder::FlushBuilderCells(morkEnv* ev)
|
|||
morkBuilder::OnRowEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
// mp:Row ::= OnNewRow mp:RowItem* OnRowEnd
|
||||
{
|
||||
MORK_USED_1(inSpan);
|
||||
// mParser_InRow = morkBool_kFalse;
|
||||
if ( mBuilder_Row )
|
||||
{
|
||||
|
@ -502,6 +516,7 @@ morkBuilder::OnNewDict(morkEnv* ev, const morkPlace& inPlace)
|
|||
// mp:Dict ::= OnNewDict mp:DictItem* OnDictEnd
|
||||
// mp:DictItem ::= OnAlias | OnAliasGlitch | mp:Meta | OnDictGlitch
|
||||
{
|
||||
MORK_USED_2(ev,inPlace);
|
||||
// mParser_InDict = morkBool_kTrue;
|
||||
|
||||
mBuilder_CellForm = mBuilder_DictForm = mBuilder_PortForm;
|
||||
|
@ -518,6 +533,7 @@ morkBuilder::OnDictGlitch(morkEnv* ev, const morkGlitch& inGlitch)
|
|||
morkBuilder::OnDictEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
// mp:Dict ::= OnNewDict mp:DictItem* OnDictEnd
|
||||
{
|
||||
MORK_USED_2(ev,inSpan);
|
||||
// mParser_InDict = morkBool_kFalse;
|
||||
|
||||
mBuilder_DictForm = 0;
|
||||
|
@ -528,6 +544,7 @@ morkBuilder::OnDictEnd(morkEnv* ev, const morkSpan& inSpan)
|
|||
morkBuilder::OnAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkMid& inMid)
|
||||
{
|
||||
MORK_USED_1(inSpan);
|
||||
if ( mParser_InDict )
|
||||
{
|
||||
morkMid mid = inMid; // local copy for modification
|
||||
|
@ -583,6 +600,7 @@ morkBuilder::OnNewCell(morkEnv* ev, const morkPlace& inPlace,
|
|||
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
|
||||
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
|
||||
{
|
||||
MORK_USED_1(inPlace);
|
||||
// mParser_InCell = morkBool_kTrue;
|
||||
|
||||
mBuilder_CellAtomScope = mBuilder_RowAtomScope;
|
||||
|
@ -699,6 +717,7 @@ morkBuilder::OnCellForm(morkEnv* ev, mork_cscode inCharsetFormat)
|
|||
morkBuilder::OnCellEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
// mp:Cell ::= OnNewCell mp:CellItem? OnCellEnd
|
||||
{
|
||||
MORK_USED_2(ev,inSpan);
|
||||
// mParser_InCell = morkBool_kFalse;
|
||||
|
||||
mBuilder_MetaTokenSlot = 0;
|
||||
|
@ -711,6 +730,7 @@ morkBuilder::OnValue(morkEnv* ev, const morkSpan& inSpan,
|
|||
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
|
||||
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
|
||||
{
|
||||
MORK_USED_1(inSpan);
|
||||
morkStore* store = mBuilder_Store;
|
||||
morkCell* cell = mBuilder_Cell;
|
||||
if ( cell )
|
||||
|
@ -751,6 +771,7 @@ morkBuilder::OnValueMid(morkEnv* ev, const morkSpan& inSpan,
|
|||
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
|
||||
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
|
||||
{
|
||||
MORK_USED_1(inSpan);
|
||||
morkStore* store = mBuilder_Store;
|
||||
morkCell* cell = mBuilder_Cell;
|
||||
|
||||
|
@ -779,7 +800,7 @@ morkBuilder::OnValueMid(morkEnv* ev, const morkSpan& inSpan,
|
|||
mork_token* metaSlot = mBuilder_MetaTokenSlot;
|
||||
if ( metaSlot )
|
||||
{
|
||||
mork_scope valScope = valOid->mOid_Scope;
|
||||
mork_scope valScope = valOid->mOid_Scope;
|
||||
if ( !valScope || valScope == morkStore_kColumnSpaceScope )
|
||||
{
|
||||
if ( ev->Good() && valMid.HasSomeId() )
|
||||
|
@ -810,6 +831,7 @@ morkBuilder::OnRowMid(morkEnv* ev, const morkSpan& inSpan,
|
|||
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
|
||||
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
|
||||
{
|
||||
MORK_USED_1(inSpan);
|
||||
morkStore* store = mBuilder_Store;
|
||||
morkCell* cell = mBuilder_Cell;
|
||||
if ( cell )
|
||||
|
@ -846,6 +868,7 @@ morkBuilder::OnTableMid(morkEnv* ev, const morkSpan& inSpan,
|
|||
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
|
||||
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
|
||||
{
|
||||
MORK_USED_1(inSpan);
|
||||
morkStore* store = mBuilder_Store;
|
||||
morkCell* cell = mBuilder_Cell;
|
||||
if ( cell )
|
||||
|
|
|
@ -57,12 +57,14 @@ morkCell::SetYarn(morkEnv* ev, const mdbYarn* inYarn, morkStore* ioStore)
|
|||
void
|
||||
morkCell::GetYarn(morkEnv* ev, mdbYarn* outYarn) const
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
mCell_Atom->GetYarn(outYarn);
|
||||
}
|
||||
|
||||
void
|
||||
morkCell::AliasYarn(morkEnv* ev, mdbYarn* outYarn) const
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
mCell_Atom->AliasYarn(outYarn);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,236 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKOBJECT_
|
||||
#include "morkObject.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKCELLOBJECT_
|
||||
#include "morkCellObject.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKROWOBJECT_
|
||||
#include "morkRowObject.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKROW_
|
||||
#include "morkRow.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKCELL_
|
||||
#include "morkCell.h"
|
||||
#endif
|
||||
|
||||
#ifndef _ORKINCELL_
|
||||
#include "orkinCell.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkCellObject::CloseMorkNode(morkEnv* ev) // CloseCellObject() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->CloseCellObject(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkCellObject::~morkCellObject() // assert CloseCellObject() executed earlier
|
||||
{
|
||||
MORK_ASSERT(mCellObject_Row==0);
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkCellObject::morkCellObject(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, morkRow* ioRow, morkCell* ioCell,
|
||||
mork_column inCol, mork_pos inPos)
|
||||
: morkObject(ev, inUsage, ioHeap, (morkHandle*) 0)
|
||||
, mCellObject_RowObject( 0 )
|
||||
, mCellObject_Row( 0 )
|
||||
, mCellObject_Cell( 0 )
|
||||
, mCellObject_Col( inCol )
|
||||
, mCellObject_RowSeed( 0 )
|
||||
, mCellObject_Pos( (mork_u2) inPos )
|
||||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
if ( ioRow && ioCell )
|
||||
{
|
||||
if ( ioRow->IsRow() )
|
||||
{
|
||||
morkStore* store = ioRow->GetRowSpaceStore(ev);
|
||||
if ( 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);
|
||||
|
||||
mCellObject_RowObject = rowObj; // assume control of strong ref
|
||||
}
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kCellObject;
|
||||
}
|
||||
}
|
||||
else
|
||||
ioRow->NonRowTypeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkCellObject::CloseCellObject(morkEnv* ev) // called by CloseMorkNode();
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
morkRowObject::SlotStrongRowObject((morkRowObject*) 0, ev,
|
||||
&mCellObject_RowObject);
|
||||
mCellObject_Row = 0;
|
||||
mCellObject_Cell = 0;
|
||||
mCellObject_RowSeed = 0;
|
||||
this->CloseObject(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
mork_bool
|
||||
morkCellObject::ResyncWithRow(morkEnv* ev)
|
||||
{
|
||||
morkRow* row = mCellObject_Row;
|
||||
mork_pos pos = 0;
|
||||
morkCell* cell = row->GetCell(ev, mCellObject_Col, &pos);
|
||||
if ( cell )
|
||||
{
|
||||
mCellObject_Pos = pos;
|
||||
mCellObject_Cell = cell;
|
||||
mCellObject_RowSeed = row->mRow_Seed;
|
||||
}
|
||||
else
|
||||
{
|
||||
mCellObject_Cell = 0;
|
||||
this->MissingRowColumnError(ev);
|
||||
}
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
morkAtom*
|
||||
morkCellObject::GetCellAtom(morkEnv* ev) const
|
||||
{
|
||||
morkCell* cell = mCellObject_Cell;
|
||||
if ( cell )
|
||||
return cell->GetAtom();
|
||||
else
|
||||
this->NilCellError(ev);
|
||||
|
||||
return (morkAtom*) 0;
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkCellObject::WrongRowObjectRowError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("mCellObject_Row != mCellObject_RowObject->mRowObject_Row");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkCellObject::NilRowError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("nil mCellObject_Row");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkCellObject::NilRowObjectError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("nil mCellObject_RowObject");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkCellObject::NilCellError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("nil mCellObject_Cell");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkCellObject::NonCellObjectTypeError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("non morkCellObject");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkCellObject::MissingRowColumnError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("mCellObject_Col not in mCellObject_Row");
|
||||
}
|
||||
|
||||
nsIMdbCell*
|
||||
morkCellObject::AcquireCellHandle(morkEnv* ev)
|
||||
{
|
||||
nsIMdbCell* outCell = 0;
|
||||
orkinCell* c = (orkinCell*) mObject_Handle;
|
||||
if ( c ) // have an old handle?
|
||||
c->AddStrongRef(ev->AsMdbEnv());
|
||||
else // need new handle?
|
||||
{
|
||||
c = orkinCell::MakeCell(ev, this);
|
||||
mObject_Handle = c;
|
||||
}
|
||||
if ( c )
|
||||
outCell = c;
|
||||
return outCell;
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
|
@ -1,250 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKCONFIG_
|
||||
#include "morkConfig.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
/* ----- ----- ----- ----- MORK_OBSOLETE ----- ----- ----- ----- */
|
||||
#ifdef MORK_OBSOLETE
|
||||
|
||||
#include <Types.h>
|
||||
#include "plstr.h"
|
||||
|
||||
static void // copied almost verbatim from the IronDoc debugger sources:
|
||||
mork_mac_break_string(register const char* inMessage) /*i*/
|
||||
{
|
||||
Str255 pascalStr; // to hold Pascal string version of inMessage
|
||||
mork_u4 length = PL_strlen(inMessage);
|
||||
|
||||
// if longer than maximum 255 bytes, just copy 255 bytes worth
|
||||
pascalStr[ 0 ] = (length > 255)? 255 : length;
|
||||
if ( length ) // anything to copy? */
|
||||
{
|
||||
register mork_u1* p = ((mork_u1*) &pascalStr) + 1; // after length byte
|
||||
register mork_u1* end = p + length; // one past last byte to copy
|
||||
while ( p < end ) // more bytes to copy?
|
||||
{
|
||||
register int c = (mork_u1) *inMessage++;
|
||||
if ( c == ';' ) // c is the MacsBug ';' metacharacter?
|
||||
c = ':'; // change to ':', rendering harmless in a MacsBug context
|
||||
*p++ = (mork_u1) c;
|
||||
}
|
||||
}
|
||||
|
||||
DebugStr(pascalStr); /* call Mac debugger entry point */
|
||||
}
|
||||
#endif /*MORK_OBSOLETE*/
|
||||
/* ----- ----- ----- ----- MORK_OBSOLETE ----- ----- ----- ----- */
|
||||
|
||||
void mork_assertion_signal(const char* inMessage)
|
||||
{
|
||||
#ifdef MORK_OBSOLETE
|
||||
mork_mac_break_string(inMessage);
|
||||
#endif /*MORK_OBSOLETE*/
|
||||
|
||||
#if defined(MORK_WIN) || defined(MORK_MAC)
|
||||
// asm { int 3 }
|
||||
NS_ASSERTION(0, inMessage);
|
||||
#endif /*MORK_WIN*/
|
||||
}
|
||||
|
||||
#ifdef MORK_PROVIDE_STDLIB
|
||||
|
||||
MORK_LIB_IMPL(mork_i4)
|
||||
mork_memcmp(const void* inOne, const void* inTwo, mork_size inSize)
|
||||
{
|
||||
register const mork_u1* t = (const mork_u1*) inTwo;
|
||||
register const mork_u1* s = (const mork_u1*) inOne;
|
||||
const mork_u1* end = s + inSize;
|
||||
register mork_i4 delta;
|
||||
|
||||
while ( s < end )
|
||||
{
|
||||
delta = ((mork_i4) *s) - ((mork_i4) *t);
|
||||
if ( delta )
|
||||
return delta;
|
||||
else
|
||||
{
|
||||
++t;
|
||||
++s;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
MORK_LIB_IMPL(void)
|
||||
mork_memcpy(void* outDst, const void* inSrc, mork_size inSize)
|
||||
{
|
||||
register mork_u1* d = (mork_u1*) outDst;
|
||||
mork_u1* end = d + inSize;
|
||||
register const mork_u1* s = ((const mork_u1*) inSrc);
|
||||
|
||||
while ( inSize >= 8 )
|
||||
{
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
|
||||
inSize -= 8;
|
||||
}
|
||||
|
||||
while ( d < end )
|
||||
*d++ = *s++;
|
||||
}
|
||||
|
||||
MORK_LIB_IMPL(void)
|
||||
mork_memmove(void* outDst, const void* inSrc, mork_size inSize)
|
||||
{
|
||||
register mork_u1* d = (mork_u1*) outDst;
|
||||
register const mork_u1* s = (const mork_u1*) inSrc;
|
||||
if ( d != s && inSize ) // copy is necessary?
|
||||
{
|
||||
const mork_u1* srcEnd = s + inSize; // one past last source byte
|
||||
|
||||
if ( d > s && d < srcEnd ) // overlap? need to copy backwards?
|
||||
{
|
||||
s = srcEnd; // start one past last source byte
|
||||
d += inSize; // start one past last dest byte
|
||||
mork_u1* dstBegin = d; // last byte to write is first in dest range
|
||||
while ( d - dstBegin >= 8 )
|
||||
{
|
||||
*--d = *--s;
|
||||
*--d = *--s;
|
||||
*--d = *--s;
|
||||
*--d = *--s;
|
||||
|
||||
*--d = *--s;
|
||||
*--d = *--s;
|
||||
*--d = *--s;
|
||||
*--d = *--s;
|
||||
}
|
||||
while ( d > dstBegin )
|
||||
*--d = *--s;
|
||||
}
|
||||
else // can copy forwards without any overlap
|
||||
{
|
||||
mork_u1* dstEnd = d + inSize;
|
||||
while ( dstEnd - d >= 8 )
|
||||
{
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
}
|
||||
while ( d < dstEnd )
|
||||
*d++ = *s++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MORK_LIB_IMPL(void)
|
||||
mork_memset(void* outDst, int inByte, mork_size inSize)
|
||||
{
|
||||
register mork_u1* d = (mork_u1*) outDst;
|
||||
mork_u1* end = d + inSize;
|
||||
while ( d < end )
|
||||
*d++ = (mork_u1) inByte;
|
||||
}
|
||||
|
||||
MORK_LIB_IMPL(void)
|
||||
mork_strcpy(void* outDst, const void* inSrc)
|
||||
{
|
||||
// back up one first to support preincrement
|
||||
register mork_u1* d = ((mork_u1*) outDst) - 1;
|
||||
register const mork_u1* s = ((const mork_u1*) inSrc) - 1;
|
||||
while ( ( *++d = *++s ) != 0 )
|
||||
/* empty */;
|
||||
}
|
||||
|
||||
MORK_LIB_IMPL(mork_i4)
|
||||
mork_strcmp(const void* inOne, const void* inTwo)
|
||||
{
|
||||
register const mork_u1* t = (const mork_u1*) inTwo;
|
||||
register const mork_u1* s = ((const mork_u1*) inOne);
|
||||
register mork_i4 a;
|
||||
register mork_i4 b;
|
||||
register mork_i4 delta;
|
||||
|
||||
do
|
||||
{
|
||||
a = (mork_i4) *s++;
|
||||
b = (mork_i4) *t++;
|
||||
delta = a - b;
|
||||
}
|
||||
while ( !delta && a && b );
|
||||
|
||||
return delta;
|
||||
}
|
||||
|
||||
MORK_LIB_IMPL(mork_i4)
|
||||
mork_strncmp(const void* inOne, const void* inTwo, mork_size inSize)
|
||||
{
|
||||
register const mork_u1* t = (const mork_u1*) inTwo;
|
||||
register const mork_u1* s = (const mork_u1*) inOne;
|
||||
const mork_u1* end = s + inSize;
|
||||
register mork_i4 delta;
|
||||
register mork_i4 a;
|
||||
register mork_i4 b;
|
||||
|
||||
while ( s < end )
|
||||
{
|
||||
a = (mork_i4) *s++;
|
||||
b = (mork_i4) *t++;
|
||||
delta = a - b;
|
||||
if ( delta || !a || !b )
|
||||
return delta;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
MORK_LIB_IMPL(mork_size)
|
||||
mork_strlen(const void* inString)
|
||||
{
|
||||
// back up one first to support preincrement
|
||||
register const mork_u1* s = ((const mork_u1*) inString) - 1;
|
||||
while ( *++s ) // preincrement is cheapest
|
||||
/* empty */;
|
||||
|
||||
return s - ((const mork_u1*) inString); // distance from original address
|
||||
}
|
||||
|
||||
#endif /*MORK_PROVIDE_STDLIB*/
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
|
@ -30,6 +30,10 @@
|
|||
#endif
|
||||
|
||||
// { %%%%% begin platform defs peculiar to Mork %%%%%
|
||||
|
||||
//#define XP_MAC 1
|
||||
//#define MORK_ALONE 1
|
||||
|
||||
#ifdef XP_MAC
|
||||
#define MORK_MAC 1
|
||||
#endif
|
||||
|
@ -59,7 +63,10 @@
|
|||
#include "errno.h"
|
||||
#include "string.h"
|
||||
#include "memory.h"
|
||||
|
||||
#ifndef MORK_ALONE
|
||||
#include "nsDebug.h"
|
||||
#endif /*MORK_ALONE*/
|
||||
|
||||
#define MORK_ISPRINT(c) isprint(c)
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ morkDeque::IndexOf(const morkLink* member) const /*i*/
|
|||
{
|
||||
++count;
|
||||
if ( member == link )
|
||||
return count;
|
||||
return (mork_pos) count;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -185,15 +185,15 @@ morkEnv::OidAsHex(void* outBuf, const mdbOid& inOid)
|
|||
mork_scope scope = inOid.mOid_Scope;
|
||||
if ( scope < 0x80 && morkCh_IsName((mork_ch) scope) )
|
||||
{
|
||||
*p++ = (mork_u1) scope;
|
||||
*p = 0; // null termination
|
||||
outSize += 2;
|
||||
*p++ = (mork_u1) scope;
|
||||
*p = 0; // null termination
|
||||
outSize += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
*p++ = '^';
|
||||
mork_size scopeSize = this->TokenAsHex(p, scope);
|
||||
outSize += scopeSize + 2;
|
||||
*p++ = '^';
|
||||
mork_size scopeSize = this->TokenAsHex(p, scope);
|
||||
outSize += scopeSize + 2;
|
||||
}
|
||||
return outSize;
|
||||
}
|
||||
|
@ -205,20 +205,20 @@ morkEnv::HexToByte(mork_ch inFirstHex, mork_ch inSecondHex)
|
|||
mork_u1 hi = 0; // high four hex bits
|
||||
mork_flags f = morkCh_GetFlags(inFirstHex);
|
||||
if ( morkFlags_IsDigit(f) )
|
||||
hi = inFirstHex - '0';
|
||||
hi = (mork_u1) (inFirstHex - (mork_ch) '0');
|
||||
else if ( morkFlags_IsUpper(f) )
|
||||
hi = (inFirstHex - 'A') + 10;
|
||||
hi = (mork_u1) ((inFirstHex - (mork_ch) 'A') + 10);
|
||||
else if ( morkFlags_IsLower(f) )
|
||||
hi = (inFirstHex - 'a') + 10;
|
||||
hi = (mork_u1) ((inFirstHex - (mork_ch) 'a') + 10);
|
||||
|
||||
mork_u1 lo = 0; // low four hex bits
|
||||
f = morkCh_GetFlags(inSecondHex);
|
||||
if ( morkFlags_IsDigit(f) )
|
||||
lo = inSecondHex - '0';
|
||||
lo = (mork_u1) (inSecondHex - (mork_ch) '0');
|
||||
else if ( morkFlags_IsUpper(f) )
|
||||
lo = (inSecondHex - 'A') + 10;
|
||||
lo = (mork_u1) ((inSecondHex - (mork_ch) 'A') + 10);
|
||||
else if ( morkFlags_IsLower(f) )
|
||||
lo = (inSecondHex - 'a') + 10;
|
||||
lo = (mork_u1) ((inSecondHex - (mork_ch) 'a') + 10);
|
||||
|
||||
return (mork_u1) ((hi << 4) | lo);
|
||||
}
|
||||
|
@ -240,7 +240,7 @@ morkEnv::TokenAsHex(void* outBuf, mork_token inToken)
|
|||
}
|
||||
*p = 0; // end the string with a null byte
|
||||
char* s = (char*) outBuf; // first byte in string
|
||||
mork_size size = p - s; // distance from start
|
||||
mork_size size = (mork_size) (p - s); // distance from start
|
||||
|
||||
// now reverse the string in place:
|
||||
// note that p starts on the null byte, so we need predecrement:
|
||||
|
@ -311,7 +311,7 @@ morkEnv::NewErrorAndCode(const char* inString, mork_u2 inCode)
|
|||
MORK_ASSERT(morkBool_kFalse); // get developer's attention
|
||||
|
||||
++mEnv_ErrorCount;
|
||||
mEnv_ErrorCode = (inCode)? inCode: morkEnv_kGenericError;
|
||||
mEnv_ErrorCode = (mork_u4) ((inCode)? inCode: morkEnv_kGenericError);
|
||||
|
||||
if ( mEnv_ErrorHook )
|
||||
mEnv_ErrorHook->OnErrorString(this->AsMdbEnv(), inString);
|
||||
|
|
|
@ -373,6 +373,7 @@ morkStdioFile::AcquireBud(morkEnv* ev, nsIMdbHeap* ioHeap)
|
|||
// behavior is exhibited by the file, so crashes protect old files.
|
||||
// Note that AcquireBud() is an illegal operation on readonly files.
|
||||
{
|
||||
MORK_USED_1(ioHeap);
|
||||
morkFile* outFile = 0;
|
||||
if ( this->IsOpenAndActiveFile() )
|
||||
{
|
||||
|
@ -491,7 +492,7 @@ morkStdioFile::Read(morkEnv* ev, void* outBuf, mork_size inSize)
|
|||
FILE* file = (FILE*) mStdioFile_File;
|
||||
if ( file )
|
||||
{
|
||||
long count = MORK_FILEREAD(outBuf, inSize, file);
|
||||
long count = (long) MORK_FILEREAD(outBuf, inSize, file);
|
||||
if ( count >= 0 )
|
||||
{
|
||||
outCount = (mork_num) count;
|
||||
|
|
|
@ -132,10 +132,10 @@ public: // non-poly morkFile methods
|
|||
mork_bool FileIoOpen() const { return mFile_IoOpen == 'O'; }
|
||||
mork_bool FileActive() const { return mFile_Active == 'A'; }
|
||||
|
||||
void SetFileFrozen(mork_bool b) { mFile_Frozen = (b)? 'F' : 0; }
|
||||
void SetFileDoTrace(mork_bool b) { mFile_DoTrace = (b)? 'T' : 0; }
|
||||
void SetFileIoOpen(mork_bool b) { mFile_IoOpen = (b)? 'O' : 0; }
|
||||
void SetFileActive(mork_bool b) { mFile_Active = (b)? 'A' : 0; }
|
||||
void SetFileFrozen(mork_bool b) { mFile_Frozen = (mork_u1) ((b)? 'F' : 0); }
|
||||
void SetFileDoTrace(mork_bool b) { mFile_DoTrace = (mork_u1) ((b)? 'T' : 0); }
|
||||
void SetFileIoOpen(mork_bool b) { mFile_IoOpen = (mork_u1) ((b)? 'O' : 0); }
|
||||
void SetFileActive(mork_bool b) { mFile_Active = (mork_u1) ((b)? 'A' : 0); }
|
||||
|
||||
|
||||
mork_bool IsOpenActiveAndMutableFile() const
|
||||
|
|
|
@ -147,6 +147,7 @@ void morkHandle::NonOpenObjectError(morkEnv* ev) const
|
|||
|
||||
void morkHandle::NewBadMagicHandleError(morkEnv* ev, mork_magic inMagic) const
|
||||
{
|
||||
MORK_USED_1(inMagic);
|
||||
ev->NewError("wrong mHandle_Magic");
|
||||
}
|
||||
|
||||
|
@ -393,6 +394,7 @@ morkHandle::Handle_CloseMdbObject(nsIMdbEnv* mev)
|
|||
/*virtual*/ mdb_err
|
||||
morkHandle::Handle_IsOpenMdbObject(nsIMdbEnv* mev, mdb_bool* outOpen)
|
||||
{
|
||||
MORK_USED_1(mev);
|
||||
mdb_err outErr = 0;
|
||||
|
||||
MORK_ASSERT(outOpen);
|
||||
|
|
|
@ -100,7 +100,7 @@ public: // morkHandle memory management operators
|
|||
{ return ioPool.NewHandle(ev, inSize); }
|
||||
|
||||
void* operator new(size_t inSize, morkHandleFace* ioFace)
|
||||
{ return ioFace; }
|
||||
{ MORK_USED_1(inSize); return ioFace; }
|
||||
|
||||
void operator delete(void* ioAddress)
|
||||
{ morkNode::OnDeleteAssert(ioAddress); }
|
||||
|
|
|
@ -1,148 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKMAP_
|
||||
#include "morkMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKINTMAP_
|
||||
#include "morkIntMap.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkIntMap::CloseMorkNode(morkEnv* ev) // CloseIntMap() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->CloseIntMap(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkIntMap::~morkIntMap() // assert CloseIntMap() executed earlier
|
||||
{
|
||||
MORK_ASSERT(this->IsShutNode());
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkIntMap::morkIntMap(morkEnv* ev,
|
||||
const morkUsage& inUsage, mork_size inValSize,
|
||||
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap, mork_bool inHoldChanges)
|
||||
: morkMap(ev, inUsage, ioHeap, sizeof(mork_u4), inValSize,
|
||||
morkIntMap_kStartSlotCount, ioSlotHeap, inHoldChanges)
|
||||
{
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kIntMap;
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkIntMap::CloseIntMap(morkEnv* ev) // called by CloseMorkNode();
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
this->CloseMap(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
// { ===== begin morkMap poly interface =====
|
||||
/*virtual*/ mork_bool // *((mork_u4*) inKeyA) == *((mork_u4*) inKeyB)
|
||||
morkIntMap::Equal(morkEnv* ev, const void* inKeyA, const void* inKeyB) const
|
||||
{
|
||||
return *((const mork_u4*) inKeyA) == *((const mork_u4*) inKeyB);
|
||||
}
|
||||
|
||||
/*virtual*/ mork_u4 // some integer function of *((mork_u4*) inKey)
|
||||
morkIntMap::Hash(morkEnv* ev, const void* inKey) const
|
||||
{
|
||||
return *((const mork_u4*) inKey);
|
||||
}
|
||||
// } ===== end morkMap poly interface =====
|
||||
|
||||
mork_bool
|
||||
morkIntMap::AddInt(morkEnv* ev, mork_u4 inKey, void* ioAddress)
|
||||
// the AddInt() method return value equals ev->Good().
|
||||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
this->Put(ev, &inKey, &ioAddress,
|
||||
/*key*/ (void*) 0, /*val*/ (void*) 0, (mork_change**) 0);
|
||||
}
|
||||
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkIntMap::CutInt(morkEnv* ev, mork_u4 inKey)
|
||||
{
|
||||
return this->Cut(ev, &inKey, /*key*/ (void*) 0, /*val*/ (void*) 0,
|
||||
(mork_change**) 0);
|
||||
}
|
||||
|
||||
void*
|
||||
morkIntMap::GetInt(morkEnv* ev, mork_u4 inKey)
|
||||
// Note the returned val does NOT have an increase in refcount for this.
|
||||
{
|
||||
void* val = 0; // old val in the map
|
||||
this->Get(ev, &inKey, /*key*/ (void*) 0, &val, (mork_change**) 0);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkIntMap::HasInt(morkEnv* ev, mork_u4 inKey)
|
||||
// Note the returned val does NOT have an increase in refcount for this.
|
||||
{
|
||||
return this->Get(ev, &inKey, /*key*/ (void*) 0, /*val*/ (void*) 0,
|
||||
(mork_change**) 0);
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
|
@ -1,87 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MORKINTMAP_
|
||||
#define _MORKINTMAP_ 1
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKMAP_
|
||||
#include "morkMap.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#define morkDerived_kIntMap /*i*/ 0x694D /* ascii 'iM' */
|
||||
|
||||
#define morkIntMap_kStartSlotCount 512
|
||||
|
||||
/*| morkIntMap: maps mork_token -> morkNode
|
||||
|*/
|
||||
class morkIntMap : public morkMap { // for mapping tokens to maps
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
virtual void CloseMorkNode(morkEnv* ev); // CloseIntMap() only if open
|
||||
virtual ~morkIntMap(); // assert that CloseIntMap() executed earlier
|
||||
|
||||
public: // morkMap construction & destruction
|
||||
|
||||
// keySize for morkIntMap equals sizeof(mork_u4)
|
||||
morkIntMap(morkEnv* ev, const morkUsage& inUsage, mork_size inValSize,
|
||||
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap, mork_bool inHoldChanges);
|
||||
void CloseIntMap(morkEnv* ev); // called by CloseMorkNode();
|
||||
|
||||
public: // dynamic type identification
|
||||
mork_bool IsIntMap() const
|
||||
{ return IsNode() && mNode_Derived == morkDerived_kIntMap; }
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
// { ===== begin morkMap poly interface =====
|
||||
virtual mork_bool // *((mork_u4*) inKeyA) == *((mork_u4*) inKeyB)
|
||||
Equal(morkEnv* ev, const void* inKeyA, const void* inKeyB) const;
|
||||
|
||||
virtual mork_u4 // some integer function of *((mork_u4*) inKey)
|
||||
Hash(morkEnv* ev, const void* inKey) const;
|
||||
// } ===== end morkMap poly interface =====
|
||||
|
||||
public: // other map methods
|
||||
|
||||
mork_bool AddInt(morkEnv* ev, mork_u4 inKey, void* ioAddress);
|
||||
// the AddInt() boolean return equals ev->Good().
|
||||
|
||||
mork_bool CutInt(morkEnv* ev, mork_token inKey);
|
||||
// The CutInt() boolean return indicates whether removal happened.
|
||||
|
||||
void* GetInt(morkEnv* ev, mork_token inKey);
|
||||
// Note the returned node does NOT have an increase in refcount for this.
|
||||
|
||||
mork_bool HasInt(morkEnv* ev, mork_u4 inKey);
|
||||
// Note the returned node does NOT have an increase in refcount for this.
|
||||
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKINTMAP_ */
|
|
@ -1,937 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
// This code is mostly a port to C++ from public domain IronDoc C sources.
|
||||
// Note many code comments here come verbatim from cut-and-pasted IronDoc.
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKMAP_
|
||||
#include "morkMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
|
||||
class morkHashArrays {
|
||||
public:
|
||||
nsIMdbHeap* mHashArrays_Heap; // copy of mMap_Heap
|
||||
mork_count mHashArrays_Slots; // copy of mMap_Slots
|
||||
|
||||
mork_u1* mHashArrays_Keys; // copy of mMap_Keys
|
||||
mork_u1* mHashArrays_Vals; // copy of mMap_Vals
|
||||
morkAssoc* mHashArrays_Assocs; // copy of mMap_Assocs
|
||||
mork_change* mHashArrays_Changes; // copy of mMap_Changes
|
||||
morkAssoc** mHashArrays_Buckets; // copy of mMap_Buckets
|
||||
morkAssoc* mHashArrays_FreeList; // copy of mMap_FreeList
|
||||
|
||||
public:
|
||||
void finalize(morkEnv* ev);
|
||||
};
|
||||
|
||||
void morkHashArrays::finalize(morkEnv* ev)
|
||||
{
|
||||
nsIMdbEnv* menv = ev->AsMdbEnv();
|
||||
nsIMdbHeap* heap = mHashArrays_Heap;
|
||||
|
||||
if ( heap )
|
||||
{
|
||||
if ( mHashArrays_Keys )
|
||||
heap->Free(menv, mHashArrays_Keys);
|
||||
if ( mHashArrays_Vals )
|
||||
heap->Free(menv, mHashArrays_Vals);
|
||||
if ( mHashArrays_Assocs )
|
||||
heap->Free(menv, mHashArrays_Assocs);
|
||||
if ( mHashArrays_Changes )
|
||||
heap->Free(menv, mHashArrays_Changes);
|
||||
if ( mHashArrays_Buckets )
|
||||
heap->Free(menv, mHashArrays_Buckets);
|
||||
}
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkMap::CloseMorkNode(morkEnv* ev) // CloseMap() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->CloseMap(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkMap::~morkMap() // assert CloseMap() executed earlier
|
||||
{
|
||||
MORK_ASSERT(mMap_FreeList==0);
|
||||
MORK_ASSERT(mMap_Buckets==0);
|
||||
MORK_ASSERT(mMap_Keys==0);
|
||||
MORK_ASSERT(mMap_Vals==0);
|
||||
MORK_ASSERT(mMap_Changes==0);
|
||||
MORK_ASSERT(mMap_Assocs==0);
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkMap::CloseMap(morkEnv* ev) // called by CloseMorkNode();
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
nsIMdbHeap* heap = mMap_Heap;
|
||||
if ( heap ) /* need to free the arrays? */
|
||||
{
|
||||
nsIMdbEnv* menv = ev->AsMdbEnv();
|
||||
|
||||
if ( mMap_Keys )
|
||||
heap->Free(menv, mMap_Keys);
|
||||
|
||||
if ( mMap_Vals )
|
||||
heap->Free(menv, mMap_Vals);
|
||||
|
||||
if ( mMap_Assocs )
|
||||
heap->Free(menv, mMap_Assocs);
|
||||
|
||||
if ( mMap_Buckets )
|
||||
heap->Free(menv, mMap_Buckets);
|
||||
|
||||
if ( mMap_Changes )
|
||||
heap->Free(menv, mMap_Changes);
|
||||
}
|
||||
mMap_Keys = 0;
|
||||
mMap_Vals = 0;
|
||||
mMap_Buckets = 0;
|
||||
mMap_Assocs = 0;
|
||||
mMap_Changes = 0;
|
||||
mMap_FreeList = 0;
|
||||
MORK_MEMSET(&mMap_Form, 0, sizeof(morkMapForm));
|
||||
this->MarkShut();
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
void
|
||||
morkMap::clear_map(morkEnv* ev, nsIMdbHeap* ioSlotHeap)
|
||||
{
|
||||
mMap_Tag = 0;
|
||||
mMap_Seed = 0;
|
||||
mMap_Slots = 0;
|
||||
mMap_Fill = 0;
|
||||
mMap_Keys = 0;
|
||||
mMap_Vals = 0;
|
||||
mMap_Assocs = 0;
|
||||
mMap_Changes = 0;
|
||||
mMap_Buckets = 0;
|
||||
mMap_FreeList = 0;
|
||||
MORK_MEMSET(&mMap_Form, 0, sizeof(morkMapForm));
|
||||
|
||||
mMap_Heap = 0;
|
||||
if ( ioSlotHeap )
|
||||
{
|
||||
nsIMdbHeap_SlotStrongHeap(ioSlotHeap, ev, &mMap_Heap);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
morkMap::morkMap(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap,
|
||||
mork_size inKeySize, mork_size inValSize,
|
||||
mork_size inSlots, nsIMdbHeap* ioSlotHeap, mork_bool inHoldChanges)
|
||||
: morkNode(ev, inUsage, ioHeap)
|
||||
, mMap_Heap( 0 )
|
||||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
this->clear_map(ev, ioSlotHeap);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
mMap_Form.mMapForm_HoldChanges = inHoldChanges;
|
||||
|
||||
mMap_Form.mMapForm_KeySize = inKeySize;
|
||||
mMap_Form.mMapForm_ValSize = inValSize;
|
||||
mMap_Form.mMapForm_KeyIsIP = ( inKeySize == sizeof(mork_ip) );
|
||||
mMap_Form.mMapForm_ValIsIP = ( inValSize == sizeof(mork_ip) );
|
||||
|
||||
this->InitMap(ev, inSlots);
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kMap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
morkMap::NewIterOutOfSyncError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("map iter out of sync");
|
||||
}
|
||||
|
||||
void morkMap::NewBadMapError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("bad morkMap tag");
|
||||
if ( !this )
|
||||
ev->NewError("nil morkMap instance");
|
||||
}
|
||||
|
||||
void morkMap::NewSlotsUnderflowWarning(morkEnv* ev)
|
||||
{
|
||||
ev->NewWarning("member count underflow");
|
||||
}
|
||||
|
||||
void morkMap::InitMap(morkEnv* ev, mork_size inSlots)
|
||||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
morkHashArrays old;
|
||||
// MORK_MEMCPY(&mMap_Form, &inForm, sizeof(morkMapForm));
|
||||
if ( inSlots < 3 ) /* requested capacity absurdly small? */
|
||||
inSlots = 3; /* bump it up to a minimum practical level */
|
||||
else if ( inSlots > (128 * 1024) ) /* requested slots absurdly big? */
|
||||
inSlots = (128 * 1024); /* decrease it to a maximum practical level */
|
||||
|
||||
if ( this->new_arrays(ev, &old, inSlots) )
|
||||
mMap_Tag = morkMap_kTag;
|
||||
|
||||
MORK_MEMSET(&old, 0, sizeof(morkHashArrays)); // do NOT finalize
|
||||
}
|
||||
}
|
||||
|
||||
morkAssoc**
|
||||
morkMap::find(morkEnv* ev, const void* inKey, mork_u4 inHash) const
|
||||
{
|
||||
mork_u1* keys = mMap_Keys;
|
||||
mork_num keySize = this->FormKeySize();
|
||||
// morkMap_mEqual equal = this->FormEqual();
|
||||
|
||||
morkAssoc** ref = mMap_Buckets + (inHash % mMap_Slots);
|
||||
morkAssoc* assoc = *ref;
|
||||
while ( assoc ) /* look at another assoc in the bucket? */
|
||||
{
|
||||
mork_pos i = assoc - mMap_Assocs; /* index of this assoc */
|
||||
if ( this->Equal(ev, keys + (i * keySize), inKey) ) /* found? */
|
||||
return ref;
|
||||
|
||||
ref = &assoc->mAssoc_Next; /* consider next assoc slot in bucket */
|
||||
assoc = *ref; /* if this is null, then we are done */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*| get_assoc: read the key and/or value at index inPos
|
||||
|*/
|
||||
void
|
||||
morkMap::get_assoc(void* outKey, void* outVal, mork_pos inPos) const
|
||||
{
|
||||
mork_num valSize = this->FormValSize();
|
||||
if ( valSize && outVal ) /* map holds values? caller wants the value? */
|
||||
{
|
||||
const mork_u1* value = mMap_Vals + (valSize * inPos);
|
||||
if ( valSize == sizeof(mork_ip) && this->FormValIsIP() ) /* ip case? */
|
||||
*((mork_ip*) outVal) = *((const mork_ip*) value);
|
||||
else
|
||||
MORK_MEMCPY(outVal, value, valSize);
|
||||
}
|
||||
if ( outKey ) /* caller wants the key? */
|
||||
{
|
||||
mork_num keySize = this->FormKeySize();
|
||||
const mork_u1* key = mMap_Keys + (keySize * inPos);
|
||||
if ( keySize == sizeof(mork_ip) && this->FormKeyIsIP() ) /* ip case? */
|
||||
*((mork_ip*) outKey) = *((const mork_ip*) key);
|
||||
else
|
||||
MORK_MEMCPY(outKey, key, keySize);
|
||||
}
|
||||
}
|
||||
|
||||
/*| put_assoc: write the key and/or value at index inPos
|
||||
|*/
|
||||
void
|
||||
morkMap::put_assoc(const void* inKey, const void* inVal, mork_pos inPos) const
|
||||
{
|
||||
mork_num valSize = this->FormValSize();
|
||||
if ( valSize && inVal ) /* map holds values? caller sends a value? */
|
||||
{
|
||||
mork_u1* value = mMap_Vals + (valSize * inPos);
|
||||
if ( valSize == sizeof(mork_ip) && this->FormValIsIP() ) /* ip case? */
|
||||
*((mork_ip*) value) = *((const mork_ip*) inVal);
|
||||
else
|
||||
MORK_MEMCPY(value, inVal, valSize);
|
||||
}
|
||||
if ( inKey ) /* caller sends a key? */
|
||||
{
|
||||
mork_num keySize = this->FormKeySize();
|
||||
mork_u1* key = mMap_Keys + (keySize * inPos);
|
||||
if ( keySize == sizeof(mork_ip) && this->FormKeyIsIP() ) /* ip case? */
|
||||
*((mork_ip*) key) = *((const mork_ip*) inKey);
|
||||
else
|
||||
MORK_MEMCPY(key, inKey, keySize);
|
||||
}
|
||||
}
|
||||
|
||||
void*
|
||||
morkMap::clear_alloc(morkEnv* ev, mork_size inSize)
|
||||
{
|
||||
void* p = 0;
|
||||
nsIMdbHeap* heap = mMap_Heap;
|
||||
if ( heap )
|
||||
{
|
||||
if ( heap->Alloc(ev->AsMdbEnv(), inSize, (void**) &p) == 0 && p )
|
||||
{
|
||||
MORK_MEMSET(p, 0, inSize);
|
||||
return p;
|
||||
}
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
|
||||
return (void*) 0;
|
||||
}
|
||||
|
||||
void*
|
||||
morkMap::alloc(morkEnv* ev, mork_size inSize)
|
||||
{
|
||||
void* p = 0;
|
||||
nsIMdbHeap* heap = mMap_Heap;
|
||||
if ( heap )
|
||||
{
|
||||
if ( heap->Alloc(ev->AsMdbEnv(), inSize, (void**) &p) == 0 && p )
|
||||
return p;
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
|
||||
return (void*) 0;
|
||||
}
|
||||
|
||||
/*| new_keys: allocate an array of inSlots new keys filled with zero.
|
||||
|*/
|
||||
mork_u1*
|
||||
morkMap::new_keys(morkEnv* ev, mork_num inSlots)
|
||||
{
|
||||
mork_num size = inSlots * this->FormKeySize();
|
||||
return (mork_u1*) this->clear_alloc(ev, size);
|
||||
}
|
||||
|
||||
/*| new_values: allocate an array of inSlots new values filled with zero.
|
||||
**| When values are zero sized, we just return a null pointer.
|
||||
|*/
|
||||
mork_u1*
|
||||
morkMap::new_values(morkEnv* ev, mork_num inSlots)
|
||||
{
|
||||
mork_u1* values = 0;
|
||||
mork_num size = inSlots * this->FormValSize();
|
||||
if ( size )
|
||||
values = (mork_u1*) this->clear_alloc(ev, size);
|
||||
return values;
|
||||
}
|
||||
|
||||
mork_change*
|
||||
morkMap::new_changes(morkEnv* ev, mork_num inSlots)
|
||||
{
|
||||
mork_change* changes = 0;
|
||||
mork_num size = inSlots * sizeof(mork_change);
|
||||
if ( size && mMap_Form.mMapForm_HoldChanges )
|
||||
changes = (mork_change*) this->clear_alloc(ev, size);
|
||||
return changes;
|
||||
}
|
||||
|
||||
/*| new_buckets: allocate an array of inSlots new buckets filled with zero.
|
||||
|*/
|
||||
morkAssoc**
|
||||
morkMap::new_buckets(morkEnv* ev, mork_num inSlots)
|
||||
{
|
||||
mork_num size = inSlots * sizeof(morkAssoc*);
|
||||
return (morkAssoc**) this->clear_alloc(ev, size);
|
||||
}
|
||||
|
||||
/*| new_assocs: allocate an array of inSlots new assocs, with each assoc
|
||||
**| linked together in a list with the first array element at the list head
|
||||
**| and the last element at the list tail. (morkMap::grow() needs this.)
|
||||
|*/
|
||||
morkAssoc*
|
||||
morkMap::new_assocs(morkEnv* ev, mork_num inSlots)
|
||||
{
|
||||
mork_num size = inSlots * sizeof(morkAssoc);
|
||||
morkAssoc* assocs = (morkAssoc*) this->alloc(ev, size);
|
||||
if ( assocs ) /* able to allocate the array? */
|
||||
{
|
||||
morkAssoc* a = assocs + (inSlots - 1); /* the last array element */
|
||||
a->mAssoc_Next = 0; /* terminate tail element of the list with null */
|
||||
while ( --a >= assocs ) /* another assoc to link into the list? */
|
||||
a->mAssoc_Next = a + 1; /* each points to the following assoc */
|
||||
}
|
||||
return assocs;
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkMap::new_arrays(morkEnv* ev, morkHashArrays* old, mork_num inSlots)
|
||||
{
|
||||
mork_bool outNew = morkBool_kFalse;
|
||||
|
||||
/* see if we can allocate all the new arrays before we go any further: */
|
||||
morkAssoc** newBuckets = this->new_buckets(ev, inSlots);
|
||||
morkAssoc* newAssocs = this->new_assocs(ev, inSlots);
|
||||
mork_u1* newKeys = this->new_keys(ev, inSlots);
|
||||
mork_u1* newValues = this->new_values(ev, inSlots);
|
||||
mork_change* newChanges = this->new_changes(ev, inSlots);
|
||||
|
||||
/* it is okay for newChanges to be null when changes are not held: */
|
||||
mork_bool okayChanges = ( newChanges || !this->FormHoldChanges() );
|
||||
|
||||
/* it is okay for newValues to be null when values are zero sized: */
|
||||
mork_bool okayValues = ( newValues || !this->FormValSize() );
|
||||
|
||||
if ( newBuckets && newAssocs && newKeys && okayChanges && okayValues )
|
||||
{
|
||||
outNew = morkBool_kTrue; /* yes, we created all the arrays we need */
|
||||
|
||||
/* init the old hashArrays with slots from this hash table: */
|
||||
old->mHashArrays_Heap = mMap_Heap;
|
||||
|
||||
old->mHashArrays_Slots = mMap_Slots;
|
||||
old->mHashArrays_Keys = mMap_Keys;
|
||||
old->mHashArrays_Vals = mMap_Vals;
|
||||
old->mHashArrays_Assocs = mMap_Assocs;
|
||||
old->mHashArrays_Buckets = mMap_Buckets;
|
||||
old->mHashArrays_Changes = mMap_Changes;
|
||||
|
||||
/* now replace all our array slots with the new structures: */
|
||||
++mMap_Seed; /* note the map is now changed */
|
||||
mMap_Keys = newKeys;
|
||||
mMap_Vals = newValues;
|
||||
mMap_Buckets = newBuckets;
|
||||
mMap_Assocs = newAssocs;
|
||||
mMap_FreeList = newAssocs; /* all are free to start with */
|
||||
mMap_Changes = newChanges;
|
||||
mMap_Slots = inSlots;
|
||||
}
|
||||
else /* free the partial set of arrays that were actually allocated */
|
||||
{
|
||||
nsIMdbEnv* menv = ev->AsMdbEnv();
|
||||
nsIMdbHeap* heap = mMap_Heap;
|
||||
if ( newBuckets )
|
||||
heap->Free(menv, newBuckets);
|
||||
if ( newAssocs )
|
||||
heap->Free(menv, newAssocs);
|
||||
if ( newKeys )
|
||||
heap->Free(menv, newKeys);
|
||||
if ( newValues )
|
||||
heap->Free(menv, newValues);
|
||||
if ( newChanges )
|
||||
heap->Free(menv, newChanges);
|
||||
|
||||
MORK_MEMSET(old, 0, sizeof(morkHashArrays));
|
||||
}
|
||||
|
||||
return outNew;
|
||||
}
|
||||
|
||||
/*| grow: make the map arrays bigger by 33%. The old map is completely
|
||||
**| full, or else we would not have called grow() to get more space. This
|
||||
**| means the free list is empty, and also means every old key and value is in
|
||||
**| use in the old arrays. So every key and value must be copied to the new
|
||||
**| arrays, and since they are contiguous in the old arrays, we can efficiently
|
||||
**| bitwise copy them in bulk from the old arrays to the new arrays, without
|
||||
**| paying any attention to the structure of the old arrays.
|
||||
**|
|
||||
**|| The content of the old bucket and assoc arrays need not be copied because
|
||||
**| this information is going to be completely rebuilt by rehashing all the
|
||||
**| keys into their new buckets, given the new larger map capacity. The new
|
||||
**| bucket array from new_arrays() is assumed to contain all zeroes, which is
|
||||
**| necessary to ensure the lists in each bucket stay null terminated as we
|
||||
**| build the new linked lists. (Note no old bucket ordering is preserved.)
|
||||
**|
|
||||
**|| If the old capacity is N, then in the new arrays the assocs with indexes
|
||||
**| from zero to N-1 are still allocated and must be rehashed into the map.
|
||||
**| The new free list contains all the following assocs, starting with the new
|
||||
**| assoc link at index N. (We call the links in the link array "assocs"
|
||||
**| because allocating a link is the same as allocating the key/value pair
|
||||
**| with the same index as the link.)
|
||||
**|
|
||||
**|| The new free list is initialized simply by pointing at the first new link
|
||||
**| in the assoc array after the size of the old assoc array. This assumes
|
||||
**| that FeHashTable_new_arrays() has already linked all the new assocs into a
|
||||
**| list with the first at the head of the list and the last at the tail of the
|
||||
**| list. So by making the free list point to the first of the new uncopied
|
||||
**| assocs, the list is already well-formed.
|
||||
|*/
|
||||
mork_bool morkMap::grow(morkEnv* ev)
|
||||
{
|
||||
if ( mMap_Heap ) /* can we grow the map? */
|
||||
{
|
||||
mork_num newSlots = ((mMap_Slots * 4) / 3) + 1; /* +33% */
|
||||
morkHashArrays old; /* a place to temporarily hold all the old arrays */
|
||||
if ( this->new_arrays(ev, &old, newSlots) ) /* have more? */
|
||||
{
|
||||
// morkMap_mHash hash = this->FormHash(); /* for terse loop use */
|
||||
|
||||
/* figure out the bulk volume sizes of old keys and values to move: */
|
||||
mork_num oldSlots = old.mHashArrays_Slots; /* number of old assocs */
|
||||
mork_num keyBulk = oldSlots * this->FormKeySize(); /* key volume */
|
||||
mork_num valBulk = oldSlots * this->FormValSize(); /* values */
|
||||
|
||||
/* convenient variables for new arrays that need to be rehashed: */
|
||||
morkAssoc** newBuckets = mMap_Buckets; /* new all zeroes */
|
||||
morkAssoc* newAssocs = mMap_Assocs; /* hash into buckets */
|
||||
morkAssoc* newFreeList = newAssocs + oldSlots; /* new room is free */
|
||||
mork_u1* key = mMap_Keys; /* the first key to rehash */
|
||||
--newAssocs; /* back up one before preincrement used in while loop */
|
||||
|
||||
/* move all old keys and values to the new arrays: */
|
||||
MORK_MEMCPY(mMap_Keys, old.mHashArrays_Keys, keyBulk);
|
||||
if ( valBulk ) /* are values nonzero sized? */
|
||||
MORK_MEMCPY(mMap_Vals, old.mHashArrays_Vals, valBulk);
|
||||
|
||||
mMap_FreeList = newFreeList; /* remaining assocs are free */
|
||||
|
||||
while ( ++newAssocs < newFreeList ) /* rehash another old assoc? */
|
||||
{
|
||||
morkAssoc** top = newBuckets + (this->Hash(ev, key) % newSlots);
|
||||
key += this->FormKeySize(); /* the next key to rehash */
|
||||
newAssocs->mAssoc_Next = *top; /* link to prev bucket top */
|
||||
*top = newAssocs; /* push assoc on top of bucket */
|
||||
}
|
||||
++mMap_Seed; /* note the map has changed */
|
||||
old.finalize(ev); /* remember to free the old arrays */
|
||||
}
|
||||
}
|
||||
else ev->OutOfMemoryError();
|
||||
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
|
||||
mork_bool
|
||||
morkMap::Put(morkEnv* ev, const void* inKey, const void* inVal,
|
||||
void* outKey, void* outVal, mork_change** outChange)
|
||||
{
|
||||
mork_bool outPut = morkBool_kFalse;
|
||||
|
||||
if ( this->GoodMap() ) /* looks good? */
|
||||
{
|
||||
mork_u4 hash = this->Hash(ev, inKey);
|
||||
morkAssoc** ref = this->find(ev, inKey, hash);
|
||||
if ( ref ) /* assoc was found? reuse an existing assoc slot? */
|
||||
{
|
||||
outPut = morkBool_kTrue; /* inKey was indeed already inside the map */
|
||||
}
|
||||
else /* assoc not found -- need to allocate a new assoc slot */
|
||||
{
|
||||
morkAssoc* assoc = this->pop_free_assoc();
|
||||
if ( !assoc ) /* no slots remaining in free list? must grow map? */
|
||||
{
|
||||
if ( this->grow(ev) ) /* successfully made map larger? */
|
||||
assoc = this->pop_free_assoc();
|
||||
}
|
||||
if ( assoc ) /* allocated new assoc without error? */
|
||||
{
|
||||
ref = mMap_Buckets + (hash % mMap_Slots);
|
||||
assoc->mAssoc_Next = *ref; /* link to prev bucket top */
|
||||
*ref = assoc; /* push assoc on top of bucket */
|
||||
|
||||
++mMap_Fill; /* one more member in the collection */
|
||||
++mMap_Seed; /* note the map has changed */
|
||||
}
|
||||
}
|
||||
if ( ref ) /* did not have an error during possible growth? */
|
||||
{
|
||||
mork_pos i = (*ref) - mMap_Assocs; /* index of assoc */
|
||||
if ( outPut && (outKey || outVal) ) /* copy old before cobbering? */
|
||||
this->get_assoc(outKey, outVal, i);
|
||||
|
||||
this->put_assoc(inKey, inVal, i);
|
||||
++mMap_Seed; /* note the map has changed */
|
||||
|
||||
if ( outChange )
|
||||
{
|
||||
if ( mMap_Changes )
|
||||
*outChange = mMap_Changes + i;
|
||||
else
|
||||
*outChange = this->FormDummyChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
else this->NewBadMapError(ev);
|
||||
|
||||
return outPut;
|
||||
}
|
||||
|
||||
mork_num
|
||||
morkMap::CutAll(morkEnv* ev)
|
||||
{
|
||||
mork_num outCutAll = 0;
|
||||
|
||||
if ( this->GoodMap() ) /* map looks good? */
|
||||
{
|
||||
mork_num slots = mMap_Slots;
|
||||
morkAssoc* before = mMap_Assocs - 1; /* before first member */
|
||||
morkAssoc* assoc = before + slots; /* the very last member */
|
||||
|
||||
++mMap_Seed; /* note the map is changed */
|
||||
|
||||
/* make the assoc array a linked list headed by first & tailed by last: */
|
||||
assoc->mAssoc_Next = 0; /* null terminate the new free list */
|
||||
while ( --assoc > before ) /* another assoc to link into the list? */
|
||||
assoc->mAssoc_Next = assoc + 1;
|
||||
mMap_FreeList = mMap_Assocs; /* all are free */
|
||||
|
||||
outCutAll = mMap_Fill; /* we'll cut all of them of course */
|
||||
|
||||
mMap_Fill = 0; /* the map is completely empty */
|
||||
}
|
||||
else this->NewBadMapError(ev);
|
||||
|
||||
return outCutAll;
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkMap::Cut(morkEnv* ev, const void* inKey,
|
||||
void* outKey, void* outVal, mork_change** outChange)
|
||||
{
|
||||
mork_bool outCut = morkBool_kFalse;
|
||||
|
||||
if ( this->GoodMap() ) /* looks good? */
|
||||
{
|
||||
mork_u4 hash = this->Hash(ev, inKey);
|
||||
morkAssoc** ref = this->find(ev, inKey, hash);
|
||||
if ( ref ) /* found an assoc for key? */
|
||||
{
|
||||
outCut = morkBool_kTrue;
|
||||
morkAssoc* assoc = *ref;
|
||||
mork_pos i = assoc - mMap_Assocs; /* index of assoc */
|
||||
*ref = assoc->mAssoc_Next; /* unlink the found assoc */
|
||||
this->push_free_assoc(assoc); /* and put it in free list */
|
||||
|
||||
if ( outChange )
|
||||
{
|
||||
if ( mMap_Changes )
|
||||
*outChange = mMap_Changes + i;
|
||||
else
|
||||
*outChange = this->FormDummyChange();
|
||||
}
|
||||
|
||||
++mMap_Seed; /* note the map has changed */
|
||||
if ( mMap_Fill ) /* the count shows nonzero members? */
|
||||
--mMap_Fill; /* one less member in the collection */
|
||||
else
|
||||
this->NewSlotsUnderflowWarning(ev);
|
||||
}
|
||||
}
|
||||
else this->NewBadMapError(ev);
|
||||
|
||||
return outCut;
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkMap::Get(morkEnv* ev, const void* inKey,
|
||||
void* outKey, void* outVal, mork_change** outChange)
|
||||
{
|
||||
mork_bool outGet = morkBool_kFalse;
|
||||
|
||||
if ( this->GoodMap() ) /* looks good? */
|
||||
{
|
||||
mork_u4 hash = this->Hash(ev, inKey);
|
||||
morkAssoc** ref = this->find(ev, inKey, hash);
|
||||
if ( ref ) /* found an assoc for inKey? */
|
||||
{
|
||||
mork_pos i = (*ref) - mMap_Assocs; /* index of assoc */
|
||||
outGet = morkBool_kTrue;
|
||||
this->get_assoc(outKey, outVal, i);
|
||||
if ( outChange )
|
||||
{
|
||||
if ( mMap_Changes )
|
||||
*outChange = mMap_Changes + i;
|
||||
else
|
||||
*outChange = this->FormDummyChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
else this->NewBadMapError(ev);
|
||||
|
||||
return outGet;
|
||||
}
|
||||
|
||||
|
||||
morkMapIter::morkMapIter( )
|
||||
: mMapIter_Map( 0 )
|
||||
, mMapIter_Seed( 0 )
|
||||
|
||||
, mMapIter_Bucket( 0 )
|
||||
, mMapIter_AssocRef( 0 )
|
||||
, mMapIter_Assoc( 0 )
|
||||
, mMapIter_Next( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
morkMapIter::InitMapIter(morkEnv* ev, morkMap* ioMap)
|
||||
{
|
||||
mMapIter_Map = 0;
|
||||
mMapIter_Seed = 0;
|
||||
|
||||
mMapIter_Bucket = 0;
|
||||
mMapIter_AssocRef = 0;
|
||||
mMapIter_Assoc = 0;
|
||||
mMapIter_Next = 0;
|
||||
|
||||
if ( ioMap )
|
||||
{
|
||||
if ( ioMap->GoodMap() )
|
||||
{
|
||||
mMapIter_Map = ioMap;
|
||||
mMapIter_Seed = ioMap->mMap_Seed;
|
||||
}
|
||||
else ioMap->NewBadMapError(ev);
|
||||
}
|
||||
else ev->NilPointerError();
|
||||
}
|
||||
|
||||
morkMapIter::morkMapIter(morkEnv* ev, morkMap* ioMap)
|
||||
: mMapIter_Map( 0 )
|
||||
, mMapIter_Seed( 0 )
|
||||
|
||||
, mMapIter_Bucket( 0 )
|
||||
, mMapIter_AssocRef( 0 )
|
||||
, mMapIter_Assoc( 0 )
|
||||
, mMapIter_Next( 0 )
|
||||
{
|
||||
if ( ioMap )
|
||||
{
|
||||
if ( ioMap->GoodMap() )
|
||||
{
|
||||
mMapIter_Map = ioMap;
|
||||
mMapIter_Seed = ioMap->mMap_Seed;
|
||||
}
|
||||
else ioMap->NewBadMapError(ev);
|
||||
}
|
||||
else ev->NilPointerError();
|
||||
}
|
||||
|
||||
void
|
||||
morkMapIter::CloseMapIter(morkEnv* ev)
|
||||
{
|
||||
mMapIter_Map = 0;
|
||||
mMapIter_Seed = 0;
|
||||
|
||||
mMapIter_Bucket = 0;
|
||||
mMapIter_AssocRef = 0;
|
||||
mMapIter_Assoc = 0;
|
||||
mMapIter_Next = 0;
|
||||
}
|
||||
|
||||
mork_change*
|
||||
morkMapIter::First(morkEnv* ev, void* outKey, void* outVal)
|
||||
{
|
||||
mork_change* outFirst = 0;
|
||||
|
||||
morkMap* map = mMapIter_Map;
|
||||
|
||||
if ( map && map->GoodMap() ) /* map looks good? */
|
||||
{
|
||||
morkAssoc** bucket = map->mMap_Buckets;
|
||||
morkAssoc** end = bucket + map->mMap_Slots; /* one past last */
|
||||
|
||||
mMapIter_Seed = map->mMap_Seed; /* sync the seeds */
|
||||
|
||||
while ( bucket < end ) /* another bucket in which to look for assocs? */
|
||||
{
|
||||
morkAssoc* assoc = *bucket++;
|
||||
if ( assoc ) /* found the first map assoc in use? */
|
||||
{
|
||||
mork_pos i = assoc - map->mMap_Assocs;
|
||||
mork_change* c = map->mMap_Changes;
|
||||
outFirst = ( c )? (c + i) : map->FormDummyChange();
|
||||
|
||||
mMapIter_Assoc = assoc; /* current assoc in iteration */
|
||||
mMapIter_Next = assoc->mAssoc_Next; /* more in bucket */
|
||||
mMapIter_Bucket = --bucket; /* bucket for this assoc */
|
||||
mMapIter_AssocRef = bucket; /* slot referencing assoc */
|
||||
|
||||
map->get_assoc(outKey, outVal, i);
|
||||
|
||||
break; /* end while loop */
|
||||
}
|
||||
}
|
||||
}
|
||||
else map->NewBadMapError(ev);
|
||||
|
||||
return outFirst;
|
||||
}
|
||||
|
||||
mork_change*
|
||||
morkMapIter::Next(morkEnv* ev, void* outKey, void* outVal)
|
||||
{
|
||||
mork_change* outNext = 0;
|
||||
|
||||
morkMap* map = mMapIter_Map;
|
||||
|
||||
if ( map && map->GoodMap() ) /* map looks good? */
|
||||
{
|
||||
if ( mMapIter_Seed == map->mMap_Seed ) /* in sync? */
|
||||
{
|
||||
morkAssoc* here = mMapIter_Assoc; /* current assoc */
|
||||
if ( here ) /* iteration is not yet concluded? */
|
||||
{
|
||||
morkAssoc* next = mMapIter_Next;
|
||||
morkAssoc* assoc = next; /* default new mMapIter_Assoc */
|
||||
if ( next ) /* there are more assocs in the same bucket after Here? */
|
||||
{
|
||||
morkAssoc** ref = mMapIter_AssocRef;
|
||||
|
||||
/* (*HereRef) equals Here, except when Here has been cut, after
|
||||
** which (*HereRef) always equals Next. So if (*HereRef) is not
|
||||
** equal to Next, then HereRef still needs to be updated to point
|
||||
** somewhere else other than Here. Otherwise it is fine.
|
||||
*/
|
||||
if ( *ref != next ) /* Here was not cut? must update HereRef? */
|
||||
mMapIter_AssocRef = &here->mAssoc_Next;
|
||||
|
||||
mMapIter_Next = next->mAssoc_Next;
|
||||
}
|
||||
else /* look for the next assoc in the next nonempty bucket */
|
||||
{
|
||||
morkAssoc** bucket = map->mMap_Buckets;
|
||||
morkAssoc** end = bucket + map->mMap_Slots; /* beyond */
|
||||
mMapIter_Assoc = 0; /* default to no more assocs */
|
||||
bucket = mMapIter_Bucket; /* last exhausted bucket */
|
||||
mMapIter_Assoc = 0; /* default to iteration ended */
|
||||
|
||||
while ( ++bucket < end ) /* another bucket to search for assocs? */
|
||||
{
|
||||
assoc = *bucket;
|
||||
if ( assoc ) /* found another map assoc in use? */
|
||||
{
|
||||
mMapIter_Bucket = bucket;
|
||||
mMapIter_AssocRef = bucket; /* ref to assoc */
|
||||
mMapIter_Next = assoc->mAssoc_Next; /* more */
|
||||
|
||||
break; /* end while loop */
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( assoc ) /* did we find another assoc in the iteration? */
|
||||
{
|
||||
mMapIter_Assoc = assoc; /* current assoc */
|
||||
mork_pos i = assoc - map->mMap_Assocs;
|
||||
mork_change* c = map->mMap_Changes;
|
||||
outNext = ( c )? (c + i) : map->FormDummyChange();
|
||||
|
||||
map->get_assoc( outKey, outVal, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
else map->NewIterOutOfSyncError(ev);
|
||||
}
|
||||
else map->NewBadMapError(ev);
|
||||
|
||||
return outNext;
|
||||
}
|
||||
|
||||
mork_change*
|
||||
morkMapIter::Here(morkEnv* ev, void* outKey, void* outVal)
|
||||
{
|
||||
mork_change* outHere = 0;
|
||||
|
||||
morkMap* map = mMapIter_Map;
|
||||
|
||||
if ( map && map->GoodMap() ) /* map looks good? */
|
||||
{
|
||||
if ( mMapIter_Seed == map->mMap_Seed ) /* in sync? */
|
||||
{
|
||||
morkAssoc* here = mMapIter_Assoc; /* current assoc */
|
||||
if ( here ) /* iteration is not yet concluded? */
|
||||
{
|
||||
mork_pos i = here - map->mMap_Assocs;
|
||||
mork_change* c = map->mMap_Changes;
|
||||
outHere = ( c )? (c + i) : map->FormDummyChange();
|
||||
|
||||
map->get_assoc(outKey, outVal, i);
|
||||
}
|
||||
}
|
||||
else map->NewIterOutOfSyncError(ev);
|
||||
}
|
||||
else map->NewBadMapError(ev);
|
||||
|
||||
return outHere;
|
||||
}
|
||||
|
||||
mork_change*
|
||||
morkMapIter::CutHere(morkEnv* ev, void* outKey, void* outVal)
|
||||
{
|
||||
mork_change* outCutHere = 0;
|
||||
morkMap* map = mMapIter_Map;
|
||||
|
||||
if ( map && map->GoodMap() ) /* map looks good? */
|
||||
{
|
||||
if ( mMapIter_Seed == map->mMap_Seed ) /* in sync? */
|
||||
{
|
||||
morkAssoc* here = mMapIter_Assoc; /* current assoc */
|
||||
if ( here ) /* iteration is not yet concluded? */
|
||||
{
|
||||
morkAssoc** ref = mMapIter_AssocRef;
|
||||
if ( *ref != mMapIter_Next ) /* not already cut? */
|
||||
{
|
||||
mork_pos i = here - map->mMap_Assocs;
|
||||
mork_change* c = map->mMap_Changes;
|
||||
outCutHere = ( c )? (c + i) : map->FormDummyChange();
|
||||
if ( outKey || outVal )
|
||||
map->get_assoc(outKey, outVal, i);
|
||||
|
||||
map->push_free_assoc(here); /* add to free list */
|
||||
*ref = mMapIter_Next; /* unlink here from bucket list */
|
||||
|
||||
/* note the map has changed, but we are still in sync: */
|
||||
mMapIter_Seed = ++map->mMap_Seed; /* sync */
|
||||
|
||||
if ( map->mMap_Fill ) /* still has nonzero value? */
|
||||
--map->mMap_Fill; /* one less member in the collection */
|
||||
else
|
||||
map->NewSlotsUnderflowWarning(ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
else map->NewIterOutOfSyncError(ev);
|
||||
}
|
||||
else map->NewBadMapError(ev);
|
||||
|
||||
return outCutHere;
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
|
@ -368,13 +368,16 @@ morkNode::SlotStrongNode(morkNode* me, morkEnv* ev, morkNode** ioSlot)
|
|||
// expression 'morkNode::SlotStrongNode((morkNode*) 0, ev, &slot)'.
|
||||
{
|
||||
morkNode* node = *ioSlot;
|
||||
if ( node )
|
||||
if ( me != node )
|
||||
{
|
||||
*ioSlot = 0;
|
||||
node->CutStrongRef(ev);
|
||||
if ( node )
|
||||
{
|
||||
*ioSlot = 0;
|
||||
node->CutStrongRef(ev);
|
||||
}
|
||||
if ( me && me->AddStrongRef(ev) )
|
||||
*ioSlot = me;
|
||||
}
|
||||
if ( me && me->AddStrongRef(ev) )
|
||||
*ioSlot = me;
|
||||
}
|
||||
|
||||
/*public static*/ void
|
||||
|
@ -386,13 +389,16 @@ morkNode::SlotWeakNode(morkNode* me, morkEnv* ev, morkNode** ioSlot)
|
|||
// expression 'morkNode::SlotWeakNode((morkNode*) 0, ev, &slot)'.
|
||||
{
|
||||
morkNode* node = *ioSlot;
|
||||
if ( node )
|
||||
if ( me != node )
|
||||
{
|
||||
*ioSlot = 0;
|
||||
node->CutWeakRef(ev);
|
||||
if ( node )
|
||||
{
|
||||
*ioSlot = 0;
|
||||
node->CutWeakRef(ev);
|
||||
}
|
||||
if ( me && me->AddWeakRef(ev) )
|
||||
*ioSlot = me;
|
||||
}
|
||||
if ( me && me->AddWeakRef(ev) )
|
||||
*ioSlot = me;
|
||||
}
|
||||
|
||||
/*public non-poly*/ mork_uses
|
||||
|
|
|
@ -198,7 +198,7 @@ public: // other morkNode methods
|
|||
mork_bool BadRefs() const { return mNode_Refs < mNode_Uses; }
|
||||
|
||||
mork_uses StrongRefsOnly() const { return mNode_Uses; }
|
||||
mork_refs WeakRefsOnly() const { return ( mNode_Refs - mNode_Uses ); }
|
||||
mork_refs WeakRefsOnly() const { return (mork_refs) ( mNode_Refs - mNode_Uses ); }
|
||||
|
||||
// (this refcounting derives from public domain IronDoc node refcounts)
|
||||
mork_refs AddStrongRef(morkEnv* ev);
|
||||
|
|
|
@ -211,6 +211,7 @@ morkParser::NonUsableParserError(morkEnv* ev) //
|
|||
/*protected non-poly*/ void
|
||||
morkParser::StartParse(morkEnv* ev)
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
mParser_InCell = morkBool_kFalse;
|
||||
mParser_InMeta = morkBool_kFalse;
|
||||
mParser_InDict = morkBool_kFalse;
|
||||
|
@ -792,6 +793,7 @@ morkParser::EofInsteadOfHexError(morkEnv* ev)
|
|||
/*static*/ void
|
||||
morkParser::ExpectedHexDigitError(morkEnv* ev, int c)
|
||||
{
|
||||
MORK_USED_1(c);
|
||||
ev->NewWarning("expected hex digit");
|
||||
}
|
||||
|
||||
|
@ -969,6 +971,45 @@ morkParser::NonParserTypeError(morkEnv* ev)
|
|||
ev->NewError("non morkParser");
|
||||
}
|
||||
|
||||
mork_bool morkParser::MatchPattern(morkEnv* ev, const char* inPattern)
|
||||
{
|
||||
// if an error occurs, we want original inPattern in the debugger:
|
||||
const char* pattern = inPattern; // mutable copy
|
||||
morkStream* s = mParser_Stream;
|
||||
register int c;
|
||||
while ( *inPattern && ev->Good() )
|
||||
{
|
||||
char byte = *pattern++;
|
||||
if ( (c = s->Getc(ev)) != byte )
|
||||
{
|
||||
ev->NewError("byte not in expected pattern");
|
||||
}
|
||||
}
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
void morkParser::ReadGroup(morkEnv* ev)
|
||||
/* groups must be ignored until properly terminated */
|
||||
// zm:Group ::= zm:GroupStart zm:Content zm:GroupEnd /* transaction */
|
||||
// zm:GroupStart ::= zm:S? '@$${' zm:Id '{@' /* transaction id has own space */
|
||||
// zm:GroupEnd ::= zm:GroupCommit | zm:GroupAbort
|
||||
// zm:GroupCommit ::= zm:S? '@$$}' zm:Id '}@' /* id matches start id */
|
||||
// zm:GroupAbort ::= zm:S? '@$$}~~' zm:Id '}@' /* id matches start id */
|
||||
/* We must allow started transactions to be aborted in summary files. */
|
||||
/* Note '$$' will never occur unescaped in values we will see in Mork. */
|
||||
{
|
||||
if ( this->MatchPattern(ev, "$${") )
|
||||
{
|
||||
//morkMid cellMid = &mParser_CellMid;
|
||||
//if ( this->ReadMid(ev, cellMid) )
|
||||
//{
|
||||
// if ( this->MatchPattern(ev, "}@") )
|
||||
// {
|
||||
// }
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
void morkParser::ReadDict(morkEnv* ev)
|
||||
// zm:Dict ::= zm:S? '<' zm:DictItem* zm:S? '>'
|
||||
// zm:DictItem ::= zm:MetaDict | zm:Alias
|
||||
|
@ -1060,6 +1101,10 @@ morkParser::OnPortState(morkEnv* ev)
|
|||
this->ReadDict(ev);
|
||||
break;
|
||||
|
||||
case '@': // group
|
||||
this->ReadGroup(ev);
|
||||
break;
|
||||
|
||||
case '+': // plus
|
||||
mParser_Change = morkChange_kAdd;
|
||||
break;
|
||||
|
@ -1181,7 +1226,7 @@ morkParser::ParseMore( // return count of bytes consumed now
|
|||
*outPos = endPos;
|
||||
|
||||
if ( endPos > startPos )
|
||||
outCount = endPos - startPos;
|
||||
outCount = (mdb_count) (endPos - startPos);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -476,6 +476,7 @@ protected: // protected parser helper methods
|
|||
void ReadTable(morkEnv* ev);
|
||||
void ReadTableMeta(morkEnv* ev);
|
||||
void ReadDict(morkEnv* ev);
|
||||
void ReadGroup(morkEnv* ev);
|
||||
void ReadMeta(morkEnv* ev, int inEndMeta);
|
||||
void ReadAlias(morkEnv* ev);
|
||||
mork_id ReadHex(morkEnv* ev, int* outNextChar);
|
||||
|
@ -483,6 +484,8 @@ protected: // protected parser helper methods
|
|||
morkBuf* ReadName(morkEnv* ev, int c);
|
||||
mork_bool ReadMid(morkEnv* ev, morkMid* outMid);
|
||||
|
||||
mork_bool MatchPattern(morkEnv* ev, const char* inPattern);
|
||||
|
||||
void EndSpanOnThisByte(morkEnv* ev, morkSpan* ioSpan);
|
||||
void StartSpanOnLastByte(morkEnv* ev, morkSpan* ioSpan);
|
||||
|
||||
|
|
|
@ -1,381 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKPOOL_
|
||||
#include "morkPool.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKATOM_
|
||||
#include "morkAtom.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKHANDLE_
|
||||
#include "morkHandle.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKCELL_
|
||||
#include "morkCell.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKROW_
|
||||
#include "morkRow.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKBLOB_
|
||||
#include "morkBlob.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKDEQUE_
|
||||
#include "morkDeque.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkPool::CloseMorkNode(morkEnv* ev) // ClosePool() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->ClosePool(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkPool::~morkPool() // assert ClosePool() executed earlier
|
||||
{
|
||||
MORK_ASSERT(this->IsShutNode());
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkPool::morkPool(const morkUsage& inUsage, nsIMdbHeap* ioHeap,
|
||||
nsIMdbHeap* ioSlotHeap)
|
||||
: morkNode(inUsage, ioHeap)
|
||||
, mPool_Heap( ioSlotHeap )
|
||||
{
|
||||
// mPool_Heap is NOT refcounted
|
||||
MORK_ASSERT(ioSlotHeap);
|
||||
if ( ioSlotHeap )
|
||||
mNode_Derived = morkDerived_kPool;
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkPool::morkPool(morkEnv* ev,
|
||||
const morkUsage& inUsage, nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap)
|
||||
: morkNode(ev, inUsage, ioHeap)
|
||||
, mPool_Heap( ioSlotHeap )
|
||||
{
|
||||
if ( ioSlotHeap )
|
||||
{
|
||||
// mPool_Heap is NOT refcounted:
|
||||
// nsIMdbHeap_SlotStrongHeap(ioSlotHeap, ev, &mPool_Heap);
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kPool;
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkPool::ClosePool(morkEnv* ev) // called by CloseMorkNode();
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
// mPool_Heap is NOT refcounted:
|
||||
// nsIMdbHeap_SlotStrongHeap((nsIMdbHeap*) 0, ev, &mPool_Heap);
|
||||
this->MarkShut();
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
|
||||
// alloc and free individual instances of handles (inside hand frames):
|
||||
morkHandleFace*
|
||||
morkPool::NewHandle(morkEnv* ev, mork_size inSize)
|
||||
{
|
||||
void* newBlock = 0;
|
||||
mPool_Heap->Alloc(ev->AsMdbEnv(), inSize, (void**) &newBlock);
|
||||
return (morkHandleFace*) newBlock;
|
||||
}
|
||||
|
||||
void
|
||||
morkPool::ZapHandle(morkEnv* ev, morkHandleFace* ioHandle)
|
||||
{
|
||||
if ( ioHandle )
|
||||
mPool_Heap->Free(ev->AsMdbEnv(), ioHandle);
|
||||
}
|
||||
|
||||
// alloc and free individual instances of rows:
|
||||
morkRow*
|
||||
morkPool::NewRow(morkEnv* ev) // allocate a new row instance
|
||||
{
|
||||
morkRow* newRow = 0;
|
||||
mPool_Heap->Alloc(ev->AsMdbEnv(), sizeof(morkRow), (void**) &newRow);
|
||||
if ( newRow )
|
||||
MORK_MEMSET(newRow, 0, sizeof(morkRow));
|
||||
|
||||
if ( newRow )
|
||||
{
|
||||
}
|
||||
return newRow;
|
||||
}
|
||||
|
||||
void
|
||||
morkPool::ZapRow(morkEnv* ev, morkRow* ioRow) // free old row instance
|
||||
{
|
||||
if ( ioRow )
|
||||
mPool_Heap->Free(ev->AsMdbEnv(), ioRow);
|
||||
}
|
||||
|
||||
// alloc and free entire vectors of cells (not just one cell at a time)
|
||||
morkCell*
|
||||
morkPool::NewCells(morkEnv* ev, mork_size inSize)
|
||||
{
|
||||
morkCell* newCells = 0;
|
||||
mork_size size = inSize * sizeof(morkCell);
|
||||
if ( size )
|
||||
mPool_Heap->Alloc(ev->AsMdbEnv(), size, (void**) &newCells);
|
||||
|
||||
// note morkAtom depends on having nil stored in all new mCell_Atom slots:
|
||||
if ( newCells )
|
||||
MORK_MEMSET(newCells, 0, size);
|
||||
return newCells;
|
||||
}
|
||||
|
||||
void
|
||||
morkPool::ZapCells(morkEnv* ev, morkCell* ioVector, mork_size inSize)
|
||||
{
|
||||
if ( ioVector )
|
||||
mPool_Heap->Free(ev->AsMdbEnv(), ioVector);
|
||||
}
|
||||
|
||||
// resize (grow or trim) cell vectors inside a containing row instance
|
||||
mork_bool
|
||||
morkPool::AddRowCells(morkEnv* ev, morkRow* ioRow, mork_size inNewSize)
|
||||
{
|
||||
// note strong implementation similarity to morkArray::Grow()
|
||||
|
||||
mork_fill fill = ioRow->mRow_Length;
|
||||
if ( ev->Good() && fill < inNewSize ) // need more cells?
|
||||
{
|
||||
morkCell* newCells = this->NewCells(ev, inNewSize);
|
||||
if ( newCells )
|
||||
{
|
||||
morkCell* c = newCells; // for iterating during copy
|
||||
morkCell* oldCells = ioRow->mRow_Cells;
|
||||
morkCell* end = oldCells + fill; // copy all the old cells
|
||||
while ( oldCells < end )
|
||||
{
|
||||
*c++ = *oldCells++; // bitwise copy each old cell struct
|
||||
}
|
||||
oldCells = ioRow->mRow_Cells;
|
||||
ioRow->mRow_Cells = newCells;
|
||||
ioRow->mRow_Length = inNewSize;
|
||||
++ioRow->mRow_Seed;
|
||||
|
||||
if ( oldCells )
|
||||
this->ZapCells(ev, oldCells, fill);
|
||||
}
|
||||
}
|
||||
return ( ev->Good() && ioRow->mRow_Length >= inNewSize );
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkPool::CutRowCells(morkEnv* ev, morkRow* ioRow,
|
||||
mork_size inNewSize)
|
||||
{
|
||||
mork_fill fill = ioRow->mRow_Length;
|
||||
if ( ev->Good() && fill > inNewSize ) // need fewer cells?
|
||||
{
|
||||
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;
|
||||
ioRow->mRow_Cells = 0;
|
||||
ioRow->mRow_Length = 0;
|
||||
++ioRow->mRow_Seed;
|
||||
|
||||
if ( oldCells )
|
||||
this->ZapCells(ev, oldCells, fill);
|
||||
}
|
||||
}
|
||||
return ( ev->Good() && ioRow->mRow_Length <= inNewSize );
|
||||
}
|
||||
|
||||
// alloc & free individual instances of atoms (lots of atom subclasses):
|
||||
void
|
||||
morkPool::ZapAtom(morkEnv* ev, morkAtom* ioAtom) // any subclass (by kind)
|
||||
{
|
||||
if ( ioAtom )
|
||||
mPool_Heap->Free(ev->AsMdbEnv(), ioAtom);
|
||||
}
|
||||
|
||||
morkOidAtom*
|
||||
morkPool::NewRowOidAtom(morkEnv* ev, const mdbOid& inOid)
|
||||
{
|
||||
morkOidAtom* newAtom = 0;
|
||||
mPool_Heap->Alloc(ev->AsMdbEnv(), sizeof(morkOidAtom),(void**) &newAtom);
|
||||
if ( newAtom )
|
||||
newAtom->InitRowOidAtom(ev, inOid);
|
||||
return newAtom;
|
||||
}
|
||||
|
||||
morkOidAtom*
|
||||
morkPool::NewTableOidAtom(morkEnv* ev, const mdbOid& inOid)
|
||||
{
|
||||
morkOidAtom* newAtom = 0;
|
||||
mPool_Heap->Alloc(ev->AsMdbEnv(), sizeof(morkOidAtom), (void**) &newAtom);
|
||||
if ( newAtom )
|
||||
newAtom->InitTableOidAtom(ev, inOid);
|
||||
return newAtom;
|
||||
}
|
||||
|
||||
morkAtom*
|
||||
morkPool::NewAnonAtom(morkEnv* ev, const morkBuf& inBuf,
|
||||
mork_cscode inForm)
|
||||
// if inForm is zero, and inBuf.mBuf_Fill is less than 256, then a 'wee'
|
||||
// anon atom will be created, and otherwise a 'big' anon atom.
|
||||
{
|
||||
morkAtom* newAtom = 0;
|
||||
mork_bool needBig = ( inForm || inBuf.mBuf_Fill > 255 );
|
||||
mork_size size = ( needBig )?
|
||||
morkBigAnonAtom::SizeForFill(inBuf.mBuf_Fill) :
|
||||
morkWeeAnonAtom::SizeForFill(inBuf.mBuf_Fill);
|
||||
|
||||
mPool_Heap->Alloc(ev->AsMdbEnv(), size, (void**) &newAtom);
|
||||
if ( newAtom )
|
||||
{
|
||||
if ( needBig )
|
||||
((morkBigAnonAtom*) newAtom)->InitBigAnonAtom(ev, inBuf, inForm);
|
||||
else
|
||||
((morkWeeAnonAtom*) newAtom)->InitWeeAnonAtom(ev, inBuf);
|
||||
}
|
||||
return newAtom;
|
||||
}
|
||||
|
||||
morkBookAtom*
|
||||
morkPool::NewBookAtom(morkEnv* ev, const morkBuf& inBuf,
|
||||
mork_cscode inForm, morkAtomSpace* ioSpace, mork_aid inAid)
|
||||
// if inForm is zero, and inBuf.mBuf_Fill is less than 256, then a 'wee'
|
||||
// book atom will be created, and otherwise a 'big' book atom.
|
||||
{
|
||||
morkBookAtom* newAtom = 0;
|
||||
mork_bool needBig = ( inForm || inBuf.mBuf_Fill > 255 );
|
||||
mork_size size = ( needBig )?
|
||||
morkBigBookAtom::SizeForFill(inBuf.mBuf_Fill) :
|
||||
morkWeeBookAtom::SizeForFill(inBuf.mBuf_Fill);
|
||||
|
||||
mPool_Heap->Alloc(ev->AsMdbEnv(), size, (void**) &newAtom);
|
||||
if ( newAtom )
|
||||
{
|
||||
if ( needBig )
|
||||
((morkBigBookAtom*) newAtom)->InitBigBookAtom(ev,
|
||||
inBuf, inForm, ioSpace, inAid);
|
||||
else
|
||||
((morkWeeBookAtom*) newAtom)->InitWeeBookAtom(ev,
|
||||
inBuf, ioSpace, inAid);
|
||||
}
|
||||
return newAtom;
|
||||
}
|
||||
|
||||
morkBookAtom*
|
||||
morkPool::NewBookAtomCopy(morkEnv* ev, const morkBigBookAtom& inAtom)
|
||||
// make the smallest kind of book atom that can hold content in inAtom.
|
||||
// The inAtom parameter is often expected to be a staged book atom in
|
||||
// the store, which was used to search an atom space for existing atoms.
|
||||
{
|
||||
morkBookAtom* newAtom = 0;
|
||||
mork_cscode form = inAtom.mBigBookAtom_Form;
|
||||
mork_fill fill = inAtom.mBigBookAtom_Size;
|
||||
mork_bool needBig = ( form || fill > 255 );
|
||||
mork_size size = ( needBig )?
|
||||
morkBigBookAtom::SizeForFill(fill) :
|
||||
morkWeeBookAtom::SizeForFill(fill);
|
||||
|
||||
mPool_Heap->Alloc(ev->AsMdbEnv(), size, (void**) &newAtom);
|
||||
if ( newAtom )
|
||||
{
|
||||
morkBuf buf(inAtom.mBigBookAtom_Body, fill);
|
||||
if ( needBig )
|
||||
((morkBigBookAtom*) newAtom)->InitBigBookAtom(ev,
|
||||
buf, form, inAtom.mBookAtom_Space, inAtom.mBookAtom_Id);
|
||||
else
|
||||
((morkWeeBookAtom*) newAtom)->InitWeeBookAtom(ev,
|
||||
buf, inAtom.mBookAtom_Space, inAtom.mBookAtom_Id);
|
||||
}
|
||||
return newAtom;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
|
@ -1,317 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKCURSOR_
|
||||
#include "morkCursor.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKPORTTABLECURSOR_
|
||||
#include "morkPortTableCursor.h"
|
||||
#endif
|
||||
|
||||
#ifndef _ORKINPORTTABLECURSOR_
|
||||
#include "orkinPortTableCursor.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKSTORE_
|
||||
#include "morkStore.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkPortTableCursor::CloseMorkNode(morkEnv* ev) // ClosePortTableCursor() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->ClosePortTableCursor(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkPortTableCursor::~morkPortTableCursor() // ClosePortTableCursor() executed earlier
|
||||
{
|
||||
MORK_ASSERT(this->IsShutNode());
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkPortTableCursor::morkPortTableCursor(morkEnv* ev,
|
||||
const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, morkStore* ioStore, mdb_scope inRowScope,
|
||||
mdb_kind inTableKind, nsIMdbHeap* ioSlotHeap)
|
||||
: morkCursor(ev, inUsage, ioHeap)
|
||||
, mPortTableCursor_Store( 0 )
|
||||
, mPortTableCursor_RowScope( (mdb_scope) -1 ) // we want != inRowScope
|
||||
, mPortTableCursor_TableKind( (mdb_kind) -1 ) // we want != inTableKind
|
||||
, mPortTableCursor_LastTable ( 0 ) // not refcounted
|
||||
, mPortTableCursor_RowSpace( 0 ) // strong ref to row space
|
||||
, mPortTableCursor_TablesDidEnd( morkBool_kFalse )
|
||||
, mPortTableCursor_SpacesDidEnd( morkBool_kFalse )
|
||||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
if ( ioStore )
|
||||
{
|
||||
mCursor_Pos = -1;
|
||||
mCursor_Seed = 0; // let the iterator do it's own seed handling
|
||||
morkStore::SlotWeakStore(ioStore, ev, &mPortTableCursor_Store);
|
||||
|
||||
if ( this->SetRowScope(ev, inRowScope) )
|
||||
this->SetTableKind(ev, inTableKind);
|
||||
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kPortTableCursor;
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkPortTableCursor::ClosePortTableCursor(morkEnv* ev)
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
mCursor_Pos = -1;
|
||||
mCursor_Seed = 0;
|
||||
mPortTableCursor_LastTable = 0;
|
||||
morkStore::SlotWeakStore((morkStore*) 0, ev, &mPortTableCursor_Store);
|
||||
morkRowSpace::SlotStrongRowSpace((morkRowSpace*) 0, ev,
|
||||
&mPortTableCursor_RowSpace);
|
||||
this->CloseCursor(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
/*static*/ void
|
||||
morkPortTableCursor::NilCursorStoreError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("nil mPortTableCursor_Store");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkPortTableCursor::NonPortTableCursorTypeError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("non morkPortTableCursor");
|
||||
}
|
||||
|
||||
orkinPortTableCursor*
|
||||
morkPortTableCursor::AcquirePortTableCursorHandle(morkEnv* ev)
|
||||
{
|
||||
orkinPortTableCursor* outCursor = 0;
|
||||
orkinPortTableCursor* c = (orkinPortTableCursor*) mObject_Handle;
|
||||
if ( c ) // have an old handle?
|
||||
c->AddStrongRef(ev->AsMdbEnv());
|
||||
else // need new handle?
|
||||
{
|
||||
c = orkinPortTableCursor::MakePortTableCursor(ev, this);
|
||||
mObject_Handle = c;
|
||||
}
|
||||
if ( c )
|
||||
outCursor = c;
|
||||
return outCursor;
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkPortTableCursor::SetRowScope(morkEnv* ev, mork_scope inRowScope)
|
||||
{
|
||||
mPortTableCursor_RowScope = inRowScope;
|
||||
mPortTableCursor_LastTable = 0; // restart iteration of space
|
||||
|
||||
mPortTableCursor_TableIter.CloseMapIter(ev);
|
||||
mPortTableCursor_TablesDidEnd = morkBool_kTrue;
|
||||
mPortTableCursor_SpacesDidEnd = morkBool_kTrue;
|
||||
|
||||
morkStore* store = mPortTableCursor_Store;
|
||||
if ( store )
|
||||
{
|
||||
morkRowSpace* space = mPortTableCursor_RowSpace;
|
||||
|
||||
if ( inRowScope ) // intend to cover a specific scope only?
|
||||
{
|
||||
space = store->LazyGetRowSpace(ev, inRowScope);
|
||||
morkRowSpace::SlotStrongRowSpace(space, ev,
|
||||
&mPortTableCursor_RowSpace);
|
||||
|
||||
// We want mPortTableCursor_SpacesDidEnd == morkBool_kTrue
|
||||
// to show this is the only space to be covered.
|
||||
}
|
||||
else // prepare space map iter to cover all space scopes
|
||||
{
|
||||
morkRowSpaceMapIter* rsi = &mPortTableCursor_SpaceIter;
|
||||
rsi->InitRowSpaceMapIter(ev, &store->mStore_RowSpaces);
|
||||
|
||||
space = 0;
|
||||
(void) rsi->FirstRowSpace(ev, (mork_scope*) 0, &space);
|
||||
morkRowSpace::SlotStrongRowSpace(space, ev,
|
||||
&mPortTableCursor_RowSpace);
|
||||
|
||||
if ( space ) // found first space in store
|
||||
mPortTableCursor_SpacesDidEnd = morkBool_kFalse;
|
||||
}
|
||||
|
||||
this->init_space_tables_map(ev);
|
||||
}
|
||||
else
|
||||
this->NilCursorStoreError(ev);
|
||||
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
void
|
||||
morkPortTableCursor::init_space_tables_map(morkEnv* ev)
|
||||
{
|
||||
morkRowSpace* space = mPortTableCursor_RowSpace;
|
||||
if ( space && ev->Good() )
|
||||
{
|
||||
morkTableMapIter* ti = &mPortTableCursor_TableIter;
|
||||
ti->InitTableMapIter(ev, &space->mRowSpace_Tables);
|
||||
if ( ev->Good() )
|
||||
mPortTableCursor_TablesDidEnd = morkBool_kFalse;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
mork_bool
|
||||
morkPortTableCursor::SetTableKind(morkEnv* ev, mork_kind inTableKind)
|
||||
{
|
||||
mPortTableCursor_TableKind = inTableKind;
|
||||
mPortTableCursor_LastTable = 0; // restart iteration of space
|
||||
|
||||
mPortTableCursor_TablesDidEnd = morkBool_kTrue;
|
||||
|
||||
morkRowSpace* space = mPortTableCursor_RowSpace;
|
||||
if ( !space && mPortTableCursor_RowScope == 0 )
|
||||
{
|
||||
this->SetRowScope(ev, 0);
|
||||
space = mPortTableCursor_RowSpace;
|
||||
}
|
||||
this->init_space_tables_map(ev);
|
||||
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
morkRowSpace*
|
||||
morkPortTableCursor::NextSpace(morkEnv* ev)
|
||||
{
|
||||
morkRowSpace* outSpace = 0;
|
||||
mPortTableCursor_LastTable = 0;
|
||||
mPortTableCursor_SpacesDidEnd = morkBool_kTrue;
|
||||
mPortTableCursor_TablesDidEnd = morkBool_kTrue;
|
||||
|
||||
if ( !mPortTableCursor_RowScope ) // not just one scope?
|
||||
{
|
||||
morkStore* store = mPortTableCursor_Store;
|
||||
if ( store )
|
||||
{
|
||||
morkRowSpaceMapIter* rsi = &mPortTableCursor_SpaceIter;
|
||||
|
||||
(void) rsi->NextRowSpace(ev, (mork_scope*) 0, &outSpace);
|
||||
morkRowSpace::SlotStrongRowSpace(outSpace, ev,
|
||||
&mPortTableCursor_RowSpace);
|
||||
|
||||
if ( outSpace ) // found next space in store
|
||||
{
|
||||
mPortTableCursor_SpacesDidEnd = morkBool_kFalse;
|
||||
|
||||
this->init_space_tables_map(ev);
|
||||
|
||||
if ( ev->Bad() )
|
||||
outSpace = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
this->NilCursorStoreError(ev);
|
||||
}
|
||||
|
||||
return outSpace;
|
||||
}
|
||||
|
||||
morkTable *
|
||||
morkPortTableCursor::NextTable(morkEnv* ev)
|
||||
{
|
||||
mork_kind kind = mPortTableCursor_TableKind;
|
||||
|
||||
do // until spaces end, or until we find a table in a space
|
||||
{
|
||||
morkRowSpace* space = mPortTableCursor_RowSpace;
|
||||
if ( mPortTableCursor_TablesDidEnd ) // current space exhausted?
|
||||
space = this->NextSpace(ev); // go on to the next space
|
||||
|
||||
if ( space ) // have a space remaining that might hold tables?
|
||||
{
|
||||
mork_tid* key = 0; // ignore keys in table map
|
||||
morkTable* table = 0; // old value table in the map
|
||||
morkTableMapIter* ti = &mPortTableCursor_TableIter;
|
||||
mork_change* c = ( mPortTableCursor_LastTable )?
|
||||
ti->NextTable(ev, key, &table) : ti->FirstTable(ev, key, &table);
|
||||
|
||||
for ( ; c && ev->Good(); c = ti->NextTable(ev, key, &table) )
|
||||
{
|
||||
if ( table && table->IsTable() )
|
||||
{
|
||||
if ( !kind || kind == table->mTable_Kind )
|
||||
{
|
||||
mPortTableCursor_LastTable = table; // ti->NextTable() hence
|
||||
return table;
|
||||
}
|
||||
}
|
||||
else
|
||||
table->NonTableTypeWarning(ev);
|
||||
}
|
||||
mPortTableCursor_TablesDidEnd = morkBool_kTrue; // space is done
|
||||
mPortTableCursor_LastTable = 0; // make sure next space starts fresh
|
||||
}
|
||||
|
||||
} while ( ev->Good() && !mPortTableCursor_SpacesDidEnd );
|
||||
|
||||
return (morkTable*) 0;
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
|
@ -69,8 +69,13 @@
|
|||
mork_u2
|
||||
morkRow::AddTableUse(morkEnv* ev)
|
||||
{
|
||||
if ( mRow_TableUses < morkRow_kMaxTableUses ) // not already maxed out?
|
||||
++mRow_TableUses;
|
||||
if ( this->IsRow() )
|
||||
{
|
||||
if ( mRow_TableUses < morkRow_kMaxTableUses ) // not already maxed out?
|
||||
++mRow_TableUses;
|
||||
}
|
||||
else
|
||||
this->NonRowTypeError(ev);
|
||||
|
||||
return mRow_TableUses;
|
||||
}
|
||||
|
@ -78,13 +83,18 @@ morkRow::AddTableUse(morkEnv* ev)
|
|||
mork_u2
|
||||
morkRow::CutTableUse(morkEnv* ev)
|
||||
{
|
||||
if ( mRow_TableUses ) // any outstanding uses to cut?
|
||||
if ( this->IsRow() )
|
||||
{
|
||||
if ( mRow_TableUses < morkRow_kMaxTableUses ) // not frozen at max?
|
||||
--mRow_TableUses;
|
||||
if ( mRow_TableUses ) // any outstanding uses to cut?
|
||||
{
|
||||
if ( mRow_TableUses < morkRow_kMaxTableUses ) // not frozen at max?
|
||||
--mRow_TableUses;
|
||||
}
|
||||
else
|
||||
this->TableUsesUnderflowWarning(ev);
|
||||
}
|
||||
else
|
||||
this->TableUsesUnderflowWarning(ev);
|
||||
this->NonRowTypeError(ev);
|
||||
|
||||
return mRow_TableUses;
|
||||
}
|
||||
|
@ -142,7 +152,7 @@ morkRow::InitRow(morkEnv* ev, const mdbOid* inOid, morkRowSpace* ioSpace,
|
|||
mRow_Cells = 0;
|
||||
mRow_Oid = *inOid;
|
||||
|
||||
mRow_Length = inLength;
|
||||
mRow_Length = (mork_u2) inLength;
|
||||
mRow_Seed = (mork_u2) this; // "random" assignment
|
||||
|
||||
mRow_TableUses = 0;
|
||||
|
@ -300,7 +310,7 @@ morkRow::TakeCells(morkEnv* ev, morkCell* ioVector, mork_fill inVecLength,
|
|||
if ( ioVector && inVecLength && ev->Good() )
|
||||
{
|
||||
++mRow_Seed; // intend to change structure of mRow_Cells
|
||||
mork_pos length = (mork_pos) mRow_Length;
|
||||
mork_size length = (mork_size) mRow_Length;
|
||||
|
||||
mork_count overlap = this->CountOverlap(ev, ioVector, inVecLength);
|
||||
|
||||
|
@ -328,8 +338,8 @@ morkRow::NewCell(morkEnv* ev, mdb_column inColumn,
|
|||
mork_pos* outPos, morkStore* ioStore)
|
||||
{
|
||||
++mRow_Seed; // intend to change structure of mRow_Cells
|
||||
mork_pos length = (mork_pos) mRow_Length;
|
||||
*outPos = length;
|
||||
mork_size length = (mork_size) mRow_Length;
|
||||
*outPos = (mork_pos) length;
|
||||
morkPool* pool = ioStore->StorePool();
|
||||
if ( pool->AddRowCells(ev, this, length + 1) )
|
||||
{
|
||||
|
@ -344,6 +354,7 @@ morkRow::NewCell(morkEnv* ev, mdb_column inColumn,
|
|||
morkCell*
|
||||
morkRow::CellAt(morkEnv* ev, mork_pos inPos) const
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
morkCell* cells = mRow_Cells;
|
||||
if ( cells && inPos < mRow_Length && inPos >= 0 )
|
||||
{
|
||||
|
@ -355,6 +366,7 @@ morkRow::CellAt(morkEnv* ev, mork_pos inPos) const
|
|||
morkCell*
|
||||
morkRow::GetCell(morkEnv* ev, mdb_column inColumn, mork_pos* outPos) const
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
morkCell* cells = mRow_Cells;
|
||||
if ( cells )
|
||||
{
|
||||
|
@ -375,6 +387,42 @@ morkRow::GetCell(morkEnv* ev, mdb_column inColumn, mork_pos* outPos) const
|
|||
return (morkCell*) 0;
|
||||
}
|
||||
|
||||
mork_aid
|
||||
morkRow::GetCellAtomAid(morkEnv* ev, mdb_column inColumn) const
|
||||
// GetCellAtomAid() finds the cell with column inColumn, and sees if the
|
||||
// atom has a token ID, and returns the atom's ID if there is one. Or
|
||||
// else zero is returned if there is no such column, or no atom, or if
|
||||
// the atom has no ID to return. This method is intended to support
|
||||
// efficient updating of column indexes for rows in a row space.
|
||||
{
|
||||
if ( this && this->IsRow() )
|
||||
{
|
||||
morkCell* cells = mRow_Cells;
|
||||
if ( cells )
|
||||
{
|
||||
morkCell* end = cells + mRow_Length;
|
||||
while ( cells < end )
|
||||
{
|
||||
mork_column col = cells->GetColumn();
|
||||
if ( col == inColumn ) // found desired column?
|
||||
{
|
||||
morkAtom* atom = cells->mCell_Atom;
|
||||
if ( atom && atom->IsBook() )
|
||||
return ((morkBookAtom*) atom)->mBookAtom_Id;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
++cells;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
this->NonRowTypeError(ev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
morkRow::EmptyAllCells(morkEnv* ev)
|
||||
{
|
||||
|
@ -396,12 +444,46 @@ morkRow::EmptyAllCells(morkEnv* ev)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
morkRow::cut_all_index_entries(morkEnv* ev)
|
||||
{
|
||||
morkRowSpace* rowSpace = mRow_Space;
|
||||
if ( rowSpace->mRowSpace_IndexCount ) // any indexes?
|
||||
{
|
||||
morkCell* cells = mRow_Cells;
|
||||
if ( cells )
|
||||
{
|
||||
morkCell* end = cells + mRow_Length;
|
||||
--cells; // prepare for preincrement:
|
||||
while ( ++cells < end )
|
||||
{
|
||||
morkAtom* atom = cells->mCell_Atom;
|
||||
if ( atom )
|
||||
{
|
||||
mork_aid atomAid = atom->GetBookAtomAid();
|
||||
if ( atomAid )
|
||||
{
|
||||
mork_column col = cells->GetColumn();
|
||||
morkAtomRowMap* map = rowSpace->FindMap(ev, col);
|
||||
if ( map ) // cut row from index for this column?
|
||||
map->CutAid(ev, atomAid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
morkRow::CutAllColumns(morkEnv* ev)
|
||||
{
|
||||
morkStore* store = this->GetRowSpaceStore(ev);
|
||||
if ( store )
|
||||
{
|
||||
morkRowSpace* rowSpace = mRow_Space;
|
||||
if ( rowSpace->mRowSpace_IndexCount ) // any indexes?
|
||||
this->cut_all_index_entries(ev);
|
||||
|
||||
morkPool* pool = store->StorePool();
|
||||
pool->CutRowCells(ev, this, /*newSize*/ 0);
|
||||
}
|
||||
|
@ -415,6 +497,9 @@ morkRow::SetRow(morkEnv* ev, const morkRow* inSourceRow)
|
|||
morkStore* srcStore = inSourceRow->GetRowSpaceStore(ev);
|
||||
if ( store && srcStore )
|
||||
{
|
||||
morkRowSpace* rowSpace = mRow_Space;
|
||||
mork_count indexes = rowSpace->mRowSpace_IndexCount; // any indexes?
|
||||
|
||||
mork_bool sameStore = ( store == srcStore ); // identical stores?
|
||||
morkPool* pool = store->StorePool();
|
||||
if ( pool->CutRowCells(ev, this, /*newSize*/ 0) )
|
||||
|
@ -432,17 +517,17 @@ morkRow::SetRow(morkEnv* ev, const morkRow* inSourceRow)
|
|||
while ( ++dst < dstEnd && ++src < srcEnd && ev->Good() )
|
||||
{
|
||||
morkAtom* atom = src->mCell_Atom;
|
||||
mork_column col = src->GetColumn();
|
||||
mork_column dstCol = src->GetColumn();
|
||||
if ( sameStore ) // source and dest in same store?
|
||||
{
|
||||
dst->SetColumnAndChange(col, morkChange_kAdd);
|
||||
dst->SetColumnAndChange(dstCol, 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);
|
||||
dstCol = store->CopyToken(ev, dstCol, srcStore);
|
||||
if ( dstCol )
|
||||
{
|
||||
dst->SetColumnAndChange(dstCol, morkChange_kAdd);
|
||||
|
@ -452,6 +537,16 @@ morkRow::SetRow(morkEnv* ev, const morkRow* inSourceRow)
|
|||
atom->AddCellUse(ev);
|
||||
}
|
||||
}
|
||||
if ( indexes && atom )
|
||||
{
|
||||
mork_aid atomAid = atom->GetBookAtomAid();
|
||||
if ( atomAid )
|
||||
{
|
||||
morkAtomRowMap* map = rowSpace->FindMap(ev, dstCol);
|
||||
if ( map )
|
||||
map->AddAid(ev, atomAid, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -473,12 +568,14 @@ void
|
|||
morkRow::OnZeroTableUse(morkEnv* ev)
|
||||
// OnZeroTableUse() is called when CutTableUse() returns zero.
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
// ev->NewWarning("need to implement OnZeroTableUse");
|
||||
}
|
||||
|
||||
void
|
||||
morkRow::DirtyAllRowContent(morkEnv* ev)
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
this->SetRowDirty();
|
||||
|
||||
morkCell* cells = mRow_Cells;
|
||||
|
@ -527,6 +624,20 @@ void morkRow::CutColumn(morkEnv* ev, mdb_column inColumn)
|
|||
morkStore* store = this->GetRowSpaceStore(ev);
|
||||
if ( store )
|
||||
{
|
||||
morkRowSpace* rowSpace = mRow_Space;
|
||||
morkAtomRowMap* map = ( rowSpace->mRowSpace_IndexCount )?
|
||||
rowSpace->FindMap(ev, inColumn) : (morkAtomRowMap*) 0;
|
||||
if ( map ) // this row attribute is indexed by row space?
|
||||
{
|
||||
morkAtom* oldAtom = cell->mCell_Atom;
|
||||
if ( oldAtom ) // need to cut an entry from the index?
|
||||
{
|
||||
mork_aid oldAid = oldAtom->GetBookAtomAid();
|
||||
if ( oldAid ) // cut old row attribute from row index in space?
|
||||
map->CutAid(ev, oldAid);
|
||||
}
|
||||
}
|
||||
|
||||
morkPool* pool = store->StorePool();
|
||||
cell->SetAtom(ev, (morkAtom*) 0, pool);
|
||||
|
||||
|
@ -553,6 +664,25 @@ void morkRow::CutColumn(morkEnv* ev, mdb_column inColumn)
|
|||
}
|
||||
}
|
||||
|
||||
// void morkRow::cut_cell_from_space_index(morkEnv* ev, morkCell* ioCell)
|
||||
// {
|
||||
// morkAtom* oldAtom = ioCell->mCell_Atom;
|
||||
// if ( oldAtom )
|
||||
// {
|
||||
// mork_column col = ioCell->GetColumn();
|
||||
// morkRowSpace* rowSpace = mRow_Space;
|
||||
// morkAtomRowMap* map = ( rowSpace->mRowSpace_IndexCount )?
|
||||
// rowSpace->FindMap(ev, col) : (morkAtomRowMap*) 0;
|
||||
//
|
||||
// if ( map ) // col is indexed by row space?
|
||||
// {
|
||||
// mork_aid oldAid = oldAtom->GetBookAtomAid();
|
||||
// if ( oldAid ) // cut old row attribute from row index in space?
|
||||
// map->CutAid(ev, oldAid);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
void morkRow::AddColumn(morkEnv* ev, mdb_column inColumn,
|
||||
const mdbYarn* inYarn, morkStore* ioStore)
|
||||
{
|
||||
|
@ -570,7 +700,31 @@ void morkRow::AddColumn(morkEnv* ev, mdb_column inColumn,
|
|||
// cell->SetYarn(ev, inYarn, ioStore);
|
||||
morkAtom* atom = ioStore->YarnToAtom(ev, inYarn);
|
||||
if ( atom )
|
||||
{
|
||||
morkRowSpace* rowSpace = mRow_Space;
|
||||
morkAtomRowMap* map = ( rowSpace->mRowSpace_IndexCount )?
|
||||
rowSpace->FindMap(ev, inColumn) : (morkAtomRowMap*) 0;
|
||||
|
||||
if ( map ) // inColumn is indexed by row space?
|
||||
{
|
||||
morkAtom* oldAtom = cell->mCell_Atom;
|
||||
if ( oldAtom && oldAtom != atom ) // cut old cell from index?
|
||||
{
|
||||
mork_aid oldAid = oldAtom->GetBookAtomAid();
|
||||
if ( oldAid ) // cut old row attribute from row index in space?
|
||||
map->CutAid(ev, oldAid);
|
||||
}
|
||||
}
|
||||
|
||||
cell->SetAtom(ev, atom, ioStore->StorePool()); // refcounts atom
|
||||
|
||||
if ( map ) // inColumn is indexed by row space?
|
||||
{
|
||||
mork_aid newAid = atom->GetBookAtomAid();
|
||||
if ( newAid ) // add new row attribute to row index in space?
|
||||
map->AddAid(ev, newAid, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,6 +74,10 @@ public: // other row methods
|
|||
|
||||
public: // internal row methods
|
||||
|
||||
void cut_all_index_entries(morkEnv* ev);
|
||||
|
||||
// void cut_cell_from_space_index(morkEnv* ev, morkCell* ioCell);
|
||||
|
||||
mork_count CountOverlap(morkEnv* ev, morkCell* ioVector, mork_fill inFill);
|
||||
// Count cells in ioVector that change existing cells in this row when
|
||||
// ioVector is added to the row (as in TakeCells()). This is the set
|
||||
|
@ -100,6 +104,13 @@ public: // internal row methods
|
|||
morkCell* GetCell(morkEnv* ev, mdb_column inColumn, mork_pos* outPos) const;
|
||||
morkCell* CellAt(morkEnv* ev, mork_pos inPos) const;
|
||||
|
||||
mork_aid GetCellAtomAid(morkEnv* ev, mdb_column inColumn) const;
|
||||
// GetCellAtomAid() finds the cell with column inColumn, and sees if the
|
||||
// atom has a token ID, and returns the atom's ID if there is one. Or
|
||||
// else zero is returned if there is no such column, or no atom, or if
|
||||
// the atom has no ID to return. This method is intended to support
|
||||
// efficient updating of column indexes for rows in a row space.
|
||||
|
||||
public: // external row methods
|
||||
|
||||
void DirtyAllRowContent(morkEnv* ev);
|
||||
|
@ -132,7 +143,7 @@ public: // hash and equal
|
|||
return (mRow_Oid.mOid_Scope << 16) ^ mRow_Oid.mOid_Id;
|
||||
}
|
||||
|
||||
mork_u4 EqualRow(const morkRow* ioRow) const
|
||||
mork_bool EqualRow(const morkRow* ioRow) const
|
||||
{
|
||||
return
|
||||
(
|
||||
|
@ -141,7 +152,7 @@ public: // hash and equal
|
|||
);
|
||||
}
|
||||
|
||||
mork_u4 EqualOid(const mdbOid* ioOid) const
|
||||
mork_bool EqualOid(const mdbOid* ioOid) const
|
||||
{
|
||||
return
|
||||
(
|
||||
|
|
|
@ -1,171 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKMAP_
|
||||
#include "morkMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKROWMAP_
|
||||
#include "morkRowMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKROW_
|
||||
#include "morkRow.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkRowMap::CloseMorkNode(morkEnv* ev) // CloseRowMap() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->CloseRowMap(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkRowMap::~morkRowMap() // assert CloseRowMap() executed earlier
|
||||
{
|
||||
MORK_ASSERT(this->IsShutNode());
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkRowMap::morkRowMap(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap, mork_size inSlots)
|
||||
: morkMap(ev, inUsage, ioHeap,
|
||||
/*inKeySize*/ sizeof(morkRow*), /*inValSize*/ 0,
|
||||
inSlots, ioSlotHeap, /*inHoldChanges*/ morkBool_kFalse)
|
||||
{
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kRowMap;
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkRowMap::CloseRowMap(morkEnv* ev) // called by CloseMorkNode();
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
this->CloseMap(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
|
||||
// { ===== begin morkMap poly interface =====
|
||||
/*virtual*/ mork_bool //
|
||||
morkRowMap::Equal(morkEnv* ev, const void* inKeyA,
|
||||
const void* inKeyB) const
|
||||
{
|
||||
return (*(const morkRow**) inKeyA)->EqualRow(*(const morkRow**) inKeyB);
|
||||
}
|
||||
|
||||
/*virtual*/ mork_u4 //
|
||||
morkRowMap::Hash(morkEnv* ev, const void* inKey) const
|
||||
{
|
||||
return (*(const morkRow**) inKey)->HashRow();
|
||||
}
|
||||
// } ===== end morkMap poly interface =====
|
||||
|
||||
|
||||
mork_bool
|
||||
morkRowMap::AddRow(morkEnv* ev, morkRow* ioRow)
|
||||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
this->Put(ev, &ioRow, /*val*/ (void*) 0,
|
||||
/*key*/ (void*) 0, /*val*/ (void*) 0, (mork_change**) 0);
|
||||
}
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
morkRow*
|
||||
morkRowMap::CutOid(morkEnv* ev, const mdbOid* inOid)
|
||||
{
|
||||
morkRow row(inOid);
|
||||
morkRow* key = &row;
|
||||
morkRow* oldKey = 0;
|
||||
this->Cut(ev, &key, &oldKey, /*val*/ (void*) 0,
|
||||
(mork_change**) 0);
|
||||
|
||||
return oldKey;
|
||||
}
|
||||
|
||||
morkRow*
|
||||
morkRowMap::CutRow(morkEnv* ev, const morkRow* ioRow)
|
||||
{
|
||||
morkRow* oldKey = 0;
|
||||
this->Cut(ev, &ioRow, &oldKey, /*val*/ (void*) 0,
|
||||
(mork_change**) 0);
|
||||
|
||||
return oldKey;
|
||||
}
|
||||
|
||||
morkRow*
|
||||
morkRowMap::GetOid(morkEnv* ev, const mdbOid* inOid)
|
||||
{
|
||||
morkRow row(inOid);
|
||||
morkRow* key = &row;
|
||||
morkRow* oldKey = 0;
|
||||
this->Get(ev, &key, &oldKey, /*val*/ (void*) 0, (mork_change**) 0);
|
||||
|
||||
return oldKey;
|
||||
}
|
||||
|
||||
morkRow*
|
||||
morkRowMap::GetRow(morkEnv* ev, const morkRow* ioRow)
|
||||
{
|
||||
morkRow* oldKey = 0;
|
||||
this->Get(ev, &ioRow, &oldKey, /*val*/ (void*) 0, (mork_change**) 0);
|
||||
|
||||
return oldKey;
|
||||
}
|
||||
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
|
@ -68,6 +68,10 @@
|
|||
#include "morkRow.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKATOMMAP_
|
||||
#include "morkAtomMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKROWOBJECT_
|
||||
#include "morkRowObject.h"
|
||||
#endif
|
||||
|
@ -99,14 +103,29 @@ morkRowSpace::morkRowSpace(morkEnv* ev,
|
|||
const morkUsage& inUsage, mork_scope inScope, morkStore* ioStore,
|
||||
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap)
|
||||
: morkSpace(ev, inUsage, inScope, ioStore, ioHeap, ioSlotHeap)
|
||||
, mRowSpace_SlotHeap( ioSlotHeap )
|
||||
, mRowSpace_Rows(ev, morkUsage::kMember, (nsIMdbHeap*) 0, ioSlotHeap,
|
||||
morkRowSpace_kStartRowMapSlotCount)
|
||||
, mRowSpace_Tables(ev, morkUsage::kMember, (nsIMdbHeap*) 0, ioSlotHeap)
|
||||
, mRowSpace_NextTableId( 1 )
|
||||
, mRowSpace_NextRowId( 1 )
|
||||
|
||||
, mRowSpace_IndexCount( 0 )
|
||||
{
|
||||
morkAtomRowMap** cache = mRowSpace_IndexCache;
|
||||
morkAtomRowMap** cacheEnd = cache + morkRowSpace_kPrimeCacheSize;
|
||||
while ( cache < cacheEnd )
|
||||
*cache++ = 0; // put nil into every slot of cache table
|
||||
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kRowSpace;
|
||||
{
|
||||
if ( ioSlotHeap )
|
||||
{
|
||||
mNode_Derived = morkDerived_kRowSpace;
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
|
@ -116,11 +135,20 @@ morkRowSpace::CloseRowSpace(morkEnv* ev) // called by CloseMorkNode();
|
|||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
morkAtomRowMap** cache = mRowSpace_IndexCache;
|
||||
morkAtomRowMap** cacheEnd = cache + morkRowSpace_kPrimeCacheSize;
|
||||
--cache; // prepare for preincrement:
|
||||
while ( ++cache < cacheEnd )
|
||||
{
|
||||
if ( *cache )
|
||||
morkAtomRowMap::SlotStrongAtomRowMap(0, ev, cache);
|
||||
}
|
||||
|
||||
mRowSpace_Tables.CloseMorkNode(ev);
|
||||
|
||||
morkStore* store = mSpace_Store;
|
||||
if ( store )
|
||||
this->CutAllRows(ev, &store->mStore_Pool);
|
||||
this->CutAllRows(ev, &store->mStore_Pool);
|
||||
|
||||
mRowSpace_Rows.CloseMorkNode(ev);
|
||||
this->CloseSpace(ev);
|
||||
|
@ -187,18 +215,22 @@ morkRowSpace::CutAllRows(morkEnv* ev, morkPool* ioPool)
|
|||
for ( c = i.FirstRow(ev, &r); c && ev->Good();
|
||||
c = i.NextRow(ev, &r) )
|
||||
{
|
||||
if ( r->IsRow() )
|
||||
if ( r )
|
||||
{
|
||||
if ( r->mRow_Object )
|
||||
if ( r->IsRow() )
|
||||
{
|
||||
morkRowObject::SlotWeakRowObject((morkRowObject*) 0, ev,
|
||||
&r->mRow_Object);
|
||||
}
|
||||
if ( r )
|
||||
if ( r->mRow_Object )
|
||||
{
|
||||
morkRowObject::SlotWeakRowObject((morkRowObject*) 0, ev,
|
||||
&r->mRow_Object);
|
||||
}
|
||||
ioPool->ZapRow(ev, r);
|
||||
}
|
||||
else
|
||||
r->NonRowTypeWarning(ev);
|
||||
}
|
||||
else
|
||||
r->NonRowTypeWarning(ev);
|
||||
ev->NilPointerError();
|
||||
|
||||
i.CutHereRow(ev, /*key*/ (morkRow**) 0);
|
||||
}
|
||||
|
@ -346,6 +378,136 @@ morkRowSpace::MakeNewRowId(morkEnv* ev)
|
|||
return outRid;
|
||||
}
|
||||
|
||||
morkAtomRowMap*
|
||||
morkRowSpace::make_index(morkEnv* ev, mork_column inCol)
|
||||
{
|
||||
morkAtomRowMap* outMap = 0;
|
||||
nsIMdbHeap* heap = mRowSpace_SlotHeap;
|
||||
if ( heap ) // have expected heap for allocations?
|
||||
{
|
||||
morkAtomRowMap* map = new(*heap, ev)
|
||||
morkAtomRowMap(ev, morkUsage::kHeap, heap, heap, inCol);
|
||||
|
||||
if ( map ) // able to create new map index?
|
||||
{
|
||||
if ( ev->Good() ) // no errors during construction?
|
||||
{
|
||||
morkRowMapIter i(ev, &mRowSpace_Rows);
|
||||
mork_change* c = 0;
|
||||
morkRow* row = 0;
|
||||
mork_aid aidKey = 0;
|
||||
|
||||
for ( c = i.FirstRow(ev, &row); c && ev->Good();
|
||||
c = i.NextRow(ev, &row) ) // another row in space?
|
||||
{
|
||||
aidKey = row->GetCellAtomAid(ev, inCol);
|
||||
if ( aidKey ) // row has indexed attribute?
|
||||
map->AddAid(ev, aidKey, row); // include in map
|
||||
}
|
||||
}
|
||||
if ( ev->Good() ) // no errors constructing index?
|
||||
outMap = map; // return from function
|
||||
else
|
||||
map->CutStrongRef(ev); // discard map on error
|
||||
}
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
|
||||
return outMap;
|
||||
}
|
||||
|
||||
morkAtomRowMap*
|
||||
morkRowSpace::ForceMap(morkEnv* ev, mork_column inCol)
|
||||
{
|
||||
morkAtomRowMap* outMap = this->FindMap(ev, inCol);
|
||||
|
||||
if ( !outMap && ev->Good() ) // no such existing index?
|
||||
{
|
||||
if ( mRowSpace_IndexCount < morkRowSpace_kMaxIndexCount )
|
||||
{
|
||||
morkAtomRowMap* map = this->make_index(ev, inCol);
|
||||
if ( map ) // created a new index for col?
|
||||
{
|
||||
mork_count wrap = 0; // count times wrap-around occurs
|
||||
morkAtomRowMap** slot = mRowSpace_IndexCache; // table
|
||||
morkAtomRowMap** end = slot + morkRowSpace_kPrimeCacheSize;
|
||||
slot += ( inCol % morkRowSpace_kPrimeCacheSize ); // hash
|
||||
while ( *slot ) // empty slot not yet found?
|
||||
{
|
||||
if ( ++slot >= end ) // wrap around?
|
||||
{
|
||||
slot = mRowSpace_IndexCache; // back to table start
|
||||
if ( ++wrap > 1 ) // wrapped more than once?
|
||||
{
|
||||
ev->NewError("no free cache slots"); // disaster
|
||||
break; // end while loop
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( ev->Good() ) // everything went just fine?
|
||||
{
|
||||
++mRowSpace_IndexCount; // note another new map
|
||||
*slot = map; // install map in the hash table
|
||||
outMap = map; // return the new map from function
|
||||
}
|
||||
else
|
||||
map->CutStrongRef(ev); // discard map on error
|
||||
}
|
||||
}
|
||||
else
|
||||
ev->NewError("too many indexes"); // why so many indexes?
|
||||
}
|
||||
return outMap;
|
||||
}
|
||||
|
||||
morkAtomRowMap*
|
||||
morkRowSpace::FindMap(morkEnv* ev, mork_column inCol)
|
||||
{
|
||||
if ( mRowSpace_IndexCount && ev->Good() )
|
||||
{
|
||||
mork_count wrap = 0; // count times wrap-around occurs
|
||||
morkAtomRowMap** slot = mRowSpace_IndexCache; // table
|
||||
morkAtomRowMap** end = slot + morkRowSpace_kPrimeCacheSize;
|
||||
slot += ( inCol % morkRowSpace_kPrimeCacheSize ); // hash
|
||||
morkAtomRowMap* map = *slot;
|
||||
while ( map ) // another used slot to examine?
|
||||
{
|
||||
if ( inCol == map->mAtomRowMap_IndexColumn ) // found col?
|
||||
return map;
|
||||
if ( ++slot >= end ) // wrap around?
|
||||
{
|
||||
slot = mRowSpace_IndexCache;
|
||||
if ( ++wrap > 1 ) // wrapped more than once?
|
||||
return (morkAtomRowMap*) 0; // stop searching
|
||||
}
|
||||
map = *slot;
|
||||
}
|
||||
}
|
||||
return (morkAtomRowMap*) 0;
|
||||
}
|
||||
|
||||
morkRow*
|
||||
morkRowSpace::FindRow(morkEnv* ev, mork_column inCol, const mdbYarn* inYarn)
|
||||
{
|
||||
morkRow* outRow = 0;
|
||||
|
||||
morkAtom* atom = mSpace_Store->YarnToAtom(ev, inYarn);
|
||||
if ( atom ) // have or created an atom corresponding to input yarn?
|
||||
{
|
||||
mork_aid atomAid = atom->GetBookAtomAid();
|
||||
if ( atomAid ) // atom has an identity for use in hash table?
|
||||
{
|
||||
morkAtomRowMap* map = this->ForceMap(ev, inCol);
|
||||
if ( map ) // able to find or create index for col?
|
||||
{
|
||||
outRow = map->GetAid(ev, atomAid); // search for row
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return outRow;
|
||||
}
|
||||
|
||||
morkRow*
|
||||
morkRowSpace::NewRowWithOid(morkEnv* ev, const mdbOid* inOid)
|
||||
|
|
|
@ -43,12 +43,21 @@
|
|||
#include "morkTable.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKARRAY_
|
||||
#include "morkArray.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#define morkDerived_kRowSpace /*i*/ 0x7253 /* ascii 'rS' */
|
||||
|
||||
#define morkRowSpace_kStartRowMapSlotCount 512
|
||||
|
||||
#define morkRowSpace_kMaxIndexCount 8 /* no more indexes than this */
|
||||
#define morkRowSpace_kPrimeCacheSize 17 /* should be prime number */
|
||||
|
||||
class morkAtomRowMap;
|
||||
|
||||
/*| morkRowSpace:
|
||||
|*/
|
||||
class morkRowSpace : public morkSpace { //
|
||||
|
@ -76,11 +85,18 @@ class morkRowSpace : public morkSpace { //
|
|||
|
||||
public: // state is public because the entire Mork system is private
|
||||
|
||||
nsIMdbHeap* mRowSpace_SlotHeap;
|
||||
|
||||
morkRowMap mRowSpace_Rows; // hash table of morkRow instances
|
||||
morkTableMap mRowSpace_Tables; // all the tables in this row scope
|
||||
|
||||
mork_tid mRowSpace_NextTableId; // for auto-assigning table IDs
|
||||
mork_rid mRowSpace_NextRowId; // for auto-assigning row IDs
|
||||
mork_tid mRowSpace_NextTableId; // for auto-assigning table IDs
|
||||
mork_rid mRowSpace_NextRowId; // for auto-assigning row IDs
|
||||
|
||||
mork_count mRowSpace_IndexCount; // if nonzero, row indexes exist
|
||||
|
||||
// every nonzero slot in IndexCache is a strong ref to a morkAtomRowMap:
|
||||
morkAtomRowMap* mRowSpace_IndexCache[ morkRowSpace_kPrimeCacheSize ];
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
|
@ -131,6 +147,14 @@ public: // other space methods
|
|||
morkRow* NewRowWithOid(morkEnv* ev, const mdbOid* inOid);
|
||||
morkRow* NewRow(morkEnv* ev);
|
||||
|
||||
morkRow* FindRow(morkEnv* ev, mork_column inColumn, const mdbYarn* inYarn);
|
||||
|
||||
morkAtomRowMap* ForceMap(morkEnv* ev, mork_column inColumn);
|
||||
morkAtomRowMap* FindMap(morkEnv* ev, mork_column inColumn);
|
||||
|
||||
protected: // internal utilities
|
||||
morkAtomRowMap* make_index(morkEnv* ev, mork_column inColumn);
|
||||
|
||||
public: // typesafe refcounting inlines calling inherited morkNode methods
|
||||
static void SlotWeakRowSpace(morkRowSpace* me,
|
||||
morkEnv* ev, morkRowSpace** ioSlot)
|
||||
|
|
|
@ -1,305 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKSINK_
|
||||
#include "morkSink.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKBLOB_
|
||||
#include "morkBlob.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
/*virtual*/ morkSink::~morkSink()
|
||||
{
|
||||
mSink_At = 0;
|
||||
mSink_End = 0;
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkSpool::FlushSink(morkEnv* ev) // sync mSpool_Coil->mBuf_Fill
|
||||
{
|
||||
morkCoil* coil = mSpool_Coil;
|
||||
if ( coil )
|
||||
{
|
||||
mork_u1* body = (mork_u1*) coil->mBuf_Body;
|
||||
if ( body )
|
||||
{
|
||||
mork_u1* at = mSink_At;
|
||||
mork_u1* end = mSink_End;
|
||||
if ( at >= body && at <= end ) // expected cursor order?
|
||||
{
|
||||
mork_fill fill = at - body; // current content size
|
||||
if ( fill <= coil->mBlob_Size )
|
||||
coil->mBuf_Fill = fill;
|
||||
else
|
||||
{
|
||||
coil->BlobFillOverSizeError(ev);
|
||||
coil->mBuf_Fill = coil->mBlob_Size; // make it safe
|
||||
}
|
||||
}
|
||||
else
|
||||
this->BadSpoolCursorOrderError(ev);
|
||||
}
|
||||
else
|
||||
coil->NilBufBodyError(ev);
|
||||
}
|
||||
else
|
||||
this->NilSpoolCoilError(ev);
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkSpool::SpillPutc(morkEnv* ev, int c) // grow coil and write byte
|
||||
{
|
||||
morkCoil* coil = mSpool_Coil;
|
||||
if ( coil )
|
||||
{
|
||||
mork_u1* body = (mork_u1*) coil->mBuf_Body;
|
||||
if ( body )
|
||||
{
|
||||
mork_u1* at = mSink_At;
|
||||
mork_u1* end = mSink_End;
|
||||
if ( at >= body && at <= end ) // expected cursor order?
|
||||
{
|
||||
mork_size size = coil->mBlob_Size;
|
||||
mork_fill fill = at - body; // current content size
|
||||
if ( fill <= size ) // less content than medium size?
|
||||
{
|
||||
coil->mBuf_Fill = fill;
|
||||
if ( at >= end ) // need to grow the coil?
|
||||
{
|
||||
if ( size > 2048 ) // grow slower over 2K?
|
||||
size += 512;
|
||||
else
|
||||
{
|
||||
mork_size growth = ( size * 4 ) / 3; // grow by 33%
|
||||
if ( growth < 64 ) // grow faster under (64 * 3)?
|
||||
growth = 64;
|
||||
size += growth;
|
||||
}
|
||||
if ( coil->GrowCoil(ev, size) ) // made coil bigger?
|
||||
{
|
||||
body = (mork_u1*) coil->mBuf_Body;
|
||||
if ( body ) // have a coil body?
|
||||
{
|
||||
mSink_At = at = body + fill;
|
||||
mSink_End = end = body + coil->mBlob_Size;
|
||||
}
|
||||
else
|
||||
coil->NilBufBodyError(ev);
|
||||
}
|
||||
}
|
||||
if ( ev->Good() ) // seem ready to write byte c?
|
||||
{
|
||||
if ( at < end ) // morkSink::Putc() would succeed?
|
||||
{
|
||||
*at++ = c;
|
||||
mSink_At = at;
|
||||
coil->mBuf_Fill = fill + 1;
|
||||
}
|
||||
else
|
||||
this->BadSpoolCursorOrderError(ev);
|
||||
}
|
||||
}
|
||||
else // fill exceeds size
|
||||
{
|
||||
coil->BlobFillOverSizeError(ev);
|
||||
coil->mBuf_Fill = coil->mBlob_Size; // make it safe
|
||||
}
|
||||
}
|
||||
else
|
||||
this->BadSpoolCursorOrderError(ev);
|
||||
}
|
||||
else
|
||||
coil->NilBufBodyError(ev);
|
||||
}
|
||||
else
|
||||
this->NilSpoolCoilError(ev);
|
||||
}
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
// public: // public non-poly morkSink methods
|
||||
|
||||
/*virtual*/
|
||||
morkSpool::~morkSpool()
|
||||
// Zero all slots to show this sink is disabled, but destroy no memory.
|
||||
// Note it is typically unnecessary to flush this coil sink, since all
|
||||
// content is written directly to the coil without any buffering.
|
||||
{
|
||||
mSink_At = 0;
|
||||
mSink_End = 0;
|
||||
mSpool_Coil = 0;
|
||||
}
|
||||
|
||||
morkSpool::morkSpool(morkEnv* ev, morkCoil* ioCoil)
|
||||
// After installing the coil, calls Seek(ev, 0) to prepare for writing.
|
||||
: morkSink()
|
||||
, mSpool_Coil( 0 )
|
||||
{
|
||||
mSink_At = 0; // set correctly later in Seek()
|
||||
mSink_End = 0; // set correctly later in Seek()
|
||||
|
||||
if ( ev->Good() )
|
||||
{
|
||||
if ( ioCoil )
|
||||
{
|
||||
mSpool_Coil = ioCoil;
|
||||
this->Seek(ev, /*pos*/ 0);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
}
|
||||
|
||||
// ----- All boolean return values below are equal to ev->Good(): -----
|
||||
|
||||
/*static*/ void
|
||||
morkSpool::BadSpoolCursorOrderError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("bad morkSpool cursor order");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkSpool::NilSpoolCoilError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("nil mSpool_Coil");
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkSpool::Seek(morkEnv* ev, mork_pos inPos)
|
||||
// Changed the current write position in coil's buffer to inPos.
|
||||
// For example, to start writing the coil from scratch, use inPos==0.
|
||||
{
|
||||
morkCoil* coil = mSpool_Coil;
|
||||
if ( coil )
|
||||
{
|
||||
mork_size minSize = inPos + 64;
|
||||
|
||||
if ( coil->mBlob_Size < minSize )
|
||||
coil->GrowCoil(ev, minSize);
|
||||
|
||||
if ( ev->Good() )
|
||||
{
|
||||
coil->mBuf_Fill = inPos;
|
||||
mork_u1* body = (mork_u1*) coil->mBuf_Body;
|
||||
if ( body )
|
||||
{
|
||||
mSink_At = body + inPos;
|
||||
mSink_End = body + coil->mBlob_Size;
|
||||
}
|
||||
else
|
||||
coil->NilBufBodyError(ev);
|
||||
}
|
||||
}
|
||||
else
|
||||
this->NilSpoolCoilError(ev);
|
||||
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkSpool::Write(morkEnv* ev, const void* inBuf, mork_size inSize)
|
||||
// write inSize bytes of inBuf to current position inside coil's buffer
|
||||
{
|
||||
// This method is conceptually very similar to morkStream::Write(),
|
||||
// and this code was written while looking at that method for clues.
|
||||
|
||||
morkCoil* coil = mSpool_Coil;
|
||||
if ( coil )
|
||||
{
|
||||
mork_u1* body = (mork_u1*) coil->mBuf_Body;
|
||||
if ( body )
|
||||
{
|
||||
if ( inBuf && inSize ) // anything to write?
|
||||
{
|
||||
mork_u1* at = mSink_At;
|
||||
mork_u1* end = mSink_End;
|
||||
if ( at >= body && at <= end ) // expected cursor order?
|
||||
{
|
||||
// note coil->mBuf_Fill can be stale after morkSink::Putc():
|
||||
mork_pos fill = at - body; // current content size
|
||||
mork_num space = end - at; // space left in body
|
||||
if ( space < inSize ) // not enough to hold write?
|
||||
{
|
||||
mork_size minGrowth = space + 16;
|
||||
mork_size minSize = coil->mBlob_Size + minGrowth;
|
||||
if ( coil->GrowCoil(ev, minSize) )
|
||||
{
|
||||
body = (mork_u1*) coil->mBuf_Body;
|
||||
if ( body )
|
||||
{
|
||||
mSink_At = at = body + fill;
|
||||
mSink_End = end = body + coil->mBlob_Size;
|
||||
space = end - at; // space left in body
|
||||
}
|
||||
else
|
||||
coil->NilBufBodyError(ev);
|
||||
}
|
||||
}
|
||||
if ( ev->Good() )
|
||||
{
|
||||
if ( space >= inSize ) // enough room to hold write?
|
||||
{
|
||||
MORK_MEMCPY(at, inBuf, inSize); // into body
|
||||
mSink_At = at + inSize; // advance past written bytes
|
||||
coil->mBuf_Fill = fill + inSize; // "flush" to fix fill
|
||||
}
|
||||
else
|
||||
ev->NewError("insufficient morkSpool space");
|
||||
}
|
||||
}
|
||||
else
|
||||
this->BadSpoolCursorOrderError(ev);
|
||||
}
|
||||
}
|
||||
else
|
||||
coil->NilBufBodyError(ev);
|
||||
}
|
||||
else
|
||||
this->NilSpoolCoilError(ev);
|
||||
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkSpool::PutString(morkEnv* ev, const char* inString)
|
||||
// call Write() with inBuf=inString and inSize=strlen(inString),
|
||||
// unless inString is null, in which case we then do nothing at all.
|
||||
{
|
||||
if ( inString )
|
||||
{
|
||||
mork_size size = MORK_STRLEN(inString);
|
||||
this->Write(ev, inString, size);
|
||||
}
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
|
@ -94,7 +94,7 @@ morkSpace::morkSpace(morkEnv* ev,
|
|||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
if ( ioStore )
|
||||
if ( ioStore && ioSlotHeap )
|
||||
{
|
||||
morkStore::SlotWeakStore(ioStore, ev, &mSpace_Store);
|
||||
if ( ev->Good() )
|
||||
|
|
|
@ -274,6 +274,7 @@ morkStore::CloseStore(morkEnv* ev) // called by CloseMorkNode();
|
|||
void
|
||||
morkStore::RenumberAllCollectableContent(morkEnv* ev)
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
// do nothing currently
|
||||
}
|
||||
|
||||
|
@ -367,6 +368,7 @@ morkStore::StageStringAsBookAtom(morkEnv* ev, const char* inString,
|
|||
|
||||
morkAtomSpace* morkStore::LazyGetOidAtomSpace(morkEnv* ev)
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
if ( !mStore_OidAtomSpace )
|
||||
{
|
||||
}
|
||||
|
@ -551,6 +553,7 @@ mork_bool
|
|||
morkStore::OpenStoreFile(morkEnv* ev, mork_bool inFrozen,
|
||||
const char* inFilePath, const mdbOpenPolicy* inOpenPolicy)
|
||||
{
|
||||
MORK_USED_1(inOpenPolicy);
|
||||
morkFile::SlotStrongFile((morkFile*) 0, ev, &mStore_File);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
|
@ -571,6 +574,7 @@ mork_bool
|
|||
morkStore::CreateStoreFile(morkEnv* ev,
|
||||
const char* inFilePath, const mdbOpenPolicy* inOpenPolicy)
|
||||
{
|
||||
MORK_USED_1(inOpenPolicy);
|
||||
morkFile::SlotStrongFile((morkFile*) 0, ev, &mStore_File);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
|
@ -736,6 +740,7 @@ morkStore::MidToAtom(morkEnv* ev, const morkMid& inMid)
|
|||
morkStore::SmallTokenToOneByteYarn(morkEnv* ev, mdb_token inToken,
|
||||
mdbYarn* outYarn)
|
||||
{
|
||||
MORK_USED_1(ev);
|
||||
if ( outYarn->mYarn_Buf && outYarn->mYarn_Size ) // any space in yarn at all?
|
||||
{
|
||||
mork_u1* buf = (mork_u1*) outYarn->mYarn_Buf; // for byte arithmetic
|
||||
|
@ -1028,10 +1033,14 @@ mork_bool
|
|||
morkStore::HasTableKind(morkEnv* ev, mdb_scope inRowScope,
|
||||
mdb_kind inTableKind, mdb_count* outTableCount)
|
||||
{
|
||||
MORK_USED_2(inRowScope,inTableKind);
|
||||
mork_bool outBool = morkBool_kFalse;
|
||||
mdb_count tableCount = 0;
|
||||
|
||||
ev->StubMethodOnlyError();
|
||||
|
||||
if ( outTableCount )
|
||||
*outTableCount = tableCount;
|
||||
return outBool;
|
||||
}
|
||||
|
||||
|
@ -1059,6 +1068,22 @@ morkStore::GetTableKind(morkEnv* ev, mdb_scope inRowScope,
|
|||
return outTable;
|
||||
}
|
||||
|
||||
morkRow*
|
||||
morkStore::FindRow(morkEnv* ev, mdb_scope inScope, mdb_column inColumn,
|
||||
const mdbYarn* inYarn)
|
||||
{
|
||||
morkRow* outRow = 0;
|
||||
if ( ev->Good() )
|
||||
{
|
||||
morkRowSpace* rowSpace = this->LazyGetRowSpace(ev, inScope);
|
||||
if ( rowSpace )
|
||||
{
|
||||
outRow = rowSpace->FindRow(ev, inColumn, inYarn);
|
||||
}
|
||||
}
|
||||
return outRow;
|
||||
}
|
||||
|
||||
morkRow*
|
||||
morkStore::GetRow(morkEnv* ev, const mdbOid* inOid)
|
||||
{
|
||||
|
|
|
@ -294,6 +294,9 @@ public: // other store methods
|
|||
morkTable* GetTableKind(morkEnv* ev, mdb_scope inRowScope,
|
||||
mdb_kind inTableKind, mdb_count* outTableCount,
|
||||
mdb_bool* outMustBeUnique);
|
||||
|
||||
morkRow* FindRow(morkEnv* ev, mdb_scope inScope, mdb_column inColumn,
|
||||
const mdbYarn* inTargetCellValue);
|
||||
|
||||
morkRow* GetRow(morkEnv* ev, const mdbOid* inOid);
|
||||
morkTable* GetTable(morkEnv* ev, const mdbOid* inOid);
|
||||
|
|
|
@ -381,6 +381,7 @@ morkStream::AcquireBud(morkEnv* ev, nsIMdbHeap* ioHeap)
|
|||
// behavior is exhibited by the file, so crashes protect old files.
|
||||
// Note that AcquireBud() is an illegal operation on readonly files.
|
||||
{
|
||||
MORK_USED_1(ioHeap);
|
||||
morkFile* outFile = 0;
|
||||
morkFile* file = mStream_ContentFile;
|
||||
if ( this->IsOpenAndActiveFile() && file )
|
||||
|
@ -508,7 +509,7 @@ morkStream::Read(morkEnv* ev, void* outBuf, mork_size inSize)
|
|||
mork_u1* buf = mStream_Buf;
|
||||
if ( at >= buf && at <= end ) // expected cursor order?
|
||||
{
|
||||
mork_num remaining = end - at; // bytes left in buffer
|
||||
mork_num remaining = (mork_num) (end - at); // bytes left in buffer
|
||||
|
||||
mork_num quantum = inSize; // number of bytes to copy
|
||||
if ( quantum > remaining ) // more than buffer content?
|
||||
|
@ -534,7 +535,7 @@ morkStream::Read(morkEnv* ev, void* outBuf, mork_size inSize)
|
|||
// exhausted the local buffer, so we need to show
|
||||
// it is now empty, and adjust the current buf pos.
|
||||
|
||||
mork_num posDelta = (at - buf); // old buf content
|
||||
mork_num posDelta = (mork_num) (at - buf); // old buf content
|
||||
mStream_BufPos += posDelta; // past now empty buf
|
||||
|
||||
mStream_At = mStream_ReadEnd = buf; // empty buffer
|
||||
|
@ -569,7 +570,7 @@ morkStream::Read(morkEnv* ev, void* outBuf, mork_size inSize)
|
|||
if ( ev->Bad() )
|
||||
outActual = 0;
|
||||
|
||||
return outActual;
|
||||
return (mork_size) outActual;
|
||||
}
|
||||
|
||||
/*public virtual*/ mork_pos
|
||||
|
@ -658,7 +659,7 @@ morkStream::Write(morkEnv* ev, const void* inBuf, mork_size inSize)
|
|||
mork_u1* buf = mStream_Buf;
|
||||
if ( at >= buf && at <= end ) // expected cursor order?
|
||||
{
|
||||
mork_num space = end - at; // space left in buffer
|
||||
mork_num space = (mork_num) (end - at); // space left in buffer
|
||||
|
||||
mork_num quantum = inSize; // number of bytes to write
|
||||
if ( quantum > space ) // more than buffer size?
|
||||
|
@ -695,7 +696,7 @@ morkStream::Write(morkEnv* ev, const void* inBuf, mork_size inSize)
|
|||
|
||||
if ( ev->Good() ) // no errors?
|
||||
{
|
||||
space = end - at; // space left in buffer
|
||||
space = (mork_num) (end - at); // space left in buffer
|
||||
if ( space > inSize ) // write to buffer?
|
||||
{
|
||||
mStream_Dirty = morkBool_kTrue; // ensure flush
|
||||
|
@ -817,7 +818,7 @@ morkStream::spill_buf(morkEnv* ev) // spill/flush from buffer to file
|
|||
mork_u1* at = mStream_At;
|
||||
if ( at >= buf && at <= mStream_WriteEnd ) // order?
|
||||
{
|
||||
mork_num count = at - buf; // the number of bytes buffered
|
||||
mork_num count = (mork_num) (at - buf); // bytes buffered
|
||||
if ( count ) // anything to write to the string?
|
||||
{
|
||||
if ( count > mStream_BufSize ) // no more than max?
|
||||
|
|
|
@ -210,7 +210,7 @@ public: // public non-poly morkStream methods
|
|||
{ this->PutString(ev, inString); }
|
||||
|
||||
void Ungetc(int c) /*i*/
|
||||
{ if ( mStream_At > mStream_Buf && c > 0 ) *--mStream_At = c; }
|
||||
{ if ( mStream_At > mStream_Buf && c > 0 ) *--mStream_At = (mork_u1) c; }
|
||||
|
||||
// Note Getc() returns EOF consistently after any fill_getc() error occurs.
|
||||
int Getc(morkEnv* ev) /*i*/
|
||||
|
@ -220,7 +220,7 @@ public: // public non-poly morkStream methods
|
|||
{
|
||||
mStream_Dirty = morkBool_kTrue;
|
||||
if ( mStream_At < mStream_WriteEnd )
|
||||
*mStream_At++ = c;
|
||||
*mStream_At++ = (mork_u1) c;
|
||||
else
|
||||
spill_putc(ev, c);
|
||||
}
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче