#include "stdafx.h" #include "SpBase.h" #include "SpXmlPersistStream.h" #include "scew.h" #include "base64.h" /* */ template static const char *GetIntrinsicTypeName() {_ASSERT(FALSE);return NULL;} template<> const char *GetIntrinsicTypeName() {return "ULONGLONG";} template<> const char *GetIntrinsicTypeName() {return "LONGLONG";} template<> const char *GetIntrinsicTypeName() {return "DWORD";} template<> const char *GetIntrinsicTypeName() {return "WORD";} template<> const char *GetIntrinsicTypeName() {return "BYTE";} template<> const char *GetIntrinsicTypeName() {return "CHAR";} template<> const char *GetIntrinsicTypeName() {return "FLOAT";} template<> const char *GetIntrinsicTypeName() {return "DOUBLE";} template<> const char *GetIntrinsicTypeName() {return "SHORT";} template<> const char *GetIntrinsicTypeName() {return "STRING";} template<> const char *GetIntrinsicTypeName() {return "STRING";} template static scew_element * AddIntrinsicNode(scew_element *pParentNode, const char *pszKey, const T t) { char tmp[32]; int len; const char *pTypeName = GetIntrinsicTypeName(); len = base64_encode_len(sizeof(t)); _ASSERT(len <= sizeof(tmp)); base64_encode(tmp, (char*)&t, sizeof(t)); scew_element *node = scew_element_create("intrinsic"); if (_stricmp(scew_element_name(pParentNode), "object") == 0) { scew_element_add_attribute_pair(node, "type", pTypeName); scew_element_add_attribute_pair(node, "key", pszKey); } scew_element_set_contents(node, tmp); scew_element_add_element(pParentNode, node); return node; } template<> #ifdef _WIN32 static #endif //_WIN32 scew_element * AddIntrinsicNode(scew_element *pParentNode, const char *pszKey, const char *t) { char tmp[32]; int len; const char *pTypeName = GetIntrinsicTypeName(); int slen = t ? strlen(t) : 0; len = base64_encode_len(slen); _ASSERT(len <= sizeof(tmp)); base64_encode(tmp, (char*)t, slen); scew_element *node = scew_element_create("intrinsic"); if (_stricmp(scew_element_name(pParentNode), "object") == 0) { scew_element_add_attribute_pair(node, "type", pTypeName); scew_element_add_attribute_pair(node, "key", pszKey); } scew_element_set_contents(node, len ? tmp : ""); scew_element_add_element(pParentNode, node); return node; } template<> #ifdef _WIN32 static #endif //_WIN32 scew_element * AddIntrinsicNode(scew_element *pParentNode, const char *pszKey, const CSimpleStringA &t) { const char *tmp = t.GetData(); return AddIntrinsicNode(pParentNode, pszKey, tmp); } static scew_element *AddObjectNode(scew_element *pParentNode, const char *pszKey) { scew_element *node = scew_element_create("object"); scew_element_add_attribute_pair(node, "key", pszKey); scew_element_add_element(pParentNode, node); return node; } template static scew_element *AddIntrinsicArrayNode(scew_element *pParentNode, const char *pszKey, const CAutoArray &arrObjects) { const char *pTypeName = GetIntrinsicTypeName(); scew_element *node = scew_element_create("array"); scew_element_add_attribute_pair(node, "type", pTypeName); scew_element_add_attribute_pair(node, "key", pszKey); for (int i = 0; i < arrObjects.GetCount(); ++i) { AddIntrinsicNode(node, pszKey, arrObjects[i]); } scew_element_add_element(pParentNode, node); return node; } static scew_element *find_element_by_key(scew_element *pParentNode, const char *pszKey) { scew_list *it = scew_element_children(pParentNode); while (it) { scew_element *elem = (scew_element*)scew_list_data(it); scew_attribute *attr = scew_element_attribute_by_name(elem, "key"); if (attr) { if (_stricmp(scew_attribute_name(attr), pszKey) == 0) return elem; } it = scew_list_next(it); } return NULL; } template static ErrorCodeEnum ReadValue(scew_element *node, T &v) { char *data = (char*)scew_element_contents(node); if (data) { int len = base64_decode_len(data); if (len == sizeof(T)) { base64_decode((char*)&v, data); return Error_Succeed; } } return Error_Unexpect; } template<> #ifdef _WIN32 static #endif //_WIN32 ErrorCodeEnum ReadValue(scew_element *node, CSimpleStringA &v) { char *data = (char*)scew_element_contents(node); if (data) { int len = base64_decode_len(data); CSimpleStringA strTmp('\0', len); base64_decode((char*)&strTmp[0], data); v = strTmp; return Error_Succeed; } return Error_Unexpect; } static ErrorCodeEnum CheckType(scew_element *node, const char *pTypeName) { if (_stricmp(scew_element_name(scew_element_parent(node)), "object") == 0) { scew_attribute *attr = scew_element_attribute_by_name(node, "type"); if (attr) { if (_stricmp(scew_attribute_name(attr), pTypeName) == 0) return Error_Succeed; } } return Error_Unexpect; } template static ErrorCodeEnum ReadIntrinsicNode(scew_element *pParentNode, const char *pszKey, T &v) { scew_element *node = find_element_by_key(pParentNode, pszKey); if (node) { ErrorCodeEnum Error = CheckType(node, GetIntrinsicTypeName()); if (Error) return Error; return ReadValue(node, v); } return Error_NotExist; } template static ErrorCodeEnum ReadIntrinsicArrayNode(scew_element *pParentNode, const char *pszKey, CAutoArray &v) { scew_element *node = find_element_by_key(pParentNode, pszKey); if (node) { ErrorCodeEnum Error = CheckType(node, GetIntrinsicTypeName()); if (Error) return Error; int cnt = 0; scew_list *it = scew_element_children(node); while (it) { cnt++; it = scew_list_next(it); } v.Init(cnt); int i = 0; it = scew_element_children(node); while (it && !Error) { scew_element *child = (scew_element *)scew_list_data(it); Error = ReadValue(child, v[i++]); it = scew_list_next(it); } return Error; } return Error_NotExist; } SpXmlPersistStream::SpXmlPersistStream( int iMode, scew_element *pNode ) : m_iMode(iMode), m_pNode(pNode) { } SpXmlPersistStream::~SpXmlPersistStream() { // } ErrorCodeEnum SpXmlPersistStream::Set(const char *pszKey,const char *pszValue) { _ASSERT(pszKey); AddIntrinsicNode(m_pNode, pszKey, pszValue); return Error_Succeed; } ErrorCodeEnum SpXmlPersistStream::Set(const char *pszKey,const ULONGLONG nValue) { _ASSERT(pszKey); AddIntrinsicNode(m_pNode, pszKey, nValue); return Error_Succeed; } ErrorCodeEnum SpXmlPersistStream::Set(const char *pszKey,const DWORD nValue) { _ASSERT(pszKey); AddIntrinsicNode(m_pNode, pszKey, nValue); return Error_Succeed; } ErrorCodeEnum SpXmlPersistStream::Set(const char *pszKey,const WORD nValue) { _ASSERT(pszKey); AddIntrinsicNode(m_pNode, pszKey, nValue); return Error_Succeed; } ErrorCodeEnum SpXmlPersistStream::Set(const char *pszKey,const BYTE nValue) { _ASSERT(pszKey); AddIntrinsicNode(m_pNode, pszKey, nValue); return Error_Succeed; } ErrorCodeEnum SpXmlPersistStream::Set(const char *pszKey,const FLOAT nValue) { _ASSERT(pszKey); AddIntrinsicNode(m_pNode, pszKey, nValue); return Error_Succeed; } ErrorCodeEnum SpXmlPersistStream::Set(const char *pszKey,const DOUBLE nValue) { _ASSERT(pszKey); AddIntrinsicNode(m_pNode, pszKey, nValue); return Error_Succeed; } ErrorCodeEnum SpXmlPersistStream::Set(const char *pszKey,const IEntityPersistObject *pValue) { _ASSERT(pszKey); _ASSERT(pValue); scew_element *child = AddObjectNode(m_pNode, pszKey); CSmartPointer pStream; pStream.Attach(new SpXmlPersistStream(SpXmlPersistStream::Write, child)); ErrorCodeEnum Error = pValue->OnWrite(pStream); return Error; } ErrorCodeEnum SpXmlPersistStream::SetArray(const char *pszKey,const CAutoArray &strValues) { _ASSERT(pszKey); AddIntrinsicArrayNode(m_pNode, pszKey, strValues); return Error_Succeed; } ErrorCodeEnum SpXmlPersistStream::SetArray(const char *pszKey,const CAutoArray &nValues) { _ASSERT(pszKey); AddIntrinsicArrayNode(m_pNode, pszKey, nValues); return Error_Succeed; } ErrorCodeEnum SpXmlPersistStream::SetArray(const char *pszKey,const CAutoArray &nValues) { _ASSERT(pszKey); AddIntrinsicArrayNode(m_pNode, pszKey, nValues); return Error_Succeed; } ErrorCodeEnum SpXmlPersistStream::SetArray(const char *pszKey,const CAutoArray &nValues) { _ASSERT(pszKey); AddIntrinsicArrayNode(m_pNode, pszKey, nValues); return Error_Succeed; } ErrorCodeEnum SpXmlPersistStream::SetArray(const char *pszKey,const CAutoArray &nValues) { _ASSERT(pszKey); AddIntrinsicArrayNode(m_pNode, pszKey, nValues); return Error_Succeed; } ErrorCodeEnum SpXmlPersistStream::SetArray(const char *pszKey,const CAutoArray &nValues) { _ASSERT(pszKey); AddIntrinsicArrayNode(m_pNode, pszKey, nValues); return Error_Succeed; } ErrorCodeEnum SpXmlPersistStream::SetArray(const char *pszKey,const CAutoArray &nValues) { _ASSERT(pszKey); AddIntrinsicArrayNode(m_pNode, pszKey, nValues); return Error_Succeed; } ErrorCodeEnum SpXmlPersistStream::Get(const char *pszKey,CSimpleStringA &strValue) { _ASSERT(pszKey); return ReadIntrinsicNode(m_pNode, pszKey, strValue); } ErrorCodeEnum SpXmlPersistStream::Get(const char *pszKey,ULONGLONG &nValue) { _ASSERT(pszKey); return ReadIntrinsicNode(m_pNode, pszKey, nValue); } ErrorCodeEnum SpXmlPersistStream::Get(const char *pszKey,DWORD &nValue) { _ASSERT(pszKey); return ReadIntrinsicNode(m_pNode, pszKey, nValue); } ErrorCodeEnum SpXmlPersistStream::Get(const char *pszKey,WORD &nValue) { _ASSERT(pszKey); return ReadIntrinsicNode(m_pNode, pszKey, nValue); } ErrorCodeEnum SpXmlPersistStream::Get(const char *pszKey,BYTE &nValue) { _ASSERT(pszKey); return ReadIntrinsicNode(m_pNode, pszKey, nValue); } ErrorCodeEnum SpXmlPersistStream::Get(const char *pszKey,FLOAT &nValue) { _ASSERT(pszKey); return ReadIntrinsicNode(m_pNode, pszKey, nValue); } ErrorCodeEnum SpXmlPersistStream::Get(const char *pszKey,DOUBLE &nValue) { _ASSERT(pszKey); return ReadIntrinsicNode(m_pNode, pszKey, nValue); } ErrorCodeEnum SpXmlPersistStream::Get(const char *pszKey,IEntityPersistObject *pValue) { _ASSERT(pszKey); scew_element *child = find_element_by_key(m_pNode, pszKey); CSmartPointer pStream; pStream.Attach(new SpXmlPersistStream(SpXmlPersistStream::Read, child)); ErrorCodeEnum Error = pValue->OnRead(pStream); return Error; } ErrorCodeEnum SpXmlPersistStream::GetArray(const char *pszKey,CAutoArray &strValues) { _ASSERT(pszKey); return ReadIntrinsicArrayNode(m_pNode, pszKey, strValues); } ErrorCodeEnum SpXmlPersistStream::GetArray(const char *pszKey,CAutoArray &nValues) { _ASSERT(pszKey); return ReadIntrinsicArrayNode(m_pNode, pszKey, nValues); } ErrorCodeEnum SpXmlPersistStream::GetArray(const char *pszKey,CAutoArray &nValues) { _ASSERT(pszKey); return ReadIntrinsicArrayNode(m_pNode, pszKey, nValues); } ErrorCodeEnum SpXmlPersistStream::GetArray(const char *pszKey,CAutoArray &nValues) { _ASSERT(pszKey); return ReadIntrinsicArrayNode(m_pNode, pszKey, nValues); } ErrorCodeEnum SpXmlPersistStream::GetArray(const char *pszKey,CAutoArray &nValues) { _ASSERT(pszKey); return ReadIntrinsicArrayNode(m_pNode, pszKey, nValues); } ErrorCodeEnum SpXmlPersistStream::GetArray(const char *pszKey,CAutoArray &nValues) { _ASSERT(pszKey); return ReadIntrinsicArrayNode(m_pNode, pszKey, nValues); } ErrorCodeEnum SpXmlPersistStream::GetArray(const char *pszKey,CAutoArray &nValues) { _ASSERT(pszKey); return ReadIntrinsicArrayNode(m_pNode, pszKey, nValues); }