SpXmlPersistStream.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  1. #include "stdafx.h"
  2. #include "SpBase.h"
  3. #include "SpXmlPersistStream.h"
  4. #include "scew.h"
  5. #include "base64.h"
  6. /*
  7. <intrinsic type="int" key="" value=""/>
  8. <object key="">
  9. </object>
  10. <array type="" key="">
  11. <intrinsic value=""/>
  12. </array>
  13. */
  14. template<class T>
  15. static const char *GetIntrinsicTypeName() {_ASSERT(FALSE);return NULL;}
  16. template<> const char *GetIntrinsicTypeName<ULONGLONG>() {return "ULONGLONG";}
  17. template<> const char *GetIntrinsicTypeName<LONGLONG>() {return "LONGLONG";}
  18. template<> const char *GetIntrinsicTypeName<DWORD>() {return "DWORD";}
  19. template<> const char *GetIntrinsicTypeName<WORD>() {return "WORD";}
  20. template<> const char *GetIntrinsicTypeName<BYTE>() {return "BYTE";}
  21. template<> const char *GetIntrinsicTypeName<CHAR>() {return "CHAR";}
  22. template<> const char *GetIntrinsicTypeName<FLOAT>() {return "FLOAT";}
  23. template<> const char *GetIntrinsicTypeName<DOUBLE>() {return "DOUBLE";}
  24. template<> const char *GetIntrinsicTypeName<SHORT>() {return "SHORT";}
  25. template<> const char *GetIntrinsicTypeName<const char*>() {return "STRING";}
  26. template<> const char *GetIntrinsicTypeName<CSimpleStringA>() {return "STRING";}
  27. template<class T>
  28. static scew_element * AddIntrinsicNode(scew_element *pParentNode, const char *pszKey, const T t)
  29. {
  30. char tmp[32];
  31. int len;
  32. const char *pTypeName = GetIntrinsicTypeName<T>();
  33. len = base64_encode_len(sizeof(t));
  34. _ASSERT(len <= sizeof(tmp));
  35. base64_encode(tmp, (char*)&t, sizeof(t));
  36. scew_element *node = scew_element_create("intrinsic");
  37. if (_stricmp(scew_element_name(pParentNode), "object") == 0) {
  38. scew_element_add_attribute_pair(node, "type", pTypeName);
  39. scew_element_add_attribute_pair(node, "key", pszKey);
  40. }
  41. scew_element_set_contents(node, tmp);
  42. scew_element_add_element(pParentNode, node);
  43. return node;
  44. }
  45. template<>
  46. #ifdef _WIN32
  47. static
  48. #endif //_WIN32
  49. scew_element * AddIntrinsicNode(scew_element *pParentNode, const char *pszKey, const char *t)
  50. {
  51. char tmp[32];
  52. int len;
  53. const char *pTypeName = GetIntrinsicTypeName<const char *>();
  54. int slen = t ? strlen(t) : 0;
  55. len = base64_encode_len(slen);
  56. _ASSERT(len <= sizeof(tmp));
  57. base64_encode(tmp, (char*)t, slen);
  58. scew_element *node = scew_element_create("intrinsic");
  59. if (_stricmp(scew_element_name(pParentNode), "object") == 0) {
  60. scew_element_add_attribute_pair(node, "type", pTypeName);
  61. scew_element_add_attribute_pair(node, "key", pszKey);
  62. }
  63. scew_element_set_contents(node, len ? tmp : "");
  64. scew_element_add_element(pParentNode, node);
  65. return node;
  66. }
  67. template<>
  68. #ifdef _WIN32
  69. static
  70. #endif //_WIN32
  71. scew_element * AddIntrinsicNode(scew_element *pParentNode, const char *pszKey, const CSimpleStringA &t)
  72. {
  73. const char *tmp = t.GetData();
  74. return AddIntrinsicNode(pParentNode, pszKey, tmp);
  75. }
  76. static scew_element *AddObjectNode(scew_element *pParentNode, const char *pszKey)
  77. {
  78. scew_element *node = scew_element_create("object");
  79. scew_element_add_attribute_pair(node, "key", pszKey);
  80. scew_element_add_element(pParentNode, node);
  81. return node;
  82. }
  83. template<class T>
  84. static scew_element *AddIntrinsicArrayNode(scew_element *pParentNode, const char *pszKey, const CAutoArray<T> &arrObjects)
  85. {
  86. const char *pTypeName = GetIntrinsicTypeName<T>();
  87. scew_element *node = scew_element_create("array");
  88. scew_element_add_attribute_pair(node, "type", pTypeName);
  89. scew_element_add_attribute_pair(node, "key", pszKey);
  90. for (int i = 0; i < arrObjects.GetCount(); ++i) {
  91. AddIntrinsicNode(node, pszKey, arrObjects[i]);
  92. }
  93. scew_element_add_element(pParentNode, node);
  94. return node;
  95. }
  96. static scew_element *find_element_by_key(scew_element *pParentNode, const char *pszKey)
  97. {
  98. scew_list *it = scew_element_children(pParentNode);
  99. while (it) {
  100. scew_element *elem = (scew_element*)scew_list_data(it);
  101. scew_attribute *attr = scew_element_attribute_by_name(elem, "key");
  102. if (attr) {
  103. if (_stricmp(scew_attribute_name(attr), pszKey) == 0)
  104. return elem;
  105. }
  106. it = scew_list_next(it);
  107. }
  108. return NULL;
  109. }
  110. template<class T>
  111. static ErrorCodeEnum ReadValue(scew_element *node, T &v)
  112. {
  113. char *data = (char*)scew_element_contents(node);
  114. if (data) {
  115. int len = base64_decode_len(data);
  116. if (len == sizeof(T)) {
  117. base64_decode((char*)&v, data);
  118. return Error_Succeed;
  119. }
  120. }
  121. return Error_Unexpect;
  122. }
  123. template<>
  124. #ifdef _WIN32
  125. static
  126. #endif //_WIN32
  127. ErrorCodeEnum ReadValue(scew_element *node, CSimpleStringA &v)
  128. {
  129. char *data = (char*)scew_element_contents(node);
  130. if (data) {
  131. int len = base64_decode_len(data);
  132. CSimpleStringA strTmp('\0', len);
  133. base64_decode((char*)&strTmp[0], data);
  134. v = strTmp;
  135. return Error_Succeed;
  136. }
  137. return Error_Unexpect;
  138. }
  139. static ErrorCodeEnum CheckType(scew_element *node, const char *pTypeName)
  140. {
  141. if (_stricmp(scew_element_name(scew_element_parent(node)), "object") == 0) {
  142. scew_attribute *attr = scew_element_attribute_by_name(node, "type");
  143. if (attr) {
  144. if (_stricmp(scew_attribute_name(attr), pTypeName) == 0)
  145. return Error_Succeed;
  146. }
  147. }
  148. return Error_Unexpect;
  149. }
  150. template<class T>
  151. static ErrorCodeEnum ReadIntrinsicNode(scew_element *pParentNode, const char *pszKey, T &v)
  152. {
  153. scew_element *node = find_element_by_key(pParentNode, pszKey);
  154. if (node) {
  155. ErrorCodeEnum Error = CheckType(node, GetIntrinsicTypeName<T>());
  156. if (Error)
  157. return Error;
  158. return ReadValue(node, v);
  159. }
  160. return Error_NotExist;
  161. }
  162. template<class T>
  163. static ErrorCodeEnum ReadIntrinsicArrayNode(scew_element *pParentNode, const char *pszKey, CAutoArray<T> &v)
  164. {
  165. scew_element *node = find_element_by_key(pParentNode, pszKey);
  166. if (node) {
  167. ErrorCodeEnum Error = CheckType(node, GetIntrinsicTypeName<T>());
  168. if (Error)
  169. return Error;
  170. int cnt = 0;
  171. scew_list *it = scew_element_children(node);
  172. while (it) {
  173. cnt++;
  174. it = scew_list_next(it);
  175. }
  176. v.Init(cnt);
  177. int i = 0;
  178. it = scew_element_children(node);
  179. while (it && !Error) {
  180. scew_element *child = (scew_element *)scew_list_data(it);
  181. Error = ReadValue(child, v[i++]);
  182. it = scew_list_next(it);
  183. }
  184. return Error;
  185. }
  186. return Error_NotExist;
  187. }
  188. SpXmlPersistStream::SpXmlPersistStream( int iMode, scew_element *pNode )
  189. : m_iMode(iMode), m_pNode(pNode)
  190. {
  191. }
  192. SpXmlPersistStream::~SpXmlPersistStream()
  193. {
  194. //
  195. }
  196. ErrorCodeEnum SpXmlPersistStream::Set(const char *pszKey,const char *pszValue)
  197. {
  198. _ASSERT(pszKey);
  199. AddIntrinsicNode(m_pNode, pszKey, pszValue);
  200. return Error_Succeed;
  201. }
  202. ErrorCodeEnum SpXmlPersistStream::Set(const char *pszKey,const ULONGLONG nValue)
  203. {
  204. _ASSERT(pszKey);
  205. AddIntrinsicNode(m_pNode, pszKey, nValue);
  206. return Error_Succeed;
  207. }
  208. ErrorCodeEnum SpXmlPersistStream::Set(const char *pszKey,const DWORD nValue)
  209. {
  210. _ASSERT(pszKey);
  211. AddIntrinsicNode(m_pNode, pszKey, nValue);
  212. return Error_Succeed;
  213. }
  214. ErrorCodeEnum SpXmlPersistStream::Set(const char *pszKey,const WORD nValue)
  215. {
  216. _ASSERT(pszKey);
  217. AddIntrinsicNode(m_pNode, pszKey, nValue);
  218. return Error_Succeed;
  219. }
  220. ErrorCodeEnum SpXmlPersistStream::Set(const char *pszKey,const BYTE nValue)
  221. {
  222. _ASSERT(pszKey);
  223. AddIntrinsicNode(m_pNode, pszKey, nValue);
  224. return Error_Succeed;
  225. }
  226. ErrorCodeEnum SpXmlPersistStream::Set(const char *pszKey,const FLOAT nValue)
  227. {
  228. _ASSERT(pszKey);
  229. AddIntrinsicNode(m_pNode, pszKey, nValue);
  230. return Error_Succeed;
  231. }
  232. ErrorCodeEnum SpXmlPersistStream::Set(const char *pszKey,const DOUBLE nValue)
  233. {
  234. _ASSERT(pszKey);
  235. AddIntrinsicNode(m_pNode, pszKey, nValue);
  236. return Error_Succeed;
  237. }
  238. ErrorCodeEnum SpXmlPersistStream::Set(const char *pszKey,const IEntityPersistObject *pValue)
  239. {
  240. _ASSERT(pszKey);
  241. _ASSERT(pValue);
  242. scew_element *child = AddObjectNode(m_pNode, pszKey);
  243. CSmartPointer<IEntityPersistStreamWrite> pStream;
  244. pStream.Attach(new SpXmlPersistStream(SpXmlPersistStream::Write, child));
  245. ErrorCodeEnum Error = pValue->OnWrite(pStream);
  246. return Error;
  247. }
  248. ErrorCodeEnum SpXmlPersistStream::SetArray(const char *pszKey,const CAutoArray<CSimpleStringA> &strValues)
  249. {
  250. _ASSERT(pszKey);
  251. AddIntrinsicArrayNode(m_pNode, pszKey, strValues);
  252. return Error_Succeed;
  253. }
  254. ErrorCodeEnum SpXmlPersistStream::SetArray(const char *pszKey,const CAutoArray<ULONGLONG> &nValues)
  255. {
  256. _ASSERT(pszKey);
  257. AddIntrinsicArrayNode(m_pNode, pszKey, nValues);
  258. return Error_Succeed;
  259. }
  260. ErrorCodeEnum SpXmlPersistStream::SetArray(const char *pszKey,const CAutoArray<DWORD> &nValues)
  261. {
  262. _ASSERT(pszKey);
  263. AddIntrinsicArrayNode(m_pNode, pszKey, nValues);
  264. return Error_Succeed;
  265. }
  266. ErrorCodeEnum SpXmlPersistStream::SetArray(const char *pszKey,const CAutoArray<WORD> &nValues)
  267. {
  268. _ASSERT(pszKey);
  269. AddIntrinsicArrayNode(m_pNode, pszKey, nValues);
  270. return Error_Succeed;
  271. }
  272. ErrorCodeEnum SpXmlPersistStream::SetArray(const char *pszKey,const CAutoArray<BYTE> &nValues)
  273. {
  274. _ASSERT(pszKey);
  275. AddIntrinsicArrayNode(m_pNode, pszKey, nValues);
  276. return Error_Succeed;
  277. }
  278. ErrorCodeEnum SpXmlPersistStream::SetArray(const char *pszKey,const CAutoArray<FLOAT> &nValues)
  279. {
  280. _ASSERT(pszKey);
  281. AddIntrinsicArrayNode(m_pNode, pszKey, nValues);
  282. return Error_Succeed;
  283. }
  284. ErrorCodeEnum SpXmlPersistStream::SetArray(const char *pszKey,const CAutoArray<DOUBLE> &nValues)
  285. {
  286. _ASSERT(pszKey);
  287. AddIntrinsicArrayNode(m_pNode, pszKey, nValues);
  288. return Error_Succeed;
  289. }
  290. ErrorCodeEnum SpXmlPersistStream::Get(const char *pszKey,CSimpleStringA &strValue)
  291. {
  292. _ASSERT(pszKey);
  293. return ReadIntrinsicNode(m_pNode, pszKey, strValue);
  294. }
  295. ErrorCodeEnum SpXmlPersistStream::Get(const char *pszKey,ULONGLONG &nValue)
  296. {
  297. _ASSERT(pszKey);
  298. return ReadIntrinsicNode(m_pNode, pszKey, nValue);
  299. }
  300. ErrorCodeEnum SpXmlPersistStream::Get(const char *pszKey,DWORD &nValue)
  301. {
  302. _ASSERT(pszKey);
  303. return ReadIntrinsicNode(m_pNode, pszKey, nValue);
  304. }
  305. ErrorCodeEnum SpXmlPersistStream::Get(const char *pszKey,WORD &nValue)
  306. {
  307. _ASSERT(pszKey);
  308. return ReadIntrinsicNode(m_pNode, pszKey, nValue);
  309. }
  310. ErrorCodeEnum SpXmlPersistStream::Get(const char *pszKey,BYTE &nValue)
  311. {
  312. _ASSERT(pszKey);
  313. return ReadIntrinsicNode(m_pNode, pszKey, nValue);
  314. }
  315. ErrorCodeEnum SpXmlPersistStream::Get(const char *pszKey,FLOAT &nValue)
  316. {
  317. _ASSERT(pszKey);
  318. return ReadIntrinsicNode(m_pNode, pszKey, nValue);
  319. }
  320. ErrorCodeEnum SpXmlPersistStream::Get(const char *pszKey,DOUBLE &nValue)
  321. {
  322. _ASSERT(pszKey);
  323. return ReadIntrinsicNode(m_pNode, pszKey, nValue);
  324. }
  325. ErrorCodeEnum SpXmlPersistStream::Get(const char *pszKey,IEntityPersistObject *pValue)
  326. {
  327. _ASSERT(pszKey);
  328. scew_element *child = find_element_by_key(m_pNode, pszKey);
  329. CSmartPointer<IEntityPersistStreamRead> pStream;
  330. pStream.Attach(new SpXmlPersistStream(SpXmlPersistStream::Read, child));
  331. ErrorCodeEnum Error = pValue->OnRead(pStream);
  332. return Error;
  333. }
  334. ErrorCodeEnum SpXmlPersistStream::GetArray(const char *pszKey,CAutoArray<CSimpleStringA> &strValues)
  335. {
  336. _ASSERT(pszKey);
  337. return ReadIntrinsicArrayNode(m_pNode, pszKey, strValues);
  338. }
  339. ErrorCodeEnum SpXmlPersistStream::GetArray(const char *pszKey,CAutoArray<ULONGLONG> &nValues)
  340. {
  341. _ASSERT(pszKey);
  342. return ReadIntrinsicArrayNode(m_pNode, pszKey, nValues);
  343. }
  344. ErrorCodeEnum SpXmlPersistStream::GetArray(const char *pszKey,CAutoArray<DWORD> &nValues)
  345. {
  346. _ASSERT(pszKey);
  347. return ReadIntrinsicArrayNode(m_pNode, pszKey, nValues);
  348. }
  349. ErrorCodeEnum SpXmlPersistStream::GetArray(const char *pszKey,CAutoArray<WORD> &nValues)
  350. {
  351. _ASSERT(pszKey);
  352. return ReadIntrinsicArrayNode(m_pNode, pszKey, nValues);
  353. }
  354. ErrorCodeEnum SpXmlPersistStream::GetArray(const char *pszKey,CAutoArray<BYTE> &nValues)
  355. {
  356. _ASSERT(pszKey);
  357. return ReadIntrinsicArrayNode(m_pNode, pszKey, nValues);
  358. }
  359. ErrorCodeEnum SpXmlPersistStream::GetArray(const char *pszKey,CAutoArray<FLOAT> &nValues)
  360. {
  361. _ASSERT(pszKey);
  362. return ReadIntrinsicArrayNode(m_pNode, pszKey, nValues);
  363. }
  364. ErrorCodeEnum SpXmlPersistStream::GetArray(const char *pszKey,CAutoArray<DOUBLE> &nValues)
  365. {
  366. _ASSERT(pszKey);
  367. return ReadIntrinsicArrayNode(m_pNode, pszKey, nValues);
  368. }