123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555 |
- #pragma once
- #include "openmpt/all/BuildSettings.hpp"
- #include "mpt/io/io.hpp"
- #include "mpt/io/io_stdstream.hpp"
- #include "openmpt/base/Endian.hpp"
- #include "../common/mptBaseTypes.h"
- #include <algorithm>
- #include <bitset>
- #include <ios>
- #include <iosfwd>
- #include <limits>
- #include <string>
- #include <vector>
- #include <istream>
- #include <ostream>
- #include <cstring>
- OPENMPT_NAMESPACE_BEGIN
- namespace srlztn
- {
- typedef std::ios::off_type Offtype;
- typedef Offtype Postype;
- typedef uintptr_t DataSize;
- typedef uintptr_t RposType;
- typedef uintptr_t NumType;
- const DataSize invalidDatasize = DataSize(-1);
- enum
- {
- SNT_PROGRESS = 0x08000000,
- SNT_FAILURE = 0x40000000,
- SNT_NOTE = 0x20000000,
- SNT_WARNING = 0x10000000,
- SNT_NONE = 0,
- SNRW_BADGIVEN_STREAM = 1 | SNT_FAILURE,
-
- SNR_BADSTREAM_AFTER_MAPHEADERSEEK = 2 | SNT_FAILURE,
- SNR_STARTBYTE_MISMATCH = 3 | SNT_FAILURE,
- SNR_BADSTREAM_AT_MAP_READ = 4 | SNT_FAILURE,
- SNR_INSUFFICIENT_STREAM_OFFTYPE = 5 | SNT_FAILURE,
- SNR_OBJECTCLASS_IDMISMATCH = 6 | SNT_FAILURE,
- SNR_TOO_MANY_ENTRIES_TO_READ = 7 | SNT_FAILURE,
- SNR_INSUFFICIENT_RPOSTYPE = 8 | SNT_FAILURE,
-
- SNR_ZEROENTRYCOUNT = 0x80 | SNT_NOTE,
- SNR_NO_ENTRYIDS_WITH_CUSTOMID_DEFINED = 0x100 | SNT_NOTE,
- SNR_LOADING_OBJECT_WITH_LARGER_VERSION = 0x200 | SNT_NOTE,
-
-
- SNW_INSUFFICIENT_FIXEDSIZE = (0x10) | SNT_FAILURE,
- SNW_CHANGING_IDSIZE_WITH_FIXED_IDSIZESETTING = (0x11) | SNT_FAILURE,
- SNW_DATASIZETYPE_OVERFLOW = (0x13) | SNT_FAILURE,
- SNW_MAX_WRITE_COUNT_REACHED = (0x14) | SNT_FAILURE,
- SNW_INSUFFICIENT_DATASIZETYPE = (0x16) | SNT_FAILURE
- };
- enum
- {
- IdSizeVariable = std::numeric_limits<uint16>::max(),
- IdSizeMaxFixedSize = (std::numeric_limits<uint8>::max() >> 1)
- };
- typedef int32 SsbStatus;
- struct ReadEntry
- {
- ReadEntry() : nIdpos(0), rposStart(0), nSize(invalidDatasize), nIdLength(0) {}
- uintptr_t nIdpos;
- RposType rposStart;
- DataSize nSize;
- uint16 nIdLength;
- };
- enum Rwf
- {
- RwfWMapStartPosEntry,
- RwfWMapSizeEntry,
- RwfWMapDescEntry,
- RwfWVersionNum,
- RwfRMapCached,
- RwfRMapHasId,
- RwfRMapHasStartpos,
- RwfRMapHasSize,
- RwfRMapHasDesc,
- RwfRTwoBytesDescChar,
- RwfRHeaderIsRead,
- RwfRwHasMap,
- RwfNumFlags
- };
- template<class T>
- inline void Binarywrite(std::ostream& oStrm, const T& data)
- {
- mpt::IO::WriteIntLE(oStrm, data);
- }
- template<>
- inline void Binarywrite(std::ostream& oStrm, const float& data)
- {
- IEEE754binary32LE tmp = IEEE754binary32LE(data);
- mpt::IO::Write(oStrm, tmp);
- }
- template<>
- inline void Binarywrite(std::ostream& oStrm, const double& data)
- {
- IEEE754binary64LE tmp = IEEE754binary64LE(data);
- mpt::IO::Write(oStrm, tmp);
- }
- template <class T>
- inline void WriteItem(std::ostream& oStrm, const T& data)
- {
- static_assert(std::is_trivial<T>::value == true, "");
- Binarywrite(oStrm, data);
- }
- void WriteItemString(std::ostream& oStrm, const std::string &str);
- template <>
- inline void WriteItem<std::string>(std::ostream& oStrm, const std::string& str) {WriteItemString(oStrm, str);}
- template<class T>
- inline void Binaryread(std::istream& iStrm, T& data)
- {
- mpt::IO::ReadIntLE(iStrm, data);
- }
- template<>
- inline void Binaryread(std::istream& iStrm, float& data)
- {
- IEEE754binary32LE tmp = IEEE754binary32LE(0.0f);
- mpt::IO::Read(iStrm, tmp);
- data = tmp;
- }
- template<>
- inline void Binaryread(std::istream& iStrm, double& data)
- {
- IEEE754binary64LE tmp = IEEE754binary64LE(0.0);
- mpt::IO::Read(iStrm, tmp);
- data = tmp;
- }
- template <class T>
- inline void Binaryread(std::istream& iStrm, T& data, const Offtype bytecount)
- {
- mpt::IO::ReadBinaryTruncatedLE(iStrm, data, static_cast<std::size_t>(bytecount));
- }
- template <>
- inline void Binaryread<float>(std::istream& iStrm, float& data, const Offtype bytecount)
- {
- typedef IEEE754binary32LE T;
- std::byte bytes[sizeof(T)];
- std::memset(bytes, 0, sizeof(T));
- mpt::IO::ReadRaw(iStrm, bytes, std::min(static_cast<std::size_t>(bytecount), sizeof(T)));
-
-
- data = 0.0f;
- }
- template <>
- inline void Binaryread<double>(std::istream& iStrm, double& data, const Offtype bytecount)
- {
- typedef IEEE754binary64LE T;
- std::byte bytes[sizeof(T)];
- std::memset(bytes, 0, sizeof(T));
- mpt::IO::ReadRaw(iStrm, bytes, std::min(static_cast<std::size_t>(bytecount), sizeof(T)));
-
-
- data = 0.0;
- }
- template <class T>
- inline void ReadItem(std::istream& iStrm, T& data, const DataSize nSize)
- {
- static_assert(std::is_trivial<T>::value == true, "");
- if (nSize == sizeof(T) || nSize == invalidDatasize)
- Binaryread(iStrm, data);
- else
- Binaryread(iStrm, data, nSize);
- }
- void ReadItemString(std::istream& iStrm, std::string& str, const DataSize);
- template <>
- inline void ReadItem<std::string>(std::istream& iStrm, std::string& str, const DataSize nSize)
- {
- ReadItemString(iStrm, str, nSize);
- }
- class ID
- {
- private:
- std::string m_ID;
- public:
- ID() { }
- ID(const std::string &id) : m_ID(id) { }
- ID(const char *beg, const char *end) : m_ID(beg, end) { }
- ID(const char *id) : m_ID(id?id:"") { }
- ID(const char * str, std::size_t len) : m_ID(str, str + len) { }
- template <typename T>
- static ID FromInt(const T &val)
- {
- static_assert(std::numeric_limits<T>::is_integer);
- typename mpt::make_le<T>::type valle;
- valle = val;
- return ID(std::string(mpt::byte_cast<const char*>(mpt::as_raw_memory(valle).data()), mpt::byte_cast<const char*>(mpt::as_raw_memory(valle).data() + sizeof(valle))));
- }
- bool IsPrintable() const;
- mpt::ustring AsString() const;
- const char *GetBytes() const { return m_ID.c_str(); }
- std::size_t GetSize() const { return m_ID.length(); }
- bool operator == (const ID &other) const { return m_ID == other.m_ID; }
- bool operator != (const ID &other) const { return m_ID != other.m_ID; }
- };
- class Ssb
- {
- protected:
- Ssb();
- public:
- SsbStatus GetStatus() const
- {
- return m_Status;
- }
- protected:
-
-
- NumType GetCounter() const {return m_nCounter;}
- void SetFlag(Rwf flag, bool val) {m_Flags.set(flag, val);}
- bool GetFlag(Rwf flag) const {return m_Flags[flag];}
- protected:
- SsbStatus m_Status;
- uint32 m_nFixedEntrySize;
- Postype m_posStart;
- uint16 m_nIdbytes;
- NumType m_nCounter;
- std::bitset<RwfNumFlags> m_Flags;
- protected:
- enum : uint8 { s_DefaultFlagbyte = 0 };
- static const char s_EntryID[3];
- };
- class SsbRead
- : public Ssb
- {
- public:
- enum ReadRv
- {
- EntryRead,
- EntryNotFound
- };
- enum IdMatchStatus
- {
- IdMatch, IdMismatch
- };
- typedef std::vector<ReadEntry>::const_iterator ReadIterator;
- SsbRead(std::istream& iStrm);
-
- void BeginRead(const ID &id, const uint64& nVersion);
-
- NumType GetNumEntries() const {return m_nReadEntrycount;}
-
-
-
- ReadIterator GetReadBegin();
-
- ReadIterator GetReadEnd();
-
- IdMatchStatus CompareId(const ReadIterator& iter, const ID &id);
- uint64 GetReadVersion() {return m_nReadVersion;}
-
- template <class T>
- ReadRv ReadItem(T& obj, const ID &id) {return ReadItem(obj, id, srlztn::ReadItem<T>);}
-
- template <class T, class FuncObj>
- ReadRv ReadItem(T& obj, const ID &id, FuncObj);
-
- template <class T>
- ReadRv ReadIterItem(const ReadIterator& iter, T& obj) {return ReadIterItem(iter, obj, srlztn::ReadItem<T>);}
- template <class T, class FuncObj>
- ReadRv ReadIterItem(const ReadIterator& iter, T& obj, FuncObj func);
- private:
-
- void CacheMap();
-
-
- const ReadEntry* Find(const ID &id);
-
- ReadRv OnReadEntry(const ReadEntry* pE, const ID &id, const Postype& posReadBegin);
- void AddReadNote(const SsbStatus s);
-
- void AddReadNote(const ReadEntry* const pRe, const NumType nNum);
- void ResetReadstatus();
- private:
-
-
-
-
-
-
-
- std::istream& iStrm;
- std::vector<char> m_Idarray;
- std::vector<ReadEntry> mapData;
- uint64 m_nReadVersion;
- RposType m_rposMapBegin;
- Postype m_posMapEnd;
- Postype m_posDataBegin;
- RposType m_rposEndofHdrData;
- NumType m_nReadEntrycount;
- NumType m_nNextReadHint;
- };
- class SsbWrite
- : public Ssb
- {
- public:
- SsbWrite(std::ostream& oStrm);
-
- void BeginWrite(const ID &id, const uint64& nVersion);
-
- template <class T>
- void WriteItem(const T& obj, const ID &id) {WriteItem(obj, id, &srlztn::WriteItem<T>);}
-
- template <class T, class FuncObj>
- void WriteItem(const T& obj, const ID &id, FuncObj);
-
- void FinishWrite();
- private:
-
- void OnWroteItem(const ID &id, const Postype& posBeforeWrite);
- void AddWriteNote(const SsbStatus s);
- void AddWriteNote(const ID &id,
- const NumType nEntryNum,
- const DataSize nBytecount,
- const RposType rposStart);
-
- void WriteMapItem(const ID &id,
- const RposType& rposDataStart,
- const DataSize& nDatasize,
- const char* pszDesc);
- void ResetWritestatus() {m_Status = SNT_NONE;}
- void IncrementWriteCounter();
- private:
- std::ostream& oStrm;
- Postype m_posEntrycount;
- Postype m_posMapPosField;
- std::string m_MapStreamString;
- };
- template <class T, class FuncObj>
- void SsbWrite::WriteItem(const T& obj, const ID &id, FuncObj Func)
- {
- const Postype pos = oStrm.tellp();
- Func(oStrm, obj);
- OnWroteItem(id, pos);
- }
- template <class T, class FuncObj>
- SsbRead::ReadRv SsbRead::ReadItem(T& obj, const ID &id, FuncObj Func)
- {
- const ReadEntry* pE = Find(id);
- const Postype pos = iStrm.tellg();
- if (pE != nullptr || GetFlag(RwfRMapHasId) == false)
- Func(iStrm, obj, (pE) ? (pE->nSize) : invalidDatasize);
- return OnReadEntry(pE, id, pos);
- }
- template <class T, class FuncObj>
- SsbRead::ReadRv SsbRead::ReadIterItem(const ReadIterator& iter, T& obj, FuncObj func)
- {
- iStrm.clear();
- if (iter->rposStart != 0)
- iStrm.seekg(m_posStart + Postype(iter->rposStart));
- const Postype pos = iStrm.tellg();
- func(iStrm, obj, iter->nSize);
- return OnReadEntry(&(*iter), ID(&m_Idarray[iter->nIdpos], iter->nIdLength), pos);
- }
- inline SsbRead::IdMatchStatus SsbRead::CompareId(const ReadIterator& iter, const ID &id)
- {
- if(iter->nIdpos >= m_Idarray.size()) return IdMismatch;
- return (id == ID(&m_Idarray[iter->nIdpos], iter->nIdLength)) ? IdMatch : IdMismatch;
- }
- inline SsbRead::ReadIterator SsbRead::GetReadBegin()
- {
- MPT_ASSERT(GetFlag(RwfRMapHasId) && (GetFlag(RwfRMapHasStartpos) || GetFlag(RwfRMapHasSize) || m_nFixedEntrySize > 0));
- if (GetFlag(RwfRMapCached) == false)
- CacheMap();
- return mapData.begin();
- }
- inline SsbRead::ReadIterator SsbRead::GetReadEnd()
- {
- if (GetFlag(RwfRMapCached) == false)
- CacheMap();
- return mapData.end();
- }
- template <class T>
- struct VectorWriter
- {
- VectorWriter(size_t nCount) : m_nCount(nCount) {}
- void operator()(std::ostream &oStrm, const std::vector<T> &vec)
- {
- for(size_t i = 0; i < m_nCount; i++)
- {
- Binarywrite(oStrm, vec[i]);
- }
- }
- size_t m_nCount;
- };
- template <class T>
- struct VectorReader
- {
- VectorReader(size_t nCount) : m_nCount(nCount) {}
- void operator()(std::istream& iStrm, std::vector<T> &vec, const size_t)
- {
- vec.resize(m_nCount);
- for(std::size_t i = 0; i < m_nCount; ++i)
- {
- Binaryread(iStrm, vec[i]);
- }
- }
- size_t m_nCount;
- };
- template <class T>
- struct ArrayReader
- {
- ArrayReader(size_t nCount) : m_nCount(nCount) {}
- void operator()(std::istream& iStrm, T* pData, const size_t)
- {
- for(std::size_t i=0; i<m_nCount; ++i)
- {
- Binaryread(iStrm, pData[i]);
- }
- }
- size_t m_nCount;
- };
- }
- OPENMPT_NAMESPACE_END
|