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 _MORKNODEMAP_
7 #define _MORKNODEMAP_ 1
8 
9 #ifndef _MORK_
10 #  include "mork.h"
11 #endif
12 
13 #ifndef _MORKNODE_
14 #  include "morkNode.h"
15 #endif
16 
17 #ifndef _MORKMAP_
18 #  include "morkMap.h"
19 #endif
20 
21 #ifndef _MORKINTMAP_
22 #  include "morkIntMap.h"
23 #endif
24 
25 // 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
26 
27 #define morkDerived_kNodeMap /*i*/ 0x6E4D /* ascii 'nM' */
28 
29 #define morkNodeMap_kStartSlotCount 512
30 
31 /*| morkNodeMap: maps mork_token -> morkNode
32 |*/
33 class morkNodeMap : public morkIntMap {  // for mapping tokens to nodes
34 
35   // { ===== begin morkNode interface =====
36  public:  // morkNode virtual methods
37   virtual void CloseMorkNode(
38       morkEnv* ev) override;  // CloseNodeMap() only if open
39   virtual ~morkNodeMap();     // assert that CloseNodeMap() executed earlier
40 
41  public:  // morkMap construction & destruction
42   morkNodeMap(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap,
43               nsIMdbHeap* ioSlotHeap);
44   void CloseNodeMap(morkEnv* ev);  // called by CloseMorkNode();
45 
46  public:  // dynamic type identification
IsNodeMap()47   mork_bool IsNodeMap() const {
48     return IsNode() && mNode_Derived == morkDerived_kNodeMap;
49   }
50   // } ===== end morkNode methods =====
51 
52   // { ===== begin morkMap poly interface =====
53   // use the Equal() and Hash() for mork_u4 inherited from morkIntMap
54   // } ===== end morkMap poly interface =====
55 
56  protected:  // we want all subclasses to provide typesafe wrappers:
57   mork_bool AddNode(morkEnv* ev, mork_token inToken, morkNode* ioNode);
58   // the AddNode() boolean return equals ev->Good().
59 
60   mork_bool CutNode(morkEnv* ev, mork_token inToken);
61   // The CutNode() boolean return indicates whether removal happened.
62 
63   morkNode* GetNode(morkEnv* ev, mork_token inToken);
64   // Note the returned node does NOT have an increase in refcount for this.
65 
66   mork_num CutAllNodes(morkEnv* ev);
67   // CutAllNodes() releases all the reference node values.
68 };
69 
70 class morkNodeMapIter : public morkMapIter {  // typesafe wrapper class
71 
72  public:
morkNodeMapIter(morkEnv * ev,morkNodeMap * ioMap)73   morkNodeMapIter(morkEnv* ev, morkNodeMap* ioMap) : morkMapIter(ev, ioMap) {}
74 
morkNodeMapIter()75   morkNodeMapIter() : morkMapIter() {}
InitNodeMapIter(morkEnv * ev,morkNodeMap * ioMap)76   void InitNodeMapIter(morkEnv* ev, morkNodeMap* ioMap) {
77     this->InitMapIter(ev, ioMap);
78   }
79 
FirstNode(morkEnv * ev,mork_token * outToken,morkNode ** outNode)80   mork_change* FirstNode(morkEnv* ev, mork_token* outToken,
81                          morkNode** outNode) {
82     return this->First(ev, outToken, outNode);
83   }
84 
NextNode(morkEnv * ev,mork_token * outToken,morkNode ** outNode)85   mork_change* NextNode(morkEnv* ev, mork_token* outToken, morkNode** outNode) {
86     return this->Next(ev, outToken, outNode);
87   }
88 
HereNode(morkEnv * ev,mork_token * outToken,morkNode ** outNode)89   mork_change* HereNode(morkEnv* ev, mork_token* outToken, morkNode** outNode) {
90     return this->Here(ev, outToken, outNode);
91   }
92 
CutHereNode(morkEnv * ev,mork_token * outToken,morkNode ** outNode)93   mork_change* CutHereNode(morkEnv* ev, mork_token* outToken,
94                            morkNode** outNode) {
95     return this->CutHere(ev, outToken, outNode);
96   }
97 };
98 
99 // 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
100 
101 #endif /* _MORKNODEMAP_ */
102