summaryrefslogtreecommitdiffstats
path: root/comm/mailnews/db/mork/morkObject.h
blob: 9548c779d1da8207d9e5134f7c940e7896f5b1aa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-  */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef _MORKOBJECT_
#define _MORKOBJECT_ 1

#ifndef _MORK_
#  include "mork.h"
#endif

#ifndef _MORKNODE_
#  include "morkNode.h"
#endif

#ifndef _MORKBEAD_
#  include "morkBead.h"
#endif

#ifndef _MORKCONFIG_
#  include "morkConfig.h"
#endif

#ifndef _ORKINHEAP_
#  include "orkinHeap.h"
#endif

// 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789

#define morkDerived_kObject /*i*/ 0x6F42 /* ascii 'oB' */

/*| morkObject: subclass of morkNode that adds knowledge of db suite factory
**| and containing port to those objects that are exposed as instances of
**| nsIMdbObject in the public interface.
|*/
class morkObject : public morkBead, public nsIMdbObject {
  // public: // slots inherited from morkNode (meant to inform only)
  // nsIMdbHeap*    mNode_Heap;

  // mork_base      mNode_Base;     // must equal morkBase_kNode
  // mork_derived   mNode_Derived;  // depends on specific node subclass

  // mork_access    mNode_Access;   // kOpen, kClosing, kShut, or kDead
  // mork_usage     mNode_Usage;    // kHeap, kStack, kMember, kGlobal, kNone
  // mork_able      mNode_Mutable;  // can this node be modified?
  // mork_load      mNode_Load;     // is this node clean or dirty?

  // mork_uses      mNode_Uses;     // refcount for strong refs
  // mork_refs      mNode_Refs;     // refcount for strong refs + weak refs

  // mork_color      mBead_Color;   // ID for this bead

 public:  // state is public because the entire Mork system is private
  morkHandle* mObject_Handle;  // weak ref to handle for this object

  morkEnv* mMorkEnv;  // weak ref to environment this object created in.

  // { ===== begin morkNode interface =====
 public:
  virtual void CloseMorkNode(
      morkEnv* ev) override;  // CloseObject() only if open
#ifdef MORK_DEBUG_HEAP_STATS
  void operator delete(void* ioAddress, size_t size) {
    mork_u4* array = (mork_u4*)ioAddress;
    array -= 3;
    orkinHeap* heap = (orkinHeap*)*array;
    if (heap) heap->Free(nullptr, ioAddress);
  }
#endif

  NS_DECL_ISUPPORTS

  // { ----- begin attribute methods -----
  NS_IMETHOD IsFrozenMdbObject(nsIMdbEnv* ev, mdb_bool* outIsReadonly) override;
  // same as nsIMdbPort::GetIsPortReadonly() when this object is inside a port.
  // } ----- end attribute methods -----

  // { ----- begin factory methods -----
  NS_IMETHOD GetMdbFactory(nsIMdbEnv* ev, nsIMdbFactory** acqFactory) override;
  // } ----- end factory methods -----

  // { ----- begin ref counting for well-behaved cyclic graphs -----
  NS_IMETHOD GetWeakRefCount(nsIMdbEnv* ev,  // weak refs
                             mdb_count* outCount) override;
  NS_IMETHOD GetStrongRefCount(nsIMdbEnv* ev,  // strong refs
                               mdb_count* outCount) override;

  NS_IMETHOD AddWeakRef(nsIMdbEnv* ev) override;
#ifndef _MSC_VER
  // The first declaration of AddStrongRef is to suppress
  // -Werror,-Woverloaded-virtual.
  NS_IMETHOD_(mork_uses) AddStrongRef(morkEnv* ev) override;
#endif
  NS_IMETHOD_(mork_uses) AddStrongRef(nsIMdbEnv* ev) override;

  NS_IMETHOD CutWeakRef(nsIMdbEnv* ev) override;
#ifndef _MSC_VER
  // The first declaration of CutStrongRef is to suppress
  // -Werror,-Woverloaded-virtual.
  NS_IMETHOD_(mork_uses) CutStrongRef(morkEnv* ev) override;
#endif
  NS_IMETHOD CutStrongRef(nsIMdbEnv* ev) override;

  NS_IMETHOD CloseMdbObject(
      nsIMdbEnv* ev) override;  // called at strong refs zero
  NS_IMETHOD IsOpenMdbObject(nsIMdbEnv* ev, mdb_bool* outOpen) override;
  // } ----- end ref counting -----

 protected:  // special case construction of first env without preceding env
  morkObject(const morkUsage& inUsage, nsIMdbHeap* ioHeap,
             mork_color inBeadColor);
  virtual ~morkObject();  // assert that CloseObject() executed earlier

 public:  // morkEnv construction & destruction
  morkObject(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap,
             mork_color inBeadColor,
             morkHandle* ioHandle);  // ioHandle can be nil
  void CloseObject(morkEnv* ev);     // called by CloseMorkNode();

 private:  // copying is not allowed
  morkObject(const morkObject& other);
  morkObject& operator=(const morkObject& other);

 public:  // dynamic type identification
  mork_bool IsObject() const {
    return IsNode() && mNode_Derived == morkDerived_kObject;
  }
  // } ===== end morkNode methods =====

  // void NewNilHandleError(morkEnv* ev); // mObject_Handle is nil

 public:  // typesafe refcounting inlines calling inherited morkNode methods
  static void SlotWeakObject(morkObject* me, morkEnv* ev, morkObject** ioSlot) {
    morkNode::SlotWeakNode((morkNode*)me, ev, (morkNode**)ioSlot);
  }

  static void SlotStrongObject(morkObject* me, morkEnv* ev,
                               morkObject** ioSlot) {
    morkNode::SlotStrongNode((morkNode*)me, ev, (morkNode**)ioSlot);
  }
};

// 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789

#endif /* _MORKOBJECT_ */