safeSave.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. ///////////////////////////////////////////
  2. //do not remove this notice
  3. //(c) Luta Vlad
  4. //
  5. // safeSave 1.0.4
  6. //
  7. ///////////////////////////////////////////
  8. #pragma once
  9. #include <fstream>
  10. #include <vector>
  11. #include <unordered_map>
  12. #include <initializer_list>
  13. #ifdef _MSC_VER
  14. #pragma warning( disable : 26812 )
  15. #endif
  16. namespace sfs
  17. {
  18. enum Errors: int
  19. {
  20. noError = 0,
  21. couldNotOpenFinle,
  22. fileSizeDitNotMatch,
  23. checkSumFailed,
  24. couldNotMakeBackup,
  25. readBackup,
  26. warningEntryAlreadyExists,
  27. entryNotFound,
  28. entryHasDifferentDataType,
  29. couldNotParseData,
  30. fileSizeNotBigEnough,
  31. };
  32. const char *getErrorString(Errors e);
  33. //can return error: couldNotOpenFinle
  34. Errors readEntireFile(std::vector<char> &data, const char *name);
  35. //reades the content of a file (size bytes), if shouldMatchSize is false will read the entire fill untill size bytes are read or the entire file was read
  36. //can return error: couldNotOpenFinle, fileSizeDitNotMatch
  37. Errors readEntireFile(void *data, size_t size, const char *name, bool shouldMatchSize,
  38. int *bytesRead = nullptr);
  39. //gets the file size
  40. //can return error: couldNotOpenFinle
  41. Errors getFileSize(const char *name, size_t &size);
  42. //reades the entire content of the data to a file and uses checkSum
  43. //can return error: couldNotOpenFinle, fileSizeDitNotMatch, checkSumFailed
  44. Errors readEntireFileWithCheckSum(void *data, size_t size, const char *name);
  45. //reades the entire content of the data to a file and uses checkSum
  46. //can return error: couldNotOpenFinle, fileSizeNotBigEnough
  47. Errors readEntireFileWithCheckSum(std::vector<char> &data, const char *name);
  48. //writes the entire content of the data to a file and uses checkSum
  49. //can return error: couldNotOpenFinle
  50. Errors writeEntireFileWithCheckSum(const void *data, size_t size, const char *name);
  51. //writes the entire content of the data to a file
  52. //can return error: couldNotOpenFinle
  53. Errors writeEntireFile(const std::vector<char> &data, const char *name);
  54. //writes the entire content of the data to a file
  55. //can return error: couldNotOpenFinle
  56. Errors writeEntireFile(const void *data, size_t size, const char *name);
  57. //saved the data with a check sum and a backup
  58. // It will also use a temporary file to make sure the saving is safe.
  59. //can return error: couldNotOpenFinle,
  60. // couldNotMakeBackup (if reportnotMakingBackupAsAnError is true, but will still save the first file)
  61. Errors safeSave(const void *data, size_t size, const char *nameWithoutExtension, bool reportnotMakingBackupAsAnError);
  62. //saved the data with a check sum. It will use a temporary file to make sure the saving is safe.
  63. //can return error: couldNotOpenFinle
  64. Errors safeSaveNoBackup(const void *data, size_t size, const char *nameWithoutExtension);
  65. //loads the data that was saved using safeSave
  66. //can return error: couldNotOpenFinle, fileSizeDitNotMatch, checkSumFailed,
  67. // readBackup (if reportLoadingBackupAsAnError but data will still be loaded with the backup)'
  68. // is checkSumFailed is returned, the data was still read!
  69. Errors safeLoad(void *data, size_t size, const char *nameWithoutExtension, bool reportLoadingBackupAsAnError);
  70. //loads the data that was saved using safeSave and stored as a SafeSafeKeyValueData structure
  71. //can return error: couldNotOpenFinle, checkSumFailed, fileSizeNotBigEnough
  72. // readBackup (if reportLoadingBackupAsAnError but data will still be loaded with the backup)
  73. Errors safeLoad(std::vector<char> &data, const char *nameWithoutExtension,
  74. bool reportLoadingBackupAsAnError);
  75. //same as safeLoad but only loads the backup file.
  76. //can return error: couldNotOpenFinle, fileSizeDitNotMatch, checkSumFailed
  77. Errors safeLoadBackup(void *data, size_t size, const char *nameWithoutExtension);
  78. //used to save data and read it
  79. struct SafeSafeKeyValueData
  80. {
  81. struct Entry
  82. {
  83. enum Types
  84. {
  85. no_type = 0,
  86. rawData_type,
  87. int_type,
  88. float_type,
  89. bool_type,
  90. string_type,
  91. uint64_type,
  92. int64_type,
  93. keyValueData_type,
  94. char_type,
  95. uchar_type,
  96. uint_type,
  97. double_type,
  98. vec2_type,
  99. vec3_type,
  100. vec4_type,
  101. ivec2_type,
  102. ivec3_type,
  103. ivec4_type,
  104. };
  105. std::vector<char> data;
  106. char type = 0;
  107. union Primitives
  108. {
  109. std::uint64_t uint64Data = 0;
  110. std::int64_t int64Data;
  111. std::int32_t intData;
  112. float floatData;
  113. bool boolData;
  114. char charData;
  115. unsigned char uCharData;
  116. unsigned int uintData;
  117. double doubleData;
  118. struct Vec
  119. {
  120. float x;
  121. float y;
  122. float z;
  123. float w;
  124. }vec;
  125. struct IVec
  126. {
  127. int x;
  128. int y;
  129. int z;
  130. int w;
  131. }ivec;
  132. }primitives;
  133. bool operator== (const Entry &other) const;
  134. bool operator!= (const Entry &other) const
  135. {
  136. return !(*this == other);
  137. }
  138. // Implicit constructors for primitive types
  139. Entry() = default;
  140. Entry(int v) { type = int_type; primitives.intData = v; }
  141. Entry(float v) { type = float_type; primitives.floatData = v; }
  142. Entry(bool v) { type = bool_type; primitives.boolData = v; }
  143. Entry(std::int64_t v) { type = int64_type; primitives.int64Data = v; }
  144. Entry(std::uint64_t v) { type = uint64_type; primitives.uint64Data = v; }
  145. Entry(const std::string &v)
  146. {
  147. type = string_type;
  148. data.assign(v.begin(), v.end());
  149. }
  150. Entry(const char *v): Entry(std::string(v)) {}
  151. Entry(char c) { type = char_type; primitives.charData = c; }
  152. Entry(unsigned char c) { type = uchar_type; primitives.uCharData = c; }
  153. Entry(unsigned int i) { type = uint_type; primitives.uintData = i; }
  154. Entry(double d) { type = double_type; primitives.doubleData = d; }
  155. Entry(float x, float y) { type = vec2_type; primitives.vec = {}; primitives.vec.x = x; primitives.vec.y = y; }
  156. Entry(float x, float y, float z) { type = vec3_type; primitives.vec = {}; primitives.vec.x = x; primitives.vec.y = y; primitives.vec.y = z; }
  157. Entry(float x, float y, float z, float w) { type = vec4_type; primitives.vec = {}; primitives.vec.x = x; primitives.vec.y = y; primitives.vec.y = z; primitives.vec.w = w; }
  158. Entry(int x, int y) { type = ivec2_type; primitives.ivec = {}; primitives.ivec.x = x; primitives.ivec.y = y; }
  159. Entry(int x, int y, int z) { type = ivec3_type; primitives.ivec = {}; primitives.ivec.x = x; primitives.ivec.y = y; primitives.ivec.y = z; }
  160. Entry(int x, int y, int z, int w) { type = ivec4_type; primitives.ivec = {}; primitives.ivec.x = x; primitives.ivec.y = y; primitives.ivec.y = z; primitives.ivec.w = w; }
  161. };
  162. SafeSafeKeyValueData() = default;
  163. SafeSafeKeyValueData(std::initializer_list<std::pair<std::string, Entry>> init)
  164. {
  165. for (const auto &pair : init)
  166. {
  167. entries[pair.first] = pair.second;
  168. }
  169. }
  170. std::unordered_map<std::string, Entry> entries;
  171. bool operator== (const SafeSafeKeyValueData &other) const;
  172. bool operator!= (const SafeSafeKeyValueData &other) const
  173. {
  174. return !(*this == other);
  175. }
  176. //returns true if entry exists
  177. bool entryExists(std::string at);
  178. //can return error: entryNotFound
  179. Errors getEntryType(std::string at, char &type);
  180. //can return error: warningEntryAlreadyExists, if so it will overwrite data
  181. Errors setRawData(std::string at, void *data, size_t size);
  182. //this can be usefull to hold nested key value data objects in one another!
  183. //can return error: warningEntryAlreadyExists, if so it will overwrite data
  184. Errors setKeyValueData(std::string at, const SafeSafeKeyValueData &data);
  185. //won't change data if failed
  186. //can return error: entryNotFound, entryHasDifferentDataType, couldNotParseData
  187. Errors getKeyValueData(std::string at, SafeSafeKeyValueData &data);
  188. //can return error: entryNotFound, entryHasDifferentDataType
  189. Errors getRawDataPointer(std::string at, void *&data, size_t &size);
  190. //won't change i if failed
  191. //can return error: entryNotFound, entryHasDifferentDataType
  192. Errors getInt(std::string at, int32_t &i);
  193. //can return error: warningEntryAlreadyExists, if so it will overwrite data
  194. Errors setInt(std::string at, int32_t i);
  195. //can return error: warningEntryAlreadyExists, if so it will overwrite data
  196. Errors setChar(std::string at, char c);
  197. //can return error: warningEntryAlreadyExists, if so it will overwrite data
  198. Errors setUCHar(std::string at, unsigned char c);
  199. //can return error: warningEntryAlreadyExists, if so it will overwrite data
  200. Errors setUInt(std::string at, uint32_t u);
  201. //can return error: warningEntryAlreadyExists, if so it will overwrite data
  202. Errors setDouble(std::string at, double d);
  203. //can return error: warningEntryAlreadyExists, if so it will overwrite data
  204. Errors setVec2(std::string at, float x, float y);
  205. //can return error: warningEntryAlreadyExists, if so it will overwrite data
  206. Errors setVec3(std::string at, float x, float y, float z);
  207. //can return error: warningEntryAlreadyExists, if so it will overwrite data
  208. Errors setVec4(std::string at, float x, float y, float z, float w);
  209. //can return error: warningEntryAlreadyExists, if so it will overwrite data
  210. Errors setIVec2(std::string at, int x, int y);
  211. //can return error: warningEntryAlreadyExists, if so it will overwrite data
  212. Errors setIVec3(std::string at, int x, int y, int z);
  213. //can return error: warningEntryAlreadyExists, if so it will overwrite data
  214. Errors setIVec4(std::string at, int x, int y, int z, int w);
  215. //won't change the variable if failed
  216. //can return error: entryNotFound, entryHasDifferentDataType
  217. Errors getVec2(std::string at, float &x, float &y);
  218. //won't change the variable if failed
  219. //can return error: entryNotFound, entryHasDifferentDataType
  220. Errors getVec3(std::string at, float &x, float &y, float &z);
  221. //won't change the variable if failed
  222. //can return error: entryNotFound, entryHasDifferentDataType
  223. Errors getVec4(std::string at, float &x, float &y, float &z, float &w);
  224. //won't change the variable if failed
  225. //can return error: entryNotFound, entryHasDifferentDataType
  226. Errors getIVec2(std::string at, int &x, int &y);
  227. //won't change the variable if failed
  228. //can return error: entryNotFound, entryHasDifferentDataType
  229. Errors getIVec3(std::string at, int &x, int &y, int &z);
  230. //won't change the variable if failed
  231. //can return error: entryNotFound, entryHasDifferentDataType
  232. Errors getIVec4(std::string at, int &x, int &y, int &z, int &w);
  233. //can return error: warningEntryAlreadyExists, if so it will overwrite data
  234. Errors setuInt64(std::string at, uint64_t i);
  235. //won't change i if failed
  236. //can return error: entryNotFound, entryHasDifferentDataType
  237. Errors getuInt64(std::string at, uint64_t &i);
  238. //can return error: warningEntryAlreadyExists, if so it will overwrite data
  239. Errors setInt64(std::string at, int64_t i);
  240. //won't change i if failed
  241. //can return error: entryNotFound, entryHasDifferentDataType
  242. Errors getInt64(std::string at, int64_t &i);
  243. //won't change f if failed
  244. //can return error: entryNotFound, entryHasDifferentDataType
  245. Errors getFloat(std::string at, float &f);
  246. //won't change c if failed
  247. //can return error: entryNotFound, entryHasDifferentDataType
  248. Errors getChar(std::string at, char &c);
  249. //won't change c if failed
  250. //can return error: entryNotFound, entryHasDifferentDataType
  251. Errors getUChar(std::string at, unsigned char &c);
  252. //won't change u if failed
  253. //can return error: entryNotFound, entryHasDifferentDataType
  254. Errors getUInt(std::string at, unsigned int &u);
  255. //won't change d if failed
  256. //can return error: entryNotFound, entryHasDifferentDataType
  257. Errors getDobule(std::string at, double &d);
  258. //can return error: warningEntryAlreadyExists, if so it will overwrite data
  259. Errors setFloat(std::string at, float f);
  260. //won't change b if failed
  261. //can return error: entryNotFound, entryHasDifferentDataType
  262. Errors getBool(std::string at, bool &b);
  263. //can return error: warningEntryAlreadyExists, if so it will overwrite data
  264. Errors setBool(std::string at, bool b);
  265. //can return error: warningEntryAlreadyExists, if so it will overwrite data
  266. Errors setString(std::string at, std::string value);
  267. //won't change s if failed
  268. //can return error: entryNotFound, entryHasDifferentDataType
  269. Errors getString(std::string at, std::string &s);
  270. std::vector<char> formatIntoFileDataBinary() const;
  271. //not finished yet
  272. //std::vector<char> formatIntoFileDataTextBased();
  273. //can return error: couldNotParseData
  274. Errors loadFromFileData(char *data, size_t size);
  275. };
  276. //saved the data stored as a SafeSafeKeyValueData structure in a binary format with a check sum and a backup
  277. //Uses a temporary file to make sure the saving is safe
  278. //can return error: couldNotOpenFinle,
  279. // couldNotMakeBackup (if reportnotMakingBackupAsAnError is true, but will still save the first file)
  280. Errors safeSave(SafeSafeKeyValueData &data, const char *nameWithoutExtension, bool reportnotMakingBackupAsAnError);
  281. //saved the data stored as a SafeSafeKeyValueData structure in a binary format with a check.
  282. //Uses a temporary file to make sure the saving is safe
  283. //can return error: couldNotOpenFinle,
  284. Errors safeSaveNoBackup(SafeSafeKeyValueData &data, const char *nameWithoutExtension);
  285. //loads the data that was saved using safeSave and stored as a SafeSafeKeyValueData structure
  286. //can return error: couldNotOpenFinle, fileSizeNotBigEnough, checkSumFailed, couldNotParseData
  287. // readBackup (if reportLoadingBackupAsAnError but data will still be loaded from the backup)
  288. Errors safeLoad(SafeSafeKeyValueData &data, const char *nameWithoutExtension, bool reportLoadingBackupAsAnError);
  289. #if defined WIN32 || defined _WIN32 || defined __WIN32__ || defined __NT__
  290. struct FileMapping
  291. {
  292. void *pointer = {};
  293. size_t size = 0;
  294. struct
  295. {
  296. void *fileHandle = 0;
  297. void *fileMapping = 0;
  298. }internal = {};
  299. };
  300. #elif defined __linux__
  301. struct FileMapping
  302. {
  303. void *pointer = {};
  304. size_t size = 0;
  305. struct
  306. {
  307. int fd = 0;
  308. }internal = {};
  309. };
  310. #endif
  311. //a file mapping maps the content of a file to ram
  312. //can return error: couldNotOpenFinle
  313. Errors openFileMapping(FileMapping &fileMapping, const char *name, size_t size, bool createIfNotExisting);
  314. void closeFileMapping(FileMapping &fileMapping);
  315. };