#ifndef _AECDBOBJXDATAMAP_H__ #define _AECDBOBJXDATAMAP_H__ #if _MSC_VER > 1000 #pragma once #endif #include #include "dbfiler.h" #include "shJson.h" #include // VARENUM / VT_* ,供 AecXData::EType 使用 #ifdef AECRXBASE_EXPORT #define AECDLLIMPEXP __declspec(dllexport) #else #define AECDLLIMPEXP __declspec(dllimport) #endif #define XData_Func_Const(ent_ptr, func_name, ...)\ {\ if ((ent_ptr))\ {\ const AecDbObjXDataMap *pMap((ent_ptr)->GetSpecialtyData());\ if (pMap) pMap->##func_name(##__VA_ARGS__);\ }\ } #define XData_Func(ent_ptr, func_name, ...)\ {\ if ((ent_ptr))\ {\ AecDbObjXDataMap *pMap((ent_ptr)->GetSpecialtyData());\ if (pMap) pMap->##func_name(##__VA_ARGS__);\ }\ } typedef std::pair SH_BIM_REC; typedef std::vector SH_BIM_BLOCK; // AecXData 会被其它模块(CoreLibrary / 各 Cmd)直接构造使用,必须随 AecRxBase 一起导出, // 否则成员函数定义在 .cpp 里时其它模块会 LNK2019(unresolved external symbol)。 typedef struct AECDLLIMPEXP AecXData { // 数据类型标签(nVt)。直接用 wtypes.h 的 VARENUM(VT_*) 组合来表达,直观且与 // 原实现逐位一致;nVt 会写入 DWG/DXF/XData,改数值会破坏旧图兼容,务必保持不变。 enum EType { kTypeShort = VT_I2, // short kTypeInt = VT_I4, // int kTypeDouble = VT_R8, // double kTypeString = VT_BSTR, // TCHAR* 字符串 kTypeSoftId = VT_UI4, // AcDbObjectId 软指针 kTypeInt64 = VT_I8, // 历史遗留(仅读) kTypeHardId = VT_UI8, // AcDbObjectId 硬指针 kTypePoint = (VT_BYREF | VT_R8), // 点,不随实体变换 kTypePointWorld = (VT_BYREF | VT_R8) + 1, // 点,随实体变换 kTypeVector = (VT_BYREF | VT_R8) + 2, // 向量,不随实体变换 kTypeVectorWorld = (VT_BYREF | VT_R8) + 3, // 向量,随实体变换 kTypeMatrix = (VT_BYREF | VT_R8) + 4, // 矩阵(16个double,二进制块,128字节) kTypeBinary = (VT_BYREF | VT_R8) + 5, // 二进制块 }; int nVt; LONG_PTR npszLen; //对应字符数据长度 union { short iVal; // short型 LONG_PTR nVal; // 整型数据 double dVal[3]; // 浮点数据 TCHAR* pszVal; // 字符数据 void* pData; // binary data }; // 1. 默认构造函数,替代原有代码中散落的 memset(&xdata, 0, sizeof(xdata)); // 实现见 AecDbObjXDataMap.cpp(随本 DLL 导出,其它模块可直接构造)。 AecXData(); // 2. 核心清理函数 void Free(); // 3. 深拷贝:先释放自身已持有的资源,再从 src 深拷贝。 // 字符串/矩阵/二进制会重新分配内存,不与 src 共享缓冲; // 支持类型变化(nVt 不同也照常覆盖)。this == &src 时直接返回。 bool CopyFrom(const AecXData &src); }AECXDATA; class AECDLLIMPEXP AecDbObjXDataMap { private: static const int g_nVersion; public: AecDbObjXDataMap(); AecDbObjXDataMap(const AecDbObjXDataMap& datamap); virtual ~AecDbObjXDataMap(); // 把 kTypeMatrix 的 16 个 double 二进制块格式化为逗号分隔文本(供显示/比较使用) static CString MatrixToString(const AecXData& xdata); public: BOOL SetAt(LPCTSTR pszKey, const int &nVal); BOOL SetAt(LPCTSTR pszKey, const DWORD &dw); BOOL SetAt(LPCTSTR pszKey, const Adesk::Int16 &nVal); BOOL SetAt(LPCTSTR pszKey, const double &dVal); BOOL SetAt(LPCTSTR pszKey,const AcGeDoubleArray& arVal); BOOL SetAt(LPCTSTR pszKey,const AcGeVector3d& vt,BOOL bTransformBy = FALSE); BOOL SetAt(LPCTSTR pszKey,const AcGePoint3d& ptGe,BOOL bTransformBy = FALSE); BOOL SetAt(LPCTSTR pszKey,const AcGePoint3dArray& arPt,BOOL bTransformBy = FALSE); BOOL SetAt(LPCTSTR pszKey,LPCTSTR pszValue); BOOL SetAt(LPCTSTR pszKey,const AcDbObjectId& id,BOOL bIsSoft = TRUE); BOOL SetAt(LPCTSTR pszKey,const AcDbHandle& handle); BOOL SetAt(LPCTSTR pszKey,const AcGeMatrix3d& xform); BOOL SetAt(LPCTSTR pszKey,void* pData,int nSize); BOOL SetAt(LPCTSTR pszKey, const AecDbObjXDataMap& xDataMap); BOOL GetAt(LPCTSTR pszKey, AecDbObjXDataMap& xDataMap); BOOL GetAt(LPCTSTR pszKey,void*& pData,int& nSize) const; BOOL GetAt(LPCTSTR pszKey,int& nVal) const; BOOL GetAt(LPCTSTR pszKey, short &nVal) const; BOOL GetAt(LPCTSTR pszKey, DWORD &dw) const; BOOL GetAt(LPCTSTR pszKey,double& dVal) const; BOOL GetAt(LPCTSTR pszKey,AcGeDoubleArray& arVal) const; BOOL GetAt(LPCTSTR pszKey,AcGeVector3d& vt) const; BOOL GetAt(LPCTSTR pszKey,AcGePoint3d& ptGe) const; BOOL GetAt(LPCTSTR pszKey,AcGePoint3dArray& arPt) const; BOOL GetAt(LPCTSTR pszKey,AcGeMatrix3d& xform) const; BOOL GetAt(LPCTSTR pszKey,CString &sValue) const; /* TCHAR [] 作为参数时,会退化为 TCHAR*。 所以, 程序中 GetAt(LPCTSTR, TCHAR[]) 的情况下,会调用此重载。 而数组退化后的指针无法使用strlen()得到 pszValue的真实长度。 内部的 strcpy() 会导致缓冲区溢出,而strcpy_s/strncpy_s 得不到长度参数,也无法使用,故废弃。 字符数组的情况,会用 下面的 GetAt(LPCTSTR pszKey, TCHAR(&va)[N]) 模板来处理。 字符串缓存的情况,会用 GetAt(LPCTSTR pszKey, TCHAR* psz, const int &len) 处理。 */ //BOOL GetAt(LPCTSTR pszKey,TCHAR* pszValue) const; BOOL GetAt(LPCTSTR pszKey,AcDbObjectId& id) const; BOOL GetAt(LPCTSTR pszKey,AcDbHandle& handle,AcDbDatabase* pDb = NULL) const; BOOL SetAt(LPCTSTR pszKey,int iIndex,LPCTSTR pszValue); BOOL GetAt(LPCTSTR pszKey,int iIndex,CString &sValue) const; BOOL SetAt(LPCTSTR pszKey,int iIndex,const AecDbObjXDataMap& xDataMap); BOOL GetAt(LPCTSTR pszKey,int iIndex,AecDbObjXDataMap& xDataMap) const; BOOL SetAt(LPCTSTR pszKey,const AecXData& XData); BOOL GetAt(LPCTSTR pszKey,AecXData& XData) const; BOOL GetAt(LPCTSTR pszKey, TCHAR* psz, const int &len) const; BOOL HasKey(LPCTSTR pszKey,int& nVt) const; void Empty(); BOOL RemoveAt(LPCTSTR pszKey); BOOL RemoveAt(LPCTSTR pszKey,int nIndex); //支持扩展数据的4个方法 bXRecord = fase 操作扩展数据 bXRecord = true 操作扩展词典 BOOL Write(AcDbObject* pEnt,LPCTSTR pszApp,BOOL bXRecord = FALSE,BOOL bAppend = FALSE,BOOL bOnlyWriteSecond = FALSE) const; BOOL Write(const AcDbObjectId& id,LPCTSTR pszApp,BOOL bXRecord = FALSE,BOOL bAppend = FALSE,BOOL bOnlyWriteSecond = FALSE) const; BOOL Write(CFile* pFileOut,BOOL bWriteUserData) const; BOOL Write(CString &strOut, BOOL bWriteUserData) const; BOOL WriteExDic(AcDbObject* pEnt,LPCTSTR pszApp) const; BOOL WriteExDic(const AcDbObjectId& id,LPCTSTR pszApp) const; BOOL ReadExDic(AcDbObject* pEnt,LPCTSTR pszApp); BOOL ReadExDic(const AcDbObjectId& id,LPCTSTR pszApp); BOOL Read(AcDbObject* pEnt,LPCTSTR pszApp,BOOL bXRecord = FALSE,BOOL bKeyAsSecond = FALSE); BOOL Read(const AcDbObjectId& id,LPCTSTR pszApp,BOOL bXRecord = FALSE,BOOL bKeyAsSecond = FALSE); BOOL Read(CFile* pFileIn,BOOL bWriteUserData); BOOL Read(LPCTSTR pszIn, BOOL bWriteUserData); AecDbObjXDataMap& operator = (const AecDbObjXDataMap& srcMap); BOOL CopyFrom(const AecDbObjXDataMap* pSrc); BOOL AppendFrom(const AecDbObjXDataMap* pSrc); virtual Acad::ErrorStatus dxfOutFields(AcDbDxfFiler* pFiler) const; virtual Acad::ErrorStatus dxfInFields(AcDbDxfFiler* pFiler); virtual Acad::ErrorStatus dwgOutFields(AcDbDwgFiler* pFiler) const; virtual Acad::ErrorStatus dwgInFields(AcDbDwgFiler* pFiler); typedef std::map::iterator It; typedef std::map::const_iterator CIt; size_t Count() const; It Begin(); BOOL GetNext(It& it,CString& sKey,AecXData& xData); It End(); //prinf输出 void List() const; // 输出到字符串数组:每个元素占两项(先 key,后 value),供界面按两列展示。 void List(std::vector &pList) const; int ComparedTo(const AecDbObjXDataMap* pXDataMap) const; // 增加 clone 的 xdatamap 的关系复制维护 void BeginCloneXlation(AecDbObjXDataMap* pMapClone,AcDbIdMapping& idMap) const; template BOOL GetAt(LPCTSTR pszKey, TCHAR(&va)[N]) const { CString s; if (GetAt(pszKey, s) == FALSE) return FALSE; // 虽然传入是的数组,最后一个字符可以不是'\0'。 // 但是,外部对字符数组的使用,大部分是按照字符串指针来使用的。 // 所以,为了外部使用的安全,还是让数组的最后一位是'\0'。 _tcsncpy_s(va, N, s, N - 1); return TRUE; } public: BOOL XDMap2Resbuf(LPCTSTR pszApp,struct resbuf*& pRb,BOOL bXRecord = FALSE,BOOL bOnlyWriteSecond = FALSE) const; BOOL Resbuf2XDMap(struct resbuf* pRb,BOOL bXRecord = FALSE,AcDbDatabase* pDb = NULL,BOOL bKeyAsSecond = FALSE ); SHJson::WValue& ToJson() const; bool ByJson(const SHJson::WValue &v); static bool getBimDatas(const AecDbObjXDataMap &XData, SH_BIM_BLOCK &bim); static bool setBimDatas(AecDbObjXDataMap &XData, const SH_BIM_BLOCK &bim); static bool findBimData(const AecDbObjXDataMap &XData , LPCTSTR pszKey , CString &strValue , CString &strUserKey ); static bool getBimData(const AecDbObjXDataMap &XData, LPCTSTR pszKey, CString &strValue); static bool setBimData(AecDbObjXDataMap &XData, LPCTSTR pszKey, LPCTSTR pszValue); static bool delBimData(AecDbObjXDataMap &XData, LPCTSTR pszKey); private: BOOL ParseToRecords(CString& sText,CStringArray& arRecords) const; BOOL ExtractRecord(CString& sRecord,CString& sKey,CString& sType,CString& sInfo) const; BOOL StringToAcGePoint3d(CString& sText,AcGePoint3d& ptGe) const; BOOL StringToAcGeVector3d(CString& sText,AcGeVector3d& ptGe) const; void SecondAsKey(CString& sTemp,AecXData& xData); // 把 xdata 以 pszKey 存入(已存在则覆盖)。接管 xdata 的所有权(内部把源置空)。 void SetXData(LPCTSTR pszKey, AecXData &xdata); private: mutable SHJson::WValue m_json;//临时,不序列化 std::map m_xData;//序列化 }; #endif //_AecDbObjXDataMap_H__