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