Back to index

lightning-sunbird  0.9+nobinonly
morkCellObject.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 _MORKOBJECT_
00051 #include "morkObject.h"
00052 #endif
00053 
00054 #ifndef _MORKENV_
00055 #include "morkEnv.h"
00056 #endif
00057 
00058 #ifndef _MORKCELLOBJECT_
00059 #include "morkCellObject.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 _MORKCELL_
00071 #include "morkCell.h"
00072 #endif
00073 
00074 #ifndef _MORKSTORE_
00075 #include "morkStore.h"
00076 #endif
00077 
00078 //3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
00079 
00080 // ````` ````` ````` ````` ````` 
00081 // { ===== begin morkNode interface =====
00082 
00083 /*public virtual*/ void
00084 morkCellObject::CloseMorkNode(morkEnv* ev) // CloseCellObject() only if open
00085 {
00086   if ( this->IsOpenNode() )
00087   {
00088     this->MarkClosing();
00089     this->CloseCellObject(ev);
00090     this->MarkShut();
00091   }
00092 }
00093 
00094 /*public virtual*/
00095 morkCellObject::~morkCellObject() // assert CloseCellObject() executed earlier
00096 {
00097   CloseMorkNode(mMorkEnv);
00098   MORK_ASSERT(mCellObject_Row==0);
00099 }
00100 
00101 /*public non-poly*/
00102 morkCellObject::morkCellObject(morkEnv* ev, const morkUsage& inUsage,
00103   nsIMdbHeap* ioHeap, morkRow* ioRow, morkCell* ioCell,
00104   mork_column inCol, mork_pos inPos)
00105 : morkObject(ev, inUsage, ioHeap, morkColor_kNone, (morkHandle*) 0)
00106 , mCellObject_RowObject( 0 )
00107 , mCellObject_Row( 0 )
00108 , mCellObject_Cell( 0 )
00109 , mCellObject_Col( inCol )
00110 , mCellObject_RowSeed( 0 )
00111 , mCellObject_Pos( (mork_u2) inPos )
00112 {
00113   if ( ev->Good() )
00114   {
00115     if ( ioRow && ioCell )
00116     {
00117       if ( ioRow->IsRow() )
00118       {
00119         morkStore* store = ioRow->GetRowSpaceStore(ev);
00120         if ( store )
00121         {
00122           morkRowObject* rowObj = ioRow->AcquireRowObject(ev, store);
00123           if ( rowObj )
00124           {
00125             mCellObject_Row = ioRow;
00126             mCellObject_Cell = ioCell;
00127             mCellObject_RowSeed = ioRow->mRow_Seed;
00128             
00129             // morkRowObject::SlotStrongRowObject(rowObj, ev,
00130             //  &mCellObject_RowObject);
00131               
00132             mCellObject_RowObject = rowObj; // assume control of strong ref
00133           }
00134           if ( ev->Good() )
00135             mNode_Derived = morkDerived_kCellObject;
00136         }
00137       }
00138       else
00139         ioRow->NonRowTypeError(ev);
00140     }
00141     else
00142       ev->NilPointerError();
00143   }
00144 }
00145 
00146 NS_IMPL_ISUPPORTS_INHERITED1(morkCellObject, morkObject, nsIMdbCell)
00147 
00148 /*public non-poly*/ void
00149 morkCellObject::CloseCellObject(morkEnv* ev) // called by CloseMorkNode();
00150 {
00151   if ( this )
00152   {
00153     if ( this->IsNode() )
00154     {
00155       NS_RELEASE(mCellObject_RowObject);
00156       mCellObject_Row = 0;
00157       mCellObject_Cell = 0;
00158       mCellObject_RowSeed = 0;
00159       this->CloseObject(ev);
00160       this->MarkShut();
00161     }
00162     else
00163       this->NonNodeError(ev);
00164   }
00165   else
00166     ev->NilPointerError();
00167 }
00168 
00169 // } ===== end morkNode methods =====
00170 // ````` ````` ````` ````` ````` 
00171 
00172 mork_bool
00173 morkCellObject::ResyncWithRow(morkEnv* ev)
00174 {
00175   morkRow* row = mCellObject_Row;
00176   mork_pos pos = 0;
00177   morkCell* cell = row->GetCell(ev, mCellObject_Col, &pos);
00178   if ( cell )
00179   {
00180     mCellObject_Pos = (mork_u2) pos;
00181     mCellObject_Cell = cell;
00182     mCellObject_RowSeed = row->mRow_Seed;
00183   }
00184   else
00185   {
00186     mCellObject_Cell = 0;
00187     this->MissingRowColumnError(ev);
00188   }
00189   return ev->Good();
00190 }
00191 
00192 morkAtom*
00193 morkCellObject::GetCellAtom(morkEnv* ev) const
00194 {
00195   morkCell* cell = mCellObject_Cell;
00196   if ( cell )
00197     return cell->GetAtom();
00198   else
00199     this->NilCellError(ev);
00200     
00201   return (morkAtom*) 0;
00202 }
00203 
00204 /*static*/ void
00205 morkCellObject::WrongRowObjectRowError(morkEnv* ev)
00206 {
00207   ev->NewError("mCellObject_Row != mCellObject_RowObject->mRowObject_Row");
00208 }
00209 
00210 /*static*/ void
00211 morkCellObject::NilRowError(morkEnv* ev)
00212 {
00213   ev->NewError("nil mCellObject_Row");
00214 }
00215 
00216 /*static*/ void
00217 morkCellObject::NilRowObjectError(morkEnv* ev)
00218 {
00219   ev->NewError("nil mCellObject_RowObject");
00220 }
00221 
00222 /*static*/ void
00223 morkCellObject::NilCellError(morkEnv* ev)
00224 {
00225   ev->NewError("nil mCellObject_Cell");
00226 }
00227 
00228 /*static*/ void
00229 morkCellObject::NonCellObjectTypeError(morkEnv* ev)
00230 {
00231   ev->NewError("non morkCellObject");
00232 }
00233 
00234 /*static*/ void
00235 morkCellObject::MissingRowColumnError(morkEnv* ev)
00236 {
00237   ev->NewError("mCellObject_Col not in mCellObject_Row");
00238 }
00239 
00240 nsIMdbCell*
00241 morkCellObject::AcquireCellHandle(morkEnv* ev)
00242 {
00243   nsIMdbCell* outCell = this;
00244   NS_ADDREF(outCell);
00245   return outCell;
00246 }
00247 
00248 
00249 morkEnv*
00250 morkCellObject::CanUseCell(nsIMdbEnv* mev, mork_bool inMutable,
00251   mdb_err* outErr, morkCell** outCell) 
00252 {
00253   morkEnv* outEnv = 0;
00254   morkCell* cell = 0;
00255   morkEnv* ev = morkEnv::FromMdbEnv(mev);
00256   if ( ev )
00257   {
00258     if ( IsCellObject() )
00259     {
00260       if ( IsMutable() || !inMutable )
00261       {
00262         morkRowObject* rowObj = mCellObject_RowObject;
00263         if ( rowObj )
00264         {
00265           morkRow* row = mCellObject_Row;
00266           if ( row )
00267           {
00268             if ( rowObj->mRowObject_Row == row )
00269             {
00270               mork_u2 oldSeed = mCellObject_RowSeed;
00271               if ( row->mRow_Seed == oldSeed || ResyncWithRow(ev) )
00272               {
00273                 cell = mCellObject_Cell;
00274                 if ( cell )
00275                 {
00276                   outEnv = ev;
00277                 }
00278                 else
00279                   NilCellError(ev);
00280               }
00281             }
00282             else
00283               WrongRowObjectRowError(ev);
00284           }
00285           else
00286             NilRowError(ev);
00287         }
00288         else
00289           NilRowObjectError(ev);
00290       }
00291       else
00292         NonMutableNodeError(ev);
00293     }
00294     else
00295       NonCellObjectTypeError(ev);
00296   }
00297   *outErr = ev->AsErr();
00298   MORK_ASSERT(outEnv);
00299   *outCell = cell;
00300   
00301   return outEnv;
00302 }
00303 
00304 // { ----- begin attribute methods -----
00305 NS_IMETHODIMP morkCellObject::SetBlob(nsIMdbEnv* /* mev */,
00306   nsIMdbBlob* /* ioBlob */)
00307 {
00308   NS_ASSERTION(PR_FALSE, "not implemented");
00309   return NS_ERROR_NOT_IMPLEMENTED;
00310 } // reads inBlob slots
00311 
00312 // when inBlob is in the same suite, this might be fastest cell-to-cell
00313 
00314 NS_IMETHODIMP morkCellObject::ClearBlob( // make empty (so content has zero length)
00315   nsIMdbEnv*  /* mev */)
00316 {
00317   NS_ASSERTION(PR_FALSE, "not implemented");
00318   return NS_ERROR_NOT_IMPLEMENTED;
00319   // remember row->MaybeDirtySpaceStoreAndRow();
00320 }
00321 // clearing a yarn is like SetYarn() with empty yarn instance content
00322 
00323 NS_IMETHODIMP morkCellObject::GetBlobFill(nsIMdbEnv* mev,
00324   mdb_fill* outFill)
00325 // Same value that would be put into mYarn_Fill, if one called GetYarn()
00326 // with a yarn instance that had mYarn_Buf==nil and mYarn_Size==0.
00327 {
00328   NS_ASSERTION(PR_FALSE, "not implemented");
00329   return NS_ERROR_NOT_IMPLEMENTED;
00330 }  // size of blob 
00331 
00332 NS_IMETHODIMP morkCellObject::SetYarn(nsIMdbEnv* mev, 
00333   const mdbYarn* inYarn)
00334 {
00335   mdb_err outErr = 0;
00336   morkCell* cell = 0;
00337   morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue,
00338     &outErr, &cell);
00339   if ( ev )
00340   {
00341     morkRow* row = mCellObject_Row;
00342     if ( row )
00343     {
00344       morkStore* store = row->GetRowSpaceStore(ev);
00345       if ( store )
00346       {
00347         cell->SetYarn(ev, inYarn, store);
00348         if ( row->IsRowClean() && store->mStore_CanDirty )
00349           row->MaybeDirtySpaceStoreAndRow();
00350       }
00351     }
00352     else
00353       ev->NilPointerError();
00354 
00355     outErr = ev->AsErr();
00356   }
00357     
00358   return outErr;
00359 }   // reads from yarn slots
00360 // make this text object contain content from the yarn's buffer
00361 
00362 NS_IMETHODIMP morkCellObject::GetYarn(nsIMdbEnv* mev, 
00363   mdbYarn* outYarn)
00364 {
00365   mdb_err outErr = 0;
00366   morkCell* cell = 0;
00367   morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue,
00368     &outErr, &cell);
00369   if ( ev )
00370   {
00371     morkAtom* atom = cell->GetAtom();
00372     atom->GetYarn(outYarn);
00373     outErr = ev->AsErr();
00374   }
00375     
00376   return outErr;
00377 }  // writes some yarn slots 
00378 // copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form
00379 
00380 NS_IMETHODIMP morkCellObject::AliasYarn(nsIMdbEnv* mev, 
00381   mdbYarn* outYarn)
00382 {
00383   mdb_err outErr = 0;
00384   morkCell* cell = 0;
00385   morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue,
00386     &outErr, &cell);
00387   if ( ev )
00388   {
00389     morkAtom* atom = cell->GetAtom();
00390     atom->AliasYarn(outYarn);
00391     outErr = ev->AsErr();
00392   }
00393     
00394   return outErr;
00395 } // writes ALL yarn slots
00396 
00397 // } ----- end attribute methods -----
00398 
00399 // } ===== end nsIMdbBlob methods =====
00400 
00401 // { ===== begin nsIMdbCell methods =====
00402 
00403 // { ----- begin attribute methods -----
00404 NS_IMETHODIMP morkCellObject::SetColumn(nsIMdbEnv* mev, mdb_column inColumn)
00405 {
00406   NS_ASSERTION(PR_FALSE, "not implemented");
00407   return NS_ERROR_NOT_IMPLEMENTED;
00408   // remember row->MaybeDirtySpaceStoreAndRow();
00409 } 
00410 
00411 NS_IMETHODIMP morkCellObject::GetColumn(nsIMdbEnv* mev, mdb_column* outColumn)
00412 {
00413   mdb_err outErr = 0;
00414   mdb_column col = 0;
00415   morkCell* cell = 0;
00416   morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue,
00417     &outErr, &cell);
00418   if ( ev )
00419   {
00420     col = mCellObject_Col;
00421     outErr = ev->AsErr();
00422   }
00423   if ( outColumn )
00424     *outColumn = col;
00425   return outErr;
00426 }
00427 
00428 NS_IMETHODIMP morkCellObject::GetCellInfo(  // all cell metainfo except actual content
00429   nsIMdbEnv* mev, 
00430   mdb_column* outColumn,           // the column in the containing row
00431   mdb_fill*   outBlobFill,         // the size of text content in bytes
00432   mdbOid*     outChildOid,         // oid of possible row or table child
00433   mdb_bool*   outIsRowChild)  // nonzero if child, and a row child
00434 // Checking all cell metainfo is a good way to avoid forcing a large cell
00435 // in to memory when you don't actually want to use the content.
00436 {
00437   NS_ASSERTION(PR_FALSE, "not implemented");
00438   return NS_ERROR_NOT_IMPLEMENTED;
00439 }
00440 
00441 
00442 NS_IMETHODIMP morkCellObject::GetRow(nsIMdbEnv* mev, // parent row for this cell
00443   nsIMdbRow** acqRow)
00444 {
00445   mdb_err outErr = 0;
00446   nsIMdbRow* outRow = 0;
00447   morkCell* cell = 0;
00448   morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue,
00449     &outErr, &cell);
00450   if ( ev )
00451   {
00452     outRow = mCellObject_RowObject->AcquireRowHandle(ev);
00453     
00454     outErr = ev->AsErr();
00455   }
00456   if ( acqRow )
00457     *acqRow = outRow;
00458   return outErr;
00459 }
00460 
00461 NS_IMETHODIMP morkCellObject::GetPort(nsIMdbEnv* mev, // port containing cell
00462   nsIMdbPort** acqPort)
00463 {
00464   mdb_err outErr = 0;
00465   nsIMdbPort* outPort = 0;
00466   morkCell* cell = 0;
00467   morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue,
00468     &outErr, &cell);
00469   if ( ev )
00470   {
00471     if ( mCellObject_Row )
00472     {
00473       morkStore* store = mCellObject_Row->GetRowSpaceStore(ev);
00474       if ( store )
00475         outPort = store->AcquireStoreHandle(ev);
00476     }
00477     else
00478       ev->NilPointerError();
00479 
00480     outErr = ev->AsErr();
00481   }
00482   if ( acqPort )
00483     *acqPort = outPort;
00484   return outErr;
00485 }
00486 // } ----- end attribute methods -----
00487 
00488 // { ----- begin children methods -----
00489 NS_IMETHODIMP morkCellObject::HasAnyChild( // does cell have a child instead of text?
00490   nsIMdbEnv* mev,
00491   mdbOid* outOid,  // out id of row or table (or unbound if no child)
00492   mdb_bool* outIsRow) // nonzero if child is a row (rather than a table)
00493 {
00494   mdb_err outErr = 0;
00495   mdb_bool isRow = morkBool_kFalse;
00496   outOid->mOid_Scope = 0;
00497   outOid->mOid_Id = morkId_kMinusOne;
00498   morkCell* cell = 0;
00499   morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue,
00500     &outErr, &cell);
00501   if ( ev )
00502   {
00503     morkAtom* atom = GetCellAtom(ev);
00504     if ( atom )
00505     {
00506       isRow = atom->IsRowOid();
00507       if ( isRow || atom->IsTableOid() )
00508         *outOid = ((morkOidAtom*) atom)->mOidAtom_Oid;
00509     }
00510       
00511     outErr = ev->AsErr();
00512   }
00513   if ( outIsRow )
00514     *outIsRow = isRow;
00515     
00516   return outErr;
00517 }
00518 
00519 NS_IMETHODIMP morkCellObject::GetAnyChild( // access table of specific attribute
00520   nsIMdbEnv* mev, // context
00521   nsIMdbRow** acqRow, // child row (or null)
00522   nsIMdbTable** acqTable) // child table (or null)
00523 {
00524   NS_ASSERTION(PR_FALSE, "not implemented");
00525   return NS_ERROR_NOT_IMPLEMENTED;
00526 }
00527 
00528 
00529 NS_IMETHODIMP morkCellObject::SetChildRow( // access table of specific attribute
00530   nsIMdbEnv* mev, // context
00531   nsIMdbRow* ioRow)
00532 {
00533   NS_ASSERTION(PR_FALSE, "not implemented");
00534   return NS_ERROR_NOT_IMPLEMENTED;
00535 } // inRow must be bound inside this same db port
00536 
00537 NS_IMETHODIMP morkCellObject::GetChildRow( // access row of specific attribute
00538   nsIMdbEnv* mev, // context
00539   nsIMdbRow** acqRow) // acquire child row (or nil if no child)
00540 {
00541   NS_ASSERTION(PR_FALSE, "not implemented");
00542   return NS_ERROR_NOT_IMPLEMENTED;
00543 }
00544 
00545 
00546 NS_IMETHODIMP morkCellObject::SetChildTable( // access table of specific attribute
00547   nsIMdbEnv* mev, // context
00548   nsIMdbTable* inTable) // table must be bound inside this same db port
00549 {
00550   NS_ASSERTION(PR_FALSE, "not implemented");
00551   return NS_ERROR_NOT_IMPLEMENTED;
00552   // remember row->MaybeDirtySpaceStoreAndRow();
00553 }
00554 
00555 NS_IMETHODIMP morkCellObject::GetChildTable( // access table of specific attribute
00556   nsIMdbEnv* mev, // context
00557   nsIMdbTable** acqTable) // acquire child tabdle (or nil if no chil)
00558 {
00559   NS_ASSERTION(PR_FALSE, "not implemented");
00560   return NS_ERROR_NOT_IMPLEMENTED;
00561 }
00562 // } ----- end children methods -----
00563 
00564 // } ===== end nsIMdbCell methods =====
00565 
00566 
00567 //3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789