1 /* 2 * Copyright (C) 2005-2018 Team Kodi 3 * This file is part of Kodi - https://kodi.tv 4 * 5 * SPDX-License-Identifier: GPL-2.0-or-later 6 * See LICENSES/README.md for more information. 7 */ 8 9 #pragma once 10 11 #include "XBDateTime.h" 12 13 #include <memory> 14 #include <string> 15 #include <vector> 16 17 #define CARCHIVE_BUFFER_MAX 4096 18 19 namespace XFILE 20 { 21 class CFile; 22 } 23 class CVariant; 24 class IArchivable; 25 26 class CArchive 27 { 28 public: 29 CArchive(XFILE::CFile* pFile, int mode); 30 ~CArchive(); 31 32 /* CArchive support storing and loading of all C basic integer types 33 * C basic types was chosen instead of fixed size ints (int16_t - int64_t) to support all integer typedefs 34 * For example size_t can be typedef of unsigned int, long or long long depending on platform 35 * while int32_t and int64_t are usually unsigned short, int or long long, but not long 36 * and even if int and long can have same binary representation they are different types for compiler 37 * According to section 5.2.4.2.1 of C99 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf 38 * minimal size of short int is 16 bits 39 * minimal size of int is 16 bits (usually 32 or 64 bits, larger or equal to short int) 40 * minimal size of long int is 32 bits (larger or equal to int) 41 * minimal size of long long int is 64 bits (larger or equal to long int) */ 42 // storing 43 CArchive& operator<<(float f); 44 CArchive& operator<<(double d); 45 CArchive& operator<<(short int s); 46 CArchive& operator<<(unsigned short int us); 47 CArchive& operator<<(int i); 48 CArchive& operator<<(unsigned int ui); 49 CArchive& operator<<(long int l); 50 CArchive& operator<<(unsigned long int ul); 51 CArchive& operator<<(long long int ll); 52 CArchive& operator<<(unsigned long long int ull); 53 CArchive& operator<<(bool b); 54 CArchive& operator<<(char c); 55 CArchive& operator<<(const std::string &str); 56 CArchive& operator<<(const std::wstring& wstr); 57 CArchive& operator<<(const KODI::TIME::SystemTime& time); 58 CArchive& operator<<(IArchivable& obj); 59 CArchive& operator<<(const CVariant& variant); 60 CArchive& operator<<(const std::vector<std::string>& strArray); 61 CArchive& operator<<(const std::vector<int>& iArray); 62 63 // loading 64 inline CArchive& operator>>(float& f) 65 { 66 return streamin(&f, sizeof(f)); 67 } 68 69 inline CArchive& operator>>(double& d) 70 { 71 return streamin(&d, sizeof(d)); 72 } 73 74 inline CArchive& operator>>(short int& s) 75 { 76 return streamin(&s, sizeof(s)); 77 } 78 79 inline CArchive& operator>>(unsigned short int& us) 80 { 81 return streamin(&us, sizeof(us)); 82 } 83 84 inline CArchive& operator>>(int& i) 85 { 86 return streamin(&i, sizeof(i)); 87 } 88 89 inline CArchive& operator>>(unsigned int& ui) 90 { 91 return streamin(&ui, sizeof(ui)); 92 } 93 94 inline CArchive& operator>>(long int& l) 95 { 96 return streamin(&l, sizeof(l)); 97 } 98 99 inline CArchive& operator>>(unsigned long int& ul) 100 { 101 return streamin(&ul, sizeof(ul)); 102 } 103 104 inline CArchive& operator>>(long long int& ll) 105 { 106 return streamin(&ll, sizeof(ll)); 107 } 108 109 inline CArchive& operator>>(unsigned long long int& ull) 110 { 111 return streamin(&ull, sizeof(ull)); 112 } 113 114 inline CArchive& operator>>(bool& b) 115 { 116 return streamin(&b, sizeof(b)); 117 } 118 119 inline CArchive& operator>>(char& c) 120 { 121 return streamin(&c, sizeof(c)); 122 } 123 124 CArchive& operator>>(std::string &str); 125 CArchive& operator>>(std::wstring& wstr); 126 CArchive& operator>>(KODI::TIME::SystemTime& time); 127 CArchive& operator>>(IArchivable& obj); 128 CArchive& operator>>(CVariant& variant); 129 CArchive& operator>>(std::vector<std::string>& strArray); 130 CArchive& operator>>(std::vector<int>& iArray); 131 132 bool IsLoading() const; 133 bool IsStoring() const; 134 135 void Close(); 136 137 enum Mode {load = 0, store}; 138 139 protected: streamout(const void * dataPtr,size_t size)140 inline CArchive &streamout(const void *dataPtr, size_t size) 141 { 142 auto ptr = static_cast<const uint8_t *>(dataPtr); 143 /* Note, the buffer is flushed as soon as it is full (m_BufferRemain == size) rather 144 * than waiting until we attempt to put more data into an already full buffer */ 145 if (m_BufferRemain > size) 146 { 147 memcpy(m_BufferPos, ptr, size); 148 m_BufferPos += size; 149 m_BufferRemain -= size; 150 return *this; 151 } 152 153 return streamout_bufferwrap(ptr, size); 154 } 155 streamin(void * dataPtr,size_t size)156 inline CArchive &streamin(void *dataPtr, size_t size) 157 { 158 auto ptr = static_cast<uint8_t *>(dataPtr); 159 /* Note, refilling the buffer is deferred until we know we need to read more from it */ 160 if (m_BufferRemain >= size) 161 { 162 memcpy(ptr, m_BufferPos, size); 163 m_BufferPos += size; 164 m_BufferRemain -= size; 165 return *this; 166 } 167 168 return streamin_bufferwrap(ptr, size); 169 } 170 171 XFILE::CFile* m_pFile; //non-owning 172 int m_iMode; 173 std::unique_ptr<uint8_t[]> m_pBuffer; 174 uint8_t *m_BufferPos; 175 size_t m_BufferRemain; 176 177 private: 178 void FlushBuffer(); 179 CArchive &streamout_bufferwrap(const uint8_t *ptr, size_t size); 180 void FillBuffer(); 181 CArchive &streamin_bufferwrap(uint8_t *ptr, size_t size); 182 }; 183