#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);
}