Files
envi-code/SourceCode/Code2026/AecRxBase/AecDbObjXDataMap.cpp
T
2026-09-28 15:28:50 +08:00

3686 lines
82 KiB
C++

#include "stdafx.h"
#include "geassign.h"
#include "acutmem.h"
#include "AecDbObjXDataMap.h"
#include "AecDbObjXDataMapObj.h"
#include <algorithm>
#include "comdef.h"
#include "Base64.h"
#include "BIMEntity.h"
#include "shJson.h"
#include "Base64.h"
#include "EarThwormDef.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#define MAP_BLOCK_BEGIN _T("TDBXDATAMAP_BLOCK_BEGIN_")
#define MAP_BLOCK_END _T("TDBXDATAMAP_BLOCK_END_")
#define DIF_VT_PT _T("$vector3d") // 设置向量是在键值pszkey后增加字符串"$vector3d",与点进行区分
#define BIM_REC_LEN _T("_`!@#$^&*BIM_REC_LEN*&^$#@!`_")
#define MAX_BINARYCHUNK 127
#define BINARY_CHUNKBLOCKS "binarychunkblocks"
#define BINARY_CHUNKBLOCKS1 "binarychunkblocks:"
#ifndef _ttof
#define _ttof(pszVal) _tcstod((pszVal), NULL)
#endif
using namespace SHJson;
namespace
{
WValue& toJson(const AcGePoint3d &pt, WValue &v)
{
v.SetObject();
addMember(v, _T("x"), pt.x);
addMember(v, _T("y"), pt.y);
addMember(v, _T("z"), pt.z);
return v;
}
bool byJson(const WValue &v, AcGePoint3d &pt)
{
if (v.HasMember(_T("x")) && v.HasMember(_T("y")) && v.HasMember(_T("z")))
{
pt.x = v[_T("x")].GetDouble();
pt.y = v[_T("y")].GetDouble();
pt.z = v[_T("z")].GetDouble();
return true;
}
return false;
}
WValue& toJson(const AcGeVector3d &vt, WValue &v)
{
return toJson(AcGePoint3d(vt.x, vt.y, vt.z), v);
}
bool byJson(const WValue &v, AcGeVector3d &vt)
{
AcGePoint3d pt;
if (byJson(v, pt))
{
vt.x = pt.x;
vt.y = pt.y;
vt.z = pt.z;
}
return false;
}
WValue& toJson(const AcGeMatrix3d &mat, WValue &m)
{
m.SetObject();
AcGeVector3d x, y, z;
AcGePoint3d o;
mat.getCoordSystem(o, x, y, z);
WValue jX, jY, jZ, jO;
toJson(x, jX);
toJson(y, jY);
toJson(z, jZ);
toJson(o, jO);
addMember(m, _T("x"), jX);
addMember(m, _T("y"), jY);
addMember(m, _T("z"), jZ);
addMember(m, _T("o"), jO);
return m;
}
bool byJson(const WValue &v, AcGeMatrix3d &mat)
{
MCIt itX(v.FindMember(_T("x")));
MCIt itY(v.FindMember(_T("y")));
MCIt itZ(v.FindMember(_T("z")));
MCIt itO(v.FindMember(_T("o")));
if (itX != v.MemberEnd() && itY != v.MemberEnd() && itZ != v.MemberEnd() && itO != v.MemberEnd())
{
AcGeVector3d x, y, z;
AcGePoint3d o;
byJson(itX->value, x);
byJson(itY->value, y);
byJson(itZ->value, z);
byJson(itO->value, o);
mat.setCoordSystem(o, x, y, z);
}
return false;
}
}
AecDbObjXDataMap::AecDbObjXDataMap()
{
}
AecDbObjXDataMap::AecDbObjXDataMap(const AecDbObjXDataMap& datamap)
{
if (this != &datamap)
{
//map 互相复制
m_xData.erase(m_xData.begin(),m_xData.end());
m_xData.clear();
CopyFrom(&datamap);
}
}
//
/*
struct DelStringFunc
{
void operator () (std::pair<CString,AecXData>& pairT) const
{
if (pairT.second.nVt == VT_BSTR ||
pairT.second.nVt == (VT_BYREF | VT_R8 + 4) )
{
if (pairT.second.pszVal != NULL && pairT.second.npszLen > 0)
{
delete [] pairT.second.pszVal;
pairT.second.pszVal = NULL;
pairT.second.npszLen = 0;
}
}
}
};
*/
AecDbObjXDataMap::~AecDbObjXDataMap()
{
//释放 xData 是自符串的元素
// std::for_each(m_xData.begin(),m_xData.end(),DelStringFunc());
//std::map<CString,AecXData>::iterator itor;
It itor;
for (itor = m_xData.begin();itor != m_xData.end();++itor)
{
if (itor->second.nVt == VT_BSTR ||
itor->second.nVt == (VT_BYREF | VT_R8 + 4) )
{
if (itor->second.pszVal != NULL && itor->second.npszLen > 0)
{
delete[] itor->second.pszVal;
itor->second.pszVal = NULL;
itor->second.npszLen = 0;
}
}
if ( itor->second.nVt == (VT_BYREF | VT_R8 + 5) )
{
if (itor->second.pData != NULL && itor->second.npszLen > 0)
{
delete[] itor->second.pData;
itor->second.pData = NULL;
itor->second.npszLen = 0;
}
}
}
}
BOOL AecDbObjXDataMap::SetAt( LPCTSTR pszKey,int nVal )
{
if (pszKey != NULL)
{
AecXData xdata;
memset(&xdata,0,sizeof(xdata));
xdata.nVt = VT_I4;
xdata.nVal = nVal;
It it = m_xData.find(pszKey);
if (it != m_xData.end())
{
(*it).second = xdata;
}
else
{
std::pair<CString,AecXData> pa(pszKey,xdata);
m_xData.insert(pa);
}
return TRUE;
}
return FALSE;
}
BOOL AecDbObjXDataMap::SetAt(LPCTSTR pszKey, Adesk::Int16 nVal)
{
if (pszKey != NULL)
{
AecXData xdata;
memset(&xdata, 0, sizeof(xdata));
xdata.nVt = VT_I2;
xdata.nVal = nVal;
It it = m_xData.find(pszKey);
if (it != m_xData.end())
{
(*it).second = xdata;
}
else
{
std::pair<CString, AecXData> pa(pszKey, xdata);
m_xData.insert(pa);
}
return TRUE;
}
return FALSE;
}
BOOL AecDbObjXDataMap::SetAt(LPCTSTR pszKey, DWORD dw)
{
if (pszKey != NULL)
{
AecXData xdata;
memset(&xdata,0,sizeof(xdata));
xdata.nVt = VT_I4;
xdata.nVal = dw;
It it = m_xData.find(pszKey);
if (it != m_xData.end())
{
(*it).second = xdata;
}
else
{
std::pair<CString,AecXData> pa(pszKey,xdata);
m_xData.insert(pa);
}
return TRUE;
}
return FALSE;
}
BOOL AecDbObjXDataMap::SetAt(LPCTSTR pszKey,double dVal)
{
if (pszKey != NULL)
{
AecXData xdata;
memset(&xdata,0,sizeof(xdata));
xdata.nVt = VT_R8;
xdata.dVal[0] = dVal;
It it = m_xData.find(pszKey);
if (it != m_xData.end())
{
(*it).second = xdata;
}
else
{
std::pair<CString,AecXData> pa(pszKey,xdata);
m_xData.insert(pa);
}
return TRUE;
}
return FALSE;
}
BOOL AecDbObjXDataMap::SetAt(LPCTSTR pszKey,const AcGeDoubleArray& arVal)
{
if (pszKey != NULL)
{
CString sSubKey;
for (int i = 0;i < arVal.length();++i)
{
sSubKey.Format(_T("%s%d"),pszKey,i);
SetAt(sSubKey,arVal[i]);
}
return TRUE;
}
return FALSE;
}
BOOL AecDbObjXDataMap::SetAt(LPCTSTR pszKey,const AcGeVector3d& vt,BOOL bTransformBy)
{
/*
设置向量是在键值pszkey后增加字符串"$vector3d",与点进行区分
bTransformBy标识向量是否随cad实体所变化
*/
if (pszKey != NULL)
{
CString sTmpKey = pszKey;
sTmpKey += DIF_VT_PT;
AecXData xdata;
memset(&xdata,0,sizeof(xdata));
xdata.nVt = (VT_BYREF | VT_R8 + 2);
if(bTransformBy)
{
// 向量随cad实体变化而改变
xdata.nVt = (VT_BYREF | VT_R8 + 3);
}
xdata.dVal[0] = vt.x;
xdata.dVal[1] = vt.y;
xdata.dVal[2] = vt.z;
It it = m_xData.find(sTmpKey);
if (it != m_xData.end())
{
(*it).second = xdata;
}
else
{
std::pair<CString,AecXData> pa(sTmpKey,xdata);
m_xData.insert(pa);
}
return TRUE;
}
return FALSE;
}
BOOL AecDbObjXDataMap::SetAt(LPCTSTR pszKey,const AcGePoint3d& ptGe,BOOL bTransformBy)
{
/*
bTransformBy标识点是否随cad实体所变化
*/
if (pszKey != NULL)
{
AecXData xdata;
memset(&xdata,0,sizeof(xdata));
xdata.nVt = VT_BYREF | VT_R8;
if (bTransformBy)
{
// 点随cad实体变化而改变
xdata.nVt = (VT_BYREF|VT_R8 + 1);
}
xdata.dVal[0] = ptGe.x;
xdata.dVal[1] = ptGe.y;
xdata.dVal[2] = ptGe.z;
It it = m_xData.find(pszKey);
if (it != m_xData.end())
{
(*it).second = xdata;
}
else
{
std::pair<CString,AecXData> pa(pszKey,xdata);
m_xData.insert(pa);
}
return TRUE;
}
return FALSE;
}
BOOL AecDbObjXDataMap::SetAt(LPCTSTR pszKey,const AcGePoint3dArray& arPt,BOOL bTransformBy)
{
if (pszKey != NULL)
{
CString sSubKey;
for (int i = 0;i < arPt.length();++i)
{
sSubKey.Format(_T("%s%d"),pszKey,i);
SetAt(sSubKey,arPt[i],bTransformBy);
}
return TRUE;
}
return FALSE;
}
BOOL AecDbObjXDataMap::SetAt(LPCTSTR pszKey,const AcGeMatrix3d& xform)
{
if (pszKey != NULL)
{
AecXData xdata;
memset(&xdata,0,sizeof(xdata));
xdata.nVt = (VT_BYREF | VT_R8 + 4);
CString sText = _T(""),sTemp;
for (int i = 0;i < 4;i++)
{
for (int j = 0;j < 4;j++)
{
sTemp.Format(_T("%.9f"),xform.entry[i][j]);
sText += _T(",") + sTemp;
}
}
sText.TrimLeft(_T(","));
xdata.npszLen = sText.GetLength() + 1;
xdata.pszVal = new TCHAR[xdata.npszLen];
::memset(xdata.pszVal, 0, sizeof(xdata.npszLen) * sizeof(TCHAR));
_tcsncpy_s(xdata.pszVal, xdata.npszLen, sText, xdata.npszLen - 1);
It it = m_xData.find(pszKey);
if (it != m_xData.end()) //找到
{
if ( (*it).second.nVt == VT_BSTR ||
(*it).second.nVt == (VT_BYREF | VT_R8 + 4) )
{
if ( (*it).second.npszLen > 0 && (*it).second.pszVal != NULL)
{
delete[] (*it).second.pszVal;
}
}
(*it).second = xdata;
}
else //未找到
{
std::pair<CString,AecXData> pa(pszKey,xdata);
m_xData.insert(pa);
}
return TRUE;
}
return FALSE;
}
BOOL AecDbObjXDataMap::SetAt(LPCTSTR pszKey,void* pData,int nSize)
{
if (pszKey != NULL && nSize > 0 && pData != NULL)
{
AecXData xdata;
memset(&xdata,0,sizeof(xdata));
xdata.nVt = (VT_BYREF | VT_R8 + 5);
xdata.npszLen = nSize;
xdata.pData = new byte[nSize];
memcpy(xdata.pData,pData,nSize);
It it = m_xData.find(pszKey);
if (it != m_xData.end()) //找到
{
if ( (*it).second.nVt == VT_BSTR ||
(*it).second.nVt == (VT_BYREF | VT_R8 + 5) )
{
if ( (*it).second.npszLen > 0 && (*it).second.pszVal != NULL)
{
delete[] (*it).second.pszVal;
}
}
(*it).second = xdata;
}
else //未找到
{
std::pair<CString,AecXData> pa(pszKey,xdata);
m_xData.insert(pa);
}
return TRUE;
}
return FALSE;
}
static BOOL Script2StringArray(const CString& sScript,TCHAR tSpace,CStringArray& arTexts)
{
//x,y,z,d,a
int nPos = -1,nStart = 0;
CString sText;
while(TRUE)
{
nPos = sScript.Find(tSpace,nStart);
if (nPos != -1)
{
sText = sScript.Mid(nStart,nPos - nStart);
arTexts.Add(sText);
nStart = nPos + 1;
}
else
{
if (nStart <= sScript.GetLength() - 1)
{
sText = sScript.Mid(nStart);
arTexts.Add(sText);
}
break;
}
}
return arTexts.GetSize() > 0;
}
BOOL AecDbObjXDataMap::GetAt(LPCTSTR pszKey,AcGeMatrix3d& xform) const
{
if (pszKey != NULL)
{
CIt it;
if ((it = m_xData.find(pszKey)) != m_xData.end())
{
AecXData xdata = (*it).second;
if ( xdata.nVt == (VT_BYREF | VT_R8 + 4))
{
CString sText = xdata.pszVal;
CStringArray arTexts;
Script2StringArray(sText,_T(','),arTexts);
if (arTexts.GetSize() == 16)
{
for (int i = 0;i < 4;i++)
{
for (int j = 0;j < 4;j++)
{
xform.entry[i][j] = _ttof(arTexts.GetAt(i * 4 + j));
}
}
return TRUE;
}
}
}
}
return FALSE;
}
BOOL AecDbObjXDataMap::SetAt(LPCTSTR pszKey,LPCTSTR pszValue)
{
if (pszKey != NULL)
{
int nVt = 0;
if (HasKey(pszKey, nVt))
{
RemoveAt(pszKey);
}
CString sTmp = pszValue;
//if(sTmp.GetLength() >= MAX_PATH)
//return FALSE;
if (_tcslen(pszValue) < 0)
return FALSE;
AecXData xdata;
memset(&xdata,0,sizeof(xdata));
xdata.nVt = VT_BSTR;
xdata.npszLen = _tcslen(pszValue) + 1;
xdata.pszVal = new TCHAR[xdata.npszLen];
memset(xdata.pszVal,0,xdata.npszLen);
_tcsncpy_s(xdata.pszVal, xdata.npszLen, pszValue, xdata.npszLen - 1);
It it = m_xData.find(pszKey);
if (it != m_xData.end())
{
// Rem:.2010.7.23 原来的要删除
if ((*it).second.npszLen > 0 && (*it).second.pszVal != NULL)
delete[] (*it).second.pszVal;
//(*it).second = xdata;
(*it).second.pszVal = new TCHAR[xdata.npszLen];
memset((*it).second.pszVal,0,xdata.npszLen);
_tcsncpy_s((*it).second.pszVal, xdata.npszLen, pszValue, xdata.npszLen - 1);
delete[] xdata.pszVal;
xdata.pszVal = NULL;
}
else
{
std::pair<CString,AecXData> pa(pszKey,xdata);
m_xData.insert(pa);
}
return TRUE;
}
return FALSE;
}
BOOL AecDbObjXDataMap::SetAt(LPCTSTR pszKey,int iIndex,LPCTSTR pszValue)
{
if (pszKey != NULL)
{
CString sKey;
sKey.Format(_T("%s_%d"),pszKey,iIndex);
return SetAt(sKey,pszValue);
}
return FALSE;
}
BOOL AecDbObjXDataMap::GetAt(LPCTSTR pszKey,int iIndex,CString &sValue) const
{
if (pszKey != NULL)
{
CString sKey;
sKey.Format(_T("%s_%d"),pszKey,iIndex);
return GetAt(sKey,sValue);
}
return FALSE;
}
BOOL AecDbObjXDataMap::SetAt(LPCTSTR pszKey,int iIndex,const AecDbObjXDataMap& xDataMap)
{
//{key | type | inf}个隔开
CString sKey,sType,sInfo,sRecord,sText;
sText = _T("");
AecXData xdata;
memset(&xdata,0,sizeof(AecXData));
for (CIt it = xDataMap.m_xData.begin(); it != xDataMap.m_xData.end(); ++it)
{
xdata = (*it).second;
sKey = (*it).first;
sType = _T("");
sInfo = _T("");
switch (xdata.nVt)
{
case VT_I2:
{
sType.Format(_T("%d"), VT_I2);
sInfo.Format(_T("%d"), xdata.iVal);
sRecord.Format(_T("{%s|%s|%s}"), sKey, sType, sInfo);
sText += sRecord;
break;
}
case VT_I4: // 整型
{
sType.Format(_T("%d"),VT_I4);
sInfo.Format(_T("%d"),xdata.nVal);
sRecord.Format(_T("{%s|%s|%s}"),sKey,sType,sInfo);
sText += sRecord;
break;
}
case VT_UI4:
{
sType.Format(_T("%d"),VT_UI4);
sInfo.Format(_T("%d"),xdata.nVal);
sRecord.Format(_T("{%s|%s|%s}"),sKey,sType,sInfo);
sText += sRecord;
break;
}
case VT_UI8:
{
sType.Format(_T("%d"),VT_UI8);
sInfo.Format(_T("%d"),xdata.nVal);
sRecord.Format(_T("{%s|%s|%s}"),sKey,sType,sInfo);
sText += sRecord;
break;
}
case VT_R8: // 浮点
{
sType.Format(_T("%d"),VT_R8);
sInfo.Format(_T("%.9f"),xdata.dVal[0]);
sRecord.Format(_T("{%s|%s|%s}"),sKey,sType,sInfo);
sText += sRecord;
break;
}
case (VT_BYREF | VT_R8): // 点
{
sType.Format(_T("%d"),(VT_BYREF | VT_R8));
sInfo.Format(_T("%.4f,%.4f,%.4f"),xdata.dVal[0],xdata.dVal[1],xdata.dVal[2]);
sRecord.Format(_T("{%s|%s|%s}"),sKey,sType,sInfo);
sText += sRecord;
break;
}
case (VT_BYREF | VT_R8 + 1): // cad变化点
{
sType.Format(_T("%d"),(VT_BYREF | VT_R8 + 1));
sInfo.Format(_T("%.9f,%.9f,%.9f"),xdata.dVal[0],xdata.dVal[1],xdata.dVal[2]);
sRecord.Format(_T("{%s|%s|%s}"),sKey,sType,sInfo);
sText += sRecord;
break;
}
case (VT_BYREF | VT_R8 + 2): // 向量
{
sType.Format(_T("%d"),(VT_BYREF | VT_R8 + 2));
sInfo.Format(_T("%.9f,%.9f,%.9f"),xdata.dVal[0],xdata.dVal[1],xdata.dVal[2]);
sRecord.Format(_T("{%s|%s|%s}"),sKey,sType,sInfo);
sText += sRecord;
break;
}
case (VT_BYREF | VT_R8 + 3): // 变化向量
{
sType.Format(_T("%d"),(VT_BYREF | VT_R8 + 3));
sInfo.Format(_T("%.9f,%.9f,%.9f"),xdata.dVal[0],xdata.dVal[1],xdata.dVal[2]);
sRecord.Format(_T("{%s|%s|%s}"),sKey,sType,sInfo);
sText += sRecord;
break;
}
case (VT_BYREF | VT_R8 + 4): // 矩阵
{
sType.Format(_T("%d"),VT_BYREF | VT_R8 + 4);
sInfo.Format(_T("%s"),xdata.pszVal);
sRecord.Format(_T("{%s|%s|%s}"),sKey,sType,sInfo);
sText += sRecord;
break;
}
case (VT_BYREF | VT_R8 + 5): // binary data
{
break;
}
case VT_BSTR: // 字符串
{
sType.Format(_T("%d"),VT_BSTR);
sInfo.Format(_T("%s"),xdata.pszVal);
sRecord.Format(_T("{%s|%s|%s}"),sKey,sType,sInfo);
sText += sRecord;
break;
}
break;
default:
break;
}
}
if (!sText.IsEmpty())
return SetAt(pszKey,iIndex,sText);
return FALSE;
}
BOOL AecDbObjXDataMap::ParseToRecords(CString& sText,CStringArray& arRecords) const
{
CString sRecord;
int nFr = 0,nTo = 0;
//{Key|Type|Info}...
while(TRUE)
{
nFr = sText.Find(_T("{"),0);
nTo = sText.Find(_T("}"),0);
if (nFr == 0 && nTo > 0)
{
sRecord = sText.Mid(nFr,nTo + 1);
sRecord.TrimLeft(_T("{"));
sRecord.TrimRight(_T("}"));
arRecords.Add(sRecord);
if (nTo + 1 < sText.GetLength())
{
sRecord = sText.Mid(nTo + 1);
sText = sRecord;
}
else
{
break;
}
}
else
{
break;
}
}
return arRecords.GetSize() > 0;
}
BOOL AecDbObjXDataMap::ExtractRecord(CString& sRecord,CString& sKey,CString& sType,CString& sInfo) const
{
//Key|int|Info
int nFr = sRecord.Find(_T("|"),0);
if (nFr != -1)
{
CString sTemp;
sKey = sRecord.Mid(0,nFr);
if (nFr + 1 < sRecord.GetLength())
{
sTemp = sRecord.Mid(nFr + 1);
sRecord = sTemp;
nFr = sRecord.Find(_T("|"),0);
if (nFr != -1)
{
sType = sRecord.Mid(0,nFr);
if (nFr + 1 < sRecord.GetLength())
{
sInfo = sRecord.Mid(nFr + 1);
return TRUE;
}
}
}
}
return FALSE;
}
BOOL AecDbObjXDataMap::StringToAcGePoint3d(CString& sText,AcGePoint3d& ptGe) const
{
//x,y,z
CString sX,sY,sZ;
int nFr = sText.Find(_T(","),0);
if (nFr != -1)
{
CString sTemp;
sX = sText.Mid(0,nFr);
if (nFr + 1 < sText.GetLength())
{
sTemp = sText.Mid(nFr + 1);
sText = sTemp;
nFr = sText.Find(_T(","),0);
if (nFr != -1)
{
sY = sText.Mid(0,nFr);
if (nFr + 1 < sText.GetLength())
{
sZ = sText.Mid(nFr + 1);
ptGe.set(_ttof(sX),_ttof(sY),_ttof(sZ));
return TRUE;
}
}
}
}
return FALSE;
}
BOOL AecDbObjXDataMap::StringToAcGeVector3d(CString& sText,AcGeVector3d& vt) const
{
//x,y,z
AcGePoint3d ptGe;
if (StringToAcGePoint3d(sText,ptGe))
{
vt = ptGe.asVector();
return TRUE;
}
return FALSE;
}
BOOL AecDbObjXDataMap::GetAt(LPCTSTR pszKey,int iIndex,AecDbObjXDataMap& xDataMap) const
{
CString sKey,sType,sInfo,sText,sRecord;
AcGePoint3d ptGe;
AcGeVector3d vt;
BOOL bSuccess = FALSE;
AcDbObjectId id;
AecXData xDat;
if (GetAt(pszKey,iIndex,sText))
{
sText.TrimLeft();
sText.TrimRight();
if (sText.GetLength() > 1)
{
CStringArray arRecords;
bSuccess = ParseToRecords(sText,arRecords);
for (int i = 0;i < arRecords.GetSize();i++)
{
sRecord = arRecords.GetAt(i);
if (ExtractRecord(sRecord,sKey,sType,sInfo))
{
int nVt = _ttoi(sType);
switch (nVt)
{
case VT_I2:
{
xDataMap.SetAt(sKey, (short)_ttoi(sInfo));
break;
}
case VT_I4: // 整型
{
xDataMap.SetAt(sKey,_ttoi(sInfo));
break;
}
case VT_UI4:
{
id.setFromOldId((INT_PTR)_ttoi(sInfo));
xDataMap.SetAt(sKey,id);
break;
}
case VT_UI8:
{
id.setFromOldId((INT_PTR)_ttoi(sInfo));
xDataMap.SetAt(sKey,id,FALSE);
break;
}
case VT_R8: // 浮点
{
xDataMap.SetAt(sKey,_ttof(sInfo));
break;
}
case (VT_BYREF | VT_R8): // 点
{
if (StringToAcGePoint3d(sInfo,ptGe))
{
xDataMap.SetAt(sKey,ptGe);
}
break;
}
case (VT_BYREF | VT_R8 + 1): // cad变化点
{
if (StringToAcGePoint3d(sInfo,ptGe))
{
xDataMap.SetAt(sKey,ptGe,TRUE);
}
break;
}
case (VT_BYREF | VT_R8 + 2): // 向量
{
if (StringToAcGeVector3d(sInfo,vt))
{
sKey.Replace(DIF_VT_PT,_T(" "));
sKey.TrimRight();
xDataMap.SetAt(sKey,vt);
}
break;
}
case (VT_BYREF | VT_R8 + 3): // 变化向量
{
if (StringToAcGeVector3d(sInfo,vt))
{
sKey.Replace(DIF_VT_PT,_T(" "));
sKey.TrimRight();
xDataMap.SetAt(sKey,vt,TRUE);
}
break;
}
case (VT_BYREF | VT_R8 + 4): //矩阵
{
memset(&xDat,0,sizeof(AecXData));
xDat.npszLen = sInfo.GetLength() + 1;
xDat.pszVal = new TCHAR[xDat.npszLen];
_tcsncpy_s(xDat.pszVal, xDat.npszLen, sInfo, xDat.npszLen - 1);
xDataMap.SetAt(sKey,xDat);
delete[] xDat.pszVal;
break;
}
case (VT_BYREF | VT_R8 + 5): //binary data
{
break;
}
case VT_BSTR: // 字符串
{
xDataMap.SetAt(sKey,sInfo);
break;
}
break;
default:
break;
}
}
else
{
//按照常规处理
xDataMap.SetAt(pszKey,iIndex,sText);
bSuccess = TRUE;
}
}
}
else
{
//按照常规处理
xDataMap.SetAt(pszKey,iIndex,sText);
bSuccess = TRUE;
}
}
return bSuccess;
}
BOOL AecDbObjXDataMap::SetAt(LPCTSTR pszKey,const AcDbObjectId& id,BOOL bIsSoft)
{
if (pszKey != NULL)
{
AecXData xdata;
memset(&xdata,0,sizeof(xdata));
xdata.nVt = VT_UI4;
if (!bIsSoft) xdata.nVt = VT_UI8;
xdata.nVal = id.asOldId();
It it = m_xData.find(pszKey);
if (it != m_xData.end())
{
(*it).second = xdata;
}
else
{
std::pair<CString,AecXData> pa(pszKey,xdata);
m_xData.insert(pa);
}
return TRUE;
}
return FALSE;
}
BOOL AecDbObjXDataMap::SetAt(LPCTSTR pszKey,const AcDbHandle& handle)
{
if (pszKey != NULL)
{
TCHAR szHandleStr[19];
memset(szHandleStr,0,sizeof(szHandleStr) );
handle.getIntoAsciiBuffer(szHandleStr);
LPCTSTR pszVal = szHandleStr;
return SetAt(pszKey,pszVal);
}
return FALSE;
}
BOOL AecDbObjXDataMap::SetAt(LPCTSTR pszKey,const AecXData& XData)
{
if (pszKey != NULL)
{
It it = m_xData.find(pszKey);
if (it != m_xData.end()) //找到
{
if ( (*it).second.nVt == XData.nVt ) //判断类型相同
{
if ( (*it).second.nVt == VT_BSTR ||
(*it).second.nVt == (VT_BYREF | VT_R8 + 4) ) //字符串特殊处理
{
// mcl changed to below 2010.7.23
// if ((*it).second.npszLen > 0 && (*it).second.pszVal != NULL) //清空原来的
// {
// delete [] (*it).second.pszVal;
// }
// 重新分配空间赋值
if (XData.npszLen > 0 && XData.pszVal != NULL)
{
if ((*it).second.npszLen > 0 && (*it).second.pszVal != NULL) //清空原来的
delete[] (*it).second.pszVal;
(*it).second = XData;
(*it).second.pszVal = new TCHAR[XData.npszLen];
memset((*it).second.pszVal,0,XData.npszLen);
_tcsncpy_s((*it).second.pszVal, XData.npszLen, XData.pszVal, XData.npszLen - 1);
}
}
else if( (*it).second.nVt == (VT_BYREF | VT_R8 + 5) )//binary data
{
// 重新分配空间赋值
if (XData.npszLen > 0 && XData.pData != NULL)
{
if ((*it).second.npszLen > 0 && (*it).second.pData != NULL) //清空原来的
delete[] (*it).second.pData;
(*it).second = XData;
(*it).second.pData = new byte[XData.npszLen];
memset((*it).second.pData,0,XData.npszLen);
memcpy((*it).second.pData,XData.pData,XData.npszLen);
}
}
else
{
(*it).second = XData;
}
}
}
else
{
if (XData.nVt == VT_BSTR ||
XData.nVt == (VT_BYREF | VT_R8 + 4))
{
SetAt(pszKey,XData.pszVal);
}
else
{
std::pair<CString,AecXData> pa(pszKey,XData);
m_xData.insert(pa);
}
}
return TRUE;
}
return FALSE;
}
BOOL AecDbObjXDataMap::GetAt(LPCTSTR pszKey,AecXData& XData) const
{
if (pszKey != NULL)
{
CIt it;
if ((it = m_xData.find(pszKey)) != m_xData.end())
{
XData = (*it).second;
return TRUE;
}
}
return FALSE;
}
BOOL AecDbObjXDataMap::GetAt(LPCTSTR pszKey,void*& pData,int& nSize) const
{
if (pszKey != NULL)
{
AecXData XData;
CIt it;
if ((it = m_xData.find(pszKey)) != m_xData.end())
{
XData = (*it).second;
if (XData.nVt == (VT_BYREF | VT_R8 + 5) )
{
if (XData.npszLen > 0)
{
pData = new byte[XData.npszLen];
memcpy(pData,XData.pData,XData.npszLen);
nSize = XData.npszLen;
return TRUE;
}
}
}
}
return FALSE;
}
BOOL AecDbObjXDataMap::GetAt(LPCTSTR pszKey, DWORD & dw) const
{
if (pszKey != NULL)
{
CIt it;
if ((it = m_xData.find(pszKey)) != m_xData.end())
{
AecXData xdata = (*it).second;
if (xdata.nVt == VT_I4)
{
dw = (int)xdata.nVal;
return TRUE;
}
}
}
return FALSE;
}
BOOL AecDbObjXDataMap::GetAt(LPCTSTR pszKey,int& nVal) const
{
if (pszKey != NULL)
{
CIt it;
if ((it = m_xData.find(pszKey)) != m_xData.end())
{
AecXData xdata = (*it).second;
if (xdata.nVt == VT_I4)
{
nVal = (int)xdata.nVal;
return TRUE;
}
}
}
return FALSE;
}
BOOL AecDbObjXDataMap::GetAt(LPCTSTR pszKey, short &nVal) const
{
if (pszKey != NULL)
{
CIt it;
if ((it = m_xData.find(pszKey)) != m_xData.end())
{
AecXData xdata = (*it).second;
if (xdata.nVt == VT_I2)//优先
{
nVal = (short)xdata.iVal;
return TRUE;
}
}
}
return FALSE;
}
BOOL AecDbObjXDataMap::GetAt(LPCTSTR pszKey,double& dVal) const
{
if (pszKey != NULL)
{
CIt it;
if ((it = m_xData.find(pszKey)) != m_xData.end())
{
AecXData xdata = (*it).second;
if (xdata.nVt == VT_R8)
{
dVal = xdata.dVal[0];
return TRUE;
}
else if (xdata.nVt == VT_I4)
{
dVal = 1.0 * xdata.nVal;
return TRUE;
}
else if (xdata.nVt == VT_I2)//优先
{
dVal = 1.0 * xdata.iVal;
return TRUE;
}
}
}
return FALSE;
}
BOOL AecDbObjXDataMap::GetAt(LPCTSTR pszKey,AcGeDoubleArray& arVal) const
{
arVal.setLogicalLength(0);
if (pszKey != NULL)
{
CString sSubKey;
double dVal;
int nIndex = 0;
sSubKey.Format(_T("%s%d"),pszKey,nIndex++);
while(GetAt(sSubKey,dVal))
{
arVal.append(dVal);
sSubKey.Format(_T("%s%d"),pszKey,nIndex++);
}
}
return (arVal.length() > 0);
}
BOOL AecDbObjXDataMap::GetAt(LPCTSTR pszKey,AcGeVector3d& vt) const
{
/*
由于设置向量是将键值pszkey后增加字符串"$vector3d",
故获取向量时在键值pszkey后增加字符串"$vector3d"
*/
if (pszKey != NULL)
{
CString sTmpKey = pszKey;
sTmpKey += DIF_VT_PT;
CIt it;
if ((it = m_xData.find(sTmpKey)) != m_xData.end())
{
AecXData xdata = (*it).second;
if ((xdata.nVt == (VT_BYREF | VT_R8) + 2)
|| (xdata.nVt == ((VT_BYREF | VT_R8) + 3)))
{
vt.x = xdata.dVal[0];
vt.y = xdata.dVal[1];
vt.z = xdata.dVal[2];
return TRUE;
}
}
}
return FALSE;
}
BOOL AecDbObjXDataMap::GetAt(LPCTSTR pszKey,AcGePoint3d& ptGe) const
{
if (pszKey != NULL)
{
CIt it;
if ((it = m_xData.find(pszKey)) != m_xData.end())
{
AecXData xdata = (*it).second;
if ( (xdata.nVt == (VT_BYREF | VT_R8))
|| (xdata.nVt == (VT_BYREF | VT_R8 + 1)))
{
ptGe.x = xdata.dVal[0];
ptGe.y = xdata.dVal[1];
ptGe.z = xdata.dVal[2];
return TRUE;
}
}
}
return FALSE;
}
BOOL AecDbObjXDataMap::GetAt(LPCTSTR pszKey,AcGePoint3dArray& arPt) const
{
arPt.setLogicalLength(0);
if (pszKey != NULL)
{
CString sSubKey;
AcGePoint3d pt;
int nIndex = 0;
sSubKey.Format(_T("%s%d"),pszKey,nIndex++);
while(GetAt(sSubKey,pt))
{
arPt.append(pt);
sSubKey.Format(_T("%s%d"),pszKey,nIndex++);
}
}
return (arPt.length() > 0);
}
BOOL AecDbObjXDataMap::GetAt(LPCTSTR pszKey,CString &sValue) const
{
if (pszKey != NULL)
{
CIt it;
if ((it = m_xData.find(pszKey)) != m_xData.end())
{
AecXData xdata = (*it).second;
if (xdata.nVt == VT_BSTR ||
xdata.nVt == (VT_BYREF | VT_R8 + 4))
{
sValue = xdata.pszVal;
return TRUE;
}
else if (xdata.nVt == VT_I4 || xdata.nVt == VT_I8)
{
sValue.Format(_T("%d"), xdata.nVal);
return TRUE;
}
else if (xdata.nVt == VT_I2)
{
sValue.Format(_T("%d"), xdata.iVal);
return TRUE;
}
else if (xdata.nVt == VT_R8)
{
sValue.Format(_T("%.9f"), xdata.dVal[0]);
sValue.TrimRight(_T('0'));
return TRUE;
}
}
}
return FALSE;
}
//BOOL AecDbObjXDataMap::GetAt(LPCTSTR pszKey,TCHAR* pszValue) const
//{
// if (pszKey != NULL && pszValue != NULL)
// {
// CIt it;
// if ((it = m_xData.find(pszKey)) != m_xData.end())
// {
// AecXData xdata = (*it).second;
//
// if (xdata.nVt == VT_BSTR ||
// xdata.nVt == (VT_BYREF | VT_R8 + 4) )
// {
// _tcscpy(pszValue,xdata.pszVal);
// return TRUE;
// }
// else if (xdata.nVt == VT_I4 || xdata.nVt == VT_I8)
// {
// swprintf(pszValue,_T("%d"), (int)xdata.nVal);
// return TRUE;
// }
// else if (xdata.nVt == VT_I2)
// {
// swprintf(pszValue, _T("%d"), (int)xdata.iVal);
// return TRUE;
// }
// else if (xdata.nVt == VT_R8)
// {
// swprintf(pszValue,_T("%.9f"), xdata.dVal[0]);
// return TRUE;
// }
// }
// }
// return FALSE;
//}
BOOL AecDbObjXDataMap::GetAt(LPCTSTR pszKey,AcDbObjectId& id) const
{
if (pszKey != NULL)
{
CIt it;
if ((it = m_xData.find(pszKey) ) != m_xData.end())
{
AecXData xdata = (*it).second;
if (xdata.nVt == VT_UI4 ||
xdata.nVt == VT_UI8)
{
id.setFromOldId(xdata.nVal);
return TRUE;
}
}
}
return FALSE;
}
BOOL AecDbObjXDataMap::GetAt(LPCTSTR pszKey,AcDbHandle& handle,AcDbDatabase* pDb/* = NULL*/) const
{
CString sVal;
if (GetAt(pszKey,sVal))
{
AcDbHandle handleT((LPCTSTR)sVal);
if (pDb == NULL)
pDb = acdbCurDwg();
if (pDb != NULL)
{
AcDbObjectId id;
if ( Acad::eOk == pDb->getAcDbObjectId(id,false,handleT) )
{
handle = handleT;
return TRUE;
}
}
}
return FALSE;
}
BOOL AecDbObjXDataMap::GetAt(LPCTSTR pszKey, TCHAR * psz, const int & len) const
{
CString str(_T(""));
if (GetAt(pszKey, str))
{
if (str.GetLength() < len && psz)
{
::memset(psz, 0, len * sizeof(TCHAR));
_tcsncpy_s(psz, len, str, len-1);
return TRUE;
}
}
return FALSE;
}
BOOL AecDbObjXDataMap::HasKey(LPCTSTR pszKey,int& nVt) const
{
if (pszKey != NULL)
{
CString sTmpKey = pszKey;
sTmpKey += DIF_VT_PT;
CIt it;
it = m_xData.find(pszKey);
if (it != m_xData.end())
{
AecXData xdata = it->second;//m_xData[pszKey];
nVt = xdata.nVt;
return TRUE;
}
it = m_xData.find(sTmpKey);
if( it != m_xData.end())
{
AecXData xdata = it->second;//m_xData[sTmpKey];
nVt = xdata.nVt;
return TRUE;
}
else
{
return FALSE;
}
}
return FALSE;
}
void AecDbObjXDataMap::Empty()
{
m_xData.clear();
}
BOOL AecDbObjXDataMap::RemoveAt(LPCTSTR pszKey)
{
if (pszKey != NULL)
{
CString sTmpKey = pszKey;
sTmpKey += DIF_VT_PT;
It it = m_xData.find(pszKey);
It it1 = m_xData.find(sTmpKey);
if (it != m_xData.end())
{
if ( (*it).second.nVt == VT_BSTR ||
(*it).second.nVt == (VT_BYREF | VT_R8 + 4) )
{
if ((*it).second.npszLen > 0 && (*it).second.pszVal != NULL)
{
delete[] (*it).second.pszVal;
}
(*it).second.pszVal = NULL;
}
if ( (*it).second.nVt == (VT_BYREF | VT_R8 + 5) )
{
if ((*it).second.npszLen > 0 && (*it).second.pData != NULL)
{
delete[] (*it).second.pData;
(*it).second.pData = NULL;
}
}
m_xData.erase(it);
//m_xData.clear();
return TRUE;
}
else if(it1 != m_xData.end())
{
if ( (*it1).second.nVt == VT_BSTR ||
(*it1).second.nVt == (VT_BYREF | VT_R8 + 4) )
{
if ((*it1).second.pszVal != NULL)
{
delete[] (*it1).second.pszVal;
}
(*it1).second.pszVal = NULL;
}
if ( (*it1).second.nVt == (VT_BYREF | VT_R8 + 5) )
{
if ((*it1).second.npszLen > 0 && (*it1).second.pData != NULL)
{
delete[] (*it1).second.pData;
(*it1).second.pData = NULL;
}
}
m_xData.erase(it1);
//m_xData.clear();
return TRUE;
}
else
{
return FALSE;
}
}
return FALSE;
}
BOOL AecDbObjXDataMap::RemoveAt(LPCTSTR pszKey,int nIndex)
{
if (pszKey != NULL)
{
CString sKey;
sKey.Format(_T("%s_%d"),pszKey,nIndex);
return RemoveAt(sKey);
}
return FALSE;
}
AecDbObjXDataMap& AecDbObjXDataMap::operator = (const AecDbObjXDataMap& srcMap)
{
if (this != &srcMap)
{
//map 互相复制
m_xData.erase(m_xData.begin(),m_xData.end());
m_xData.clear();
CopyFrom(&srcMap);
}
return *this;
}
BOOL AecDbObjXDataMap::CopyFrom(const AecDbObjXDataMap* pSrc)
{
AecDbObjXDataMap* pTDbXDataMap = (AecDbObjXDataMap*) pSrc;
if(pTDbXDataMap != NULL && this != pSrc)
{
//map 互相复制
//m_xData = pSrc->m_xData;
m_xData.erase(m_xData.begin(),m_xData.end());
m_xData.clear();
for (CIt it = pSrc->m_xData.begin();it != pSrc->m_xData.end();it++)
{
if ( (*it).second.nVt == VT_BSTR /*||
(*it).second.nVt == (VT_BYREF | VT_R8 + 4 )*/)
{
//VT_BYREF | VT_R8 + 4 类型不能以字符串复制
//直接 INSERT 2013-10-10
SetAt( (*it).first,(*it).second);
}
else
{
if ((*it).second.nVt == (VT_BYREF | VT_R8 + 4 ))
{
AcGeMatrix3d xform;
pSrc->GetAt( (*it).first,xform);
SetAt((*it).first,xform);
}
else if ((*it).second.nVt == (VT_BYREF | VT_R8 + 5 ))
{
AecXData xData;
pSrc->GetAt((*it).first,xData);
SetAt((*it).first,xData.pData,xData.npszLen);
}
else
{
m_xData.insert( (*it) );
}
}
}
return TRUE;
}
return FALSE;
}
BOOL AecDbObjXDataMap::AppendFrom(const AecDbObjXDataMap* pSrc)
{
AecDbObjXDataMap* pTDbXDataMap = (AecDbObjXDataMap*) pSrc;
if(pTDbXDataMap != NULL && this != pSrc)
{
for (CIt it = pSrc->m_xData.begin();it != pSrc->m_xData.end();it++)
{
if ( (*it).second.nVt == VT_BSTR /*||
(*it).second.nVt == (VT_BYREF | VT_R8 + 4 )*/)
{
//VT_BYREF | VT_R8 + 4 类型不能以字符串复制
//直接 INSERT 2013-10-10
RemoveAt((*it).first);
SetAt( (*it).first,(*it).second);
}
else
{
if ((*it).second.nVt == (VT_BYREF | VT_R8 + 4 ))
{
AcGeMatrix3d xform;
pSrc->GetAt( (*it).first,xform);
SetAt((*it).first,xform);
}
else if ((*it).second.nVt == (VT_BYREF | VT_R8 + 5 ))
{
AecXData xData;
pSrc->GetAt((*it).first,xData);
SetAt((*it).first,xData.pData,xData.npszLen);
}
else
{
m_xData.insert( (*it) );
}
}
}
return TRUE;
}
return FALSE;
}
AecDbObjXDataMap::It AecDbObjXDataMap::Begin()
{
return m_xData.begin();
}
BOOL AecDbObjXDataMap::GetNext(It& it,CString& sKey,AecXData& xData)
{
if (it != m_xData.end())
{
if ((*it).second.nVt == VT_BSTR)
{
if ((*it).second.npszLen > 0 && (*it).second.pszVal != NULL)
{
memset(&xData, 0, sizeof(AecXData));
xData.nVt = VT_BSTR;
xData.npszLen = (*it).second.npszLen;//!!!
xData.pszVal = new TCHAR[xData.npszLen];//!!!
_tcsncpy_s(xData.pszVal, xData.npszLen, (*it).second.pszVal, xData.npszLen - 1);//!!!
}
else
{
//异常-->VT_I4 0 代替
memset(&xData, 0, sizeof(AecXData));
xData.nVt = VT_I4;
}
}
else
{
xData = (*it).second;
sKey = (*it).first;
}
++it;
return TRUE;
}
return FALSE;
}
AecDbObjXDataMap::It AecDbObjXDataMap::End()
{
return m_xData.end();
}
void AecDbObjXDataMap::List() const
{
AecXData xdata;
int nVt = -1;
AcGePoint3d ptVal;
AcGeVector3d vt;
AcDbObjectId id;
for (CIt it = m_xData.begin(); it != m_xData.end(); ++it)
{
xdata = (*it).second;
nVt = xdata.nVt;
acutPrintf(_T("\n%s:"),(const TCHAR *)(*it).first);
switch (nVt)
{
case VT_I2:
acutPrintf(_T("%d : VT_I2"), (int)xdata.iVal);
break;
case VT_I4: // 整型
acutPrintf(_T("%d : VT_I4"),(int)xdata.nVal);
break;
case VT_UI4: //s id
#ifndef _WIN64
acutPrintf(_T("%ld : VT_UI4"),xdata.nVal);
#else
acutPrintf(_T("%d : VT_UI4"),xdata.nVal);
#endif
break;
case VT_UI8: //h id
#ifndef _WIN64
acutPrintf(_T("%ld : VT_UI4"),xdata.nVal);
#else
acutPrintf(_T("%d : VT_UI4"),xdata.nVal);
#endif
break;
case VT_R8: // 浮点
acutPrintf(_T("%.9f : VT_R8"),xdata.dVal[0]);
break;
case (VT_BYREF | VT_R8): // 点
acutPrintf(_T("%.9f,%.9f,%.9f : Point3d"),xdata.dVal[0],xdata.dVal[1],xdata.dVal[2]);
break;
case (VT_BYREF | VT_R8 + 1): // cad变化点
acutPrintf(_T("%.9f,%.9f,%.9f : Point3d"),xdata.dVal[0],xdata.dVal[1],xdata.dVal[2]);
break;
case (VT_BYREF | VT_R8 + 2): // 向量
acutPrintf(_T("%.9f,%.9f,%.9f : Vector3d"),xdata.dVal[0],xdata.dVal[1],xdata.dVal[2]);
break;
case (VT_BYREF | VT_R8 + 3): // 变化向量
acutPrintf(_T("%.9f,%.9f,%.9f : Vector3d"),xdata.dVal[0],xdata.dVal[1],xdata.dVal[2]);
break;
case (VT_BYREF | VT_R8 + 4): // 矩阵
acutPrintf(_T("%s : Matrix3d"),xdata.pszVal);
break;
case (VT_BYREF | VT_R8 + 5): // binarydata
acutPrintf(_T("%p:%d bytes : Binary data"),xdata.pData,xdata.npszLen);
break;
case VT_BSTR: // 字符串
acutPrintf(_T("%s : String"),xdata.pszVal);
break;
default:
break;
}
}
}
void AecDbObjXDataMap::List(CListCtrl* pList,int nImage) const
{
if (pList == NULL)
return List();
AecXData xdata;
int nVt = -1;
AcGePoint3d ptVal;
AcGeVector3d vt;
AcDbObjectId id;
int nItem = -1;
TCHAR szData[MAX_PATH * 4];
for (CIt it = m_xData.begin(); it != m_xData.end(); ++it)
{
xdata = (*it).second;
nVt = xdata.nVt;
memset(szData, 0, sizeof(szData));
//acutPrintf(_T("\n%s:"), (const TCHAR *)(*it).first);
nItem = pList->InsertItem(pList->GetItemCount(), (const TCHAR *)(*it).first, nImage );
switch (nVt)
{
case VT_I2:
swprintf(szData, _T("%d : VT_I4"), xdata.iVal);
break;
case VT_I4: // 整型
swprintf(szData,_T("%d : VT_I4"), (int)xdata.nVal);
break;
case VT_UI4: //s id
#ifndef _WIN64
swprintf(szData, _T("%ld : VT_UI4"), xdata.nVal);
#else
swprintf(szData, _T("%d : VT_UI4"), (int)xdata.nVal);
#endif
break;
case VT_UI8: //h id
#ifndef _WIN64
swprintf(szData, _T("%ld : VT_UI4"), xdata.nVal);
#else
swprintf(szData, _T("%d : VT_UI4"), (int)xdata.nVal);
#endif
break;
case VT_R8: // 浮点
swprintf(szData, _T("%.3f : VT_R8"), xdata.dVal[0]);
break;
case (VT_BYREF | VT_R8): // 点
swprintf(szData, _T("(%.3f,%.3f,%.3f) : Point3d"), xdata.dVal[0], xdata.dVal[1], xdata.dVal[2]);
break;
case (VT_BYREF | VT_R8 + 1): // cad变化点
swprintf(szData, _T("(%.3f,%.3f,%.3f) : Point3d"), xdata.dVal[0], xdata.dVal[1], xdata.dVal[2]);
break;
case (VT_BYREF | VT_R8 + 2): // 向量
swprintf(szData, _T("(%.3f,%.3f,%.3f) : Vector3d"), xdata.dVal[0], xdata.dVal[1], xdata.dVal[2]);
break;
case (VT_BYREF | VT_R8 + 3): // 变化向量
swprintf(szData, _T("(%.3f,%.3f,%.3f) : Vector3d"), xdata.dVal[0], xdata.dVal[1], xdata.dVal[2]);
break;
case (VT_BYREF | VT_R8 + 4): // 矩阵
swprintf(szData, _T("%s : Matrix3d"), xdata.pszVal);
break;
case (VT_BYREF | VT_R8 + 5): // binarydata
swprintf(szData, _T("%p:%d bytes : Binary data"), xdata.pData, (int)xdata.npszLen);
break;
case VT_BSTR: // 字符串
{
//太长...多余的截掉
if (xdata.npszLen > MAX_PATH * 4)
{
wcsncpy(szData, xdata.pszVal, MAX_PATH * 4-4);
_tcscat(szData, _T("..."));
}
else
{
swprintf(szData, _T("%s : String"), xdata.pszVal);
}
break;
}
default:
break;
}
if (_tcslen(szData) > 0)
{
pList->SetItemText(nItem, 1, szData);
}
}
}
static bool XDataEqu(const AecXData& xdata1,const AecXData& xdata2)
{
if (xdata1.nVt != xdata2.nVt)
return false;
switch (xdata1.nVt)
{
case VT_I2:
if (xdata1.iVal != xdata2.iVal)
return false;
case VT_I4: // 整型
case VT_UI4: //s id
case VT_UI8: //h id
if (xdata1.nVal != xdata2.nVal)
return false;
break;
case VT_R8: // 浮点
if ( fabs(xdata1.dVal[0] - xdata2.dVal[0]) > 1.e-3)
return false;
break;
case (VT_BYREF | VT_R8): // 点
case (VT_BYREF | VT_R8 + 1): // cad变化点
case (VT_BYREF | VT_R8 + 2): // 向量
case (VT_BYREF | VT_R8 + 3): // 变化向量
if ( fabs(xdata1.dVal[0] - xdata2.dVal[0]) > 1.e-3)
return false;
if ( fabs(xdata1.dVal[1] - xdata2.dVal[1]) > 1.e-3)
return false;
if ( fabs(xdata1.dVal[2] - xdata2.dVal[2]) > 1.e-3)
return false;
break;
case (VT_BYREF | VT_R8 + 4): // 矩阵
if (_tcscmp(xdata1.pszVal,xdata2.pszVal) != 0)
return false;
break;
case (VT_BYREF | VT_R8 + 5): // binarydata
if (xdata1.npszLen != xdata2.npszLen)
return false;
break;
case VT_BSTR: // 字符串
if (_tcscmp(xdata1.pszVal,xdata2.pszVal) != 0)
return false;
break;
default:
break;
}
return true;
}
int AecDbObjXDataMap::ComparedTo(const AecDbObjXDataMap* pXDataMap) const
{
if (pXDataMap == NULL)
return 1;
if (m_xData.size() != pXDataMap->m_xData.size())
return 1;
for (CIt it1 = m_xData.begin(); it1 != m_xData.end(); ++it1)
{
CIt it2 = pXDataMap->m_xData.find(it1->first);
if (it2 == pXDataMap->m_xData.end())
{
return 1;
}
else
{
if ( !XDataEqu(it1->second,it2->second))
{
return 1;
}
}
}
return 0;
}
Acad::ErrorStatus AecDbObjXDataMap::dxfOutFields(AcDbDxfFiler* pFiler) const
{
if (pFiler == NULL) return Acad::eInvalidInput;
AecXData xdata;
int nVt = -1;
AcGePoint3d ptVal;
AcGeVector3d vt;
AcDbObjectId id;
pFiler->writeString(AcDb::kDxfXTextString, MAP_BLOCK_BEGIN);
for (CIt it = m_xData.begin(); it != m_xData.end(); ++it)
{
xdata = (*it).second;
nVt = xdata.nVt;
pFiler->writeString(AcDb::kDxfXdAsciiString, (const TCHAR *)(*it).first);
pFiler->writeInt32(AcDb::kDxfXdInteger32, nVt);
switch (nVt)
{
case VT_I2:
pFiler->writeInt16(AcDb::kDxfXdInteger16, xdata.iVal);
break;
case VT_I4: // 整型
pFiler->writeInt32(AcDb::kDxfXdInteger32, (int)xdata.nVal);
break;
case VT_UI4: //s id
id.setFromOldId(xdata.nVal);
pFiler->writeObjectId(AcDb::kDxfSoftPointerId,id);
break;
case VT_UI8: //h id
id.setFromOldId(xdata.nVal);
pFiler->writeObjectId(AcDb::kDxfHardPointerId,id);
break;
case VT_R8: // 浮点
pFiler->writeDouble(AcDb::kDxfXdReal, xdata.dVal[0]);
break;
case (VT_BYREF | VT_R8): // 点
ptVal.x = xdata.dVal[0];
ptVal.y = xdata.dVal[1];
ptVal.z = xdata.dVal[2];
pFiler->writePoint3d(AcDb::kDxfXdXCoord, ptVal);
break;
case (VT_BYREF | VT_R8 + 1): // cad变化点
ptVal.x = xdata.dVal[0];
ptVal.y = xdata.dVal[1];
ptVal.z = xdata.dVal[2];
pFiler->writePoint3d(AcDb::kDxfXdWorldXCoord, ptVal);
break;
case (VT_BYREF | VT_R8 + 2): // 向量
vt.x = xdata.dVal[0];
vt.y = xdata.dVal[1];
vt.z = xdata.dVal[2];
pFiler->writeVector3d(AcDb::kDxfXdXCoord, vt);
break;
case (VT_BYREF | VT_R8 + 3): // 变化向量
vt.x = xdata.dVal[0];
vt.y = xdata.dVal[1];
vt.z = xdata.dVal[2];
pFiler->writeVector3d(AcDb::kDxfXdWorldXDir, vt);
break;
case (VT_BYREF | VT_R8 + 4): // 矩阵
pFiler->writeString(AcDb::kDxfXdAsciiString, xdata.pszVal);
break;
case (VT_BYREF | VT_R8 + 5): // binary data
{
ads_binary binary;
binary.clen = xdata.npszLen;
binary.buf = (char*)xdata.pData;
pFiler->writeBChunk(AcDb::kDxfXdBinaryChunk,binary);
}
break;
case VT_BSTR: // 字符串
pFiler->writeString(AcDb::kDxfXdAsciiString, xdata.pszVal);
break;
default:
break;
}
}
pFiler->writeString(AcDb::kDxfXTextString, MAP_BLOCK_END);
return Acad::eOk;
}
Acad::ErrorStatus AecDbObjXDataMap::dxfInFields(AcDbDxfFiler* pFiler)
{
if (pFiler == NULL) return Acad::eInvalidInput;
BOOL bFinded = FALSE;
long nVt = 0;
TCHAR* pszKey = NULL;
TCHAR* pszVal = NULL;
AcGePoint3d ptVal;
AcGeVector3d vt;
CString sKey,sTag;
struct resbuf rb;
while ((pFiler->readItem(&rb)) == Acad::eOk)
{
if(rb.restype == AcDb::kDxfXdAsciiString)
{
sTag = rb.resval.rstring;
if (sTag.CompareNoCase(MAP_BLOCK_BEGIN) == 0)
{
bFinded = TRUE;
break;
}
}
}
if (!bFinded) return Acad::eOk;
int nMapUnitIndex = 0;
AcDbObjectId id;
while ((pFiler->readItem(&rb)) == Acad::eOk)
{
nMapUnitIndex++;
if(nMapUnitIndex == 1)
{
if(rb.restype == AcDb::kDxfXdAsciiString)
{
sKey = rb.resval.rstring;
continue;
}
}
else
{
nMapUnitIndex = 0;
}
nVt = rb.restype;
switch (nVt)
{
case VT_I2:
SetAt(sKey, rb.resval.rint);
break;
case VT_I4: // 整型
SetAt(sKey,rb.resval.rlong);
break;
case VT_UI4: //s id
#ifdef _WIN64
id.setFromOldId(rb.resval.mnInt64);
#else
id.setFromOldId(rb.resval.rlong);
#endif
SetAt(sKey,id);
break;
case VT_UI8: //h id
#ifdef _WIN64
id.setFromOldId(rb.resval.mnInt64);
#else
id.setFromOldId(rb.resval.rlong);
#endif
SetAt(sKey,id,FALSE);
break;
case VT_R8: // 浮点
SetAt(sKey,rb.resval.rreal);
break;
case (VT_BYREF | VT_R8): // 点
SetAt(sKey, asPnt3d(rb.resval.rpoint));
break;
case (VT_BYREF | VT_R8 + 1): // 变化点
SetAt(sKey, asPnt3d(rb.resval.rpoint),TRUE);
break;
case (VT_BYREF | VT_R8 + 2): // 向量
sKey.Replace(DIF_VT_PT,_T(" "));
sKey.TrimRight();
SetAt(sKey, asPnt3d(rb.resval.rpoint));
break;
case (VT_BYREF | VT_R8 + 3): // cad变化向量
sKey.Replace(DIF_VT_PT,_T(" "));
sKey.TrimRight();
SetAt(sKey, asPnt3d(rb.resval.rpoint),TRUE);
break;
case (VT_BYREF | VT_R8 + 4): //矩阵
SetAt(sKey, rb.resval.rstring);
break;
case (VT_BYREF | VT_R8 + 5): //binary data
SetAt(sKey,rb.resval.rbinary.buf,rb.resval.rbinary.clen);
break;
case VT_BSTR: // 字符串
SetAt(sKey, rb.resval.rstring);
break;
default:
break;
}
}
return Acad::eOk;
}
// 增加 clone 的 xdatamap 的关系复制维护
void AecDbObjXDataMap::BeginCloneXlation(AecDbObjXDataMap* pMapClone,AcDbIdMapping& idMap) const
{
assert(pMapClone != NULL);
AcDbObjectId id;
AecXData xdata;
AcDbIdPair idpair;
for (CIt it = m_xData.begin();it != m_xData.end();it++)
{
xdata = (*it).second;
switch (xdata.nVt)
{
case VT_UI4:
{
id.setFromOldId(xdata.nVal);
idpair.setKey(id);
if ( idMap.compute(idpair) )
{
pMapClone->SetAt((*it).first,idpair.value(),TRUE);
}
}
break;
case VT_UI8:
{
id.setFromOldId(xdata.nVal);
idpair.setKey(id);
if ( idMap.compute(idpair) )
{
pMapClone->SetAt((*it).first,idpair.value(),FALSE);
}
}
break;
default:
break;
}
}
}
Acad::ErrorStatus AecDbObjXDataMap::dwgOutFields(AcDbDwgFiler* pFiler) const
{
if (pFiler != NULL)
{
AecXData xdata;
int nVt = -1;
AcGePoint3d ptVal;
AcGeVector3d vt;
AcDbSoftPointerId id;
pFiler->writeString(MAP_BLOCK_BEGIN);
for (CIt it = m_xData.begin(); it != m_xData.end(); ++it)
{
xdata = (*it).second;
nVt = xdata.nVt;
pFiler->writeString((const TCHAR *)(*it).first);
pFiler->writeInt32(nVt);
switch (nVt)
{
case VT_I2:
pFiler->writeInt16(xdata.iVal);
break;
case VT_I4: // 整型
pFiler->writeInt32((int)xdata.nVal);
break;
case VT_UI4:
id.setFromOldId(xdata.nVal);
pFiler->writeSoftPointerId(id);
break;
case VT_UI8:
id.setFromOldId(xdata.nVal);
pFiler->writeHardPointerId(id);
break;
case VT_R8: // 浮点
pFiler->writeDouble(xdata.dVal[0]);
break;
case (VT_BYREF | VT_R8): // 点
case (VT_BYREF | VT_R8 + 1):
ptVal.x = xdata.dVal[0];
ptVal.y = xdata.dVal[1];
ptVal.z = xdata.dVal[2];
pFiler->writePoint3d(ptVal);
break;
case (VT_BYREF | VT_R8 + 2): // 向量
case (VT_BYREF | VT_R8 + 3):
vt.x = xdata.dVal[0];
vt.y = xdata.dVal[1];
vt.z = xdata.dVal[2];
pFiler->writeVector3d(vt);
break;
case (VT_BYREF | VT_R8 + 4): //矩阵
pFiler->writeString(xdata.pszVal);
case (VT_BYREF | VT_R8 + 5): //binary data
{
pFiler->writeInt32(xdata.npszLen);
pFiler->writeBytes(xdata.pData,xdata.npszLen);
break;
}
break;
case VT_BSTR: // 字符串
pFiler->writeString(xdata.pszVal);
break;
default:
break;
}
}
pFiler->writeString(MAP_BLOCK_END);
return Acad::eOk;
}
return Acad::eInvalidInput;
}
Acad::ErrorStatus AecDbObjXDataMap::dwgInFields(AcDbDwgFiler* pFiler)
{
if (pFiler == NULL) return Acad::eInvalidInput;
BOOL bFinded = FALSE;
Adesk::Int32 nVt = 0;
Adesk::Int16 iVal = 0;
AecXData xdata;
TCHAR* pszKey = NULL;
TCHAR* pszVal = NULL;
AcGePoint3d ptVal;
AcGeVector3d vt;
AcGeMatrix3d xform;
CString sKey,sTag;
CString sText;
CStringArray arTexts;
m_xData.erase(m_xData.begin(),m_xData.end());
m_xData.clear();
while ((pFiler->readString(&pszVal)) == Acad::eOk)
{
sTag = pszVal;
if (pszVal != NULL) acutDelString(pszVal);
if (sTag.CompareNoCase(MAP_BLOCK_BEGIN) == 0)
{
bFinded = TRUE;
break;
}
}
if (!bFinded) return Acad::eOk;
while ((pFiler->readString(&pszKey)) == Acad::eOk)
{
sKey = pszKey;
if (pszKey != NULL) acutDelString(pszKey);
if (sKey.CompareNoCase(MAP_BLOCK_END) == 0)
{
break;
}
pFiler->readInt32(&nVt);
xdata.nVt = (int)nVt;
AcDbSoftPointerId id;
AcDbHardPointerId idh;
switch (nVt)
{
case VT_I2:
pFiler->readInt16(&iVal);
xdata.iVal = iVal;
SetAt(sKey, xdata.iVal);
break;
case VT_I4: // 整型
pFiler->readInt32(&nVt);
xdata.nVal = (int)nVt;
SetAt(sKey, (int)xdata.nVal);
break;
case VT_UI4:
pFiler->readSoftPointerId(&id);
SetAt(sKey,id);
break;
case VT_UI8:
pFiler->readHardPointerId(&idh);
SetAt(sKey,idh,FALSE);
break;
case VT_R8: // 浮点
pFiler->readDouble(&xdata.dVal[0]);
SetAt(sKey, xdata.dVal[0]);
break;
case (VT_BYREF | VT_R8): // 点
pFiler->readPoint3d(&ptVal);
SetAt(sKey, ptVal);
break;
case (VT_BYREF | VT_R8 + 1): // cad变化点
pFiler->readPoint3d(&ptVal);
SetAt(sKey, ptVal, TRUE);
break;
case (VT_BYREF | VT_R8 + 2): // 向量
pFiler->readVector3d(&vt);
sKey.Replace(DIF_VT_PT,_T(" "));
sKey.TrimRight();
SetAt(sKey, vt);
break;
case (VT_BYREF | VT_R8 + 3): // cad变化向量
pFiler->readVector3d(&vt);
sKey.Replace(DIF_VT_PT,_T(" "));
sKey.TrimRight();
SetAt(sKey, vt, TRUE);
break;
case (VT_BYREF | VT_R8 + 4): //矩阵
pszVal = NULL;
pFiler->readString(&pszVal);
sText = pszVal;
arTexts.RemoveAll();
Script2StringArray(sText,_T(','),arTexts);
if (arTexts.GetSize() == 16)
{
for (int i = 0;i < 4;i++)
{
for (int j = 0;j < 4;j++)
{
xform.entry[i][j] = _ttof(arTexts.GetAt(i * 4 + j));
}
}
}
SetAt(sKey, xform);
if (pszVal != NULL) acutDelString(pszVal);
break;
case (VT_BYREF | VT_R8 + 5): //binary data
{
Adesk::Int32 nSize = 0;
pFiler->readInt32(&nSize);
if (nSize > 0)
{
void* pData = new byte[nSize];
pFiler->readBytes(pData,nSize);
SetAt(sKey,pData,nSize);
}
break;
}
case VT_BSTR: // 字符串
pszVal = NULL;
pFiler->readString(&pszVal);
SetAt(sKey, pszVal);
if (pszVal != NULL) acutDelString(pszVal);
break;
default:
break;
}
}
return Acad::eOk;
}
//分区链块
static struct resbuf *PartitionBlocks(AecDbObjXDataMap::CIt iter, struct resbuf *&pTemp)
{
//最大65535 blocks
int nBlocks = iter->second.npszLen / 127 + ((iter->second.npszLen % 127 > 0) ? 1 : 0);
//head
const char *pszBlocks = BINARY_CHUNKBLOCKS;
struct resbuf *pTempNext = acutNewRb(AcDb::kDxfXdBinaryChunk);
pTempNext->resval.rbinary.clen = 66;
char *pBlocks = new char[66];//binarychunkblocks
memset(pBlocks, 0, 66);
pTempNext->resval.rbinary.buf = pBlocks;
sprintf(pBlocks, "%s:%d:%d", pszBlocks,nBlocks, (int)iter->second.npszLen);
pTemp->rbnext = pTempNext;
pTemp = pTempNext;
LONG_PTR nCut = iter->second.npszLen;
char *pData = (char *)iter->second.pData;
while (nCut > 127)
{
pTempNext = acutNewRb(AcDb::kDxfXdBinaryChunk);
pTempNext->resval.rbinary.clen = (nCut > 127) ? 127 : nCut;
pTempNext->resval.rbinary.buf = new char[pTempNext->resval.rbinary.clen];
memcpy(pTempNext->resval.rbinary.buf, pData, pTempNext->resval.rbinary.clen);
pTemp->rbnext = pTempNext;
pTemp = pTempNext;
//下一段
pData += 127;
nCut -= 127;
if (nCut < 127 && nCut > 0)//最后一段
{
pTempNext = acutNewRb(AcDb::kDxfXdBinaryChunk);
pTempNext->resval.rbinary.clen = nCut;
pTempNext->resval.rbinary.buf = new char[pTempNext->resval.rbinary.clen];
memcpy(pTempNext->resval.rbinary.buf, pData, pTempNext->resval.rbinary.clen);
pTemp->rbnext = pTempNext;
pTemp = pTempNext;
}
}
return pTempNext;
}
// bXRecord = fase 操作扩展数据 bXRecord = true 操作扩展词典
BOOL AecDbObjXDataMap::XDMap2Resbuf(LPCTSTR pszApp, struct resbuf*& pRb,BOOL bXRecord,BOOL bOnlyWriteSecond) const
{
if(pszApp == NULL || m_xData.empty()) return FALSE;
struct resbuf* pTemp = NULL;
// 链表头
if (!bXRecord)
{
// 扩展数据需要链表头
pTemp = acutNewRb(AcDb::kDxfRegAppName);
acutNewString(pszApp,pTemp->resval.rstring);
pRb = pTemp;
}
AcDbObjectId id;
ads_name adsName;
struct resbuf* pTempNext = NULL;
// 遍历map
for(CIt iter = m_xData.begin(); iter != m_xData.end(); iter++)
{
if (!bOnlyWriteSecond)//如果不写key
{
pTempNext = acutNewRb(AcDb::kDxfXdAsciiString);
acutNewString(iter->first, pTempNext->resval.rstring);
if (pRb == NULL)
{
pRb = pTempNext;
}
else
{
pTemp->rbnext = pTempNext;
}
pTemp = pTempNext;
}
pTempNext = NULL;
switch (iter->second.nVt)
{
case VT_I2:
{
pTempNext = acutNewRb(AcDb::kDxfXdInteger16);
pTempNext->resval.rint = (short)iter->second.iVal;
pTemp->rbnext = pTempNext;
break;
}
case VT_I4: // 整型
pTempNext = acutNewRb(AcDb::kDxfXdInteger32);
pTempNext->resval.rlong = (long)iter->second.nVal;
pTemp->rbnext = pTempNext;
break;
/*---------------------------------------------------------------------------------------
Extended data (xdata) is created by applications written with ObjectARX? or AutoLISP?
and can be added to any object. Xdata consists of a linked list of resbufs
used by the application. (AutoCAD maintains the information but doesn't use it.)
The data is associated with a DXF group code in the range of 1000 to 1071.
*/
/*
so someguy want save id to an entity xdata ,must save as kDxfXdHandle
kDxfXdHandle is same as string;
*/
case VT_UI4: //s id
id.setFromOldId(iter->second.nVal);
acdbGetAdsName(adsName,id);
if(bXRecord)
pTempNext = acutBuildList(AcDb::kDxfSoftPointerId, adsName, 0);
else
{
pTempNext = acutNewRb(AcDb::kDxfXdHandle);
TCHAR szHandleStr[19];
memset(szHandleStr,0,sizeof(szHandleStr) );
id.handle().getIntoAsciiBuffer(szHandleStr);
#if ARX < 17
acutNewString(szHandleStr, pTempNext->resval.rstring);
#else
acutNewString(pTempNext->resval.rstring, (int)(_tcslen(szHandleStr) + 1));
_tcsncpy_s(pTempNext->resval.rstring, _tcslen(szHandleStr) + 1, szHandleStr, _tcslen(szHandleStr));
#endif
}
pTemp->rbnext = pTempNext;
break;
case VT_UI8: //h id not support xdata
id.setFromOldId(iter->second.nVal);
acdbGetAdsName(adsName,id);
if(bXRecord)
pTempNext = acutBuildList(AcDb::kDxfHardPointerId, adsName, 0);
else
{
pTempNext = acutNewRb(AcDb::kDxfXdHandle);
TCHAR szHandleStr[19];
memset(szHandleStr,0,sizeof(szHandleStr) );
id.handle().getIntoAsciiBuffer(szHandleStr);
#if ARX < 17
acutNewString(szHandleStr, pTempNext->resval.rstring);
#else
acutNewString(pTempNext->resval.rstring, (int)(_tcslen(szHandleStr) + 1));
_tcsncpy_s(pTempNext->resval.rstring, (int)(_tcslen(szHandleStr) + 1), szHandleStr, _tcslen(szHandleStr));
#endif
}
pTemp->rbnext = pTempNext;
break;
case VT_BSTR: // 字符串
pTempNext = acutNewRb(AcDb::kDxfXdAsciiString);
acutNewString(iter->second.pszVal, pTempNext->resval.rstring);
pTemp->rbnext = pTempNext;
break;
case VT_R8: // 浮点型
pTempNext = acutNewRb(AcDb::kDxfXdReal);
pTempNext->resval.rreal = iter->second.dVal[0];
pTemp->rbnext = pTempNext;
break;
case (VT_BYREF | VT_R8): // 点
pTempNext = acutNewRb(AcDb::kDxfXdXCoord);
pTempNext->resval.rpoint[0] = iter->second.dVal[0];
pTempNext->resval.rpoint[1] = iter->second.dVal[1];
pTempNext->resval.rpoint[2] = iter->second.dVal[2];
pTemp->rbnext = pTempNext;
break;
case (VT_BYREF | VT_R8 + 1): // 随cad实体变化的点
pTempNext = acutNewRb(AcDb::kDxfXdWorldXCoord);
pTempNext->resval.rpoint[0] = iter->second.dVal[0];
pTempNext->resval.rpoint[1] = iter->second.dVal[1];
pTempNext->resval.rpoint[2] = iter->second.dVal[2];
pTemp->rbnext = pTempNext;
break;
case (VT_BYREF | VT_R8 + 2): // 向量
pTempNext = acutNewRb(AcDb::kDxfXdXCoord);
pTempNext->resval.rpoint[0] = iter->second.dVal[0];
pTempNext->resval.rpoint[1] = iter->second.dVal[1];
pTempNext->resval.rpoint[2] = iter->second.dVal[2];
pTemp->rbnext = pTempNext;
break;
case (VT_BYREF | VT_R8 + 3): // 随cad实体变化的向量
pTempNext = acutNewRb(AcDb::kDxfXdWorldXDir);
pTempNext->resval.rpoint[0] = iter->second.dVal[0];
pTempNext->resval.rpoint[1] = iter->second.dVal[1];
pTempNext->resval.rpoint[2] = iter->second.dVal[2];
pTemp->rbnext = pTempNext;
break;
case (VT_BYREF | VT_R8 + 4): // 矩阵
pTempNext = acutNewRb(AcDb::kDxfXdAsciiString);
acutNewString(iter->second.pszVal, pTempNext->resval.rstring);
pTemp->rbnext = pTempNext;
break;
case (VT_BYREF | VT_R8 + 5):
/*pTempNext = acutNewRb(AcDb::kDxfXdBinaryChunk);
pTempNext->resval.rbinary.clen = iter->second.npszLen;
pTempNext->resval.rbinary.buf = new char[iter->second.npszLen];
memcpy(pTempNext->resval.rbinary.buf,iter->second.pData,iter->second.npszLen);
pTemp->rbnext = pTempNext;
if (pTempNext->resval.rbinary.clen > 127)
acutPrintf(_T("\nBinaryChunk Data overflow!!!"));*/
if (iter->second.npszLen > MAX_BINARYCHUNK)
{
pTempNext = PartitionBlocks(iter, pTemp);
}
else
{
pTempNext = acutNewRb(AcDb::kDxfXdBinaryChunk);
pTempNext->resval.rbinary.clen = iter->second.npszLen;
pTempNext->resval.rbinary.buf = new char[iter->second.npszLen];
memcpy(pTempNext->resval.rbinary.buf, iter->second.pData, iter->second.npszLen);
pTemp->rbnext = pTempNext;
}
break;
default:
continue;
}
pTemp = pTempNext;
pTempNext = NULL;
}
return (pRb != NULL);
}
void AecDbObjXDataMap::SecondAsKey(CString& sTemp,AecXData& xData)
{
switch (xData.nVt)
{
case VT_I2:
sTemp.Format(_T("%d"), xData.iVal);
break;
case VT_I4: // 整型
sTemp.Format(_T("%d"),xData.nVal);
break;
case VT_UI4:
sTemp.Format(_T("%d"),xData.nVal);
break;
case VT_UI8:
sTemp.Format(_T("%d"),xData.nVal);
break;
case VT_R8: // 浮点
sTemp.Format(_T("%.9f"),xData.dVal[0]);
break;
case (VT_BYREF | VT_R8): // 点
case (VT_BYREF | VT_R8 + 1):
case (VT_BYREF | VT_R8 + 2): // 向量
case (VT_BYREF | VT_R8 + 3):
sTemp.Format(_T("%.9f,%.9f,%.9f"),xData.dVal[0],xData.dVal[1],xData.dVal[2]);
break;
case (VT_BYREF | VT_R8 + 4): //矩阵
case VT_BSTR: // 字符串
{
sTemp = xData.pszVal;
break;
}
case (VT_BYREF | VT_R8 + 5): //binary data
{
CTime tNow = CTime::GetCurrentTime();
sTemp = tNow.Format(" %Y-%m-%d %H.%M.%S");
break;
}
default:
break;
}
}
//合并区链块
static bool MergeBlocks(AecXData &xData, struct resbuf*& pTemp)
{
if (pTemp == NULL)
return false;
char *pszBlocks = (char *)xData.pData;
if (NULL != strstr(pszBlocks, BINARY_CHUNKBLOCKS1))
{
//AAAA:5:635
//AAAA:
char *pszId = strstr(pszBlocks, BINARY_CHUNKBLOCKS1);
//5:635
char *pszNm = pszId;
pszNm += strlen(BINARY_CHUNKBLOCKS1);
int nBlocks = atoi(pszNm);
//:635
char *pszSz = strstr(pszNm, ":");
pszSz += 1;
//635
xData.npszLen = atoi(pszSz);
if (xData.npszLen == 0)
return false;
xData.pData = new char[xData.npszLen];
memset(xData.pData, 0, xData.npszLen);
struct resbuf *pLast = pTemp;
char *pPos = (char*)xData.pData;
pTemp = pTemp->rbnext;
for (int i = 0; i < nBlocks; i++)
{
assert(pTemp->restype == AcDb::kDxfXdBinaryChunk);//must
memcpy(pPos, pTemp->resval.rbinary.buf, pTemp->resval.rbinary.clen);
pPos += pTemp->resval.rbinary.clen;
pLast = pTemp;
pTemp = pTemp->rbnext;
}
//待后续下移一段,确保当前指向正读取数据段
pTemp = pLast;
return true;
}
return false;
}
// bXRecord = fase 操作扩展数据 bXRecord = true 操作扩展词典
BOOL AecDbObjXDataMap::Resbuf2XDMap(struct resbuf* pRb,BOOL bXRecord,AcDbDatabase* pDb,BOOL bKeyAsSecond/* = FALSE*/)
{
if(pRb == NULL) return FALSE;
m_xData.clear();
struct resbuf* pTemp = pRb;
// 跳过扩展数据头 扩展数据
if (!bXRecord)
{
pTemp = pRb->rbnext;
}
AcDbObjectId id;
int nMapUnitIndex = 1;
AecXData xData;
CString sTemp;
while (pTemp != NULL)
{
if (nMapUnitIndex == 1 && !bKeyAsSecond)
{
// skey键值
if (pTemp->restype == AcDb::kDxfXdAsciiString)
{
sTemp = pTemp->resval.rstring;
nMapUnitIndex++;
}
}
else
{
// value
switch (pTemp->restype)
{
case AcDb::kDxfXdAsciiString: // 字符串
xData.nVt = VT_BSTR;
xData.npszLen = _tcslen(pTemp->resval.rstring) + 1;
xData.pszVal = new TCHAR[xData.npszLen];
_tcsncpy_s(xData.pszVal, xData.npszLen, pTemp->resval.rstring, xData.npszLen - 1);
nMapUnitIndex++;
break;
case AcDb::kDxfXdInteger16:
xData.nVt = VT_I2;
xData.iVal = pTemp->resval.rint;
nMapUnitIndex++;
case AcDb::kDxfXdInteger32: // 整型
xData.nVt = VT_I4;
xData.nVal = pTemp->resval.rlong;
nMapUnitIndex++;
break;
/*---------------------------------------------------------------------------------------
Extended data (xdata) is created by applications written with ObjectARX? or AutoLISP?
and can be added to any object. Xdata consists of a linked list of resbufs
used by the application. (AutoCAD maintains the information but doesn't use it.)
The data is associated with a DXF group code in the range of 1000 to 1071.
*/
case AcDb::kDxfSoftPointerId: //s id not support xdata
acdbGetObjectId(id, pTemp->resval.rlname);
xData.nVt = VT_UI4;
xData.nVal = id.asOldId();
nMapUnitIndex++;
break;
case AcDb::kDxfHardPointerId: //h id not support xdata
acdbGetObjectId(id, pTemp->resval.rlname);
xData.nVt = VT_UI8;
xData.nVal = id.asOldId();
nMapUnitIndex++;
break;
//--------------------------------------------------------------------------------------
case AcDb::kDxfXdHandle: //handle for xdata
{
AcDbHandle handle(pTemp->resval.rstring);
if (pDb == NULL)
pDb = acdbCurDwg();
if (pDb != NULL)
{
if ( Acad::eOk == pDb->getAcDbObjectId(id,false,handle) )
{
xData.nVt = VT_UI4;
xData.nVal = id.asOldId();
nMapUnitIndex++;
}
}
}
break;
case AcDb::kDxfXdReal: // 浮点型
xData.nVt = VT_R8;
xData.dVal[0] = pTemp->resval.rreal;
nMapUnitIndex++;
break;
case AcDb::kDxfXdXCoord: // 点 向量
xData.nVt = (VT_BYREF | VT_R8);
xData.dVal[0] = pTemp->resval.rpoint[0];
xData.dVal[1] = pTemp->resval.rpoint[1];
xData.dVal[2] = pTemp->resval.rpoint[2];
nMapUnitIndex++;
if(sTemp.Find(DIF_VT_PT) >= 0)
{
// 向量
xData.nVt = (VT_BYREF | VT_R8 + 2);
}
break;
case AcDb::kDxfXdWorldXCoord:
{// 随cad实体变化的点
xData.nVt = (VT_BYREF | VT_R8 + 1);
xData.dVal[0] = pTemp->resval.rpoint[0];
xData.dVal[1] = pTemp->resval.rpoint[1];
xData.dVal[2] = pTemp->resval.rpoint[2];
nMapUnitIndex++;
break;
}
case AcDb::kDxfXdWorldXDir: // 随cad实体变化的向量
{
xData.nVt = (VT_BYREF | VT_R8 + 3);
xData.dVal[0] = pTemp->resval.rpoint[0];
xData.dVal[1] = pTemp->resval.rpoint[1];
xData.dVal[2] = pTemp->resval.rpoint[2];
nMapUnitIndex++;
break;
}
case AcDb::kDxfXdBinaryChunk:
{
xData.nVt = (VT_BYREF | VT_R8 + 5);
xData.npszLen = pTemp->resval.rbinary.clen;
xData.pData = pTemp->resval.rbinary.buf;
char* pszBlocks = (char *)xData.pData;
if (NULL != strstr(pszBlocks, BINARY_CHUNKBLOCKS) &&
NULL != strstr(pszBlocks, BINARY_CHUNKBLOCKS1) )
{
//aaaa:10:3333
MergeBlocks(xData, pTemp);
}
else
{
//...
}
nMapUnitIndex++;
break;
}
default:
break;
}
}
if (bKeyAsSecond)
{
SecondAsKey(sTemp,xData);
nMapUnitIndex++;//3
}
if(nMapUnitIndex > 2)
{
// 插入一套 skey value
std::pair<CString,AecXData> pa(sTemp,xData);
m_xData.insert(pa);
nMapUnitIndex = 1;
}
//移向下一段
pTemp = pTemp->rbnext;
}
return !m_xData.empty();
}
//支持扩展数据的4个方法
// 根据实体指针插入链表 bXRecord = fase 操作扩展数据 bXRecord = true 操作扩展词典
BOOL AecDbObjXDataMap::Write(AcDbObject* pEnt, LPCTSTR pszApp, BOOL bXRecord,BOOL bAppend,BOOL bOnlyWriteSecond) const
{
if (pEnt == NULL || pszApp == NULL) return FALSE;
// 根据map生成链表
struct resbuf* pRb = NULL;
if (!XDMap2Resbuf(pszApp ,pRb ,bXRecord,bOnlyWriteSecond)) return FALSE;
Acad::ErrorStatus eStat = Acad::eOutOfMemory;
if (!bXRecord)
{
// 扩展数据
struct resbuf* pTmpRb = pEnt->xData(pszApp);
if (pTmpRb != NULL)
{
if (!bAppend)
{
// 存在清空
struct resbuf* pTmp = acutNewRb(AcDb::kDxfRegAppName);
acutNewString(pszApp,pTmp->resval.rstring);
pEnt->setXData(pTmp);
acutRelRb(pTmpRb);
acutRelRb(pTmp);
}
else//追加
{
struct resbuf* pTmpRbNext = pTmpRb->rbnext;
struct resbuf* pTemp = pRb;
while(pTemp != NULL)
{
if (pTemp->rbnext == NULL)
{
pTemp->rbnext = pTmpRbNext;
break;
}
pTemp = pTemp->rbnext;
}
// 存在清空
struct resbuf* pTmp = acutNewRb(AcDb::kDxfRegAppName);
acutNewString(pszApp,pTmp->resval.rstring);
pEnt->setXData(pTmp);
acutRelRb(pTmp);
}
}
// 注册扩展数据链表
int nRes = acdbRegApp(pszApp);
eStat = pEnt->setXData(pRb);
acutRelRb(pRb);
return (eStat == Acad::eOk);
}
// 扩展词典
AcDbObjectId dictObjId, xrecObjId;
pEnt->createExtensionDictionary();
dictObjId = pEnt->extensionDictionary();
// 打开扩展词典指针
AcDbDictionary* pDict = NULL;
if (Acad::eOk != acdbOpenObject(pDict, dictObjId, AcDb::kForWrite))
{
if (pRb != NULL) acutRelRb(pRb);
return FALSE;
}
AcDbXrecord* pXrec = NULL;
if (pDict->has(pszApp))
{
// 存在此扩展词典 获取扩展词典指针
AcDbObject* pObj = NULL;
pDict->getAt(pszApp,pObj,AcDb::kForWrite);
if(pObj != NULL)
{
pXrec = AcDbXrecord::cast(pObj);
if(pXrec != NULL)
{
// 重新设置扩展词典
eStat = pXrec->setFromRbChain(*pRb);
}
pObj->close();
}
pDict->close();
}
else
{
// 不存在此扩展词典
pXrec = new AcDbXrecord;
eStat = pXrec->setFromRbChain(*pRb);
eStat = pDict->setAt(pszApp,pXrec,xrecObjId);
pXrec->close();
pDict->close();
}
acutRelRb(pRb);
return (eStat == Acad::eOk);
}
// 根据实体id插入链表 bXRecord = fase 操作扩展数据 bXRecord = true 操作扩展词典
BOOL AecDbObjXDataMap::Write(const AcDbObjectId& id,LPCTSTR pszApp,BOOL bXRecord,BOOL bAppend,BOOL bOnlyWriteSecond) const
{
if(pszApp == NULL) return FALSE;
AcDbObject * pEnt = NULL;
BOOL bWriteIdXData = FALSE;
if(Acad::eOk == acdbOpenObject(pEnt, id, AcDb::kForWrite))
{
// 根据实体指针设置链表
bWriteIdXData = Write(pEnt,pszApp,bXRecord,bAppend,bOnlyWriteSecond);
pEnt->close();
}
return bWriteIdXData;
}
BOOL AecDbObjXDataMap::WriteExDic(AcDbObject* pObj,LPCTSTR pszApp) const
{
if (pObj == NULL || pszApp == NULL) return FALSE;
BOOL bWriteIdXData = FALSE;
pObj->createExtensionDictionary();
AcDbObjectId idDic = pObj->extensionDictionary();
AcDbObject* pDicObj = NULL;
if ( Acad::eOk == acdbOpenObject(pDicObj,idDic,AcDb::kForWrite))
{
AcDbDictionary* pDic = AcDbDictionary::cast(pDicObj);
if (pDic != NULL)
{
Acad::ErrorStatus es;
AcDbObjectId idXdata;
//先删除
es = pDic->getAt(pszApp,idXdata);
if (es == Acad::eOk)
{
AcDbObject* pXDataObj = NULL;
if ( Acad::eOk == acdbOpenObject(pXDataObj,idXdata,AcDb::kForWrite))
{
pXDataObj->erase();
pXDataObj->close();
}
}
//再加入
AecDbObjXDataMapObj* pXDataMapObj = new AecDbObjXDataMapObj;
pXDataMapObj->SetXDataMap(*this,false);
AcDbObjectId idMap;
Acad::ErrorStatus eRes = pDic->setAt(pszApp,pXDataMapObj,idMap);
pXDataMapObj->close();
bWriteIdXData = (eRes == Acad::eOk) ? TRUE : FALSE;
}
pDicObj->close();
}
return bWriteIdXData;
}
BOOL AecDbObjXDataMap::WriteExDic(const AcDbObjectId& id,LPCTSTR pszApp) const
{
if(pszApp == NULL) return FALSE;
AcDbObject * pObj = NULL;
BOOL bWriteIdXData = FALSE;
if(Acad::eOk == acdbOpenObject(pObj, id, AcDb::kForWrite))
{
bWriteIdXData = WriteExDic(pObj,pszApp);
pObj->close();
}
return bWriteIdXData;
}
BOOL AecDbObjXDataMap::ReadExDic(AcDbObject* pObj,LPCTSTR pszApp)
{
if (pObj == NULL || pszApp == NULL) return FALSE;
BOOL bSuccess = FALSE;
AcDbObjectId idDic = pObj->extensionDictionary();
AcDbObject* pDicObj = NULL;
if ( Acad::eOk == acdbOpenObject(pDicObj,idDic,AcDb::kForRead))
{
AcDbDictionary* pDic = AcDbDictionary::cast(pDicObj);
if (pDic != NULL)
{
AcDbObject* pXDataObj = NULL;
if ( Acad::eOk == pDic->getAt(pszApp,pXDataObj,AcDb::kForRead) )
{
AecDbObjXDataMapObj* pXDataMapObj = AecDbObjXDataMapObj::cast(pXDataObj);
if (pXDataMapObj != NULL)
{
bSuccess = pXDataMapObj->GetXDataMap(*this) ? TRUE : FALSE;
}
pXDataObj->close();
}
}
pDicObj->close();
}
return bSuccess;
}
BOOL AecDbObjXDataMap::ReadExDic(const AcDbObjectId& id,LPCTSTR pszApp)
{
if(pszApp == NULL) return FALSE;
AcDbObject * pObj = NULL;
BOOL bSuccess = FALSE;
if(Acad::eOk == acdbOpenObject(pObj, id, AcDb::kForRead))
{
bSuccess = ReadExDic(pObj,pszApp);
pObj->close();
}
return bSuccess;
}
BOOL AecDbObjXDataMap::Write(CFile* pFileOut,BOOL bWriteUserData) const
{
CString sTemp = MAP_BLOCK_BEGIN;
_bstr_t bst((LPCTSTR)sTemp);
std::string str;
str.append((const char*)bst);
std::string str2 = Base64::Encode(str);
pFileOut->Write(str2.c_str(), strlen(str2.c_str()));
AecXData xdata;
int nVt = -1;
AcGePoint3d ptVal;
AcGeVector3d vt;
AcDbSoftPointerId id;
int nSize = 0;
CString sText,sVal;
if (bWriteUserData)
{
int count(0);
GetAt(BIM_REC_LEN, count);
CMapStringToString mapStr2Str;
for (int i = 0; i < count; i++) //1000条用户数据
{
sText.Format(_T("user%d"), i);
if (GetAt(sText, sVal))
{
mapStr2Str.SetAt(sText, sVal);
}
}
nSize = mapStr2Str.GetCount();
pFileOut->Write(&nSize, sizeof(int));
for (POSITION ps = mapStr2Str.GetStartPosition(); ps != NULL;)
{
mapStr2Str.GetNextAssoc(ps,sText,sVal);
bst = (LPCTSTR)sText;
//key
nSize = strlen((const char*)bst);
pFileOut->Write(&nSize,sizeof(int));
pFileOut->Write((const char*)bst,nSize);
//vt
nVt = VT_BSTR;
pFileOut->Write(&nVt,sizeof(int));
//val
bst = (LPCTSTR)sVal;
nSize = strlen( (const char*)bst);
pFileOut->Write(&nSize,sizeof(int));
pFileOut->Write((const char*)bst,nSize);
}
}
else
{
//多少个
nSize = m_xData.size();
pFileOut->Write(&nSize,sizeof(int));
for (CIt it = m_xData.begin(); it != m_xData.end(); ++it)
{
xdata = (*it).second;
nVt = xdata.nVt;
sText = (*it).first;
//key
nSize = it->first.GetLength();
pFileOut->Write(&nSize,sizeof(int));
pFileOut->Write((LPCTSTR)it->first, nSize * sizeof(TCHAR));
//vt
pFileOut->Write(&nVt,sizeof(int));
switch (nVt)
{
case VT_I2:
pFileOut->Write(&xdata.iVal,sizeof(short));
break;
case VT_I4: // 整型
pFileOut->Write(&xdata.nVal,sizeof(int));
break;
case VT_UI4:
pFileOut->Write(&xdata.nVal,sizeof(int));
break;
case VT_UI8:
pFileOut->Write(&xdata.nVal,sizeof(int));
break;
case VT_R8: // 浮点
pFileOut->Write(&xdata.dVal[0],sizeof(double));
break;
case (VT_BYREF | VT_R8): // 点
case (VT_BYREF | VT_R8 + 1):
case (VT_BYREF | VT_R8 + 2): // 向量
case (VT_BYREF | VT_R8 + 3):
pFileOut->Write(xdata.dVal,sizeof(double) * 3);
break;
case (VT_BYREF | VT_R8 + 4): //矩阵
case VT_BSTR: // 字符串
{
nSize = _tcsclen(xdata.pszVal);
pFileOut->Write(&nSize,sizeof(int));
pFileOut->Write(xdata.pszVal, nSize * sizeof(TCHAR));
}
break;
case (VT_BYREF | VT_R8 + 5):
{
pFileOut->Write(&xdata.npszLen,sizeof(int));
pFileOut->Write(xdata.pData, xdata.npszLen);
}
break;
default:
break;
}
}
}
sTemp = MAP_BLOCK_END;
bst = (LPCTSTR)sTemp;
str = std::string();
str.append((const char*)bst);
str2 = Base64::Encode(str);
pFileOut->Write(str2.c_str(), strlen(str2.c_str()));
return TRUE;
}
BOOL AecDbObjXDataMap::Write(CString &strOut, BOOL bWriteUserData) const
{
CMemFile mf;
if (Write(&mf, bWriteUserData))
{
mf.SeekToBegin();
strOut = Base64::EncodeF2W(&mf).c_str();
return 1;
}
return 0;
}
// bXRecord = fase 操作扩展数据 bXRecord = true 操作扩展词典
BOOL AecDbObjXDataMap::Read(AcDbObject* pEnt,LPCTSTR pszApp,BOOL bXRecord,BOOL bKeyAsSecond/* = FALSE*/)
{
if(pEnt == NULL || pszApp == NULL) return FALSE;
struct resbuf* pRb = NULL;
BOOL bResbuf2XDmap = FALSE;
if (!bXRecord)
{
// 扩展数据
pRb = pEnt->xData(pszApp);
if(pRb == NULL) return FALSE;
bResbuf2XDmap = Resbuf2XDMap(pRb,bXRecord,pEnt->database(),bKeyAsSecond);
acutRelRb(pRb);
return bResbuf2XDmap;
}
// 获取扩展数据(词典)id
AcDbObjectId dictObjId, xrecObjId;
dictObjId = pEnt->extensionDictionary();
if (dictObjId.isNull())
{
// 没有扩展数据
return FALSE;
}
// 打开扩展词典实体
AcDbDictionary* pDict = NULL;
if (Acad::eOk != acdbOpenObject(pDict, dictObjId, AcDb::kForRead))
{
return FALSE;
}
AcDbXrecord *pXrec = NULL;
AcDbObject* pObj = NULL;
// 获取扩展数据链表
if (Acad::eOk == pDict->getAt(pszApp,pObj,AcDb::kForRead))
{
pXrec = AcDbXrecord::cast(pObj);
if (pXrec != NULL)
{
pXrec->rbChain(&pRb);
if (pRb != NULL)
{
bResbuf2XDmap = Resbuf2XDMap(pRb,bXRecord,pEnt->database(),bKeyAsSecond);
acutRelRb(pRb);
}
}
pObj->close();
}
else
{
// 获取链表失败
pDict->close();
return FALSE;
}
pDict->close();
return bResbuf2XDmap;
}
// bXRecord = fase 操作扩展数据 bXRecord = true 操作扩展词典
BOOL AecDbObjXDataMap::Read(const AcDbObjectId& id,LPCTSTR pszApp,BOOL bXRecord,BOOL bKeyAsSecond/* = FALSE*/)
{
AcDbObject * pEnt = NULL;
BOOL bReadIdXData = FALSE;
if(Acad::eOk == acdbOpenObject(pEnt, id, AcDb::kForRead))
{
bReadIdXData = Read(pEnt,pszApp,bXRecord,bKeyAsSecond);
pEnt->close();
}
return bReadIdXData;
}
BOOL AecDbObjXDataMap::Read(CFile* pFileOut,BOOL bWriteUserData)
{
CString sTemp = MAP_BLOCK_BEGIN;
_bstr_t bst((LPCTSTR)sTemp);
std::string str;
str.append((const char*)bst);
std::string str2 = Base64::Encode(str);
char* pszBuf = new char[str2.length() + 1];
memset(pszBuf, 0, str2.length() + 1);
pFileOut->Read(pszBuf, str2.length());
int nCount = 0;
pFileOut->Read(&nCount,sizeof(int));
AecXData xdata;
int nLen = 0;
for (int i = 0;i < nCount;i++)
{
::memset(&xdata, 0, sizeof(xdata));
//key
pFileOut->Read(&nLen,sizeof(int));
TCHAR* pszKey = new TCHAR[nLen + 1];
::memset(pszKey, 0, (nLen + 1) * sizeof(TCHAR));
pFileOut->Read(pszKey, nLen * sizeof(TCHAR));
//value
pFileOut->Read(&xdata.nVt, sizeof(int));
switch (xdata.nVt)
{
case VT_I2:
pFileOut->Read(&xdata.iVal, sizeof(short));
case VT_I4: // 整型
pFileOut->Read(&xdata.nVal, sizeof(int));
break;
case VT_UI4:
pFileOut->Read(&xdata.nVal, sizeof(int));
break;
case VT_UI8:
pFileOut->Read(&xdata.nVal, sizeof(int));
break;
case VT_R8: // 浮点
pFileOut->Read(&xdata.dVal[0], sizeof(double));
break;
case (VT_BYREF | VT_R8): // 点
case (VT_BYREF | VT_R8 + 1):
case (VT_BYREF | VT_R8 + 2): // 向量
case (VT_BYREF | VT_R8 + 3):
pFileOut->Read(xdata.dVal, sizeof(double) * 3);
break;
case (VT_BYREF | VT_R8 + 4): //矩阵
case VT_BSTR: // 字符串
{
pFileOut->Read(&xdata.npszLen, sizeof(int));
xdata.pszVal = new TCHAR[xdata.npszLen + 1];
::memset(xdata.pszVal, 0, sizeof(TCHAR) * (xdata.npszLen + 1));
pFileOut->Read(xdata.pszVal, sizeof(TCHAR) * xdata.npszLen);
break;
}
case (VT_BYREF | VT_R8 + 5): //binary data
{
pFileOut->Read(&xdata.npszLen, sizeof(int));
xdata.pData = new byte[xdata.npszLen];
::memset(xdata.pszVal, 0, xdata.npszLen);
pFileOut->Read(xdata.pData, xdata.npszLen);
break;
}
default:
continue;
}
m_xData.insert(std::make_pair(pszKey, xdata));
delete[] pszKey;
pszKey = NULL;
}
return TRUE;
}
BOOL AecDbObjXDataMap::Read(LPCTSTR pszIn, BOOL bWriteUserData)
{
if (!pszIn) return 0;
CMemFile mf;
Base64::DecodeW2F(pszIn, &mf);
mf.SeekToBegin();
return Read(&mf, bWriteUserData);
}
SHJson::WValue& AecDbObjXDataMap::ToJson() const
{
AecXData xdata;
AcGePoint3d ptVal;
AcGeVector3d vt;
AcDbSoftPointerId id;
int type(-1);
std::wstring name(_T(""));
WValue node;
m_json.SetArray();
node.SetObject();
for (CIt it = m_xData.begin(); it != m_xData.end(); ++it)
{
xdata = (*it).second;
node.SetNull();
node.SetObject();
WValue value, name;
value.SetObject();
type = xdata.nVt;
addMember(node, _T("name"), it->first);
addMember(node, _T("type"), type);
switch (type)
{
case VT_I2:
addMember(node, _T("value"), xdata.iVal);
case VT_I4: // 整型
addMember(node, _T("value"), xdata.nVal);
break;
case VT_UI4:
case VT_UI8:
addMember(node, _T("value"), xdata.nVal);
break;
case VT_R8: // 浮点
addMember(node, _T("value"), xdata.dVal[0]);
break;
case (VT_BYREF | VT_R8): // 点
case (VT_BYREF | VT_R8 + 1):
toJson(AcGePoint3d(xdata.dVal[0], xdata.dVal[1], xdata.dVal[2]), value);
addMember(node, _T("value"), value);
break;
case (VT_BYREF | VT_R8 + 2): // 向量
case (VT_BYREF | VT_R8 + 3):
toJson(AcGeVector3d(xdata.dVal[0], xdata.dVal[1], xdata.dVal[2]), value);
addMember(node, _T("value"), value);
break;
case (VT_BYREF | VT_R8 + 4): //矩阵
{
AcGeMatrix3d xform;
CString sText = xdata.pszVal;
CStringArray arTexts;
Script2StringArray(sText, _T(','), arTexts);
if (arTexts.GetSize() == 16)
{
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
xform.entry[i][j] = _ttof(arTexts.GetAt(i * 4 + j));
}
}
}
toJson(xform, value);
addMember(node, _T("value"), value);
break;
}
case (VT_BYREF | VT_R8 + 5): //binary data
{
char *p = new char[xdata.npszLen];
LONG_PTR len(sizeof(char) * xdata.npszLen);
::memset(p, 0, len);
::memcpy(p, xdata.pData, len);
std::wstring ws(_T(""));
value.SetObject();
addMember(value, _T("len"), len);
if (len)
{
std::string s = Base64::Encode(p, len);
ws = Base64::ansii2Unicode(s.c_str(), CP_UTF8);
}
addMember(value, _T("data"), ws.c_str());
addMember(node, _T("value"), value);
DELETE_ARR_(p);
break;
}
break;
case VT_BSTR: // 字符串
addMember(node, _T("value"), xdata.pszVal);
break;
default:
break;
}
pushBack(m_json, node);
}
return m_json;
}
bool AecDbObjXDataMap::ByJson(const WValue &v)
{
if (!v.IsArray()) return false;
int type(-1);
std::wstring name(_T(""));
for (VCIt it = v.Begin(); it != v.End(); ++it)
{
WCValue &vv(*it);
if (!vv.IsObject()) continue;
if (!vv.HasMember(_T("type"))
|| !vv.HasMember(_T("name"))
|| !vv.HasMember(_T("value"))) continue;
type = vv[_T("type")].GetInt();
name = vv[_T("name")].GetString();
WCValue &va(vv[_T("value")]);
switch (type)
{
case VT_I2:
SetAt(name.c_str(), va.GetInt()); //??
return true;
case VT_I4: // 整型
SetAt(name.c_str(), va.GetInt());
return true;
case VT_UI4:
SetAt(name.c_str(), (DWORD)va.GetUint());
return true;
case VT_UI8:
SetAt(name.c_str(), (DWORD)va.GetUint64());
return true;
case VT_R8: // 浮点
SetAt(name.c_str(), va.GetDouble());
return true;
case (VT_BYREF | VT_R8): // 点
case (VT_BYREF | VT_R8 + 1):
{
AcGePoint3d pt;
if (!byJson(va, pt)) return false;
SetAt(name.c_str(), pt);
return true;
}
case (VT_BYREF | VT_R8 + 2): // 向量
case (VT_BYREF | VT_R8 + 3):
{
AcGeVector3d vt;
if (!byJson(va, vt)) return false;
SetAt(name.c_str(), vt);
return true;
}
case (VT_BYREF | VT_R8 + 4): //矩阵
{
AcGeMatrix3d m;
if (byJson(va, m)) return false;
SetAt(name.c_str(), m);
return true;
}
case (VT_BYREF | VT_R8 + 5): //binary data
{
char *pBuffer(NULL);
if (va.IsObject())
{
MCIt itLen = va.FindMember(_T("len"));
MCIt itData = va.FindMember(_T("data"));
if (itLen != va.MemberEnd() && itData != va.MemberEnd())
{
LONG_PTR len = itLen->value.GetInt64();
std::wstring ws = itData->value.GetString();
std::string s = Base64::unicode2Ansii(ws.c_str(), CP_UTF8);
// 这么写的原因是 decode() 函数有问题,反回的长度会大于原有长度,其内存会用0补齐
// 所以,这里直接用原有长度,并不会影响内存的释放。
if (Base64::Decode(s, pBuffer) >= len)
{
SetAt(name.c_str(), pBuffer, len);
}
}
}
DELETE_ARR_(pBuffer);
return true;
}
case VT_BSTR: // 字符串
SetAt(name.c_str(), va.GetString());
return true;
default:
break;
}
}
return false;
}
bool AecDbObjXDataMap::getBimDatas(const AecDbObjXDataMap & XData, SH_BIM_BLOCK & bim)
{
int count(0);
if (!XData.GetAt(BIM_REC_LEN, count)) return false;
bim.clear();
int idx(-1);
CString key, value, n, v;
for (int i = 0; i < count; ++i)
{
key.Format(_T("user%d"), i);
if (!XData.GetAt(key, value)) continue;
idx = value.Find(_T(":"));
if (idx == -1) continue;
n = value.Left(idx);
v = value.Right(value.GetLength() - idx - 1);
bim.push_back(std::make_pair(n, v));
}
return !bim.empty();
}
bool AecDbObjXDataMap::setBimDatas(AecDbObjXDataMap & XData, const SH_BIM_BLOCK & bim)
{
int count(0);
XData.GetAt(BIM_REC_LEN, count);
CString name, value;
for (int i = 0; i < count; ++i)
{
name.Format(_T("user%d"), i);
XData.RemoveAt(name);
}
if (XData.SetAt(BIM_REC_LEN, (int)bim.size()))
{
for (int i = 0; i < bim.size(); ++i)
{
const SH_BIM_REC &rec(bim[i]);
name.Format(_T("user%d"), i);
value.Format(_T("%s:%s"), rec.first, rec.second);
XData.SetAt(name, value);
}
return true;
}
return false;
}
bool AecDbObjXDataMap::findBimData(const AecDbObjXDataMap &XData
, LPCTSTR pszKey
, CString &strValue
, CString &strUserKey)
{
int count(0);
if (!XData.GetAt(BIM_REC_LEN, count)) return false;
int idx(-1);
CString key, value, n, v;;
for (int i = 0; i < count; ++i)
{
key.Format(_T("user%d"), i);
if (!XData.GetAt(key, value)) continue;
idx = value.Find(_T(":"));
if (idx == -1) continue;
n = value.Left(idx);
if (n == pszKey)
{
strUserKey = key;
strValue = value.Right(value.GetLength() - idx - 1);
return true;
}
}
return false;
}
bool AecDbObjXDataMap::getBimData(const AecDbObjXDataMap & XData, LPCTSTR pszKey, CString & strValue)
{
if (!pszKey) return false;
CString strUserKey;
if (!findBimData(XData, pszKey, strValue, strUserKey))
return false;
return true;
}
bool AecDbObjXDataMap::setBimData(AecDbObjXDataMap & XData, LPCTSTR pszKey, LPCTSTR pszValue)
{
if (!pszKey || !pszValue) return false;
CString strUserKey, strValue;
if (findBimData(XData, pszKey, strValue, strUserKey))
{
return XData.SetAt(strUserKey, CString(pszKey) + _T(":") + pszValue) ? true : false;
}
else
{
int count(0);
XData.GetAt(BIM_REC_LEN, count);
CString userKey(_T(""));
userKey.Format(_T("user%d"), count);
XData.SetAt(BIM_REC_LEN, count + 1);
return XData.SetAt(userKey, CString(pszKey) + _T(":") + pszValue) ? true : false;
}
return false;
}
bool AecDbObjXDataMap::delBimData(AecDbObjXDataMap & XData, LPCTSTR pszKey)
{
if (!pszKey) return false;
CString strUserKey, strValue;
if (!findBimData(XData, pszKey, strValue, strUserKey)) return false;
if (XData.RemoveAt(strUserKey))
{
int count(0);
XData.GetAt(BIM_REC_LEN, count);
if (count > 0)
XData.SetAt(BIM_REC_LEN, count - 1);
return true;
}
return false;
}
size_t AecDbObjXDataMap::Count() const
{
return m_xData.size();
}