1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #ifndef _MORKCELL_ 7 #define _MORKCELL_ 1 8 9 #ifndef _MORK_ 10 # include "mork.h" 11 #endif 12 13 // 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 14 15 #define morkDelta_kShift 8 /* 8 bit shift */ 16 #define morkDelta_kChangeMask 0x0FF /* low 8 bit mask */ 17 #define morkDelta_kColumnMask (~(mork_column)morkDelta_kChangeMask) 18 #define morkDelta_Init(self, cl, ch) \ 19 ((self) = ((cl) << morkDelta_kShift) | (ch)) 20 #define morkDelta_Change(self) ((mork_change)((self)&morkDelta_kChangeMask)) 21 #define morkDelta_Column(self) ((self) >> morkDelta_kShift) 22 23 class morkCell { // minimal cell format 24 25 public: 26 mork_delta mCell_Delta; // encoding of both column and change 27 morkAtom* mCell_Atom; // content in this cell 28 29 public: morkCell()30 morkCell() : mCell_Delta(0), mCell_Atom(0) {} 31 morkCell(const morkCell & c)32 morkCell(const morkCell& c) 33 : mCell_Delta(c.mCell_Delta), mCell_Atom(c.mCell_Atom) {} 34 35 // note if ioAtom is non-nil, caller needs to call ioAtom->AddCellUse(): morkCell(mork_column inCol,mork_change inChange,morkAtom * ioAtom)36 morkCell(mork_column inCol, mork_change inChange, morkAtom* ioAtom) { 37 morkDelta_Init(mCell_Delta, inCol, inChange); 38 mCell_Atom = ioAtom; 39 } 40 41 // note if ioAtom is non-nil, caller needs to call ioAtom->AddCellUse(): Init(mork_column inCol,mork_change inChange,morkAtom * ioAtom)42 void Init(mork_column inCol, mork_change inChange, morkAtom* ioAtom) { 43 morkDelta_Init(mCell_Delta, inCol, inChange); 44 mCell_Atom = ioAtom; 45 } 46 GetColumn()47 mork_column GetColumn() const { return morkDelta_Column(mCell_Delta); } GetChange()48 mork_change GetChange() const { return morkDelta_Change(mCell_Delta); } 49 IsCellClean()50 mork_bool IsCellClean() const { return GetChange() == morkChange_kNil; } IsCellDirty()51 mork_bool IsCellDirty() const { return GetChange() != morkChange_kNil; } 52 53 void SetCellClean(); // set change to kNil 54 void SetCellDirty(); // set change to kAdd 55 SetCellColumnDirty(mork_column inCol)56 void SetCellColumnDirty(mork_column inCol) { 57 this->SetColumnAndChange(inCol, morkChange_kAdd); 58 } 59 SetCellColumnClean(mork_column inCol)60 void SetCellColumnClean(mork_column inCol) { 61 this->SetColumnAndChange(inCol, morkChange_kNil); 62 } 63 SetColumnAndChange(mork_column inCol,mork_change inChange)64 void SetColumnAndChange(mork_column inCol, mork_change inChange) { 65 morkDelta_Init(mCell_Delta, inCol, inChange); 66 } 67 GetAtom()68 morkAtom* GetAtom() { return mCell_Atom; } 69 70 void SetAtom(morkEnv* ev, morkAtom* ioAtom, morkPool* ioPool); 71 // SetAtom() "acquires" the new ioAtom if non-nil, by calling AddCellUse() 72 // to increase the refcount, and puts ioAtom into mCell_Atom. If the old 73 // atom in mCell_Atom is non-nil, then it is "released" first by a call to 74 // CutCellUse(), and if the use count then becomes zero, then the old atom 75 // is deallocated by returning it to the pool ioPool. (And this is 76 // why ioPool is a parameter to this method.) Note that ioAtom can be nil 77 // to cause the cell to refer to nothing, and the old atom in mCell_Atom 78 // can also be nil, and all the atom refcounting is handled correctly. 79 // 80 // Note that if ioAtom was just created, it typically has a zero use count 81 // before calling SetAtom(). But use count is one higher after SetAtom(). 82 83 void SetYarn(morkEnv* ev, const mdbYarn* inYarn, morkStore* ioStore); 84 85 void AliasYarn(morkEnv* ev, mdbYarn* outYarn) const; 86 void GetYarn(morkEnv* ev, mdbYarn* outYarn) const; 87 }; 88 89 // 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 90 91 #endif /* _MORKCELL_ */ 92