/xbmc/utils/Archive.cpp

https://github.com/dahool84/xbmc · C++ · 495 lines · 384 code · 91 blank · 20 comment · 27 complexity · 2e028735cf687cae18a7a3e16661c228 MD5 · raw file

  1. /*
  2. * Copyright (C) 2005-2008 Team XBMC
  3. * http://www.xbmc.org
  4. *
  5. * This Program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2, or (at your option)
  8. * any later version.
  9. *
  10. * This Program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with XBMC; see the file COPYING. If not, write to
  17. * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  18. * http://www.gnu.org/copyleft/gpl.html
  19. *
  20. */
  21. #include "Archive.h"
  22. #include "filesystem/File.h"
  23. #include "Variant.h"
  24. using namespace XFILE;
  25. #define BUFFER_MAX 4096
  26. CArchive::CArchive(CFile* pFile, int mode)
  27. {
  28. m_pFile = pFile;
  29. m_iMode = mode;
  30. m_pBuffer = new BYTE[BUFFER_MAX];
  31. memset(m_pBuffer, 0, sizeof(m_pBuffer));
  32. m_BufferPos = 0;
  33. }
  34. CArchive::~CArchive()
  35. {
  36. FlushBuffer();
  37. delete[] m_pBuffer;
  38. m_BufferPos = 0;
  39. }
  40. void CArchive::Close()
  41. {
  42. FlushBuffer();
  43. }
  44. bool CArchive::IsLoading()
  45. {
  46. return (m_iMode == load);
  47. }
  48. bool CArchive::IsStoring()
  49. {
  50. return (m_iMode == store);
  51. }
  52. CArchive& CArchive::operator<<(float f)
  53. {
  54. int size = sizeof(float);
  55. if (m_BufferPos + size >= BUFFER_MAX)
  56. FlushBuffer();
  57. memcpy(&m_pBuffer[m_BufferPos], &f, size);
  58. m_BufferPos += size;
  59. return *this;
  60. }
  61. CArchive& CArchive::operator<<(double d)
  62. {
  63. int size = sizeof(double);
  64. if (m_BufferPos + size >= BUFFER_MAX)
  65. FlushBuffer();
  66. memcpy(&m_pBuffer[m_BufferPos], &d, size);
  67. m_BufferPos += size;
  68. return *this;
  69. }
  70. CArchive& CArchive::operator<<(int i)
  71. {
  72. int size = sizeof(int);
  73. if (m_BufferPos + size >= BUFFER_MAX)
  74. FlushBuffer();
  75. memcpy(&m_pBuffer[m_BufferPos], &i, size);
  76. m_BufferPos += size;
  77. return *this;
  78. }
  79. CArchive& CArchive::operator<<(unsigned int i)
  80. {
  81. int size = sizeof(unsigned int);
  82. if (m_BufferPos + size >= BUFFER_MAX)
  83. FlushBuffer();
  84. memcpy(&m_pBuffer[m_BufferPos], &i, size);
  85. m_BufferPos += size;
  86. return *this;
  87. }
  88. CArchive& CArchive::operator<<(int64_t i64)
  89. {
  90. int size = sizeof(int64_t);
  91. if (m_BufferPos + size >= BUFFER_MAX)
  92. FlushBuffer();
  93. memcpy(&m_pBuffer[m_BufferPos], &i64, size);
  94. m_BufferPos += size;
  95. return *this;
  96. }
  97. CArchive& CArchive::operator<<(uint64_t ui64)
  98. {
  99. int size = sizeof(uint64_t);
  100. if (m_BufferPos + size >= BUFFER_MAX)
  101. FlushBuffer();
  102. memcpy(&m_pBuffer[m_BufferPos], &ui64, size);
  103. m_BufferPos += size;
  104. return *this;
  105. }
  106. CArchive& CArchive::operator<<(bool b)
  107. {
  108. int size = sizeof(bool);
  109. if (m_BufferPos + size >= BUFFER_MAX)
  110. FlushBuffer();
  111. memcpy(&m_pBuffer[m_BufferPos], &b, size);
  112. m_BufferPos += size;
  113. return *this;
  114. }
  115. CArchive& CArchive::operator<<(char c)
  116. {
  117. int size = sizeof(char);
  118. if (m_BufferPos + size >= BUFFER_MAX)
  119. FlushBuffer();
  120. memcpy(&m_pBuffer[m_BufferPos], &c, size);
  121. m_BufferPos += size;
  122. return *this;
  123. }
  124. CArchive& CArchive::operator<<(const CStdString& str)
  125. {
  126. *this << str.GetLength();
  127. int size = str.GetLength();
  128. if (m_BufferPos + size >= BUFFER_MAX)
  129. FlushBuffer();
  130. int iBufferMaxParts=size/BUFFER_MAX;
  131. for (int i=0; i<iBufferMaxParts; i++)
  132. {
  133. memcpy(&m_pBuffer[m_BufferPos], str.c_str()+(i*BUFFER_MAX), BUFFER_MAX);
  134. m_BufferPos+=BUFFER_MAX;
  135. FlushBuffer();
  136. }
  137. int iPos=iBufferMaxParts*BUFFER_MAX;
  138. int iSizeLeft=size-iPos;
  139. memcpy(&m_pBuffer[m_BufferPos], str.c_str()+iPos, iSizeLeft);
  140. m_BufferPos+=iSizeLeft;
  141. return *this;
  142. }
  143. CArchive& CArchive::operator<<(const CStdStringW& str)
  144. {
  145. *this << str.GetLength();
  146. int size = str.GetLength();
  147. if (m_BufferPos + size >= BUFFER_MAX)
  148. FlushBuffer();
  149. int iBufferMaxParts=size/BUFFER_MAX;
  150. for (int i=0; i<iBufferMaxParts; ++i)
  151. {
  152. memcpy(&m_pBuffer[m_BufferPos], str.c_str()+(i*BUFFER_MAX), BUFFER_MAX);
  153. m_BufferPos+=BUFFER_MAX;
  154. FlushBuffer();
  155. }
  156. int iPos=iBufferMaxParts*BUFFER_MAX;
  157. int iSizeLeft=size-iPos;
  158. memcpy(&m_pBuffer[m_BufferPos], str.c_str()+iPos, iSizeLeft);
  159. m_BufferPos+=iSizeLeft;
  160. return *this;
  161. }
  162. CArchive& CArchive::operator<<(const SYSTEMTIME& time)
  163. {
  164. int size = sizeof(SYSTEMTIME);
  165. if (m_BufferPos + size >= BUFFER_MAX)
  166. FlushBuffer();
  167. memcpy(&m_pBuffer[m_BufferPos], &time, size);
  168. m_BufferPos += size;
  169. return *this;
  170. }
  171. CArchive& CArchive::operator<<(IArchivable& obj)
  172. {
  173. obj.Archive(*this);
  174. return *this;
  175. }
  176. CArchive& CArchive::operator<<(const CVariant& variant)
  177. {
  178. *this << (int)variant.type();
  179. switch (variant.type())
  180. {
  181. case CVariant::VariantTypeInteger:
  182. *this << variant.asInteger();
  183. break;
  184. case CVariant::VariantTypeUnsignedInteger:
  185. *this << variant.asUnsignedInteger();
  186. break;
  187. case CVariant::VariantTypeBoolean:
  188. *this << variant.asBoolean();
  189. break;
  190. case CVariant::VariantTypeString:
  191. *this << CStdString(variant.asString());
  192. break;
  193. case CVariant::VariantTypeDouble:
  194. *this << variant.asDouble();
  195. break;
  196. case CVariant::VariantTypeArray:
  197. *this << variant.size();
  198. for (unsigned int index = 0; index < variant.size(); index++)
  199. *this << variant[index];
  200. break;
  201. case CVariant::VariantTypeObject:
  202. *this << variant.size();
  203. for (CVariant::const_iterator_map itr = variant.begin_map(); itr != variant.end_map(); itr++)
  204. {
  205. *this << CStdString(itr->first);
  206. *this << itr->second;
  207. }
  208. break;
  209. case CVariant::VariantTypeNull:
  210. case CVariant::VariantTypeConstNull:
  211. default:
  212. break;
  213. }
  214. return *this;
  215. }
  216. CArchive& CArchive::operator<<(const std::vector<std::string>& strArray)
  217. {
  218. *this << (unsigned int)strArray.size();
  219. for (unsigned int index = 0; index < strArray.size(); index++)
  220. *this << CStdString(strArray.at(index));
  221. return *this;
  222. }
  223. CArchive& CArchive::operator<<(const std::vector<int>& iArray)
  224. {
  225. *this << (unsigned int)iArray.size();
  226. for (unsigned int index = 0; index < iArray.size(); index++)
  227. *this << iArray.at(index);
  228. return *this;
  229. }
  230. CArchive& CArchive::operator>>(float& f)
  231. {
  232. m_pFile->Read((void*)&f, sizeof(float));
  233. return *this;
  234. }
  235. CArchive& CArchive::operator>>(double& d)
  236. {
  237. m_pFile->Read((void*)&d, sizeof(double));
  238. return *this;
  239. }
  240. CArchive& CArchive::operator>>(int& i)
  241. {
  242. m_pFile->Read((void*)&i, sizeof(int));
  243. return *this;
  244. }
  245. CArchive& CArchive::operator>>(unsigned int& i)
  246. {
  247. m_pFile->Read((void*)&i, sizeof(unsigned int));
  248. return *this;
  249. }
  250. CArchive& CArchive::operator>>(int64_t& i64)
  251. {
  252. m_pFile->Read((void*)&i64, sizeof(int64_t));
  253. return *this;
  254. }
  255. CArchive& CArchive::operator>>(uint64_t& ui64)
  256. {
  257. m_pFile->Read((void*)&ui64, sizeof(uint64_t));
  258. return *this;
  259. }
  260. CArchive& CArchive::operator>>(bool& b)
  261. {
  262. m_pFile->Read((void*)&b, sizeof(bool));
  263. return *this;
  264. }
  265. CArchive& CArchive::operator>>(char& c)
  266. {
  267. m_pFile->Read((void*)&c, sizeof(char));
  268. return *this;
  269. }
  270. CArchive& CArchive::operator>>(CStdString& str)
  271. {
  272. int iLength = 0;
  273. *this >> iLength;
  274. m_pFile->Read((void*)str.GetBufferSetLength(iLength), iLength);
  275. str.ReleaseBuffer();
  276. return *this;
  277. }
  278. CArchive& CArchive::operator>>(CStdStringW& str)
  279. {
  280. int iLength = 0;
  281. *this >> iLength;
  282. m_pFile->Read((void*)str.GetBufferSetLength(iLength), iLength);
  283. str.ReleaseBuffer();
  284. return *this;
  285. }
  286. CArchive& CArchive::operator>>(SYSTEMTIME& time)
  287. {
  288. m_pFile->Read((void*)&time, sizeof(SYSTEMTIME));
  289. return *this;
  290. }
  291. CArchive& CArchive::operator>>(IArchivable& obj)
  292. {
  293. obj.Archive(*this);
  294. return *this;
  295. }
  296. CArchive& CArchive::operator>>(CVariant& variant)
  297. {
  298. int type;
  299. *this >> type;
  300. variant = CVariant((CVariant::VariantType)type);
  301. switch (variant.type())
  302. {
  303. case CVariant::VariantTypeInteger:
  304. {
  305. int64_t value;
  306. *this >> value;
  307. variant = value;
  308. break;
  309. }
  310. case CVariant::VariantTypeUnsignedInteger:
  311. {
  312. uint64_t value;
  313. *this >> value;
  314. variant = value;
  315. break;
  316. }
  317. case CVariant::VariantTypeBoolean:
  318. {
  319. bool value;
  320. *this >> value;
  321. variant = value;
  322. break;
  323. }
  324. case CVariant::VariantTypeString:
  325. {
  326. CStdString value;
  327. *this >> value;
  328. variant = value;
  329. break;
  330. }
  331. case CVariant::VariantTypeDouble:
  332. {
  333. double value;
  334. *this >> value;
  335. variant = value;
  336. break;
  337. }
  338. case CVariant::VariantTypeArray:
  339. {
  340. unsigned int size;
  341. *this >> size;
  342. for (; size > 0; size--)
  343. {
  344. CVariant value;
  345. *this >> value;
  346. variant.append(value);
  347. }
  348. break;
  349. }
  350. case CVariant::VariantTypeObject:
  351. {
  352. unsigned int size;
  353. *this >> size;
  354. for (; size > 0; size--)
  355. {
  356. CStdString name;
  357. CVariant value;
  358. *this >> name;
  359. *this >> value;
  360. variant[name] = value;
  361. }
  362. break;
  363. }
  364. case CVariant::VariantTypeNull:
  365. case CVariant::VariantTypeConstNull:
  366. default:
  367. break;
  368. }
  369. return *this;
  370. }
  371. CArchive& CArchive::operator>>(std::vector<std::string>& strArray)
  372. {
  373. int size;
  374. *this >> size;
  375. strArray.clear();
  376. for (int index = 0; index < size; index++)
  377. {
  378. CStdString str;
  379. *this >> str;
  380. strArray.push_back(str);
  381. }
  382. return *this;
  383. }
  384. CArchive& CArchive::operator>>(std::vector<int>& iArray)
  385. {
  386. int size;
  387. *this >> size;
  388. iArray.clear();
  389. for (int index = 0; index < size; index++)
  390. {
  391. int i;
  392. *this >> i;
  393. iArray.push_back(i);
  394. }
  395. return *this;
  396. }
  397. void CArchive::FlushBuffer()
  398. {
  399. if (m_BufferPos > 0)
  400. {
  401. m_pFile->Write(m_pBuffer, m_BufferPos);
  402. m_BufferPos = 0;
  403. }
  404. }