Back to index

lightning-sunbird  0.9+nobinonly
orkinRowCellCursor.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-  */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1999
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #ifndef _MDB_
00039 #include "mdb.h"
00040 #endif
00041 
00042 #ifndef _MORK_
00043 #include "mork.h"
00044 #endif
00045 
00046 #ifndef _MORKNODE_
00047 #include "morkNode.h"
00048 #endif
00049 
00050 #ifndef _MORKHANDLE_
00051 #include "morkHandle.h"
00052 #endif
00053 
00054 #ifndef _MORKROWCELLCURSOR_
00055 #include "morkRowCellCursor.h"
00056 #endif
00057 
00058 #ifndef _ORKINROWCELLCURSOR_
00059 #include "orkinRowCellCursor.h"
00060 #endif
00061 
00062 #ifndef _MORKROWOBJECT_
00063 #include "morkRowObject.h"
00064 #endif
00065 
00066 #ifndef _MORKROW_
00067 #include "morkRow.h"
00068 #endif
00069 
00070 #ifndef _ORKINROW_
00071 #include "orkinRow.h"
00072 #endif
00073 
00074 #ifndef _MORKCELL_
00075 #include "morkCell.h"
00076 #endif
00077 
00078 #ifndef _MORKENV_
00079 #include "morkEnv.h"
00080 #endif
00081 
00082 //3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
00083 
00084 /* public virtual*/
00085 orkinRowCellCursor:: ~orkinRowCellCursor() // morkHandle destructor does everything
00086 {
00087 }
00088 
00089 /*protected non-poly construction*/
00090 orkinRowCellCursor::orkinRowCellCursor(morkEnv* ev, // morkUsage is morkUsage_kPool
00091     morkHandleFace* ioFace,    // must not be nil, cookie for this handle
00092     morkRowCellCursor* ioObject)  // must not be nil, the object for this handle
00093 : morkHandle(ev, ioFace, ioObject, morkMagic_kRowCellCursor)
00094 {
00095   // do not modify mNode_Derived; leave it equal to morkDerived_kHandle
00096 }
00097 
00098 
00099 /*static */ orkinRowCellCursor*
00100 orkinRowCellCursor::MakeRowCellCursor(morkEnv* ev, morkRowCellCursor* ioObject)
00101 {
00102   mork_bool isEnv = ev->IsEnv();
00103   MORK_ASSERT(isEnv);
00104   if ( isEnv )
00105   {
00106     morkHandleFace* face = ev->NewHandle(sizeof(orkinRowCellCursor));
00107     if ( face )
00108       return new(face) orkinRowCellCursor(ev, face, ioObject);
00109     else
00110       ev->OutOfMemoryError();
00111   }
00112     
00113   return (orkinRowCellCursor*) 0;
00114 }
00115 
00116 morkEnv*
00117 orkinRowCellCursor::CanUseRowCellCursor(nsIMdbEnv* mev, mork_bool inMutable,
00118   mdb_err* outErr, morkRow** outRow) const
00119 {
00120   morkEnv* outEnv = 0;
00121   morkRow* row = 0;
00122   morkEnv* ev = morkEnv::FromMdbEnv(mev);
00123   if ( ev )
00124   {
00125     morkRowCellCursor* self = (morkRowCellCursor*)
00126       this->GetGoodHandleObject(ev, inMutable, morkMagic_kRowCellCursor,
00127         /*inClosedOkay*/ morkBool_kFalse);
00128     if ( self )
00129     {
00130       if ( self->IsRowCellCursor() )
00131       {
00132         if ( self->IsMutable() || !inMutable )
00133         {
00134           morkRowObject* rowObj = self->mRowCellCursor_RowObject;
00135           if ( rowObj )
00136           {
00137             morkRow* theRow = rowObj->mRowObject_Row;
00138             if ( theRow )
00139             {
00140               if ( theRow->IsRow() )
00141               {
00142                 outEnv = ev;
00143                 row = theRow;
00144               }
00145               else
00146                 theRow->NonRowTypeError(ev);
00147             }
00148             else
00149               rowObj->NilRowError(ev);
00150           }
00151           else
00152             self->NilRowObjectError(ev);
00153         }
00154         else
00155           self->NonMutableNodeError(ev);
00156       }
00157       else
00158         self->NonRowCellCursorTypeError(ev);
00159     }
00160     *outErr = ev->AsErr();
00161   }
00162   *outRow = row;
00163   MORK_ASSERT(outEnv);
00164   return outEnv;
00165 }
00166 
00167 // { ===== begin nsIMdbISupports methods =====
00168 NS_IMPL_QUERY_INTERFACE0(orkinRowCellCursor)
00169 
00170 /*virtual*/ nsrefcnt
00171 orkinRowCellCursor::AddRef() // add strong ref with no
00172 {
00173   morkEnv* ev = mHandle_Env;
00174   if ( ev && ev->IsEnv() )
00175     return this->Handle_AddStrongRef(ev->AsMdbEnv());
00176   else
00177     return morkEnv_kNonEnvTypeError;
00178 }
00179 
00180 /*virtual*/ nsrefcnt
00181 orkinRowCellCursor::Release() // cut strong ref
00182 {
00183   morkEnv* ev = mHandle_Env;
00184   if ( ev && ev->IsEnv() )
00185     return this->Handle_CutStrongRef(ev->AsMdbEnv());
00186   else
00187     return morkEnv_kNonEnvTypeError;
00188 }
00189 // } ===== end nsIMdbObject methods =====
00190 
00191 // { ===== begin nsIMdbObject methods =====
00192 
00193 // { ----- begin attribute methods -----
00194 /*virtual*/ mdb_err
00195 orkinRowCellCursor::IsFrozenMdbObject(nsIMdbEnv* mev, mdb_bool* outIsReadonly)
00196 {
00197   return this->Handle_IsFrozenMdbObject(mev, outIsReadonly);
00198 }
00199 // same as nsIMdbPort::GetIsPortReadonly() when this object is inside a port.
00200 // } ----- end attribute methods -----
00201 
00202 // { ----- begin factory methods -----
00203 /*virtual*/ mdb_err
00204 orkinRowCellCursor::GetMdbFactory(nsIMdbEnv* mev, nsIMdbFactory** acqFactory)
00205 {
00206   return this->Handle_GetMdbFactory(mev, acqFactory);
00207 } 
00208 // } ----- end factory methods -----
00209 
00210 // { ----- begin ref counting for well-behaved cyclic graphs -----
00211 /*virtual*/ mdb_err
00212 orkinRowCellCursor::GetWeakRefCount(nsIMdbEnv* mev, // weak refs
00213   mdb_count* outCount)
00214 {
00215   return this->Handle_GetWeakRefCount(mev, outCount);
00216 }  
00217 /*virtual*/ mdb_err
00218 orkinRowCellCursor::GetStrongRefCount(nsIMdbEnv* mev, // strong refs
00219   mdb_count* outCount)
00220 {
00221   return this->Handle_GetStrongRefCount(mev, outCount);
00222 }
00223 
00224 /*virtual*/ mdb_err
00225 orkinRowCellCursor::AddWeakRef(nsIMdbEnv* mev)
00226 {
00227   return this->Handle_AddWeakRef(mev);
00228 }
00229 /*virtual*/ mdb_err
00230 orkinRowCellCursor::AddStrongRef(nsIMdbEnv* mev)
00231 {
00232   return this->Handle_AddStrongRef(mev);
00233 }
00234 
00235 /*virtual*/ mdb_err
00236 orkinRowCellCursor::CutWeakRef(nsIMdbEnv* mev)
00237 {
00238   return this->Handle_CutWeakRef(mev);
00239 }
00240 /*virtual*/ mdb_err
00241 orkinRowCellCursor::CutStrongRef(nsIMdbEnv* mev)
00242 {
00243   return this->Handle_CutStrongRef(mev);
00244 }
00245 
00246 /*virtual*/ mdb_err
00247 orkinRowCellCursor::CloseMdbObject(nsIMdbEnv* mev)
00248 {
00249   return this->Handle_CloseMdbObject(mev);
00250 }
00251 
00252 /*virtual*/ mdb_err
00253 orkinRowCellCursor::IsOpenMdbObject(nsIMdbEnv* mev, mdb_bool* outOpen)
00254 {
00255   return this->Handle_IsOpenMdbObject(mev, outOpen);
00256 }
00257 // } ----- end ref counting -----
00258 
00259 // } ===== end nsIMdbObject methods =====
00260 
00261 // { ===== begin nsIMdbCursor methods =====
00262 
00263 // { ----- begin attribute methods -----
00264 /*virtual*/ mdb_err
00265 orkinRowCellCursor::GetCount(nsIMdbEnv* mev, mdb_count* outCount)
00266 {
00267   mdb_err outErr = 0;
00268   mdb_count count = 0;
00269   morkRow* row = 0;
00270   morkEnv* ev =
00271     this->CanUseRowCellCursor(mev, /*mut*/ morkBool_kFalse, &outErr, &row);
00272   if ( ev )
00273   {
00274     count = row->mRow_Length;
00275     outErr = ev->AsErr();
00276   }
00277   if ( outCount )
00278     *outCount = count;
00279   return outErr;
00280 }
00281 
00282 /*virtual*/ mdb_err
00283 orkinRowCellCursor::GetSeed(nsIMdbEnv* mev, mdb_seed* outSeed)
00284 {
00285   mdb_err outErr = 0;
00286   mdb_seed seed = 0;
00287   morkRow* row = 0;
00288   morkEnv* ev =
00289     this->CanUseRowCellCursor(mev, /*mut*/ morkBool_kFalse, &outErr, &row);
00290   if ( ev )
00291   {
00292     seed = row->mRow_Seed;
00293     outErr = ev->AsErr();
00294   }
00295   if ( outSeed )
00296     *outSeed = seed;
00297   return outErr;
00298 }
00299 
00300 /*virtual*/ mdb_err
00301 orkinRowCellCursor::SetPos(nsIMdbEnv* mev, mdb_pos inPos)
00302 {
00303   mdb_err outErr = 0;
00304   morkRow* row = 0;
00305   morkEnv* ev =
00306     this->CanUseRowCellCursor(mev, /*mut*/ morkBool_kFalse, &outErr, &row);
00307   if ( ev )
00308   {
00309     morkRowCellCursor* cursor = (morkRowCellCursor*) mHandle_Object;
00310     cursor->mCursor_Pos = inPos;
00311     outErr = ev->AsErr();
00312   }
00313   return outErr;
00314 }
00315 
00316 /*virtual*/ mdb_err
00317 orkinRowCellCursor::GetPos(nsIMdbEnv* mev, mdb_pos* outPos)
00318 {
00319   mdb_err outErr = 0;
00320   mdb_pos pos = 0;
00321   morkRow* row = 0;
00322   morkEnv* ev =
00323     this->CanUseRowCellCursor(mev, /*mut*/ morkBool_kFalse, &outErr, &row);
00324   if ( ev )
00325   {
00326     morkRowCellCursor* cursor = (morkRowCellCursor*) mHandle_Object;
00327     pos = cursor->mCursor_Pos;
00328     outErr = ev->AsErr();
00329   }
00330   if ( outPos )
00331     *outPos = pos;
00332   return outErr;
00333 }
00334 
00335 /*virtual*/ mdb_err
00336 orkinRowCellCursor::SetDoFailOnSeedOutOfSync(nsIMdbEnv* mev, mdb_bool inFail)
00337 {
00338   mdb_err outErr = 0;
00339   morkRow* row = 0;
00340   morkEnv* ev =
00341     this->CanUseRowCellCursor(mev, /*mut*/ morkBool_kFalse, &outErr, &row);
00342   if ( ev )
00343   {
00344     morkRowCellCursor* cursor = (morkRowCellCursor*) mHandle_Object;
00345     cursor->mCursor_DoFailOnSeedOutOfSync = inFail;
00346     outErr = ev->AsErr();
00347   }
00348   return outErr;
00349 }
00350 
00351 /*virtual*/ mdb_err
00352 orkinRowCellCursor::GetDoFailOnSeedOutOfSync(nsIMdbEnv* mev, mdb_bool* outFail)
00353 {
00354   mdb_err outErr = 0;
00355   mdb_bool doFail = morkBool_kFalse;
00356   morkRow* row = 0;
00357   morkEnv* ev =
00358     this->CanUseRowCellCursor(mev, /*mut*/ morkBool_kFalse, &outErr, &row);
00359   if ( ev )
00360   {
00361     morkRowCellCursor* cursor = (morkRowCellCursor*) mHandle_Object;
00362     doFail = cursor->mCursor_DoFailOnSeedOutOfSync;
00363     outErr = ev->AsErr();
00364   }
00365   if ( outFail )
00366     *outFail = doFail;
00367   return outErr;
00368 }
00369 // } ----- end attribute methods -----
00370 
00371 // } ===== end nsIMdbCursor methods =====
00372 
00373 // { ===== begin nsIMdbRowCellCursor methods =====
00374 
00375 // { ----- begin attribute methods -----
00376 /*virtual*/ mdb_err
00377 orkinRowCellCursor::SetRow(nsIMdbEnv* mev, nsIMdbRow* ioRow)
00378 {
00379   mdb_err outErr = 0;
00380   morkRow* row = 0;
00381   morkEnv* ev =
00382     this->CanUseRowCellCursor(mev, /*mut*/ morkBool_kFalse, &outErr, &row);
00383   if ( ev )
00384   {
00385     morkRowCellCursor* cursor = (morkRowCellCursor*) mHandle_Object;
00386     row = (morkRow *) ioRow;
00387     morkStore* store = row->GetRowSpaceStore(ev);
00388     if ( store )
00389     {
00390       morkRowObject* rowObj = row->AcquireRowObject(ev, store);
00391       if ( rowObj )
00392       {
00393         morkRowObject::SlotStrongRowObject((morkRowObject*) 0, ev,
00394           &cursor->mRowCellCursor_RowObject);
00395           
00396         cursor->mRowCellCursor_RowObject = rowObj; // take this strong ref
00397         cursor->mCursor_Seed = row->mRow_Seed;
00398         
00399         row->GetCell(ev, cursor->mRowCellCursor_Col, &cursor->mCursor_Pos);
00400       }
00401     }
00402     outErr = ev->AsErr();
00403   }
00404   return outErr;
00405 }
00406 
00407 /*virtual*/ mdb_err
00408 orkinRowCellCursor::GetRow(nsIMdbEnv* mev, nsIMdbRow** acqRow)
00409 {
00410   mdb_err outErr = 0;
00411   nsIMdbRow* outRow = 0;
00412   morkRow* row = 0;
00413   morkEnv* ev =
00414     this->CanUseRowCellCursor(mev, /*mut*/ morkBool_kFalse, &outErr, &row);
00415   if ( ev )
00416   {
00417     morkRowCellCursor* cursor = (morkRowCellCursor*) mHandle_Object;
00418     morkRowObject* rowObj = cursor->mRowCellCursor_RowObject;
00419     if ( rowObj )
00420       outRow = rowObj->AcquireRowHandle(ev);
00421 
00422     outErr = ev->AsErr();
00423   }
00424   if ( acqRow )
00425     *acqRow = outRow;
00426   return outErr;
00427 }
00428 // } ----- end attribute methods -----
00429 
00430 // { ----- begin cell creation methods -----
00431 /*virtual*/ mdb_err
00432 orkinRowCellCursor::MakeCell( // get cell at current pos in the row
00433   nsIMdbEnv* mev, // context
00434   mdb_column* outColumn, // column for this particular cell
00435   mdb_pos* outPos, // position of cell in row sequence
00436   nsIMdbCell** acqCell)
00437 {
00438   mdb_err outErr = 0;
00439   nsIMdbCell* outCell = 0;
00440   mdb_pos pos = 0;
00441   mdb_column col = 0;
00442   morkRow* row = 0;
00443   morkEnv* ev =
00444     this->CanUseRowCellCursor(mev, /*mut*/ morkBool_kFalse, &outErr, &row);
00445   if ( ev )
00446   {
00447     morkRowCellCursor* cursor = (morkRowCellCursor*) mHandle_Object;
00448     pos = cursor->mCursor_Pos;
00449     morkCell* cell = row->CellAt(ev, pos);
00450     if ( cell )
00451     {
00452       col = cell->GetColumn();
00453       outCell = row->AcquireCellHandle(ev, cell, col, pos);
00454     }
00455     outErr = ev->AsErr();
00456   }
00457   if ( acqCell )
00458     *acqCell = outCell;
00459    if ( outPos )
00460      *outPos = pos;
00461    if ( outColumn )
00462      *outColumn = col;
00463      
00464   return outErr;
00465 }
00466 // } ----- end cell creation methods -----
00467 
00468 // { ----- begin cell seeking methods -----
00469 /*virtual*/ mdb_err
00470 orkinRowCellCursor::SeekCell( // same as SetRow() followed by MakeCell()
00471   nsIMdbEnv* mev, // context
00472   mdb_pos inPos, // position of cell in row sequence
00473   mdb_column* outColumn, // column for this particular cell
00474   nsIMdbCell** acqCell)
00475 {
00476   MORK_USED_1(inPos);
00477   mdb_err outErr = 0;
00478   mdb_column column = 0;
00479   nsIMdbCell* outCell = 0;
00480   morkRow* row = 0;
00481   morkEnv* ev =
00482     this->CanUseRowCellCursor(mev, /*mut*/ morkBool_kFalse, &outErr, &row);
00483   if ( ev )
00484   {
00485     morkRowCellCursor* cursor;
00486     cursor = (morkRowCellCursor*) mHandle_Object;
00487     ev->StubMethodOnlyError();
00488     outErr = ev->AsErr();
00489   }
00490   if ( acqCell )
00491     *acqCell = outCell;
00492   if ( outColumn )
00493     *outColumn = column;
00494   return outErr;
00495 }
00496 // } ----- end cell seeking methods -----
00497 
00498 // { ----- begin cell iteration methods -----
00499 /*virtual*/ mdb_err
00500 orkinRowCellCursor::NextCell( // get next cell in the row
00501   nsIMdbEnv* mev, // context
00502   nsIMdbCell* ioCell, // changes to the next cell in the iteration
00503   mdb_column* outColumn, // column for this particular cell
00504   mdb_pos* outPos)
00505 {
00506   MORK_USED_1(ioCell);
00507   mdb_err outErr = 0;
00508   mdb_pos pos = -1;
00509   mdb_column column = 0;
00510   morkRow* row = 0;
00511   morkEnv* ev =
00512     this->CanUseRowCellCursor(mev, /*mut*/ morkBool_kFalse, &outErr, &row);
00513   if ( ev )
00514   {
00515     morkRowCellCursor* cursor;
00516     cursor = (morkRowCellCursor*) mHandle_Object;
00517     ev->StubMethodOnlyError();
00518     outErr = ev->AsErr();
00519   }
00520   if ( outColumn )
00521     *outColumn = column;
00522   if ( outPos )
00523     *outPos = pos;
00524   return outErr;
00525 }
00526   
00527 /*virtual*/ mdb_err
00528 orkinRowCellCursor::PickNextCell( // get next cell in row within filter set
00529   nsIMdbEnv* mev, // context
00530   nsIMdbCell* ioCell, // changes to the next cell in the iteration
00531   const mdbColumnSet* inFilterSet, // col set of actual caller interest
00532   mdb_column* outColumn, // column for this particular cell
00533   mdb_pos* outPos)
00534 // Note that inFilterSet should not have too many (many more than 10?)
00535 // cols, since this might imply a potential excessive consumption of time
00536 // over many cursor calls when looking for column and filter intersection.
00537 {
00538   MORK_USED_2(ioCell,inFilterSet);
00539   mdb_pos pos = -1;
00540   mdb_column column = 0;
00541   mdb_err outErr = 0;
00542   morkRow* row = 0;
00543   morkEnv* ev =
00544     this->CanUseRowCellCursor(mev, /*mut*/ morkBool_kFalse, &outErr, &row);
00545   if ( ev )
00546   {
00547     morkRowCellCursor* cursor;
00548     cursor = (morkRowCellCursor*) mHandle_Object;
00549     ev->StubMethodOnlyError();
00550     outErr = ev->AsErr();
00551   }
00552   if ( outColumn )
00553     *outColumn = column;
00554   if ( outPos )
00555     *outPos = pos;
00556   return outErr;
00557 }
00558 
00559 // } ----- end cell iteration methods -----
00560 
00561 // } ===== end nsIMdbRowCellCursor methods =====
00562 
00563 
00564 //3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789