1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1999
20 * the Initial Developer. All Rights Reserved.
24 * Alternatively, the contents of this file may be used under the terms of
25 * either of the GNU General Public License Version 2 or later (the "GPL"),
26 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
55 #include "morkCursor.h"
58 #ifndef _MORKPORTTABLECURSOR_
59 #include "morkPortTableCursor.h"
63 #include "morkStore.h"
66 //3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
68 // ````` ````` ````` ````` `````
69 // { ===== begin morkNode interface =====
71 /*public virtual*/ void
72 morkPortTableCursor::CloseMorkNode(morkEnv
* ev
) // ClosePortTableCursor() only if open
74 if ( this->IsOpenNode() )
77 this->ClosePortTableCursor(ev
);
83 morkPortTableCursor::~morkPortTableCursor() // ClosePortTableCursor() executed earlier
85 CloseMorkNode(mMorkEnv
);
89 morkPortTableCursor::morkPortTableCursor(morkEnv
* ev
,
90 const morkUsage
& inUsage
,
91 nsIMdbHeap
* ioHeap
, morkStore
* ioStore
, mdb_scope inRowScope
,
92 mdb_kind inTableKind
, nsIMdbHeap
* ioSlotHeap
)
93 : morkCursor(ev
, inUsage
, ioHeap
)
94 , mPortTableCursor_Store( 0 )
95 , mPortTableCursor_RowScope( (mdb_scope
) -1 ) // we want != inRowScope
96 , mPortTableCursor_TableKind( (mdb_kind
) -1 ) // we want != inTableKind
97 , mPortTableCursor_LastTable ( 0 ) // not refcounted
98 , mPortTableCursor_RowSpace( 0 ) // strong ref to row space
99 , mPortTableCursor_TablesDidEnd( morkBool_kFalse
)
100 , mPortTableCursor_SpacesDidEnd( morkBool_kFalse
)
104 if ( ioStore
&& ioSlotHeap
)
107 mCursor_Seed
= 0; // let the iterator do it's own seed handling
108 morkStore::SlotWeakStore(ioStore
, ev
, &mPortTableCursor_Store
);
110 if ( this->SetRowScope(ev
, inRowScope
) )
111 this->SetTableKind(ev
, inTableKind
);
114 mNode_Derived
= morkDerived_kPortTableCursor
;
117 ev
->NilPointerError();
121 NS_IMPL_ISUPPORTS_INHERITED1(morkPortTableCursor
, morkCursor
, nsIMdbPortTableCursor
)
124 morkPortTableCursor::CanUsePortTableCursor(nsIMdbEnv
* mev
,
125 mork_bool inMutable
, mdb_err
* outErr
) const
128 morkEnv
* ev
= morkEnv::FromMdbEnv(mev
);
131 if ( IsPortTableCursor() )
134 NonPortTableCursorTypeError(ev
);
135 *outErr
= ev
->AsErr();
142 /*public non-poly*/ void
143 morkPortTableCursor::ClosePortTableCursor(morkEnv
* ev
)
147 if ( this->IsNode() )
151 mPortTableCursor_LastTable
= 0;
152 morkStore::SlotWeakStore((morkStore
*) 0, ev
, &mPortTableCursor_Store
);
153 morkRowSpace::SlotStrongRowSpace((morkRowSpace
*) 0, ev
,
154 &mPortTableCursor_RowSpace
);
155 this->CloseCursor(ev
);
159 this->NonNodeError(ev
);
162 ev
->NilPointerError();
165 // } ===== end morkNode methods =====
166 // ````` ````` ````` ````` `````
169 morkPortTableCursor::NilCursorStoreError(morkEnv
* ev
)
171 ev
->NewError("nil mPortTableCursor_Store");
175 morkPortTableCursor::NonPortTableCursorTypeError(morkEnv
* ev
)
177 ev
->NewError("non morkPortTableCursor");
181 morkPortTableCursor::SetRowScope(morkEnv
* ev
, mork_scope inRowScope
)
183 mPortTableCursor_RowScope
= inRowScope
;
184 mPortTableCursor_LastTable
= 0; // restart iteration of space
186 mPortTableCursor_TableIter
.CloseMapIter(ev
);
187 mPortTableCursor_TablesDidEnd
= morkBool_kTrue
;
188 mPortTableCursor_SpacesDidEnd
= morkBool_kTrue
;
190 morkStore
* store
= mPortTableCursor_Store
;
193 morkRowSpace
* space
= mPortTableCursor_RowSpace
;
195 if ( inRowScope
) // intend to cover a specific scope only?
197 space
= store
->LazyGetRowSpace(ev
, inRowScope
);
198 morkRowSpace::SlotStrongRowSpace(space
, ev
,
199 &mPortTableCursor_RowSpace
);
201 // We want mPortTableCursor_SpacesDidEnd == morkBool_kTrue
202 // to show this is the only space to be covered.
204 else // prepare space map iter to cover all space scopes
206 morkRowSpaceMapIter
* rsi
= &mPortTableCursor_SpaceIter
;
207 rsi
->InitRowSpaceMapIter(ev
, &store
->mStore_RowSpaces
);
210 (void) rsi
->FirstRowSpace(ev
, (mork_scope
*) 0, &space
);
211 morkRowSpace::SlotStrongRowSpace(space
, ev
,
212 &mPortTableCursor_RowSpace
);
214 if ( space
) // found first space in store
215 mPortTableCursor_SpacesDidEnd
= morkBool_kFalse
;
218 this->init_space_tables_map(ev
);
221 this->NilCursorStoreError(ev
);
227 morkPortTableCursor::init_space_tables_map(morkEnv
* ev
)
229 morkRowSpace
* space
= mPortTableCursor_RowSpace
;
230 if ( space
&& ev
->Good() )
232 morkTableMapIter
* ti
= &mPortTableCursor_TableIter
;
233 ti
->InitTableMapIter(ev
, &space
->mRowSpace_Tables
);
235 mPortTableCursor_TablesDidEnd
= morkBool_kFalse
;
241 morkPortTableCursor::SetTableKind(morkEnv
* ev
, mork_kind inTableKind
)
243 mPortTableCursor_TableKind
= inTableKind
;
244 mPortTableCursor_LastTable
= 0; // restart iteration of space
246 mPortTableCursor_TablesDidEnd
= morkBool_kTrue
;
248 morkRowSpace
* space
= mPortTableCursor_RowSpace
;
249 if ( !space
&& mPortTableCursor_RowScope
== 0 )
251 this->SetRowScope(ev
, 0);
252 space
= mPortTableCursor_RowSpace
;
254 this->init_space_tables_map(ev
);
260 morkPortTableCursor::NextSpace(morkEnv
* ev
)
262 morkRowSpace
* outSpace
= 0;
263 mPortTableCursor_LastTable
= 0;
264 mPortTableCursor_SpacesDidEnd
= morkBool_kTrue
;
265 mPortTableCursor_TablesDidEnd
= morkBool_kTrue
;
267 if ( !mPortTableCursor_RowScope
) // not just one scope?
269 morkStore
* store
= mPortTableCursor_Store
;
272 morkRowSpaceMapIter
* rsi
= &mPortTableCursor_SpaceIter
;
274 (void) rsi
->NextRowSpace(ev
, (mork_scope
*) 0, &outSpace
);
275 morkRowSpace::SlotStrongRowSpace(outSpace
, ev
,
276 &mPortTableCursor_RowSpace
);
278 if ( outSpace
) // found next space in store
280 mPortTableCursor_SpacesDidEnd
= morkBool_kFalse
;
282 this->init_space_tables_map(ev
);
289 this->NilCursorStoreError(ev
);
296 morkPortTableCursor::NextTable(morkEnv
* ev
)
298 mork_kind kind
= mPortTableCursor_TableKind
;
300 do // until spaces end, or until we find a table in a space
302 morkRowSpace
* space
= mPortTableCursor_RowSpace
;
303 if ( mPortTableCursor_TablesDidEnd
) // current space exhausted?
304 space
= this->NextSpace(ev
); // go on to the next space
306 if ( space
) // have a space remaining that might hold tables?
308 #ifdef MORK_BEAD_OVER_NODE_MAPS
309 morkTableMapIter
* ti
= &mPortTableCursor_TableIter
;
310 morkTable
* table
= ( mPortTableCursor_LastTable
)?
311 ti
->NextTable(ev
) : ti
->FirstTable(ev
);
313 for ( ; table
&& ev
->Good(); table
= ti
->NextTable(ev
) )
315 #else /*MORK_BEAD_OVER_NODE_MAPS*/
316 mork_tid
* key
= 0; // ignore keys in table map
317 morkTable
* table
= 0; // old value table in the map
318 morkTableMapIter
* ti
= &mPortTableCursor_TableIter
;
319 mork_change
* c
= ( mPortTableCursor_LastTable
)?
320 ti
->NextTable(ev
, key
, &table
) : ti
->FirstTable(ev
, key
, &table
);
322 for ( ; c
&& ev
->Good(); c
= ti
->NextTable(ev
, key
, &table
) )
323 #endif /*MORK_BEAD_OVER_NODE_MAPS*/
325 if ( table
&& table
->IsTable() )
327 if ( !kind
|| kind
== table
->mTable_Kind
)
329 mPortTableCursor_LastTable
= table
; // ti->NextTable() hence
334 table
->NonTableTypeWarning(ev
);
336 mPortTableCursor_TablesDidEnd
= morkBool_kTrue
; // space is done
337 mPortTableCursor_LastTable
= 0; // make sure next space starts fresh
340 } while ( ev
->Good() && !mPortTableCursor_SpacesDidEnd
);
342 return (morkTable
*) 0;
346 // { ----- begin table iteration methods -----
348 // { ===== begin nsIMdbPortTableCursor methods =====
350 // { ----- begin attribute methods -----
352 morkPortTableCursor::SetPort(nsIMdbEnv
* mev
, nsIMdbPort
* ioPort
)
354 NS_ASSERTION(PR_FALSE
,"not implemented");
355 return NS_ERROR_NOT_IMPLEMENTED
;
359 morkPortTableCursor::GetPort(nsIMdbEnv
* mev
, nsIMdbPort
** acqPort
)
362 nsIMdbPort
* outPort
= 0;
364 this->CanUsePortTableCursor(mev
, /*inMutable*/ morkBool_kFalse
, &outErr
);
367 if ( mPortTableCursor_Store
)
368 outPort
= mPortTableCursor_Store
->AcquireStoreHandle(ev
);
369 outErr
= ev
->AsErr();
377 morkPortTableCursor::SetRowScope(nsIMdbEnv
* mev
, // sets pos to -1
378 mdb_scope inRowScope
)
382 this->CanUsePortTableCursor(mev
, /*inMutable*/ morkBool_kFalse
, &outErr
);
387 SetRowScope(ev
, inRowScope
);
388 outErr
= ev
->AsErr();
394 morkPortTableCursor::GetRowScope(nsIMdbEnv
* mev
, mdb_scope
* outRowScope
)
397 mdb_scope rowScope
= 0;
399 this->CanUsePortTableCursor(mev
, /*inMutable*/ morkBool_kFalse
, &outErr
);
402 rowScope
= mPortTableCursor_RowScope
;
403 outErr
= ev
->AsErr();
405 *outRowScope
= rowScope
;
408 // setting row scope to zero iterates over all row scopes in port
411 morkPortTableCursor::SetTableKind(nsIMdbEnv
* mev
, // sets pos to -1
412 mdb_kind inTableKind
)
416 this->CanUsePortTableCursor(mev
, /*inMutable*/ morkBool_kFalse
, &outErr
);
421 SetTableKind(ev
, inTableKind
);
422 outErr
= ev
->AsErr();
428 morkPortTableCursor::GetTableKind(nsIMdbEnv
* mev
, mdb_kind
* outTableKind
)
429 // setting table kind to zero iterates over all table kinds in row scope
432 mdb_kind tableKind
= 0;
434 this->CanUsePortTableCursor(mev
, /*inMutable*/ morkBool_kFalse
, &outErr
);
437 tableKind
= mPortTableCursor_TableKind
;
438 outErr
= ev
->AsErr();
440 *outTableKind
= tableKind
;
443 // } ----- end attribute methods -----
445 // { ----- begin table iteration methods -----
447 morkPortTableCursor::NextTable( // get table at next position in the db
448 nsIMdbEnv
* mev
, // context
449 nsIMdbTable
** acqTable
)
452 nsIMdbTable
* outTable
= 0;
454 CanUsePortTableCursor(mev
, /*inMutable*/ morkBool_kFalse
, &outErr
);
457 morkTable
* table
= NextTable(ev
);
458 if ( table
&& ev
->Good() )
459 outTable
= table
->AcquireTableHandle(ev
);
461 outErr
= ev
->AsErr();
464 *acqTable
= outTable
;
468 //3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789