#pragma once #include #include #include #include #include "CAngle.h" #include "U_Types.h" class IBinaryStream //TODO missing const { public: virtual void RawWrite(const void* data, size_t size) = 0; virtual void RawRead(void* data, size_t size) = 0; virtual bool is_eof(); virtual ~IBinaryStream() = default; void ReadData(void* data, size_t size); std::unique_ptr ReadData(size_t size); std::vector ReadDataVec(size_t size); void WriteData(const void* data, size_t size); void WriteData(std::unique_ptr data, size_t size); template void Write(const T& val) { if constexpr (std::is_same_v || std::is_same_v) { WriteString(val); } else if constexpr (std::is_same_v) { typename T::value_type degr = val.asRadians(); RawWrite(°r, sizeof(typename T::value_type)); } else if constexpr (is_glm_vec_v || is_glm_quat_v || std::is_same_v) { for(size_t i = 0; i < T::length(); i++) { Write(val[i]); } } else if constexpr (is_glm_mat_v) { for(size_t y = 0; y < T::col_type::length(); y++) { for(size_t x = 0; x < T::length(); x++) { typename T::value_type value = val[x][y]; RawWrite(&value, sizeof(float)); } } } else { RawWrite(&val, sizeof(T)); } } template T Read() { T ret{}; if constexpr (std::is_same_v || std::is_same_v) { ret = ReadString(); } else if constexpr (std::is_same_v) { typename T::value_type degr{}; RawRead(°r, sizeof(typename T::value_type)); ret = T::radians(degr); } else if constexpr (is_glm_vec_v || is_glm_quat_v || std::is_same_v) //TODO why not reading the raw data { for(size_t i = 0; i < T::length(); i++) { typename T::value_type item{}; RawRead(&item, sizeof(typename T::value_type)); ret[i] = item; } } else if constexpr (is_glm_mat_v) //TODO why not reading the raw data { for(size_t y = 0; y < T::col_type::length(); y++) { for(size_t x = 0; x < T::length(); x++) { typename T::value_type value{}; RawRead(&value, sizeof(float)); ret[x][y] = value; } } } else { RawRead(&ret, sizeof(T)); } return ret; } template String ReadString(size_t fixedSize = 0) { constexpr typename String::value_type charnull = 0; //std::is_same_v ? '\0' : L'\0'; typename String::value_type reat = 1; String ret; if(fixedSize) { ret.resize(fixedSize); ReadData(static_cast(ret.data()), fixedSize * sizeof(typename String::value_type)); } else { ret.reserve(260); for(;;) { reat = Read(); if (reat == charnull) { break; } else { ret += reat; } } } return ret; } template void WriteString(const String& str, bool null_terminated = true) { constexpr typename String::value_type charnull = 0; //std::is_same_v ? '\0' : L'\0'; WriteData(str.data(), str.size()); if (null_terminated) { Write(charnull); } } template void WriteLenString(const T& str, bool writelen = true, L forcelen = 0U) { constexpr typename T::value_type charnull = 0; //std::is_same_v ? '\0' : L'\0'; if (writelen) { Write((forcelen ? forcelen : L(str.size()))); } if (forcelen) { L lenToWrite = std::min(str.size(), forcelen); if (lenToWrite > 0) { WriteData(static_cast(const_cast(str.data())), lenToWrite * sizeof(typename T::value_type)); } if (forcelen > lenToWrite) { std::vector padding(forcelen - lenToWrite, charnull); WriteData(static_cast(padding.data()), padding.size() * sizeof(typename T::value_type)); } } else { WriteData(static_cast(const_cast(str.data())), str.size() * sizeof(typename T::value_type)); } } template T ReadLenString(bool readlen = true, L forcelen = 0U, bool removenulls = true) { constexpr typename T::value_type charnull = 0; //std::is_same_v ? '\0' : L'\0'; T ret; typename T::value_type reat; L len = forcelen; if (readlen) { len = Read(); } ret.resize(len); ReadData(static_cast(ret.data()), len * sizeof(typename T::value_type)); if (removenulls) { size_t pos = ret.find_last_not_of(charnull); if (pos != T::npos) { ret.resize(pos + 1); } else { ret.clear(); } } return ret; } template void Read(T& var) { var = Read(); } template void ReadString(String& var, size_t fixedSize = 0) { var = ReadString(fixedSize); } template void ReadLenString(T& var, bool readlen = true, L forcelen = 0U, bool removenulls = true) { var = ReadLenString(readlen, forcelen, removenulls); } };