From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- comm/mailnews/db/mork/morkEnv.cpp | 519 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 519 insertions(+) create mode 100644 comm/mailnews/db/mork/morkEnv.cpp (limited to 'comm/mailnews/db/mork/morkEnv.cpp') diff --git a/comm/mailnews/db/mork/morkEnv.cpp b/comm/mailnews/db/mork/morkEnv.cpp new file mode 100644 index 0000000000..c7c67f1e9e --- /dev/null +++ b/comm/mailnews/db/mork/morkEnv.cpp @@ -0,0 +1,519 @@ +/* -*- 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 _MDB_ +# include "mdb.h" +#endif + +#ifndef _MORK_ +# include "mork.h" +#endif + +#ifndef _MORKNODE_ +# include "morkNode.h" +#endif + +#ifndef _MORKCH_ +# include "morkCh.h" +#endif + +#ifndef _MORKENV_ +# include "morkEnv.h" +#endif + +#ifndef _MORKFACTORY_ +# include "morkFactory.h" +#endif + +#include "mozilla/Char16.h" + +// 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 + +// ````` ````` ````` ````` ````` +// { ===== begin morkNode interface ===== + +/*public virtual*/ void morkEnv::CloseMorkNode( + morkEnv* ev) /*i*/ // CloseEnv() only if open +{ + if (this->IsOpenNode()) { + this->MarkClosing(); + this->CloseEnv(ev); + this->MarkShut(); + } +} + +/*public virtual*/ +morkEnv::~morkEnv() /*i*/ // assert CloseEnv() executed earlier +{ + CloseMorkNode(mMorkEnv); + if (mEnv_Heap) { + mork_bool ownsHeap = mEnv_OwnsHeap; + nsIMdbHeap* saveHeap = mEnv_Heap; + + if (ownsHeap) { +#ifdef MORK_DEBUG_HEAP_STATS + printf("%d blocks remaining \n", + ((orkinHeap*)saveHeap)->HeapBlockCount()); + mork_u4* array = (mork_u4*)this; + array -= 3; + // null out heap ptr in mem block so we won't crash trying to use it to + // delete the env. + *array = nullptr; +#endif // MORK_DEBUG_HEAP_STATS + // whoops, this is our heap - hmm. Can't delete it, or not allocate env's + // from an orkinHeap. + delete saveHeap; + } + } + // MORK_ASSERT(mEnv_SelfAsMdbEnv==0); + MORK_ASSERT(mEnv_ErrorHook == 0); +} + +/* choose morkBool_kTrue or morkBool_kFalse for kBeVerbose: */ +#define morkEnv_kBeVerbose morkBool_kFalse + +/*public non-poly*/ +morkEnv::morkEnv(const morkUsage& inUsage, nsIMdbHeap* ioHeap, + morkFactory* ioFactory, nsIMdbHeap* ioSlotHeap) + : morkObject(inUsage, ioHeap, morkColor_kNone), + mEnv_Factory(ioFactory), + mEnv_Heap(ioSlotHeap) + + , + mEnv_SelfAsMdbEnv(0), + mEnv_ErrorHook(0), + mEnv_HandlePool(0) + + , + mEnv_ErrorCount(0), + mEnv_WarningCount(0) + + , + mEnv_ErrorCode(NS_OK) + + , + mEnv_DoTrace(morkBool_kFalse), + mEnv_AutoClear(morkAble_kDisabled), + mEnv_ShouldAbort(morkBool_kFalse), + mEnv_BeVerbose(morkEnv_kBeVerbose), + mEnv_OwnsHeap(morkBool_kFalse) { + MORK_ASSERT(ioSlotHeap && ioFactory); + if (ioSlotHeap) { + // mEnv_Heap is NOT refcounted: + // nsIMdbHeap_SlotStrongHeap(ioSlotHeap, this, &mEnv_Heap); + + mEnv_HandlePool = + new morkPool(morkUsage::kGlobal, (nsIMdbHeap*)0, ioSlotHeap); + + MORK_ASSERT(mEnv_HandlePool); + if (mEnv_HandlePool && this->Good()) { + mNode_Derived = morkDerived_kEnv; + mNode_Refs += morkEnv_kWeakRefCountEnvBonus; + } + } +} + +/*public non-poly*/ +morkEnv::morkEnv(morkEnv* ev, /*i*/ + const morkUsage& inUsage, nsIMdbHeap* ioHeap, + nsIMdbEnv* inSelfAsMdbEnv, morkFactory* ioFactory, + nsIMdbHeap* ioSlotHeap) + : morkObject(ev, inUsage, ioHeap, morkColor_kNone, (morkHandle*)0), + mEnv_Factory(ioFactory), + mEnv_Heap(ioSlotHeap) + + , + mEnv_SelfAsMdbEnv(inSelfAsMdbEnv), + mEnv_ErrorHook(0), + mEnv_HandlePool(0) + + , + mEnv_ErrorCount(0), + mEnv_WarningCount(0) + + , + mEnv_ErrorCode(NS_OK) + + , + mEnv_DoTrace(morkBool_kFalse), + mEnv_AutoClear(morkAble_kDisabled), + mEnv_ShouldAbort(morkBool_kFalse), + mEnv_BeVerbose(morkEnv_kBeVerbose), + mEnv_OwnsHeap(morkBool_kFalse) { + // $$$ do we need to refcount the inSelfAsMdbEnv nsIMdbEnv?? + + if (ioFactory && inSelfAsMdbEnv && ioSlotHeap) { + // mEnv_Heap is NOT refcounted: + // nsIMdbHeap_SlotStrongHeap(ioSlotHeap, ev, &mEnv_Heap); + + mEnv_HandlePool = new (*ioSlotHeap, ev) + morkPool(ev, morkUsage::kHeap, ioSlotHeap, ioSlotHeap); + + MORK_ASSERT(mEnv_HandlePool); + if (mEnv_HandlePool && ev->Good()) { + mNode_Derived = morkDerived_kEnv; + mNode_Refs += morkEnv_kWeakRefCountEnvBonus; + } + } else + ev->NilPointerError(); +} + +NS_IMPL_ISUPPORTS_INHERITED(morkEnv, morkObject, nsIMdbEnv) +/*public non-poly*/ void morkEnv::CloseEnv( + morkEnv* ev) /*i*/ // called by CloseMorkNode(); +{ + if (this->IsNode()) { + // $$$ release mEnv_SelfAsMdbEnv?? + // $$$ release mEnv_ErrorHook?? + + mEnv_SelfAsMdbEnv = 0; + mEnv_ErrorHook = 0; + + morkPool* savePool = mEnv_HandlePool; + morkPool::SlotStrongPool((morkPool*)0, ev, &mEnv_HandlePool); + // free the pool + if (mEnv_SelfAsMdbEnv) { + if (savePool && mEnv_Heap) mEnv_Heap->Free(this->AsMdbEnv(), savePool); + } else { + if (savePool) { + if (savePool->IsOpenNode()) savePool->CloseMorkNode(ev); + delete savePool; + } + // how do we free this? might need to get rid of asserts. + } + // mEnv_Factory is NOT refcounted + + this->MarkShut(); + } else + this->NonNodeError(ev); +} + +// } ===== end morkNode methods ===== +// ````` ````` ````` ````` ````` + +mork_size morkEnv::OidAsHex(void* outBuf, const mdbOid& inOid) +// sprintf(buf, "%lX:^%lX", (long) inOid.mOid_Id, (long) inOid.mOid_Scope); +{ + mork_u1* p = (mork_u1*)outBuf; + mork_size outSize = this->TokenAsHex(p, inOid.mOid_Id); + p += outSize; + *p++ = ':'; + + mork_scope scope = inOid.mOid_Scope; + if (scope < 0x80 && morkCh_IsName((mork_ch)scope)) { + *p++ = (mork_u1)scope; + *p = 0; // null termination + outSize += 2; + } else { + *p++ = '^'; + mork_size scopeSize = this->TokenAsHex(p, scope); + outSize += scopeSize + 2; + } + return outSize; +} + +mork_u1 morkEnv::HexToByte(mork_ch inFirstHex, mork_ch inSecondHex) { + mork_u1 hi = 0; // high four hex bits + mork_flags f = morkCh_GetFlags(inFirstHex); + if (morkFlags_IsDigit(f)) + hi = (mork_u1)(inFirstHex - (mork_ch)'0'); + else if (morkFlags_IsUpper(f)) + hi = (mork_u1)((inFirstHex - (mork_ch)'A') + 10); + else if (morkFlags_IsLower(f)) + hi = (mork_u1)((inFirstHex - (mork_ch)'a') + 10); + + mork_u1 lo = 0; // low four hex bits + f = morkCh_GetFlags(inSecondHex); + if (morkFlags_IsDigit(f)) + lo = (mork_u1)(inSecondHex - (mork_ch)'0'); + else if (morkFlags_IsUpper(f)) + lo = (mork_u1)((inSecondHex - (mork_ch)'A') + 10); + else if (morkFlags_IsLower(f)) + lo = (mork_u1)((inSecondHex - (mork_ch)'a') + 10); + + return (mork_u1)((hi << 4) | lo); +} + +// TokenAsHex() is the same as sprintf(outBuf, "%lX", (long) inToken); +// Writes up to 32 hex digits, plus a NUL-terminator. So outBuf must +// be at least 33 bytes. +// Return value is number of characters written, excluding the NUL. +mork_size morkEnv::TokenAsHex(void* outBuf, mork_token inToken) { + static const char morkEnv_kHexDigits[] = "0123456789ABCDEF"; + char* p = (char*)outBuf; + char* end = p + 32; // write no more than 32 digits for safety + if (inToken) { + // first write all the hex digits in backwards order: + while (p < end && inToken) // more digits to write? + { + *p++ = morkEnv_kHexDigits[inToken & 0x0F]; // low four bits + inToken >>= 4; // we fervently hope this does not sign extend + } + *p = 0; // end the string with a null byte + char* s = (char*)outBuf; // first byte in string + mork_size size = (mork_size)(p - s); // distance from start + + // now reverse the string in place: + // note that p starts on the null byte, so we need predecrement: + while (--p > s) // need to swap another byte in the string? + { + char c = *p; // temp for swap + *p = *s; + *s++ = c; // move s forward here, and p backward in the test + } + return size; + } else // special case for zero integer + { + *p++ = '0'; // write a zero digit + *p = 0; // end with a null byte + return 1; // one digit in hex representation + } +} + +void morkEnv::StringToYarn(const PathChar* inString, mdbYarn* outYarn) { + if (outYarn) { + mdb_fill fill = + (inString) ? (mdb_fill)MORK_STRLEN(inString) * sizeof(PathChar) : 0; + + if (fill) // have nonempty content? + { + mdb_size size = outYarn->mYarn_Size; // max dest size + if (fill > size) // too much string content? + { + outYarn->mYarn_More = fill - size; // extra string bytes omitted + fill = size; // copy no more bytes than size of yarn buffer + } + void* dest = outYarn->mYarn_Buf; // where bytes are going + if (!dest) // nil destination address buffer? + fill = 0; // we can't write any content at all + + if (fill) // anything to copy? + MORK_MEMCPY(dest, inString, fill); // copy fill bytes to yarn + + outYarn->mYarn_Fill = fill; // tell yarn size of copied content + } else // no content to put into the yarn + { + outYarn->mYarn_Fill = 0; // tell yarn that string has no bytes + } + outYarn->mYarn_Form = 0; // always update the form slot + } else + this->NilPointerError(); +} + +morkEnv::PathChar* morkEnv::CopyString(nsIMdbHeap* ioHeap, + const PathChar* inString) { + PathChar* outString = nullptr; + if (ioHeap && inString) { + mork_size size = (MORK_STRLEN(inString) + 1) * sizeof(PathChar); + ioHeap->Alloc(this->AsMdbEnv(), size, (void**)&outString); + if (outString) MORK_STRCPY(outString, inString); + } else + this->NilPointerError(); + return outString; +} + +void morkEnv::FreeString(nsIMdbHeap* ioHeap, PathChar* ioString) { + if (ioHeap) { + if (ioString) ioHeap->Free(this->AsMdbEnv(), ioString); + } else + this->NilPointerError(); +} + +void morkEnv::NewError(const char* inString) { + MORK_ASSERT(morkBool_kFalse); // get developer's attention + + ++mEnv_ErrorCount; + mEnv_ErrorCode = NS_ERROR_FAILURE; + + if (mEnv_ErrorHook) mEnv_ErrorHook->OnErrorString(this->AsMdbEnv(), inString); +} + +void morkEnv::NewWarning(const char* inString) { + MORK_ASSERT(morkBool_kFalse); // get developer's attention + + ++mEnv_WarningCount; + if (mEnv_ErrorHook) + mEnv_ErrorHook->OnWarningString(this->AsMdbEnv(), inString); +} + +void morkEnv::StubMethodOnlyError() { this->NewError("method is stub only"); } + +void morkEnv::OutOfMemoryError() { this->NewError("out of memory"); } + +void morkEnv::CantMakeWhenBadError() { + this->NewError("can't make an object when ev->Bad()"); +} + +static const char morkEnv_kNilPointer[] = "nil pointer"; + +void morkEnv::NilPointerError() { this->NewError(morkEnv_kNilPointer); } + +void morkEnv::NilPointerWarning() { this->NewWarning(morkEnv_kNilPointer); } + +void morkEnv::NewNonEnvError() { this->NewError("non-env instance"); } + +void morkEnv::NilEnvSlotError() { + if (!mEnv_HandlePool || !mEnv_Factory) { + if (!mEnv_HandlePool) this->NewError("nil mEnv_HandlePool"); + if (!mEnv_Factory) this->NewError("nil mEnv_Factory"); + } else + this->NewError("unknown nil env slot"); +} + +void morkEnv::NonEnvTypeError(morkEnv* ev) { ev->NewError("non morkEnv"); } + +void morkEnv::ClearMorkErrorsAndWarnings() { + mEnv_ErrorCount = 0; + mEnv_WarningCount = 0; + mEnv_ErrorCode = NS_OK; + mEnv_ShouldAbort = morkBool_kFalse; +} + +void morkEnv::AutoClearMorkErrorsAndWarnings() { + if (this->DoAutoClear()) { + mEnv_ErrorCount = 0; + mEnv_WarningCount = 0; + mEnv_ErrorCode = NS_OK; + mEnv_ShouldAbort = morkBool_kFalse; + } +} + +/*static*/ morkEnv* morkEnv::FromMdbEnv( + nsIMdbEnv* ioEnv) // dynamic type checking +{ + morkEnv* outEnv = 0; + if (ioEnv) { + // Note this cast is expected to perform some address adjustment of the + // pointer, so oenv likely does not equal ioEnv. Do not cast to void* + // first to force an exactly equal pointer (we tried it and it's wrong). + morkEnv* ev = (morkEnv*)ioEnv; + if (ev && ev->IsEnv()) { + if (ev->DoAutoClear()) { + ev->mEnv_ErrorCount = 0; + ev->mEnv_WarningCount = 0; + ev->mEnv_ErrorCode = NS_OK; + } + outEnv = ev; + } else + MORK_ASSERT(outEnv); + } else + MORK_ASSERT(outEnv); + return outEnv; +} + +NS_IMETHODIMP +morkEnv::GetErrorCount(mdb_count* outCount, mdb_bool* outShouldAbort) { + if (outCount) *outCount = mEnv_ErrorCount; + if (outShouldAbort) *outShouldAbort = mEnv_ShouldAbort; + return NS_OK; +} + +NS_IMETHODIMP +morkEnv::GetWarningCount(mdb_count* outCount, mdb_bool* outShouldAbort) { + if (outCount) *outCount = mEnv_WarningCount; + if (outShouldAbort) *outShouldAbort = mEnv_ShouldAbort; + return NS_OK; +} + +NS_IMETHODIMP +morkEnv::GetEnvBeVerbose(mdb_bool* outBeVerbose) { + NS_ENSURE_ARG_POINTER(outBeVerbose); + *outBeVerbose = mEnv_BeVerbose; + return NS_OK; +} + +NS_IMETHODIMP +morkEnv::SetEnvBeVerbose(mdb_bool inBeVerbose) { + mEnv_BeVerbose = inBeVerbose; + return NS_OK; +} + +NS_IMETHODIMP +morkEnv::GetDoTrace(mdb_bool* outDoTrace) { + NS_ENSURE_ARG_POINTER(outDoTrace); + *outDoTrace = mEnv_DoTrace; + return NS_OK; +} + +NS_IMETHODIMP +morkEnv::SetDoTrace(mdb_bool inDoTrace) { + mEnv_DoTrace = inDoTrace; + return NS_OK; +} + +NS_IMETHODIMP +morkEnv::GetAutoClear(mdb_bool* outAutoClear) { + NS_ENSURE_ARG_POINTER(outAutoClear); + *outAutoClear = DoAutoClear(); + return NS_OK; +} + +NS_IMETHODIMP +morkEnv::SetAutoClear(mdb_bool inAutoClear) { + if (inAutoClear) + EnableAutoClear(); + else + DisableAutoClear(); + return NS_OK; +} + +NS_IMETHODIMP +morkEnv::GetErrorHook(nsIMdbErrorHook** acqErrorHook) { + NS_ENSURE_ARG_POINTER(acqErrorHook); + *acqErrorHook = mEnv_ErrorHook; + NS_IF_ADDREF(mEnv_ErrorHook); + return NS_OK; +} + +NS_IMETHODIMP +morkEnv::SetErrorHook(nsIMdbErrorHook* ioErrorHook) // becomes referenced +{ + mEnv_ErrorHook = ioErrorHook; + return NS_OK; +} + +NS_IMETHODIMP +morkEnv::GetHeap(nsIMdbHeap** acqHeap) { + NS_ENSURE_ARG_POINTER(acqHeap); + nsIMdbHeap* outHeap = mEnv_Heap; + + if (acqHeap) *acqHeap = outHeap; + return NS_OK; +} + +NS_IMETHODIMP +morkEnv::SetHeap(nsIMdbHeap* ioHeap) // becomes referenced +{ + nsIMdbHeap_SlotStrongHeap(ioHeap, this, &mEnv_Heap); + return NS_OK; +} +// } ----- end attribute methods ----- + +NS_IMETHODIMP +morkEnv::ClearErrors() // clear errors beore re-entering db API +{ + mEnv_ErrorCount = 0; + mEnv_ErrorCode = NS_OK; + mEnv_ShouldAbort = morkBool_kFalse; + + return NS_OK; +} + +NS_IMETHODIMP +morkEnv::ClearWarnings() // clear warning +{ + mEnv_WarningCount = 0; + return NS_OK; +} + +NS_IMETHODIMP +morkEnv::ClearErrorsAndWarnings() // clear both errors & warnings +{ + ClearMorkErrorsAndWarnings(); + return NS_OK; +} +// } ===== end nsIMdbEnv methods ===== + +// 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 -- cgit v1.2.3