Back to index

lightning-sunbird  0.9+nobinonly
orkinRow.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 _MORKATOM_
00055 #include "morkAtom.h"
00056 #endif
00057 
00058 #ifndef _MORKROW_
00059 #include "morkRow.h"
00060 #endif
00061 
00062 #ifndef _ORKINROW_
00063 #include "orkinRow.h"
00064 #endif
00065 
00066 #ifndef _MORKENV_
00067 #include "morkEnv.h"
00068 #endif
00069 
00070 #ifndef _MORKROWOBJECT_
00071 #include "morkRowObject.h"
00072 #endif
00073 
00074 #ifndef _MORKCELLOBJECT_
00075 #include "morkCellObject.h"
00076 #endif
00077 
00078 #ifndef _MORKSTORE_
00079 #include "morkStore.h"
00080 #endif
00081 
00082 #ifndef _ORKINSTORE_
00083 #include "orkinStore.h"
00084 #endif
00085 
00086 #ifndef _MORKROWSPACE_
00087 #include "morkRowSpace.h"
00088 #endif
00089 
00090 #ifndef _MORKROWCELLCURSOR_
00091 #include "morkRowCellCursor.h"
00092 #endif
00093 
00094 #ifndef _ORKINROWCELLCURSOR_
00095 #include "orkinRowCellCursor.h"
00096 #endif
00097 
00098 #ifndef _ORKINCELL_
00099 #include "orkinCell.h"
00100 #endif
00101 
00102 //3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
00103 
00104 /* public virtual*/
00105 orkinRow:: ~orkinRow() // morkHandle destructor does everything
00106 {
00107 }    
00108 
00109 /*protected non-poly construction*/
00110 orkinRow::orkinRow(morkEnv* ev, // morkUsage is morkUsage_kPool
00111     morkHandleFace* ioFace,    // must not be nil, cookie for this handle
00112     morkRowObject* ioObject)  // must not be nil, the object for this handle
00113 : morkHandle(ev, ioFace, ioObject, morkMagic_kRow)
00114 {
00115   // do not modify mNode_Derived; leave it equal to morkDerived_kHandle
00116 }
00117 
00118 
00119 /*static */ orkinRow*
00120 orkinRow::MakeRow(morkEnv* ev,  morkRowObject* ioObject)
00121 {
00122   mork_bool isEnv = ev->IsEnv();
00123   MORK_ASSERT(isEnv);
00124   if ( isEnv )
00125   {
00126     morkHandleFace* face = ev->NewHandle(sizeof(orkinRow));
00127     if ( face )
00128       return new(face) orkinRow(ev, face, ioObject);
00129     else
00130       ev->OutOfMemoryError();
00131   }
00132     
00133   return (orkinRow*) 0;
00134 }
00135 
00136 morkEnv*
00137 orkinRow::CanUseRow(nsIMdbEnv* mev, mork_bool inMutable,
00138   mdb_err* outErr, morkRow** outRow) const
00139 {
00140   morkEnv* outEnv = 0;
00141   morkRow* innerRow = 0;
00142   morkEnv* ev = morkEnv::FromMdbEnv(mev);
00143   if ( ev )
00144   {
00145     morkRowObject* rowObj = (morkRowObject*)
00146       this->GetGoodHandleObject(ev, inMutable, morkMagic_kRow,
00147         /*inClosedOkay*/ morkBool_kFalse);
00148     if ( rowObj )
00149     {
00150       if ( rowObj->IsRowObject() )
00151       {
00152         morkRow* row = rowObj->mRowObject_Row;
00153         if ( row )
00154         {
00155           if ( row->IsRow() )
00156           {
00157             if ( row->mRow_Object == rowObj )
00158             {
00159               outEnv = ev;
00160               innerRow = row;
00161             }
00162             else
00163               rowObj->RowObjectRowNotSelfError(ev);
00164           }
00165           else
00166             row->NonRowTypeError(ev);
00167         }
00168         else
00169           rowObj->NilRowError(ev);
00170       }
00171       else
00172         rowObj->NonRowObjectTypeError(ev);
00173     }
00174     *outErr = ev->AsErr();
00175   }
00176   if ( outRow )
00177     *outRow = innerRow;
00178   MORK_ASSERT(outEnv);
00179   return outEnv;
00180 }
00181 
00182 morkStore*
00183 orkinRow::CanUseRowStore(morkEnv* ev) const
00184 {
00185   morkStore* outStore = 0;
00186   morkRowObject* rowObj = (morkRowObject*) mHandle_Object;
00187   if ( rowObj && rowObj->IsRowObject() )
00188   {
00189     morkStore* store = rowObj->mRowObject_Store;
00190     if ( store )
00191     {
00192       if ( store->IsStore() )
00193       {
00194         outStore = store;
00195       }
00196       else
00197         store->NonStoreTypeError(ev);
00198     }
00199     else
00200       rowObj->NilStoreError(ev);
00201   }
00202   return outStore;
00203 }
00204 
00205 
00206 // { ===== begin nsISupports methods =====
00207 NS_IMPL_QUERY_INTERFACE1(orkinRow, nsIMdbRow)
00208 
00209 /*virtual*/ nsrefcnt
00210 orkinRow::AddRef() // add strong ref with no
00211 {
00212   morkEnv* ev = mHandle_Env;
00213   if ( ev && ev->IsEnv() )
00214     return this->Handle_AddStrongRef(ev->AsMdbEnv());
00215   else
00216     return morkEnv_kNonEnvTypeError;
00217 }
00218 
00219 /*virtual*/ nsrefcnt
00220 orkinRow::Release() // cut strong ref
00221 {
00222   morkEnv* ev = mHandle_Env;
00223   if ( ev && ev->IsEnv() )
00224     return this->Handle_CutStrongRef(ev->AsMdbEnv());
00225   else
00226     return morkEnv_kNonEnvTypeError;
00227 }
00228 // } ===== end nsIMdbObject methods =====
00229 
00230 
00231 // { ===== begin nsIMdbObject methods =====
00232 
00233 // { ----- begin attribute methods -----
00234 /*virtual*/ mdb_err
00235 orkinRow::IsFrozenMdbObject(nsIMdbEnv* mev, mdb_bool* outIsReadonly)
00236 {
00237   return this->Handle_IsFrozenMdbObject(mev, outIsReadonly);
00238 }
00239 // same as nsIMdbPort::GetIsPortReadonly() when this object is inside a port.
00240 // } ----- end attribute methods -----
00241 
00242 // { ----- begin factory methods -----
00243 /*virtual*/ mdb_err
00244 orkinRow::GetMdbFactory(nsIMdbEnv* mev, nsIMdbFactory** acqFactory)
00245 {
00246   return this->Handle_GetMdbFactory(mev, acqFactory);
00247 } 
00248 // } ----- end factory methods -----
00249 
00250 // { ----- begin ref counting for well-behaved cyclic graphs -----
00251 /*virtual*/ mdb_err
00252 orkinRow::GetWeakRefCount(nsIMdbEnv* mev, // weak refs
00253   mdb_count* outCount)
00254 {
00255   return this->Handle_GetWeakRefCount(mev, outCount);
00256 }  
00257 /*virtual*/ mdb_err
00258 orkinRow::GetStrongRefCount(nsIMdbEnv* mev, // strong refs
00259   mdb_count* outCount)
00260 {
00261   return this->Handle_GetStrongRefCount(mev, outCount);
00262 }
00263 
00264 /*virtual*/ mdb_err
00265 orkinRow::AddWeakRef(nsIMdbEnv* mev)
00266 {
00267   return this->Handle_AddWeakRef(mev);
00268 }
00269 /*virtual*/ mdb_err
00270 orkinRow::AddStrongRef(nsIMdbEnv* mev)
00271 {
00272   return this->Handle_AddStrongRef(mev);
00273 }
00274 
00275 /*virtual*/ mdb_err
00276 orkinRow::CutWeakRef(nsIMdbEnv* mev)
00277 {
00278   return this->Handle_CutWeakRef(mev);
00279 }
00280 /*virtual*/ mdb_err
00281 orkinRow::CutStrongRef(nsIMdbEnv* mev)
00282 {
00283   return this->Handle_CutStrongRef(mev);
00284 }
00285 
00286 /*virtual*/ mdb_err
00287 orkinRow::CloseMdbObject(nsIMdbEnv* mev)
00288 {
00289   return this->Handle_CloseMdbObject(mev);
00290 }
00291 
00292 /*virtual*/ mdb_err
00293 orkinRow::IsOpenMdbObject(nsIMdbEnv* mev, mdb_bool* outOpen)
00294 {
00295   return this->Handle_IsOpenMdbObject(mev, outOpen);
00296 }
00297 // } ----- end ref counting -----
00298 
00299 // } ===== end nsIMdbObject methods =====
00300 
00301 
00302 // { ===== begin nsIMdbCollection methods =====
00303 
00304 // { ----- begin attribute methods -----
00305 /*virtual*/ mdb_err
00306 orkinRow::GetSeed(nsIMdbEnv* mev,
00307   mdb_seed* outSeed)
00308 {
00309   mdb_err outErr = 0;
00310   morkRow* row = 0;
00311   morkEnv* ev = this->CanUseRow(mev, /*inMutable*/ morkBool_kFalse,
00312     &outErr, &row);
00313   if ( ev )
00314   {
00315     *outSeed = (mdb_seed) row->mRow_Seed;
00316     outErr = ev->AsErr();
00317   }
00318   return outErr;
00319 }
00320 /*virtual*/ mdb_err
00321 orkinRow::GetCount(nsIMdbEnv* mev,
00322   mdb_count* outCount)
00323 {
00324   mdb_err outErr = 0;
00325   morkRow* row = 0;
00326   morkEnv* ev = this->CanUseRow(mev, /*inMutable*/ morkBool_kFalse,
00327     &outErr, &row);
00328   if ( ev )
00329   {
00330     *outCount = (mdb_count) row->mRow_Length;
00331     outErr = ev->AsErr();
00332   }
00333   return outErr;
00334 }
00335 
00336 /*virtual*/ mdb_err
00337 orkinRow::GetPort(nsIMdbEnv* mev,
00338   nsIMdbPort** acqPort)
00339 {
00340   mdb_err outErr = 0;
00341   nsIMdbPort* outPort = 0;
00342   morkRow* row = 0;
00343   morkEnv* ev = this->CanUseRow(mev, /*inMutable*/ morkBool_kFalse,
00344     &outErr, &row);
00345   if ( ev )
00346   {
00347     morkRowSpace* rowSpace = row->mRow_Space;
00348     if ( rowSpace && rowSpace->mSpace_Store )
00349     {
00350       morkStore* store = row->GetRowSpaceStore(ev);
00351       if ( store )
00352         outPort = store->AcquireStoreHandle(ev);
00353     }
00354     else
00355       ev->NilPointerError();
00356       
00357     outErr = ev->AsErr();
00358   }
00359   if ( acqPort )
00360     *acqPort = outPort;
00361     
00362   return outErr;
00363 }
00364 // } ----- end attribute methods -----
00365 
00366 // { ----- begin cursor methods -----
00367 /*virtual*/ mdb_err
00368 orkinRow::GetCursor( // make a cursor starting iter at inMemberPos
00369   nsIMdbEnv* mev, // context
00370   mdb_pos inMemberPos, // zero-based ordinal pos of member in collection
00371   nsIMdbCursor** acqCursor)
00372 {
00373   return this->GetRowCellCursor(mev, inMemberPos,
00374     (nsIMdbRowCellCursor**) acqCursor);
00375 }
00376 // } ----- end cursor methods -----
00377 
00378 // { ----- begin ID methods -----
00379 /*virtual*/ mdb_err
00380 orkinRow::GetOid(nsIMdbEnv* mev,
00381   mdbOid* outOid)
00382 {
00383   mdb_err outErr = 0;
00384   morkRow* row = 0;
00385   morkEnv* ev = this->CanUseRow(mev, /*inMutable*/ morkBool_kFalse,
00386     &outErr, &row);
00387   if ( ev )
00388   {
00389     *outOid = row->mRow_Oid;
00390     outErr = ev->AsErr();
00391   }
00392   return outErr;
00393 }
00394 
00395 /*virtual*/ mdb_err
00396 orkinRow::BecomeContent(nsIMdbEnv* mev,
00397   const mdbOid* inOid)
00398 {
00399   MORK_USED_1(inOid);
00400   mdb_err outErr = 0;
00401   morkRow* row = 0;
00402   morkEnv* ev = this->CanUseRow(mev, /*inMutable*/ morkBool_kFalse,
00403     &outErr, &row);
00404   if ( ev )
00405   {
00406     // remember row->MaybeDirtySpaceStoreAndRow();
00407     
00408     ev->StubMethodOnlyError();
00409     outErr = ev->AsErr();
00410   }
00411   return outErr;
00412 }
00413 // } ----- end ID methods -----
00414 
00415 // { ----- begin activity dropping methods -----
00416 /*virtual*/ mdb_err
00417 orkinRow::DropActivity( // tell collection usage no longer expected
00418   nsIMdbEnv* mev)
00419 {
00420   mdb_err outErr = 0;
00421   morkRow* row = 0;
00422   morkEnv* ev = this->CanUseRow(mev, /*inMutable*/ morkBool_kFalse,
00423     &outErr, &row);
00424   if ( ev )
00425   {
00426     // ev->StubMethodOnlyError(); // do nothing
00427     outErr = ev->AsErr();
00428   }
00429   return outErr;
00430     }
00431 // } ----- end activity dropping methods -----
00432 
00433 // } ===== end nsIMdbCollection methods =====
00434 
00435 // { ===== begin nsIMdbRow methods =====
00436 
00437 // { ----- begin cursor methods -----
00438 /*virtual*/ mdb_err
00439 orkinRow::GetRowCellCursor( // make a cursor starting iteration at inRowPos
00440   nsIMdbEnv* mev, // context
00441   mdb_pos inPos, // zero-based ordinal position of row in table
00442   nsIMdbRowCellCursor** acqCursor)
00443 {
00444   mdb_err outErr = 0;
00445   nsIMdbRowCellCursor* outCursor = 0;
00446   morkRow* row = 0;
00447   morkEnv* ev = this->CanUseRow(mev, /*inMutable*/ morkBool_kFalse,
00448     &outErr, &row);
00449   if ( ev )
00450   {
00451     morkRowCellCursor* cursor = row->NewRowCellCursor(ev, inPos);
00452     if ( cursor )
00453     {
00454       if ( ev->Good() )
00455       {
00456         cursor->mCursor_Seed = (mork_seed) inPos;
00457         outCursor = cursor->AcquireRowCellCursorHandle(ev);
00458       }
00459       else
00460         cursor->CutStrongRef(mev);
00461     }
00462     outErr = ev->AsErr();
00463   }
00464   if ( acqCursor )
00465     *acqCursor = outCursor;
00466   return outErr;
00467 }
00468 // } ----- end cursor methods -----
00469 
00470 // { ----- begin column methods -----
00471 /*virtual*/ mdb_err
00472 orkinRow::AddColumn( // make sure a particular column is inside row
00473   nsIMdbEnv* mev, // context
00474   mdb_column inColumn, // column to add
00475   const mdbYarn* inYarn)
00476 {
00477   mdb_err outErr = 0;
00478   morkRow* row = 0;
00479   morkEnv* ev = this->CanUseRow(mev, /*inMutable*/ morkBool_kFalse,
00480     &outErr, &row);
00481   if ( ev )
00482   {
00483     morkStore* store = this->CanUseRowStore(ev);
00484     if ( store )
00485       row->AddColumn(ev, inColumn, inYarn, store);
00486       
00487     outErr = ev->AsErr();
00488   }
00489   return outErr;
00490 }
00491 
00492 /*virtual*/ mdb_err
00493 orkinRow::CutColumn( // make sure a column is absent from the row
00494   nsIMdbEnv* mev, // context
00495   mdb_column inColumn)
00496 {
00497   mdb_err outErr = 0;
00498   morkRow* row = 0;
00499   morkEnv* ev = this->CanUseRow(mev, /*inMutable*/ morkBool_kFalse,
00500     &outErr, &row);
00501   if ( ev )
00502   {
00503     row->CutColumn(ev, inColumn);
00504     outErr = ev->AsErr();
00505   }
00506   return outErr;
00507 }
00508 
00509 /*virtual*/ mdb_err
00510 orkinRow::CutAllColumns( // remove all columns from the row
00511   nsIMdbEnv* mev)
00512 {
00513   mdb_err outErr = 0;
00514   morkRow* row = 0;
00515   morkEnv* ev = this->CanUseRow(mev, /*inMutable*/ morkBool_kFalse,
00516     &outErr, &row);
00517   if ( ev )
00518   {
00519     row->CutAllColumns(ev);
00520     outErr = ev->AsErr();
00521   }
00522   return outErr;
00523 }
00524 // } ----- end column methods -----
00525 
00526 // { ----- begin cell methods -----
00527 /*virtual*/ mdb_err
00528 orkinRow::NewCell( // get cell for specified column, or add new one
00529   nsIMdbEnv* mev, // context
00530   mdb_column inColumn, // column to add
00531   nsIMdbCell** acqCell)
00532 {
00533   mdb_err outErr = 0;
00534   nsIMdbCell* outCell = 0;
00535   morkRow* row = 0;
00536   morkEnv* ev = this->CanUseRow(mev, /*inMutable*/ morkBool_kFalse,
00537     &outErr, &row);
00538   if ( ev )
00539   {
00540     mork_pos pos = 0;
00541     morkCell* cell = row->GetCell(ev, inColumn, &pos);
00542     if ( !cell )
00543     {
00544       morkStore* store = this->CanUseRowStore(ev);
00545       if ( store )
00546       {
00547         mdbYarn yarn; // to pass empty yarn into morkRow::AddColumn()
00548         yarn.mYarn_Buf = 0;
00549         yarn.mYarn_Fill = 0;
00550         yarn.mYarn_Size = 0;
00551         yarn.mYarn_More = 0;
00552         yarn.mYarn_Form = 0;
00553         yarn.mYarn_Grow = 0;
00554         row->AddColumn(ev, inColumn, &yarn, store);
00555         cell = row->GetCell(ev, inColumn, &pos);
00556       }
00557     }
00558     if ( cell )
00559       outCell = row->AcquireCellHandle(ev, cell, inColumn, pos);
00560       
00561     outErr = ev->AsErr();
00562   }
00563   if ( acqCell )
00564     *acqCell = outCell;
00565   return outErr;
00566 }
00567   
00568 /*virtual*/ mdb_err
00569 orkinRow::AddCell( // copy a cell from another row to this row
00570   nsIMdbEnv* mev, // context
00571   const nsIMdbCell* inCell)
00572 {
00573   mdb_err outErr = 0;
00574   morkRow* row = 0;
00575   morkEnv* ev = this->CanUseRow(mev, /*inMutable*/ morkBool_kFalse,
00576     &outErr, &row);
00577   if ( ev )
00578   {
00579     morkCell* cell = 0;
00580     morkCellObject* cellObj = (morkCellObject*) inCell;
00581     if ( cellObj->CanUseCell(mev, morkBool_kFalse, &outErr, &cell) )
00582     {
00583 
00584       morkRow* cellRow = cellObj->mCellObject_Row;
00585       if ( cellRow )
00586       {
00587         if ( row != cellRow )
00588         {
00589           morkStore* store = row->GetRowSpaceStore(ev);
00590           morkStore* cellStore = cellRow->GetRowSpaceStore(ev);
00591           if ( store && cellStore )
00592           {
00593             mork_column col = cell->GetColumn();
00594             morkAtom* atom = cell->mCell_Atom;
00595             mdbYarn yarn;
00596             atom->AliasYarn(&yarn); // works even when atom is nil
00597             
00598             if ( store != cellStore )
00599               col = store->CopyToken(ev, col, cellStore);
00600             if ( ev->Good() )
00601               row->AddColumn(ev, col, &yarn, store);
00602           }
00603           else
00604             ev->NilPointerError();
00605         }
00606       }
00607       else
00608         ev->NilPointerError();
00609     }
00610 
00611     outErr = ev->AsErr();
00612   }
00613   return outErr;
00614 }
00615   
00616 /*virtual*/ mdb_err
00617 orkinRow::GetCell( // find a cell in this row
00618   nsIMdbEnv* mev, // context
00619   mdb_column inColumn, // column to find
00620   nsIMdbCell** acqCell)
00621 {
00622   mdb_err outErr = 0;
00623   nsIMdbCell* outCell = 0;
00624   morkRow* row = 0;
00625   morkEnv* ev = this->CanUseRow(mev, /*inMutable*/ morkBool_kFalse,
00626     &outErr, &row);
00627   if ( ev )
00628   {
00629     if ( inColumn )
00630     {
00631       mork_pos pos = 0;
00632       morkCell* cell = row->GetCell(ev, inColumn, &pos);
00633       if ( cell )
00634       {
00635         outCell = row->AcquireCellHandle(ev, cell, inColumn, pos);
00636       }
00637     }
00638     else
00639       row->ZeroColumnError(ev);
00640       
00641     outErr = ev->AsErr();
00642   }
00643   if ( acqCell )
00644     *acqCell = outCell;
00645   return outErr;
00646 }
00647   
00648 /*virtual*/ mdb_err
00649 orkinRow::EmptyAllCells( // make all cells in row empty of content
00650   nsIMdbEnv* mev)
00651 {
00652   mdb_err outErr = 0;
00653   morkRow* row = 0;
00654   morkEnv* ev = this->CanUseRow(mev, /*inMutable*/ morkBool_kFalse,
00655     &outErr, &row);
00656   if ( ev )
00657   {
00658     row->EmptyAllCells(ev);
00659     outErr = ev->AsErr();
00660   }
00661   return outErr;
00662 }
00663 // } ----- end cell methods -----
00664 
00665 // { ----- begin row methods -----
00666 /*virtual*/ mdb_err
00667 orkinRow::AddRow( // add all cells in another row to this one
00668   nsIMdbEnv* mev, // context
00669   nsIMdbRow* ioSourceRow)
00670 {
00671   mdb_err outErr = 0;
00672   morkRow* row = 0;
00673   morkEnv* ev = this->CanUseRow(mev, /*inMutable*/ morkBool_kFalse,
00674     &outErr, &row);
00675   if ( ev )
00676   {
00677     morkRow* source = 0;
00678     orkinRow* unsafeSource = (orkinRow*) ioSourceRow; // unsafe cast
00679     if ( unsafeSource->CanUseRow(mev, morkBool_kFalse, &outErr, &source) )
00680     {
00681       row->AddRow(ev, source);
00682     }
00683     outErr = ev->AsErr();
00684   }
00685   return outErr;
00686 }
00687   
00688 /*virtual*/ mdb_err
00689 orkinRow::SetRow( // make exact duplicate of another row
00690   nsIMdbEnv* mev, // context
00691   nsIMdbRow* ioSourceRow)
00692 {
00693   mdb_err outErr = 0;
00694   morkRow* row = 0;
00695   morkEnv* ev = this->CanUseRow(mev, /*inMutable*/ morkBool_kFalse,
00696     &outErr, &row);
00697   if ( ev )
00698   {
00699     morkRow* source = 0;
00700     orkinRow* unsafeSource = (orkinRow*) ioSourceRow; // unsafe cast
00701     if ( unsafeSource->CanUseRow(mev, morkBool_kFalse, &outErr, &source) )
00702     {
00703       row->SetRow(ev, source);
00704     }
00705     outErr = ev->AsErr();
00706   }
00707   return outErr;
00708 }
00709 // } ----- end row methods -----
00710 
00711 // { ----- begin blob methods -----
00712 /*virtual*/ mdb_err
00713 orkinRow::SetCellYarn( // synonym for AddColumn()
00714   nsIMdbEnv* mev, // context
00715   mdb_column inColumn, // column to add
00716   const mdbYarn* inYarn)
00717 {
00718   mdb_err outErr = 0;
00719   morkRow* row = 0;
00720   morkEnv* ev = this->CanUseRow(mev, /*inMutable*/ morkBool_kFalse,
00721     &outErr, &row);
00722   if ( ev )
00723   {
00724     morkStore* store = this->CanUseRowStore(ev);
00725     if ( store )
00726       row->AddColumn(ev, inColumn, inYarn, store);
00727       
00728     outErr = ev->AsErr();
00729   }
00730   return outErr;
00731 }
00732 /*virtual*/ mdb_err
00733 orkinRow::GetCellYarn(
00734   nsIMdbEnv* mev, // context
00735   mdb_column inColumn, // column to read 
00736   mdbYarn* outYarn)  // writes some yarn slots 
00737 // copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form
00738 {
00739   mdb_err outErr = 0;
00740   morkRow* row = 0;
00741   morkEnv* ev = this->CanUseRow(mev, /*inMutable*/ morkBool_kFalse,
00742     &outErr, &row);
00743   if ( ev )
00744   {
00745     morkStore* store = this->CanUseRowStore(ev);
00746     if ( store )
00747     {
00748            morkAtom* atom = row->GetColumnAtom(ev, inColumn);
00749            atom->GetYarn(outYarn);
00750            // note nil atom works and sets yarn correctly
00751     }
00752       
00753     outErr = ev->AsErr();
00754   }
00755   return outErr;
00756 }
00757 
00758 /*virtual*/ mdb_err
00759 orkinRow::AliasCellYarn(
00760   nsIMdbEnv* mev, // context
00761     mdb_column inColumn, // column to alias
00762     mdbYarn* outYarn) // writes ALL yarn slots
00763 {
00764   mdb_err outErr = 0;
00765   morkRow* row = 0;
00766   morkEnv* ev = this->CanUseRow(mev, /*inMutable*/ morkBool_kFalse,
00767     &outErr, &row);
00768   if ( ev )
00769   {
00770     morkStore* store = this->CanUseRowStore(ev);
00771     if ( store )
00772     {
00773            morkAtom* atom = row->GetColumnAtom(ev, inColumn);
00774            atom->AliasYarn(outYarn);
00775            // note nil atom works and sets yarn correctly
00776     }
00777     outErr = ev->AsErr();
00778   }
00779   return outErr;
00780 }
00781 
00782 /*virtual*/ mdb_err
00783 orkinRow::NextCellYarn(nsIMdbEnv* mev, // iterative version of GetCellYarn()
00784   mdb_column* ioColumn, // next column to read
00785   mdbYarn* outYarn)  // writes some yarn slots 
00786 // copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form
00787 //
00788 // The ioColumn argument is an inout parameter which initially contains the
00789 // last column accessed and returns the next column corresponding to the
00790 // content read into the yarn.  Callers should start with a zero column
00791 // value to say 'no previous column', which causes the first column to be
00792 // read.  Then the value returned in ioColumn is perfect for the next call
00793 // to NextCellYarn(), since it will then be the previous column accessed.
00794 // Callers need only examine the column token returned to see which cell
00795 // in the row is being read into the yarn.  When no more columns remain,
00796 // and the iteration has ended, ioColumn will return a zero token again.
00797 // So iterating over cells starts and ends with a zero column token.
00798 {
00799   mdb_err outErr = 0;
00800   morkRow* row = 0;
00801   morkEnv* ev = this->CanUseRow(mev, /*inMutable*/ morkBool_kFalse,
00802     &outErr, &row);
00803   if ( ev )
00804   {
00805     morkStore* store = this->CanUseRowStore(ev);
00806     if ( store )
00807       row->NextColumn(ev, ioColumn, outYarn);
00808       
00809     outErr = ev->AsErr();
00810   }
00811   return outErr;
00812 }
00813 
00814 /*virtual*/ mdb_err
00815 orkinRow::SeekCellYarn( // resembles nsIMdbRowCellCursor::SeekCell()
00816   nsIMdbEnv* mev, // context
00817   mdb_pos inPos, // position of cell in row sequence
00818   mdb_column* outColumn, // column for this particular cell
00819   mdbYarn* outYarn) // writes some yarn slots
00820 // copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form
00821 // Callers can pass nil for outYarn to indicate no interest in content, so
00822 // only the outColumn value is returned.  NOTE to subclasses: you must be
00823 // able to ignore outYarn when the pointer is nil; please do not crash.
00824 
00825 {
00826   mdb_err outErr = 0;
00827   morkRow* row = 0;
00828   morkEnv* ev = this->CanUseRow(mev, /*inMutable*/ morkBool_kFalse,
00829     &outErr, &row);
00830   if ( ev )
00831   {
00832     morkStore* store = this->CanUseRowStore(ev);
00833     if ( store )
00834       row->SeekColumn(ev, inPos, outColumn, outYarn);
00835       
00836     outErr = ev->AsErr();
00837   }
00838   return outErr;
00839 }
00840 
00841 // } ----- end blob methods -----
00842 
00843 
00844 // } ===== end nsIMdbRow methods =====
00845 
00846 
00847 
00848 //3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
00849