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 _MORKENV_ 7 #define _MORKENV_ 1 8 9 #ifndef _MORK_ 10 # include "mork.h" 11 #endif 12 13 #ifndef _MORKOBJECT_ 14 # include "morkObject.h" 15 #endif 16 17 #ifndef _MORKPOOL_ 18 # include "morkPool.h" 19 #endif 20 21 // sean was here 22 #include "mozilla/Path.h" 23 #include "nsError.h" 24 25 // 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 26 27 #define morkDerived_kEnv /*i*/ 0x4576 /* ascii 'Ev' */ 28 29 // use NS error codes to make Mork easier to use with the rest of mozilla 30 #define morkEnv_kNoError NS_SUCCEEDED /* no error has happened */ 31 #define morkEnv_kNonEnvTypeError \ 32 NS_ERROR_FAILURE /* morkEnv::IsEnv() is false */ 33 34 #define morkEnv_kStubMethodOnlyError NS_ERROR_NO_INTERFACE 35 #define morkEnv_kOutOfMemoryError NS_ERROR_OUT_OF_MEMORY 36 #define morkEnv_kNilPointerError NS_ERROR_NULL_POINTER 37 #define morkEnv_kNewNonEnvError NS_ERROR_FAILURE 38 #define morkEnv_kNilEnvSlotError NS_ERROR_FAILURE 39 40 #define morkEnv_kBadFactoryError NS_ERROR_FACTORY_NOT_LOADED 41 #define morkEnv_kBadFactoryEnvError NS_ERROR_FACTORY_NOT_LOADED 42 #define morkEnv_kBadEnvError NS_ERROR_FAILURE 43 44 #define morkEnv_kNonHandleTypeError NS_ERROR_FAILURE 45 #define morkEnv_kNonOpenNodeError NS_ERROR_FAILURE 46 47 /* try NOT to leak all env instances */ 48 #define morkEnv_kWeakRefCountEnvBonus 0 49 50 /*| morkEnv: 51 |*/ 52 class morkEnv : public morkObject, public nsIMdbEnv { 53 using PathChar = mozilla::filesystem::Path::value_type; 54 NS_DECL_ISUPPORTS_INHERITED 55 56 // public: // slots inherited from morkObject (meant to inform only) 57 // nsIMdbHeap* mNode_Heap; 58 59 // mork_base mNode_Base; // must equal morkBase_kNode 60 // mork_derived mNode_Derived; // depends on specific node subclass 61 62 // mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead 63 // mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone 64 // mork_able mNode_Mutable; // can this node be modified? 65 // mork_load mNode_Load; // is this node clean or dirty? 66 67 // mork_uses mNode_Uses; // refcount for strong refs 68 // mork_refs mNode_Refs; // refcount for strong refs + weak refs 69 70 // mork_color mBead_Color; // ID for this bead 71 // morkHandle* mObject_Handle; // weak ref to handle for this object 72 73 public: // state is public because the entire Mork system is private 74 morkFactory* mEnv_Factory; // NON-refcounted factory 75 nsIMdbHeap* mEnv_Heap; // NON-refcounted heap 76 77 nsIMdbEnv* mEnv_SelfAsMdbEnv; 78 nsIMdbErrorHook* mEnv_ErrorHook; 79 80 morkPool* mEnv_HandlePool; // pool for re-using handles 81 82 mork_u2 mEnv_ErrorCount; 83 mork_u2 mEnv_WarningCount; 84 85 nsresult mEnv_ErrorCode; 86 87 mork_bool mEnv_DoTrace; 88 mork_able mEnv_AutoClear; 89 mork_bool mEnv_ShouldAbort; 90 mork_bool mEnv_BeVerbose; 91 mork_bool mEnv_OwnsHeap; 92 93 // { ===== begin morkNode interface ===== 94 public: // morkNode virtual methods 95 virtual void CloseMorkNode(morkEnv* ev) override; // CloseEnv() only if open 96 virtual ~morkEnv(); // assert that CloseEnv() executed earlier 97 98 // { ----- begin attribute methods ----- 99 NS_IMETHOD GetErrorCount(mdb_count* outCount, 100 mdb_bool* outShouldAbort) override; 101 NS_IMETHOD GetWarningCount(mdb_count* outCount, 102 mdb_bool* outShouldAbort) override; 103 104 NS_IMETHOD GetEnvBeVerbose(mdb_bool* outBeVerbose) override; 105 NS_IMETHOD SetEnvBeVerbose(mdb_bool inBeVerbose) override; 106 107 NS_IMETHOD GetDoTrace(mdb_bool* outDoTrace) override; 108 NS_IMETHOD SetDoTrace(mdb_bool inDoTrace) override; 109 110 NS_IMETHOD GetAutoClear(mdb_bool* outAutoClear) override; 111 NS_IMETHOD SetAutoClear(mdb_bool inAutoClear) override; 112 113 NS_IMETHOD GetErrorHook(nsIMdbErrorHook** acqErrorHook) override; 114 NS_IMETHOD SetErrorHook( 115 nsIMdbErrorHook* ioErrorHook) override; // becomes referenced 116 117 NS_IMETHOD GetHeap(nsIMdbHeap** acqHeap) override; 118 NS_IMETHOD SetHeap(nsIMdbHeap* ioHeap) override; // becomes referenced 119 // } ----- end attribute methods ----- 120 121 NS_IMETHOD ClearErrors() override; // clear errors beore re-entering db API 122 NS_IMETHOD ClearWarnings() override; // clear warnings 123 NS_IMETHOD ClearErrorsAndWarnings() override; // clear both errors & warnings 124 // } ===== end nsIMdbEnv methods ===== 125 public: // morkEnv construction & destruction 126 morkEnv(const morkUsage& inUsage, nsIMdbHeap* ioHeap, morkFactory* ioFactory, 127 nsIMdbHeap* ioSlotHeap); 128 morkEnv(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap, 129 nsIMdbEnv* inSelfAsMdbEnv, morkFactory* ioFactory, 130 nsIMdbHeap* ioSlotHeap); 131 void CloseEnv(morkEnv* ev); // called by CloseMorkNode(); 132 133 private: // copying is not allowed 134 morkEnv(const morkEnv& other); 135 morkEnv& operator=(const morkEnv& other); 136 137 public: // dynamic type identification IsEnv()138 mork_bool IsEnv() const { 139 return IsNode() && mNode_Derived == morkDerived_kEnv; 140 } 141 // } ===== end morkNode methods ===== 142 143 public: // utility env methods 144 mork_u1 HexToByte(mork_ch inFirstHex, mork_ch inSecondHex); 145 146 mork_size TokenAsHex(void* outBuf, mork_token inToken); 147 // TokenAsHex() is the same as sprintf(outBuf, "%lX", (long) inToken); 148 149 mork_size OidAsHex(void* outBuf, const mdbOid& inOid); 150 // sprintf(buf, "%lX:^%lX", (long) inOid.mOid_Id, (long) inOid.mOid_Scope); 151 152 PathChar* CopyString(nsIMdbHeap* ioHeap, const PathChar* inString); 153 void FreeString(nsIMdbHeap* ioHeap, PathChar* ioString); 154 void StringToYarn(const PathChar* inString, mdbYarn* outYarn); 155 156 public: // other env methods NewHandle(mork_size inSize)157 morkHandleFace* NewHandle(mork_size inSize) { 158 return mEnv_HandlePool->NewHandle(this, inSize, (morkZone*)0); 159 } 160 ZapHandle(morkHandleFace * ioHandle)161 void ZapHandle(morkHandleFace* ioHandle) { 162 mEnv_HandlePool->ZapHandle(this, ioHandle); 163 } 164 EnableAutoClear()165 void EnableAutoClear() { mEnv_AutoClear = morkAble_kEnabled; } DisableAutoClear()166 void DisableAutoClear() { mEnv_AutoClear = morkAble_kDisabled; } 167 DoAutoClear()168 mork_bool DoAutoClear() const { return mEnv_AutoClear == morkAble_kEnabled; } 169 170 void NewError(const char* inString); 171 void NewWarning(const char* inString); 172 173 void ClearMorkErrorsAndWarnings(); // clear both errors & warnings 174 void AutoClearMorkErrorsAndWarnings(); // clear if auto is enabled 175 176 void StubMethodOnlyError(); 177 void OutOfMemoryError(); 178 void NilPointerError(); 179 void NilPointerWarning(); 180 void CantMakeWhenBadError(); 181 void NewNonEnvError(); 182 void NilEnvSlotError(); 183 184 void NonEnvTypeError(morkEnv* ev); 185 186 // canonical env convenience methods to check for presence of errors: Good()187 mork_bool Good() const { return (mEnv_ErrorCount == 0); } Bad()188 mork_bool Bad() const { return (mEnv_ErrorCount != 0); } 189 AsMdbEnv()190 nsIMdbEnv* AsMdbEnv() { return (nsIMdbEnv*)this; } 191 static morkEnv* FromMdbEnv(nsIMdbEnv* ioEnv); // dynamic type checking 192 AsErr()193 nsresult AsErr() const { return mEnv_ErrorCode; } 194 195 public: // typesafe refcounting inlines calling inherited morkNode methods SlotWeakEnv(morkEnv * me,morkEnv * ev,morkEnv ** ioSlot)196 static void SlotWeakEnv(morkEnv* me, morkEnv* ev, morkEnv** ioSlot) { 197 morkNode::SlotWeakNode((morkNode*)me, ev, (morkNode**)ioSlot); 198 } 199 SlotStrongEnv(morkEnv * me,morkEnv * ev,morkEnv ** ioSlot)200 static void SlotStrongEnv(morkEnv* me, morkEnv* ev, morkEnv** ioSlot) { 201 morkNode::SlotStrongNode((morkNode*)me, ev, (morkNode**)ioSlot); 202 } 203 }; 204 205 #undef MOZ_ASSERT_TYPE_OK_FOR_REFCOUNTING 206 #ifdef MOZ_IS_DESTRUCTIBLE 207 # define MOZ_ASSERT_TYPE_OK_FOR_REFCOUNTING(X) \ 208 static_assert( \ 209 !MOZ_IS_DESTRUCTIBLE(X) || mozilla::IsSame<X, morkEnv>::value, \ 210 "Reference-counted class " #X \ 211 " should not have a public destructor. " \ 212 "Try to make this class's destructor non-public. If that is really " \ 213 "not possible, you can whitelist this class by providing a " \ 214 "HasDangerousPublicDestructor specialization for it."); 215 #else 216 # define MOZ_ASSERT_TYPE_OK_FOR_REFCOUNTING(X) 217 #endif 218 219 // 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 220 221 #endif /* _MORKENV_ */ 222