summaryrefslogtreecommitdiffstats
path: root/comm/mailnews/db/mork/morkFactory.h
blob: c04d478edf565480b14176807b340c93e8b49d53 (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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
/* -*- 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 _MORKFACTORY_
#define _MORKFACTORY_ 1

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

#ifndef _MORKENV_
#  include "morkEnv.h"
#endif

#ifndef _MORKOBJECT_
#  include "morkObject.h"
#endif

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

// 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789

class nsIMdbFactory;

#define morkDerived_kFactory /*i*/ 0x4663 /* ascii 'Fc' */
#define morkFactory_kWeakRefCountBonus 0  /* try NOT to leak all factories */

/*| morkFactory:
|*/
class morkFactory : public morkObject, public nsIMdbFactory {  // nsIMdbObject
  using PathChar = mozilla::filesystem::Path::value_type;

  // public: // slots inherited from morkObject (meant to inform only)
  // nsIMdbHeap*     mNode_Heap;
  // mork_able    mNode_Mutable; // can this node be modified?
  // mork_load    mNode_Load;    // is this node clean or dirty?
  // 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_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
  // morkHandle*  mObject_Handle;  // weak ref to handle for this object

 public:  // state is public because the entire Mork system is private
  morkEnv mFactory_Env;  // private env instance used internally
  orkinHeap mFactory_Heap;

  NS_DECL_ISUPPORTS_INHERITED
  // { ===== begin morkNode interface =====
 public:  // morkFactory virtual methods
  virtual void CloseMorkNode(
      morkEnv* ev) override;  // CloseFactory() only if open

  // { ===== begin nsIMdbFactory methods =====

  // { ----- begin file methods -----
  NS_IMETHOD OpenOldFile(nsIMdbEnv* ev, nsIMdbHeap* ioHeap,
                         const PathChar* inFilePath, mdb_bool inFrozen,
                         nsIMdbFile** acqFile) override;
  // Choose some subclass of nsIMdbFile to instantiate, in order to read
  // (and write if not frozen) the file known by inFilePath.  The file
  // returned should be open and ready for use, and presumably positioned
  // at the first byte position of the file.  The exact manner in which
  // files must be opened is considered a subclass specific detail, and
  // other portions or Mork source code don't want to know how it's done.

  NS_IMETHOD CreateNewFile(nsIMdbEnv* ev, nsIMdbHeap* ioHeap,
                           const PathChar* inFilePath,
                           nsIMdbFile** acqFile) override;
  // Choose some subclass of nsIMdbFile to instantiate, in order to read
  // (and write if not frozen) the file known by inFilePath.  The file
  // returned should be created and ready for use, and presumably positioned
  // at the first byte position of the file.  The exact manner in which
  // files must be opened is considered a subclass specific detail, and
  // other portions or Mork source code don't want to know how it's done.
  // } ----- end file methods -----

  // { ----- begin env methods -----
  NS_IMETHOD MakeEnv(nsIMdbHeap* ioHeap,
                     nsIMdbEnv** acqEnv) override;  // new env
  // ioHeap can be nil, causing a MakeHeap() style heap instance to be used
  // } ----- end env methods -----

  // { ----- begin heap methods -----
  NS_IMETHOD MakeHeap(nsIMdbEnv* ev,
                      nsIMdbHeap** acqHeap) override;  // new heap
  // } ----- end heap methods -----

  // { ----- begin row methods -----
  NS_IMETHOD MakeRow(nsIMdbEnv* ev, nsIMdbHeap* ioHeap,
                     nsIMdbRow** acqRow) override;  // new row
  // ioHeap can be nil, causing the heap associated with ev to be used
  // } ----- end row methods -----

  // { ----- begin port methods -----
  NS_IMETHOD CanOpenFilePort(
      nsIMdbEnv* ev,  // context
      // const char* inFilePath, // the file to investigate
      // const mdbYarn* inFirst512Bytes,
      nsIMdbFile* ioFile,    // db abstract file interface
      mdb_bool* outCanOpen,  // whether OpenFilePort() might succeed
      mdbYarn* outFormatVersion) override;  // informal file format description

  NS_IMETHOD OpenFilePort(
      nsIMdbEnv* ev,       // context
      nsIMdbHeap* ioHeap,  // can be nil to cause ev's heap attribute to be used
      // const char* inFilePath, // the file to open for readonly import
      nsIMdbFile* ioFile,                 // db abstract file interface
      const mdbOpenPolicy* inOpenPolicy,  // runtime policies for using db
      nsIMdbThumb** acqThumb)
      override;  // acquire thumb for incremental port open
  // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
  // then call nsIMdbFactory::ThumbToOpenPort() to get the port instance.

  NS_IMETHOD
  ThumbToOpenPort(           // redeeming a completed thumb from OpenFilePort()
      nsIMdbEnv* ev,         // context
      nsIMdbThumb* ioThumb,  // thumb from OpenFilePort() with done status
      nsIMdbPort** acqPort) override;  // acquire new port object
  // } ----- end port methods -----

  // { ----- begin store methods -----
  NS_IMETHOD CanOpenFileStore(
      nsIMdbEnv* ev,  // context
      // const char* inFilePath, // the file to investigate
      // const mdbYarn* inFirst512Bytes,
      nsIMdbFile* ioFile,           // db abstract file interface
      mdb_bool* outCanOpenAsStore,  // whether OpenFileStore() might succeed
      mdb_bool* outCanOpenAsPort,   // whether OpenFilePort() might succeed
      mdbYarn* outFormatVersion) override;  // informal file format description

  NS_IMETHOD OpenFileStore(  // open an existing database
      nsIMdbEnv* ev,         // context
      nsIMdbHeap* ioHeap,  // can be nil to cause ev's heap attribute to be used
      // const char* inFilePath, // the file to open for general db usage
      nsIMdbFile* ioFile,                 // db abstract file interface
      const mdbOpenPolicy* inOpenPolicy,  // runtime policies for using db
      nsIMdbThumb** acqThumb)
      override;  // acquire thumb for incremental store open
  // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
  // then call nsIMdbFactory::ThumbToOpenStore() to get the store instance.

  NS_IMETHOD
  ThumbToOpenStore(          // redeem completed thumb from OpenFileStore()
      nsIMdbEnv* ev,         // context
      nsIMdbThumb* ioThumb,  // thumb from OpenFileStore() with done status
      nsIMdbStore** acqStore) override;  // acquire new db store object

  NS_IMETHOD CreateNewFileStore(  // create a new db with minimal content
      nsIMdbEnv* ev,              // context
      nsIMdbHeap* ioHeap,  // can be nil to cause ev's heap attribute to be used
      // const char* inFilePath, // name of file which should not yet exist
      nsIMdbFile* ioFile,                 // db abstract file interface
      const mdbOpenPolicy* inOpenPolicy,  // runtime policies for using db
      nsIMdbStore** acqStore) override;   // acquire new db store object

  // } ----- end store methods -----

  // } ===== end nsIMdbFactory methods =====

 public:          // morkYarn construction & destruction
  morkFactory();  // uses orkinHeap
  explicit morkFactory(nsIMdbHeap* ioHeap);  // caller supplied heap
  morkFactory(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap);
  void CloseFactory(morkEnv* ev);  // called by CloseMorkNode();

 public:  // morkNode memory management operators
  void* operator new(size_t inSize) noexcept(true) {
    return ::operator new(inSize);
  }

  void* operator new(size_t inSize, nsIMdbHeap& ioHeap,
                     morkEnv* ev) noexcept(true) {
    return morkNode::MakeNew(inSize, ioHeap, ev);
  }

 private:  // copying is not allowed
  morkFactory(const morkFactory& other);
  morkFactory& operator=(const morkFactory& other);
  virtual ~morkFactory();  // assert that CloseFactory() executed earlier

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

 public:  // other factory methods
  void NonFactoryTypeError(morkEnv* ev);
  morkEnv* GetInternalFactoryEnv(nsresult* outErr);
  mork_bool CanOpenMorkTextFile(morkEnv* ev, nsIMdbFile* ioFile);

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

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

// 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789

#endif /* _MORKFACTORY_ */