/////////////////////////////////////////////////////////////////////////////// // 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. /////////////////////////////////////////////////////////////////////////////// // Base implementation of XmlServer interface for GLES2 Xml device #ifndef ODTRXMLSERVERBASEIMPL #define ODTRXMLSERVERBASEIMPL #include "TD_PackPush.h" #include "XmlServer.h" #include "TrVisUniqueId.h" #include "DbBaseDatabase.h" #ifndef odabs #define odabs(X) ((X) > 0 ? (X) : -(X)) #endif /** \details */ class OdTrXmlServerBaseImpl : public OdTrXmlServer, protected OdTrVisUniqueID::DefUIDTransformer { protected: int m_nIdent; ProcessingMode m_procMode; OdDbBaseDatabasePE *m_pDbPE; OdAnsiString m_sTmpBuf; // for sprintf or format on one level upper indent char* m_pszTmpBuf; int m_lenTmpBuf; # if defined(odSprintfA) # define ODFMTBEG(len) \ { \ { \ m_pszTmpBuf = m_sTmpBuf.getBuffer(m_lenTmpBuf = (int)len + 1); \ odSprintfA(m_pszTmpBuf, m_lenTmpBuf, # define ODFMTADD() \ ); \ } \ } \ { \ { \ odSprintfA(m_pszTmpBuf += odStrLenA(m_pszTmpBuf), m_lenTmpBuf, # define ODFMTFORBEGEX(len, expr) \ { \ m_pszTmpBuf = m_sTmpBuf.getBuffer(m_lenTmpBuf = len * nData + 1); \ for (OdUInt32 index = 0; index < nData; index++, m_pszTmpBuf += odStrLenA(m_pszTmpBuf)) \ { \ expr; \ odSprintfA(m_pszTmpBuf, m_lenTmpBuf, # else # define ODFMTBEG(len) \ { \ { \ m_sTmpBuf.format( # define ODFMTADD() \ ); \ } \ } { \ { \ m_sTmpBuf += OdAnsiString().format( # define ODFMTFORBEGEX(len, expr) \ { \ m_sTmpBuf.empty(); \ for (OdUInt32 index = 0; index < nData; index++) \ { \ expr; \ m_sTmpBuf += OdAnsiString().format( # endif # define ODFMTFORBEG(len) ODFMTFORBEGEX(len,) # define ODFMTEND() \ ); \ } \ } # define ODFLTFMT(cstrpref, val, cstrsfx) \ ((val >= 0.0f ? val : - val) >= 0.1f && (val >= 0.0f ? val : - val) < 1e+16) ? cstrpref "%f" cstrsfx : cstrpref "%g" cstrsfx public: OdTrXmlServerBaseImpl(OdDbBaseDatabasePE *pDbPE = NULL) : m_nIdent(0) , m_procMode(kNormalMode) , m_pDbPE(NULL) , m_pszTmpBuf(NULL) , m_lenTmpBuf(0) { setDatabasePE(pDbPE); } void setProcessingMode(ProcessingMode procMode) { m_procMode = procMode; } void setDatabasePE(OdDbBaseDatabasePE *pDbPE = NULL) { m_pDbPE = pDbPE; } void append(OdAnsiString &to, OdDbStub* from) const override { if (m_pDbPE) OdTrVisUniqueID::DefUIDTransformer::append(to, (OdUInt64)m_pDbPE->getHandle(from)); else OdTrVisUniqueID::DefUIDTransformer::append(to, from); } // should be overrode for JSON virtual void ident(const char* pTag, const char* pText) = 0; void IncreaseNesting(const char* pLevelName) override { ODFMTBEG(odStrLenA(pLevelName) + 2) "<%s>", pLevelName ODFMTEND() ident(NULL, m_sTmpBuf.c_str()); m_nIdent += 2; } void DecreaseNesting(const char* pLevelName) override { m_nIdent -= 2; ODFMTBEG(odStrLenA(pLevelName) + 3) "", pLevelName ODFMTEND() ident(NULL, m_sTmpBuf.c_str()); } void DropId(const char* pTagName, OdUInt64 data, OdTrVisUniqueID* pId = NULL, OdInt32 enAdv = -1) override { if (pId && data > OdUInt64(100)) // is not an address { m_sTmpBuf = pId->transform(*this); ident(pTagName, m_sTmpBuf.c_str()); return; } ODA_ASSERT_ONCE(!pId || data <= OdUInt64(100)); OdTrXmlServer::DropId(pTagName, data, pId, enAdv); // DropUInt64(pTagName, data); } void DropBoolean(const char* pTagName, bool data) override { DropUInt32(pTagName, (data) ? 1 : 0); } void DropUInt8(const char* pTagName, OdUInt8 data) override { DropUInt32(pTagName, data); } void DropUInt32(const char* pTagName, OdUInt32 data) override { ODFMTBEG(16) "%u", (unsigned)data ODFMTEND() ident(pTagName, m_sTmpBuf.c_str()); } void DropUInt64(const char* pTagName, OdUInt64 data) override { ODFMTBEG(32) #if (OD_SIZEOF_LONG == 4) || defined(__APPLE__) "%" PRIu64, (unsigned long long)data #else "%" PRIu64, data #endif ODFMTEND() ident(pTagName, m_sTmpBuf.c_str()); } void DropInt32(const char* pTagName, OdInt32 data) override { ODFMTBEG(10) "%d", (int)data ODFMTEND() ident(pTagName, m_sTmpBuf.c_str()); } void DropChars(const char* pTagName, const char *pStr) override { m_sTmpBuf = pStr; m_sTmpBuf.replace("<", "<"); m_sTmpBuf.replace(">", ">"); m_sTmpBuf.replace("\n", " "); ident(pTagName, m_sTmpBuf.c_str()); } void DropUInt8s(const char* pTagName, OdUInt32 nData, const OdUInt8* pData) override { ODA_ASSERT_ONCE(nData && pData); ODFMTFORBEG(8) index ? ",%u" : "%u" , (unsigned)pData[index] ODFMTEND() ident(pTagName, m_sTmpBuf.c_str()); } void DropUInt16s(const char* pTagName, OdUInt32 nData, const OdUInt16* pData) override { ODA_ASSERT_ONCE(nData && pData); ODFMTFORBEG(16) index ? ",%u" : "%u" , (unsigned)pData[index] ODFMTEND() ident(pTagName, m_sTmpBuf.c_str()); } void DropUInt32s(const char* pTagName, OdUInt32 nData, const OdUInt32* pData) override { ODA_ASSERT_ONCE(nData && pData); ODFMTFORBEG(32) index ? ",%u" : "%u" , (unsigned)pData[index] ODFMTEND() ident(pTagName, m_sTmpBuf.c_str()); } void DropFloats(const char* pTagName, OdUInt32 nData, const float *pData) override { //ODA_ASSERT_ONCE(nData && !(nData % 3)); // test if ( odStrCmpA(pTagName, "ArrayData") || !nData || (nData % 3) || (odabs(pData[0]) < 10000 && odabs(pData[1]) < 10000 && odabs(pData[2]) < 10000)) { ODA_ASSERT_ONCE(nData && pData); ODFMTFORBEG(32) //index ? ",%g" : "%g" , pData[index] ODFLTFMT("%s", pData[index], ), index ? "," : "", pData[index] ODFMTEND() ident(pTagName, m_sTmpBuf.c_str()); return; } float val, offs[3]; #if !defined(__BORLANDC__) && !defined(__hpux) offs[0] = ceilf(pData[0]) - 1.0f; offs[1] = ceilf(pData[1]) - 1.0f; offs[2] = ceilf(pData[2]) - 1.0f; // by first #else // float-mathematics is missing in Builder offs[0] = pData[0]; offs[1] = pData[1]; offs[2] = pData[2]; #endif DropFloat3("ArrayOffset", offs[0], offs[1], offs[2]); ODA_ASSERT_ONCE(nData && pData); ODFMTFORBEGEX(16, val = pData[index] - offs[index % 3]) //index ? ",%g" : "%g" , pData[index] - offs[index % 3] ODFLTFMT("%s", val, ), index ? "," : "", val ODFMTEND() ident(pTagName, m_sTmpBuf.c_str()); } void DropDoubles(const char* pTagName, OdUInt32 nData, const double *pData) override { //ODA_ASSERT_ONCE(nData && !(nData % 3)); // test if ( odStrCmpA(pTagName, "ArrayData") || !nData || (nData % 3) || (odabs(pData[0]) < 10000 && odabs(pData[1]) < 10000 && odabs(pData[2]) < 10000)) { ODA_ASSERT_ONCE(nData && pData); ODFMTFORBEG(64) //index ? ",%g" : "%g" , pData[index] ODFLTFMT("%s", pData[index], ), index ? "," : "", pData[index] ODFMTEND() ident(pTagName, m_sTmpBuf.c_str()); return; } double val, offs[3]; offs[0] = ceil(pData[0]) - 1.0; offs[1] = ceil(pData[1]) - 1.0; offs[2] = ceil(pData[2]) - 1.0; // by first DropDouble3("ArrayOffset", offs[0], offs[1], offs[2]); ODA_ASSERT_ONCE(nData && pData); ODFMTFORBEGEX(32, val = pData[index] - offs[index % 3]) //index ? ",%g" : "%g" , pData[index] - offs[index % 3] ODFLTFMT("%s", val, ), index ? "," : "", val ODFMTEND() ident(pTagName, m_sTmpBuf.c_str()); } void DropFloat(const char* pTagName, float data) override { ODFMTBEG(32) //"%g", data ODFLTFMT( , data, ), data ODFMTEND() ident(pTagName, m_sTmpBuf.c_str()); } void DropFloat2(const char* pTagName, float data1, float data2) override { ODFMTBEG(64) //"%g, %g", data1, data2 ODFLTFMT( , data1, ), data1 ODFMTADD() ODFLTFMT(", ", data2, ), data2 ODFMTEND() ident(pTagName, m_sTmpBuf.c_str()); } void DropFloat3(const char* pTagName, float data1, float data2, float data3) override { ODFMTBEG(96) //"%g, %g, %g", data1, data2, data3 ODFLTFMT( , data1, ), data1 ODFMTADD() ODFLTFMT(", ", data2, ), data2 ODFMTADD() ODFLTFMT(", ", data3, ), data3 ODFMTEND() ident(pTagName, m_sTmpBuf.c_str()); } void DropFloat4(const char* pTagName, float data1, float data2, float data3, float data4) override { ODFMTBEG(128) //"%g, %g, %g, %g", data1, data2, data3, data4 ODFLTFMT( , data1, ), data1 ODFMTADD() ODFLTFMT(", ", data2, ), data2 ODFMTADD() ODFLTFMT(", ", data3, ), data3 ODFMTADD() ODFLTFMT(", ", data4, ), data4 ODFMTEND() ident(pTagName, m_sTmpBuf.c_str()); } void DropUInt8RGB(const char* pTagName, OdUInt8 data1, OdUInt8 data2, OdUInt8 data3, OdUInt8 data4) override { ODFMTBEG(64) "%u, %u, %u, %u", (unsigned)data1, (unsigned)data2, (unsigned)data3, (unsigned)data4 ODFMTEND() ident(pTagName, m_sTmpBuf.c_str()); } void DropMatrix(const char* pTagName, const OdGeMatrix3d &data) override { ODFMTBEG(512) //"%g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g", //data.entry[0][0], data.entry[0][1], data.entry[0][2], data.entry[0][3], //data.entry[1][0], data.entry[1][1], data.entry[1][2], data.entry[1][3], //data.entry[2][0], data.entry[2][1], data.entry[2][2], data.entry[2][3], //data.entry[3][0], data.entry[3][1], data.entry[3][2], data.entry[3][3] ODFLTFMT( , data.entry[0][0], ), (double)(float) data.entry[0][0] ODFMTADD() ODFLTFMT(", ", data.entry[0][1], ), (double)(float) data.entry[0][1] ODFMTADD() ODFLTFMT(", ", data.entry[0][2], ), (double)(float) data.entry[0][2] ODFMTADD() ODFLTFMT(", ", data.entry[0][3], ), (double)(float) data.entry[0][3] ODFMTADD() ODFLTFMT(", ", data.entry[1][0], ), (double)(float) data.entry[1][0] ODFMTADD() ODFLTFMT(", ", data.entry[1][1], ), (double)(float) data.entry[1][1] ODFMTADD() ODFLTFMT(", ", data.entry[1][2], ), (double)(float) data.entry[1][2] ODFMTADD() ODFLTFMT(", ", data.entry[1][3], ), (double)(float) data.entry[1][3] ODFMTADD() ODFLTFMT(", ", data.entry[2][0], ), (double)(float) data.entry[2][0] ODFMTADD() ODFLTFMT(", ", data.entry[2][1], ), (double)(float) data.entry[2][1] ODFMTADD() ODFLTFMT(", ", data.entry[2][2], ), (double)(float) data.entry[2][2] ODFMTADD() ODFLTFMT(", ", data.entry[2][3], ), (double)(float) data.entry[2][3] ODFMTADD() ODFLTFMT(", ", data.entry[3][0], ), (double)(float) data.entry[3][0] ODFMTADD() ODFLTFMT(", ", data.entry[3][1], ), (double)(float) data.entry[3][1] ODFMTADD() ODFLTFMT(", ", data.entry[3][2], ), (double)(float) data.entry[3][2] ODFMTADD() ODFLTFMT(", ", data.entry[3][3], ), (double)(float) data.entry[3][3] ODFMTEND() ident(pTagName, m_sTmpBuf.c_str()); } void DropBinaryStream(const char* pTagName, const OdUInt8 * pData, OdUInt32 nData) override { ODFMTFORBEG(4) "%02X", pData[index] ODFMTEND() ident(pTagName, m_sTmpBuf.c_str()); } void DropDbOwning(const char *pTagName, OdTrVisOwning owningId) override { // possible via paper object for example //ODA_ASSERT_ONCE(pDbStub); if (owningId == kTrVisNullId) return; m_sTmpBuf.empty(); append(m_sTmpBuf, OdTrVisIdToPtr(OdDbStub, owningId)); ident(pTagName, m_sTmpBuf); } ProcessingMode ClientProcessingMode() const override { return m_procMode; } }; #include "TD_PackPop.h" #endif // ODTRXMLSERVERBASEIMPL