#pragma once #include "SimpleMath/SimpleMath.h" #include #include #include #include #include struct WriteSerializer { enum { IsReading = 0 }; enum { IsWriting = 1 }; std::ofstream stream; bool SerializeData (const std::string &key, const char *data, size_t size) { size_t key_length = key.size(); stream.write (reinterpret_cast(&key_length), sizeof (size_t)); stream << key; stream.write (reinterpret_cast(&size), sizeof(size_t)); stream.write (data, size); return true; } void Open(const char* filename) { stream.open(filename, std::ofstream::trunc); } void Close() { stream.close(); } }; struct ReadSerializer { enum { IsReading = 1 }; enum { IsWriting = 0 }; struct Block { size_t size; void *pdata; Block() : size(0), pdata(nullptr) {} Block(const Block& other) : size(other.size), pdata(other.pdata) {} Block& operator=(const Block& other) { if (this != &other) { size = other.size; pdata = other.pdata; } return *this; } }; bool SerializeData (const std::string &key, char *data, size_t size) { std::unordered_map::iterator iter; iter = blocks.find(key); if (iter == blocks.end()) { return false; } // std::cout << "found block for " << key << ", size: " << iter->second.size << std::endl; assert (size == iter->second.size); // std::cout << "copying from " << iter->second.pdata << " to " << (void*) data << std::endl; // std::cout << "copying from " << blocks[key].pdata << " to " << (void*) data << std::endl; assert (blocks[key].size == size); memcpy (data, blocks[key].pdata, size); return true; } void Open(const char* filename) { // early out if file does not (yet) exist struct stat fstat; if (stat(filename, &fstat) == -1) { return; } std::ifstream stream(filename, std::ios::binary); size_t key_size; size_t block_size; while (!stream.eof() && stream.peek() != std::ifstream::traits_type::eof()) { // read key size stream.read(reinterpret_cast(&key_size), sizeof(size_t)); // std::cout << "read key size " << key_size << std::endl; assert (key_size < 1000); // read key std::string key (key_size, 0); stream.read(&key[0], key_size); // create block blocks[key] = Block(); Block *block = &blocks[key]; // read block size stream.read(reinterpret_cast(&block->size), sizeof(size_t)); // std::cout << "read block " << key << ", size = " << block->size << std::endl; block->pdata = new char[block->size + 1]; // std::cout << "block addr = " << block->pdata << std::endl; stream.read(reinterpret_cast(block->pdata), block->size); } stream.close(); } void Close() { } std::unordered_map blocks; }; template bool SerializeBool (Serializer &serializer, const std::string &key, bool& value) { return serializer.SerializeData(key, reinterpret_cast(&value), sizeof(bool)); } template bool SerializeInt (Serializer &serializer, const std::string &key, int& value) { return serializer.SerializeData(key, reinterpret_cast(&value), sizeof(int)); } template bool SerializeFloat (Serializer &serializer, const std::string &key, float& value) { return serializer.SerializeData(key, reinterpret_cast(&value), sizeof(float)); } template bool SerializedUint16 (Serializer &serializer, const std::string &key, uint16_t& value) { return serializer.SerializeData(key, reinterpret_cast(&value), sizeof(uint16_t)); } template bool SerializeVec3 (Serializer &serializer, const std::string &key, SimpleMath::Vector3f& value) { return serializer.SerializeData(key, reinterpret_cast(&value), sizeof(SimpleMath::Vector3f)); }