/////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2002-2025, Open Design Alliance (the "Alliance"). // All rights reserved. // // This software and its documentation and related materials are owned by // the Alliance. The software may only be incorporated into application // programs owned by members of the Alliance, subject to a signed // Membership Agreement and Supplemental Software License Agreement with the // Alliance. The structure and organization of this software are the valuable // trade secrets of the Alliance and its suppliers. The software is also // protected by copyright law and international treaty provisions. Application // programs incorporating this software must include the following statement // with their copyright notices: // // This application incorporates Open Design Alliance software pursuant to a license // agreement with Open Design Alliance. // Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance. // All rights reserved. // // By use of this software, its documentation or related materials, you // acknowledge and accept the above terms. /////////////////////////////////////////////////////////////////////////////// #ifndef __OdGsFilerV100Impl_H__ #define __OdGsFilerV100Impl_H__ #include "TD_PackPush.h" #include "Ge/GeMatrix3d.h" #include "Ge/GeExtents3d.h" #include "DbBaseDatabase.h" #include "GsFiler.h" #include "OdStack.h" #include "RxObjectImpl.h" #define STL_USING_MAP #define STL_USING_SET #include "OdaSTL.h" /** \details OdGsFiler database linker implementation. */ class OdGsFilerDbLinker : public OdRxObject { public: /** \details Default constructor for the OdGsFilerDbLinker class. */ OdGsFilerDbLinker() { } /** \details Destructor for the OdGsFilerDbLinker class. */ virtual ~OdGsFilerDbLinker() { } public: /** \details Computes database hash. \param pDb [in] Pointer to a database. \returns database hash. */ virtual OdBinaryData getDbHash(const OdDbBaseDatabase *pDb) const; // Transform database handle /** \details Retrieves a database handle by the specified database-resident object. \param pStub [in] Pointer to a database-resident object. */ virtual OdUInt64 stubToDbHandle(OdDbStub *pStub) const = 0; /** \details Retrieves a database-resident object by the specified database handle. \param pStub [in] Pointer to a database-resident object. */ virtual OdDbStub *handleToDbStub(OdUInt64 nHandle) const = 0; // Util methods /** \details Retrieves a pointer to a database associated with this object. \param pStub [in] Pointer to a database-resident object. */ virtual OdDbBaseDatabase *getDatabase() const = 0; /** \details Retrieves a pointer to a database that owns the specified database-resident object. \param pStub [in] Pointer to a database-resident object. */ virtual OdDbBaseDatabase *getDatabase(OdDbStub *pStub) const = 0; }; /** \details A data type that represents a smart pointer to an object. */ typedef OdSmartPtr OdGsFilerDbLinkerPtr; /** \details Implementation of substitutions processor interface for state saver substitutions processor GsFiler extension. */ struct GS_TOOLKIT_EXPORT OdGsFiler_SubstitutorImpl : public OdRxObject, public OdGsFilerExtensionSubstitutor::Substitutor { /** \details Comparator template. */ template struct DataTyp { OdUInt8 m_data[nBytes]; static int compare(const DataTyp &t1, const DataTyp &t2) { for (OdUInt32 nb = 0; nb < nBytes; nb++) { if (t1.m_data[nb] != t2.m_data[nb]) return int(t1.m_data[nb]) - int(t2.m_data[nb]); } return 0; } bool operator ==(const DataTyp &t2) const { return compare(*this, t2) == 0; } bool operator !=(const DataTyp &t2) const { return compare(*this, t2) != 0; } bool operator <(const DataTyp &t2) const { return compare(*this, t2) < 0; } bool operator <=(const DataTyp &t2) const { return compare(*this, t2) <= 0; } bool operator >(const DataTyp &t2) const { return compare(*this, t2) > 0; } bool operator >=(const DataTyp &t2) const { return compare(*this, t2) >= 0; } operator const void*() const { return this; } }; /** \details Voids container. */ struct VoidsSet { void *m_pVoid; OdGsFilerExtensionSubstitutor::SubstitutionActuator *m_pAct; }; /** \details Voids array. */ struct VoidArry : public VoidsSet { OdInt32 m_nVoids; VoidArry() : m_nVoids(0) { m_pVoid = NULL; m_pAct = NULL; } ~VoidArry() { clear(); } VoidsSet *getSet() { return (VoidsSet*)m_pVoid; } VoidsSet *at(OdInt32 n) { if (m_nVoids == 1) return this; return getSet() + n; } bool contains(void *pVoid); void add(void *pVoid, OdGsFilerExtensionSubstitutor::SubstitutionActuator *pAct); void kill(void *pVoid); void clear(); }; /** \details Abstract type. */ struct AbstractTyp { void *m_pContainer; AbstractTyp() : m_pContainer(NULL) { } }; typedef std::map RegsMap; typedef std::map SubstsMap; RegsMap m_regs; SubstsMap m_substs; /** \details Substitutions processing template. */ template struct Procs { typedef OdGsFiler_SubstitutorImpl::DataTyp ProcTyp; typedef std::map RegMap; typedef std::map SubstMap; static void makeSubst(void *pPlace, const void *pSubstitution) { *(ProcTyp*)(pPlace) = *(const ProcTyp*)(pSubstitution); } static void runSubst(void *pPlace, const void *pSubstitution, OdGsFilerExtensionSubstitutor::SubstitutionActuator *pActuator) { ODA_ASSERT(pActuator); pActuator->applySubstitution(pPlace, pSubstitution, makeSubst); } static void subst(OdGsFiler_SubstitutorImpl &impl, const void *pValue, void *pPlace, OdGsFilerExtensionSubstitutor::SubstitutionActuator *pAct, const void *pSubstitution, bool bClear) { if (pPlace && pSubstitution) { runSubst(pPlace, pSubstitution, pAct); return; } if (pValue) { if (pPlace) { RegMap *pRegMap = (RegMap*)impl.m_regs[nBytes].m_pContainer; OD_TYPENAME RegMap::iterator itReg = pRegMap->find(*(const ProcTyp*)pValue); if (itReg != pRegMap->end()) { runSubst(pPlace, itReg->second, pAct); if (bClear) pRegMap->erase(itReg); } } else if (pSubstitution) { SubstMap *pSubMap = (SubstMap*)impl.m_substs[nBytes].m_pContainer; OD_TYPENAME SubstMap::iterator itSub = pSubMap->find(*(const ProcTyp*)pValue); if (itSub != pSubMap->end()) { for (OdInt32 n = 0; n < itSub->second.m_nVoids; n++) runSubst(itSub->second.at(n)->m_pVoid, pSubstitution, itSub->second.at(n)->m_pAct); if (bClear) pSubMap->erase(itSub); } } else { RegMap *pRegMap = (RegMap*)impl.m_regs[nBytes].m_pContainer; SubstMap *pSubMap = (SubstMap*)impl.m_substs[nBytes].m_pContainer; if (pRegMap && pSubMap) { OD_TYPENAME RegMap::iterator itReg = pRegMap->find(*(const ProcTyp*)pValue); OD_TYPENAME SubstMap::iterator itSub = pSubMap->find(*(const ProcTyp*)pValue); if ((itReg != pRegMap->end()) && (itSub != pSubMap->end())) { for (OdInt32 n = 0; n < itSub->second.m_nVoids; n++) runSubst(itSub->second.at(n)->m_pVoid, itReg->second, itSub->second.at(n)->m_pAct); } if (bClear) { if (itReg != pRegMap->end()) pRegMap->erase(itReg); if (itSub != pSubMap->end()) pSubMap->erase(itSub); } } else if (bClear) { if (pRegMap) { OD_TYPENAME RegMap::iterator itReg = pRegMap->find(*(const ProcTyp*)pValue); if (itReg != pRegMap->end()) pRegMap->erase(itReg); } if (pSubMap) { OD_TYPENAME SubstMap::iterator itSub = pSubMap->find(*(const ProcTyp*)pValue); if (itSub != pSubMap->end()) pSubMap->erase(itSub); } } } return; } RegMap *pRegMap = (RegMap*)impl.m_regs[nBytes].m_pContainer; SubstMap *pSubMap = (SubstMap*)impl.m_substs[nBytes].m_pContainer; if (pRegMap && pSubMap) { OD_TYPENAME RegMap::iterator itReg = pRegMap->begin(); while (itReg != pRegMap->end()) { OD_TYPENAME SubstMap::iterator itSub = pSubMap->find(itReg->first); if (itSub != pSubMap->end()) { for (OdInt32 n = 0; n < itSub->second.m_nVoids; n++) runSubst(itSub->second.at(n)->m_pVoid, itReg->second, itSub->second.at(n)->m_pAct); } itReg++; } } if (bClear) { if (pRegMap) { delete pRegMap; impl.m_regs[nBytes].m_pContainer = NULL; } if (pSubMap) { delete pSubMap; impl.m_substs[nBytes].m_pContainer = NULL; } } } static void reg(OdGsFiler_SubstitutorImpl &impl, const void *pValue, const void *pSubstitution, bool bRegister, bool bImmediate) { if (bRegister) { OdGsFiler_SubstitutorImpl::AbstractTyp &cont = impl.m_regs[nBytes]; if (!cont.m_pContainer) cont.m_pContainer = new RegMap; RegMap &pMap = *(RegMap*)cont.m_pContainer; pMap[*(const ProcTyp*)pValue] = *(const ProcTyp*)pSubstitution; } if (bImmediate) subst(impl, pValue, NULL, NULL, pSubstitution, false); } static void req(OdGsFiler_SubstitutorImpl &impl, void *pPlace, OdGsFilerExtensionSubstitutor::SubstitutionActuator *pAct, const void *pValue, bool bRegister, bool bImmediate) { if (bRegister) { if (bImmediate) { RegMap *pRegMap = (RegMap*)impl.m_regs[nBytes].m_pContainer; if (pRegMap) { OD_TYPENAME RegMap::iterator itReg = pRegMap->find(*(const ProcTyp*)pValue); if (itReg != pRegMap->end()) { runSubst(pPlace, itReg->second, pAct); return; } } } OdGsFiler_SubstitutorImpl::AbstractTyp &cont = impl.m_substs[nBytes]; if (!cont.m_pContainer) cont.m_pContainer = new SubstMap; SubstMap &pMap = *(SubstMap*)cont.m_pContainer; pMap[*(const ProcTyp*)pValue].add(pPlace, pAct); } else if (bImmediate) subst(impl, pValue, pPlace, pAct, NULL, false); } static void clear(OdGsFiler_SubstitutorImpl &impl, const void *pValue) { RegMap *pRegMap = (RegMap*)impl.m_regs[nBytes].m_pContainer; SubstMap *pSubMap = (SubstMap*)impl.m_substs[nBytes].m_pContainer; if (pValue) { if (pRegMap) { OD_TYPENAME RegMap::iterator it = pRegMap->find(*(const ProcTyp*)pValue); if (it != pRegMap->end()) pRegMap->erase(it); } if (pSubMap) { OD_TYPENAME SubstMap::iterator it = pSubMap->find(*(const ProcTyp*)pValue); if (it != pSubMap->end()) pSubMap->erase(it); } } else { if (pRegMap) { delete pRegMap; impl.m_regs[nBytes].m_pContainer = NULL; } if (pSubMap) { delete pSubMap; impl.m_substs[nBytes].m_pContainer = NULL; } } } }; static OdGsFilerExtensionSubstitutor::SubstitutionActuator g_defActuator; /** \details Default substitutions processing method for OdRxObject pointers. */ static struct OdRxObjectSubstitutionActuator : public OdGsFilerExtensionSubstitutor::SubstitutionActuator { OdRxObjectSubstitutionActuator() { } virtual void applySubstitution(void *pPlace, const void *pValue, SetPtrFunc pSetFunc) { OdGsFilerExtensionSubstitutor::SubstitutionActuator::applySubstitution(pPlace, pValue, pSetFunc); if (pPlace) (*reinterpret_cast(pPlace))->addRef(); } } g_rxObjectActuator; /** \details Register known substitution. \param pValue [in] Address of value for which new value should be applied. \param pSubstitution [in] Address of value to be applied. \param size [in] Size of value to be applied. \param bRegister [in] Store substitution in substitutions collection. \param bImmediate [in] Apply substitution immediately if this is possible. */ virtual void registerSubstitution(const void *pValue, const void *pSubstitution, OdUInt32 size = sizeof(OdIntPtr), bool bRegister = true, bool bImmediate = false); /** \details Register substitution request. \param pPlace [in] Address where substitution should be applied. \param pValue [in] Address of value for which new value should be applied. \param size [in] Size of value place where subtitution will be applied. \param bRegister [in] Store substitution request in substitutions collection. \param bImmediate [in] Apply substitution immediately if this is possible. */ virtual void requestSubstitution(void *pPlace, const void *pValue, OdUInt32 size = sizeof(OdIntPtr), bool bRegister = true, bool bImmediate = true); /** \details Register substitution request for smart pointer. \param pPlace [in] Address where substitution should be applied. \param pValue [in] Address of value for which new value should be applied. \param bRegister [in] Store substitution request in substitutions collection. \param bImmediate [in] Apply substitution immediately if this is possible. */ virtual void requestSubstitution(OdBaseObjectPtr *pPlace, const void *pValue, bool bRegister = true, bool bImmediate = true); /** \details Register substitution with non-default behavior. \param pPlace [in] Address where substitution should be applied. \param pActuator [in] Substitution processing method. \param pValue [in] Address of value for which new value should be applied. \param size [in] Size of value place where subtitution will be applied. \param bRegister [in] Store substitution request in substitutions collection. \param bImmediate [in] Apply substitution immediately if this is possible. */ virtual void requestSubstitution(void *pPlace, OdGsFilerExtensionSubstitutor::SubstitutionActuator *pActuator, const void *pValue, OdUInt32 size = sizeof(OdIntPtr), bool bRegister = true, bool bImmediate = true); /** \details Clear substitutions. \param pValue [in] Address of value for which substitutions collection should be cleared or null to clear all. \param size [in] Size of value which should be cleared. */ virtual void clearSubstitutions(const void *pValue = NULL, OdUInt32 size = 0); /** \details Run substitutions. \param pValue [in] Address of value for which substitutions process should be executed or null to process all. \param size [in] Size of value for which substitutions should be executed. \param bClear [in] Clear substitutions collection after processing if true or keep if false. */ virtual void runSubstitutions(const void *pValue = NULL, OdUInt32 size = 0, bool bClear = true); #undef REG_FUNCCALL /** \details Destructor for the OdGsFiler_SubstitutorImpl structure. */ ~OdGsFiler_SubstitutorImpl() { clearSubstitutions(); } }; /** \details State saver substitutions processor GsFiler extension implementation. */ class GS_TOOLKIT_EXPORT OdGsFilerExtensionSubstitutorImpl : public OdGsFilerExtensionSubstitutor { protected: mutable OdSmartPtr m_subst; public: /** \details Default constructor for the OdGsFilerExtensionSubstitutorImpl class. */ OdGsFilerExtensionSubstitutorImpl() { m_subst = OdRxObjectImpl::createObject(); } /** \details Substitutions processor interface. \returns substitutions processor interface. */ virtual Substitutor *subst() const; /** \details Apply collected substitutions. \param bClear [in] Clear substitutions collection after applying. */ virtual void makeSubstitutions(bool bClear = true) const; /** \details Returns substitutions processor interface as OdRxObject pointer. */ virtual OdRxObjectPtr getSubstitutor() const; /** \details Sets external substitions processor interface. \param pSubst [in] Substitutions processor interface pointer. */ virtual void setSubstitutor(OdRxObject *pSubst); }; /** \details Arbitrary data container GsFiler extension implementation. */ class GS_TOOLKIT_EXPORT OdGsFilerExtensionArbitraryDataImpl : public OdGsFilerExtensionArbitraryData { protected: typedef std::map ArbDataMap; ArbDataMap m_arbData; public: // Arbitrary data /** \details Sets arbitrary data. \param pName [in] Dictionary entry name. \param pObject [in] Object which should be stored at specified name. */ virtual void setArbitraryData(const OdChar *pName, OdRxObject *pObject); /** \details Returns arbitrary data. \param pName [in] Dictionary entry name. \returns stored object pointer or null object pointer if name not exists. */ virtual OdRxObjectPtr getArbitraryData(const OdChar *pName) const; /** \details Checks does arbitrary data registered. \param pName [in] Dictionary entry name. \returns true if specified name exists or false elsewhere. */ virtual bool hasArbitraryData(const OdChar *pName) const; /** \details Clears arbitrary data dictionary. */ virtual void clearArbitraryData(); }; /** \details Registered pointers container GsFiler extension implementation. */ class GS_TOOLKIT_EXPORT OdGsFilerExtensionPointersRegistratorImpl : public OdGsFilerExtensionPointersRegistrator { protected: typedef std::set RegPtrsSet; RegPtrsSet m_regPtrs; public: // Pointers registration /** \details Register pointer. \param pPtr [in] Pointer which should be registered. */ virtual void registerPtr(const void *pPtr); /** \details Unregister pointer. \param pPtr [in] Pointer which should be unregistered. */ virtual void unregisterPtr(const void *pPtr); /** \details Checks does specified pointer registered. \param pPtr [in] Pointer to be checked. \returns true if specified pointer registered or false elsewhere. */ virtual bool isPtrRegistered(const void *pPtr) const; /** \details Clears registered pointers collection. */ virtual void clearRegisteredPtrs(); }; /** \details File stream accessor GsFiler extension implementation. */ class GS_TOOLKIT_EXPORT OdGsFilerExtensionStreamAccessorImpl : public OdGsFilerExtensionStreamAccessor { protected: mutable OdStreamBufPtr m_pStream; public: /** \details Attaches a specified stream. \param pStream [in] Pointer to a stream to set. */ virtual void setStream(OdStreamBuf *pStream); /** \details Retrieves a smart pointer to current stream. */ virtual OdStreamBufPtr getStream() const; }; /** \details File stream accessor GsFiler extension implementation for abstract OdGsFiler. */ class GS_TOOLKIT_EXPORT OdGsFilerExtensionStreamer : public OdGsFilerExtensionStreamAccessor , public OdStreamBuf { protected: OdGsFiler *m_pFiler; OdUInt64 m_pseudoCaret; public: /** \details Constructor for the OdGsFilerExtensionStreamer class. \param pFiler [in] Abstract OdGsFiler which will be wrapped as OdStreamBuf. */ OdGsFilerExtensionStreamer(OdGsFiler *pFiler) : m_pFiler(pFiler), m_pseudoCaret(0) {} /** \details Attaches a specified stream. This implementation does nothing. \param pStream [in] Pointer to a stream to set. */ virtual void setStream(OdStreamBuf * /*pStream*/) {} /** \details Retrieves a smart pointer to current stream. */ virtual OdStreamBufPtr getStream() const { return this; } protected: void addRef() { } void release() ODRX_NOEXCEPT { } virtual OdUInt64 seek(OdInt64 offset, OdDb::FilerSeekType seekType); virtual OdUInt8 getByte(); virtual void getBytes(void *buffer, OdUInt32 numBytes); virtual void putByte(OdUInt8 value); virtual void putBytes(const void *buffer, OdUInt32 numBytes); virtual OdUInt64 tell(); virtual OdUInt64 length(); }; /** \details Local cache object Id's processor GsFiler extension implementation. */ class GS_TOOLKIT_EXPORT OdGsFilerExtensionIdSaverImpl : public OdGsFilerExtensionIdSaver { protected: // Writing typedef std::set WritingSet; WritingSet m_writeAccum; // Objects, requested for writing. enum class WrProcState { kRegistered, kRequested, kProcessed }; typedef std::pair ProcState; typedef std::map ProcsMap; ProcsMap m_procAccum; // Loading struct RegSubst { OdUInt64 m_substVal; RegSubst() : m_substVal(0) { } ~RegSubst() { } bool hasReg() const { return m_substVal != 0; } }; typedef std::map RegMapSubst; RegMapSubst m_regMapSubst; // Register processed objects struct RegReqs { struct SubstReq { void *m_pAddr; OdUInt32 m_size; SubstitutionActuator *m_pActuator; const void *m_pArg; SubstReq(void *pAddr, OdUInt32 size, SubstitutionActuator *pActuator = nullptr, const void *pArg = nullptr) : m_pAddr(pAddr), m_size(size), m_pActuator(pActuator), m_pArg(pArg) { } void deleteRefs() { if (m_pActuator) m_pActuator->selfDelete(m_pArg); } }; OdVector m_reqs; RegReqs() { } ~RegReqs() { clearReqsArray(); } void clearReqsArray() { for (OdUInt32 n = 0; n < m_reqs.size(); n++) m_reqs[n].deleteRefs(); m_reqs.setPhysicalLength(0); } }; typedef std::map RegMapReqs; RegMapReqs m_regMapReqs; // Register requested objects friend class OdGsFilerExtensionLoadingReactorImpl; WritingSet m_loadedIds; OdGsModel *m_pActiveModel = nullptr; typedef std::map LinkMap; LinkMap m_linkMap; protected: ProcsMap::iterator preprocessWrId(OdGsFilerObjectId &gsId, const void *pLinkedObject); ProcsMap::const_iterator preprocessWrId(OdGsFilerObjectId &gsId, const void *pLinkedObject) const; static void makeSubst32(void *pPlace, const void *pSubstitution) { *(OdUInt32*)(pPlace) = (OdUInt32)*(const OdUInt64*)(pSubstitution); } static void makeSubst64(void *pPlace, const void *pSubstitution) { *(OdUInt64*)(pPlace) = *(const OdUInt64*)(pSubstitution); } void processSubstitution(const RegReqs::SubstReq &pWhere, OdUInt64 value); public: // Active model storage /** \details Store current OdGsModel for further processing. \param pModel [in] Pointer to current OdGsModel. */ virtual void setActiveModel(OdGsModel *pModel) override { m_pActiveModel = pModel; } /** \details Returns pointer to current OdGsModel if it is set or null elsewhere. */ virtual OdGsModel *activeModel() const override { return m_pActiveModel; } // Temporary objects linker /** \details Store object in internal collection by speicified object Id as key. \param gsId [in] Object Id. \param pObject [in] Object pointer to store. */ virtual void linkObject(const OdGsFilerObjectId &gsId, const OdRxObject *pObject) override; /** \details Remove object from internal collection by speicified object Id as key. \param gsId [in] Object Id. */ virtual void unlinkObject(const OdGsFilerObjectId &gsId) override; /** \details Checks does object stored under specified object Id key. \param gsId [in] Object Id. \returns true if object exists or false elsewhere. */ virtual bool hasLinkedObject(const OdGsFilerObjectId &gsId) const override; /** \details Gets object stored under specified object Id key. \param gsId [in] Object Id. \returns object pointer if object presents or nullptr elsewhere. */ virtual OdRxObject *linkedObject(const OdGsFilerObjectId &gsId) const override; // Writer /** \details Register object Id, planned for writing. \param gsId [in] Object Id. \param pLinkedObject [in] Optional linked object, requested for writing. */ virtual void regWrId(OdGsFilerObjectId &gsId, const void *pLinkedObject = nullptr) override; /** \details Returns linked object, requested for writing.. \param gsId [in] Object Id. */ virtual void *linkedWrIdObject(const OdGsFilerObjectId &gsId) const override; /** \details Write object Id. \param pFiler [in] Filer object where to write object Id. \param gsId [in] Object Id. \param pLinkedObject [in] Optional linked object, requested for writing. \param bProcessed [in] Mark store object Id as processed or not. */ virtual void wrId(OdGsFiler *pFiler, const OdGsFilerObjectId &gsId, const void *pLinkedObject = nullptr, WrIdType wrIdType = WrIdType::kRequest) override; /** \details Requests writing of specified object Id. \param gsId [in] Object Id. \param pLinkedObject [in] Optional linked object, requested for writing. */ virtual void wrRequest(const OdGsFilerObjectId &gsId, const void *pLinkedObject = nullptr) override; /** \details Marks specified object Id as processed. \param gsId [in] Object Id. \param pLinkedObject [in] Optional linked object, requested for writing. */ virtual void processedWrId(const OdGsFilerObjectId &gsId, const void *pLinkedObject = nullptr) override; /** \details Checks does specified object Id is written or not. \param gsId [in] Object Id. \param pLinkedObject [in] Optional linked object, requested for writing. \returns true if object Id is writter or false elsewhere. */ virtual bool isWrittenId(const OdGsFilerObjectId &gsId, const void *pLinkedObject = nullptr) const override; /** \details Clear written object Id's. \param pFillArray [out] Optional array where requested for writing object Id's should be placed. */ virtual void clearWrIds(OdGsFilerObjectIdArray *pFillArray = nullptr) override; // Loader combined with substitutor /** \details Reads object Id from filler object. \param pFiler [in] Filer object. \returns object Id. */ virtual OdGsFilerObjectId rdId(OdGsFiler *pFiler) override; /** \details Reads object Id from filler object and substitute runtime object Id at specified address immediately or later. \param pFiler [in] Filer object. \param pPlace [in] Address where read runtime object object Id substitution should be applied. \param size [in] Size of memory place for substitution. \returns object Id. */ virtual OdGsFilerObjectId rdId(OdGsFiler *pFiler, void *pPlace, OdUInt32 size = sizeof(OdIntPtr)) override; /** \details Request object Id reading and apply substitution of runtime object Id at specified address immediately or later. \param gsId [in] Object Id. \param pPlace [in] Address where read runtime object object Id substitution should be applied. \param size [in] Size of memory place for substitution. \param pActiator [in] Optional non-default substitution processing method. \param pArg [in] Optional argument for substitution processing method. */ virtual void requestId(const OdGsFilerObjectId &gsId, void *pPlace, OdUInt32 size = sizeof(OdIntPtr), SubstitutionActuator *pActuator = nullptr, const void *pArg = nullptr) override; /** \details Register readed object Id and provide value for requested substitutions. \param gsId [in] Object Id. \param pValue [in] Address of substitution value. \param size [in] Size of substitution value. */ virtual void registerId(const OdGsFilerObjectId &gsId, const void *pValue, OdUInt32 size) override; /** \details Checks does any additional object Id's reading requested or not. \param pFillArray [out] Optional array where requested for reading object Id's should be placed. \returns true if any additional object Id's reading requested or false elsewhere. */ virtual bool referencedIds(OdGsFilerObjectIdArray *pFillArray = nullptr) override; }; /** \details Local cache loading reactor GsFiler extension implementation. */ class GS_TOOLKIT_EXPORT OdGsFilerExtensionLoadingReactorImpl : public OdGsFilerExtensionLoadingReactor { protected: OdGsFilerLoadingReactor *m_pReactor; OdGsFilerExtensionIdSaverImpl *m_pChecker; public: /** \details Constructor for the OdGsFilerExtensionLoadingReactorImpl class. \param pChecker [in] Optional pointer to local cache object Id's processor GsFiler extension implementation. */ OdGsFilerExtensionLoadingReactorImpl(OdGsFilerExtensionIdSaverImpl *pChecker = nullptr) : m_pReactor(nullptr), m_pChecker(pChecker) { } /** \details Setup local cache loading reactor. \param pReactor [in] Local cache loading reactor pointer. */ virtual void setupReactor(OdGsFilerLoadingReactor *pReactor); /** \details Returns local cache loading reactor. */ virtual OdGsFilerLoadingReactor *reactor() const; /** \details Process loading of requested graphics system object. \param gsId [in] Object Id. \param pContext [in] Internal loading context pointer. \returns true if reading success or false elsewhere. */ virtual bool loadGsObject(const OdGsFilerObjectId &gsId, const void *pContext); }; /** \details First version of OdGsFiler implementation. */ class GS_TOOLKIT_EXPORT OdGsFilerV100Impl : public OdGsFilerGSS { protected: enum Flags { kOpenedForWrite = (1 << 0), kLastFlag = kOpenedForWrite }; protected: OdStreamBuf *m_pStream; OdGsFilerDbLinkerPtr m_pLinker; OdUInt64 m_nSectionsToWrite; OdUInt64 m_nSectionsToRead; OdUInt32 m_nFlags; OdUInt32 m_nVersion; mutable Section m_nCurSection; mutable OdUInt32 m_nCurSectionSize; struct WrSectionData { OdGsFilerGSS::Section m_type; OdUInt64 m_begin; WrSectionData() : m_type(OdGsFilerGSS::kEOFSection) , m_begin(0) { } WrSectionData(OdGsFilerGSS::Section section, OdUInt32 tell) : m_type(section) , m_begin(tell) { } }; OdStack m_sectionStack; mutable OdGsFilerExtensionStreamAccessorImpl m_extStream; mutable OdGsFilerExtensionSubstitutorImpl m_extSubst; mutable OdGsFilerExtensionArbitraryDataImpl m_extArbData; mutable OdGsFilerExtensionPointersRegistratorImpl m_extRegPtr; protected: bool isWriting() const { return GETBIT(m_nFlags, kOpenedForWrite); } void setWriting(bool bSet) { SETBIT(m_nFlags, kOpenedForWrite, bSet); } void assertWr() const { if (!isWriting()) throw OdError(eNotOpenForWrite); } void assertRd() const { if (isWriting()) throw OdError(eNotOpenForRead); } public: /** \details Default constructor for the OdGsFilerV100Impl class. Sets the following data members: Data member Value Description m_nSectionsToWrite -1 Sections for which write operations are enabled. m_nSectionsToRead -1 Sections for which read operations are enabled. m_nFlags 0 Filer flags (indicates whether filer is opened for write operations). m_nVersion kV2 File version. m_nCurSection kEOFSection Current file section. m_nCurSectionSize 0 Current file section size.
*/ OdGsFilerV100Impl() : m_nSectionsToWrite(OdUInt64(-1)) , m_nSectionsToRead(OdUInt64(-1)) , m_nFlags(0) , m_nVersion(kV2) , m_nCurSection(kEOFSection) , m_nCurSectionSize(0) { } /** \details Destructor for the OdGsFilerV100Impl class. */ ~OdGsFilerV100Impl() { } /** \details Returns file header first double word which is used to identify file format. */ OdUInt32 headerTestChunk() const; /** \details Reads a header section. \returns false if current section is not header section or if header test chunk is not read successfully or if after setting version checkEOF() call returns false. */ bool rdHeaderSection(); /** \details Writes a header test chunk to the header section. */ void wrHeaderSection(); /** \details Attaches a specified stream and opens it for read and potentially write operations. \param pStream [in] Pointer to a stream to set. \param bWrite [in] Flag that specifies whether to open stream for write operations. */ virtual bool setStream(OdStreamBuf *pStream, bool bWrite = false); /** \details Retrieves a smart pointer to current stream. */ virtual OdStreamBufPtr getStream() const; /** \details Sets a specified database. \param pDb [in] Pointer to a database to set. */ virtual void setDatabase(const OdDbBaseDatabase *pDb); /** \details Retrieves a pointer to a database that is used for this stream. */ virtual OdDbBaseDatabase *getDatabase() const; // Extensions /** \details Checks does graphics system filer supports extension. \param type [in] Extension type. \returns true if extension supported or false elsewhere. */ virtual bool hasExtension(OdGsFilerExtension::Type type) const; /** \details Returns graphics system filer extension. \param type [in] Extension type. \returns graphics system filer extension or nullptr elsewhere. */ virtual OdGsFilerExtension *getExtension(OdGsFilerExtension::Type type) const; /** \details Sets a file version for this filer. \param nVersion [in] File version. See Version enum. */ virtual void setVersion(OdUInt32 nVersion); /** \details Retrieves a file version for this filer. \returns one of the following values: * 100 - file version 1 * 200 - file version 2 */ virtual OdUInt32 version() const; /** \details Writes database hash. \param pDb [in] Pointer to a database. */ virtual void wrDbHash(const OdDbBaseDatabase *pDb); /** \details Checks readed database hash. \param pDb [in] Pointer to a database. \returns true if hashes same or false elsewhere. */ virtual bool checkDbHash(const OdDbBaseDatabase *pDb); /** \details Sets sections for write operations. \param nSections [in] Sections to set for writing. */ virtual void setWriteSections(OdUInt64 nSections); /** \details Sets the specified section for write operations. \param section [in] Section to set. \param bSet [in] Flag that specifies whether to write to the section. */ virtual void setWriteSection(Section section, bool bSet); /** \details Checks whether the specified section is opened for write operations. \param section [in] Section to check. \returns true if write operations are enabled for the section, false otherwise. */ virtual bool isWriteSection(Section section) const; /** \details Sets sections for read operations. \param nSections [in] Sections to set for reading. */ virtual void setReadSections(OdUInt64 nSections); /** \details Sets the specified section for read operations. \param section [in] Section to set. \param bSet [in] Flag that specifies whether to read the section. */ virtual void setReadSection(Section section, bool bSet); /** \details Checks whether the specified section is opened for read operations. \param section [in] Section to check. \returns true if read operations are enabled for the section, false otherwise. */ virtual bool isReadSection(Section section) const; /** \details Begins writing to the section. \param section [in] File section. */ virtual void wrSectionBegin(Section section); /** \details Ends writing to the section. \param section [in] File section. */ virtual void wrSectionEnd(Section section); /** \details Writes the end of file (EOF) section. */ virtual void wrEOFSection(); /** \details Reads sections one by one and returns a current section for which read access is not enabled or the EOF section. */ virtual Section rdSection() const; /** \details Retrieves the current section. */ virtual Section curSection() const; /** \details Skips the current section and makes the following section current. */ virtual void skipSection() const; /** \details Return to the previous section and makes it current. */ virtual void rdBackSection() const; /** \details Checks whether currently read section is the end of file (EOF) section. \returns true if current section is EOF section, false otherwise. */ virtual bool checkEOF() const; /** \details Substitutions processor interface. \returns substitutions processor interface. */ virtual OdGsFilerExtensionSubstitutor::Substitutor *subst() const; /** \details Apply collected substitutions. \param bClear [in] Clear substitutions collection after applying. */ virtual void makeSubstitutions(bool bClear = true) const; /** \details Returns substitutions processor interface as OdRxObject pointer. */ virtual OdRxObjectPtr getSubstitutor() const; /** \details Sets external substitions processor interface. \param pSubst [in] Substitutions processor interface pointer. */ virtual void setSubstitutor(OdRxObject *pSubst); /** \details Sets arbitrary data. \param pName [in] Dictionary entry name. \param pObject [in] Object which should be stored at specified name. */ virtual void setArbitraryData(const OdChar *pName, OdRxObject *pObject); /** \details Returns arbitrary data. \param pName [in] Dictionary entry name. \returns stored object pointer or null object pointer if name not exists. */ virtual OdRxObjectPtr getArbitraryData(const OdChar *pName) const; /** \details Checks does arbitrary data registered. \param pName [in] Dictionary entry name. \returns true if specified name exists or false elsewhere. */ virtual bool hasArbitraryData(const OdChar *pName) const; /** \details Clears arbitrary data dictionary. */ virtual void clearArbitraryData(); /** \details Register pointer. \param pPtr [in] Pointer which should be registered. */ virtual void registerPtr(const void *pPtr); /** \details Unregister pointer. \param pPtr [in] Pointer which should be unregistered. */ virtual void unregisterPtr(const void *pPtr); /** \details Checks does specified pointer registered. \param pPtr [in] Pointer to be checked. \returns true if specified pointer registered or false elsewhere. */ virtual bool isPtrRegistered(const void *pPtr) const; /** \details Clears registered pointers collection. */ virtual void clearRegisteredPtrs(); /** \details Writes database handle to the stream. \param pHandle [in] Pointer to database handle. */ virtual void wrHandle(OdDbStub *pHandle); /** \details Retrieves a pointer to database handle. */ virtual OdDbStub *rdHandle() const; /** \details Writes a name of the class associated with passed object to the stream. \param pObj [in] Pointer to database handle. */ virtual void wrClass(OdRxObject *pObj); /** \details Retrieves a smart pointer to a class at current stream position. \returns smart pointer to a class by read class name, if class not found by class name this method returns a smart pointer to a not valid class. */ virtual OdRxObjectPtr rdClass() const; /** \details Writes raw data to the stream. \param pData [in] Pointer to data (in bytes). \param nDataSize [in] Data size. */ virtual void wrRawData(const void *pData, OdUInt32 nDataSize); /** \details Reads raw data from the stream. \param pData [out] Pointer to data (in bytes). \param nDataSize [in] Data size. */ virtual void rdRawData(void *pData, OdUInt32 nDataSize) const; }; #include "TD_PackPop.h" #endif // __OdGsFilerV100Impl_H__