metaforce/hecl/include/hecl/FourCC.hpp

104 lines
3.8 KiB
C++
Raw Normal View History

2018-10-07 03:38:44 +00:00
#pragma once
2017-12-29 07:56:31 +00:00
#include <cstdint>
#include <cstddef>
#include <string>
#include <athena/DNA.hpp>
#include <logvisor/logvisor.hpp>
2017-12-29 07:56:31 +00:00
2018-12-08 05:18:42 +00:00
namespace hecl {
2017-12-29 07:56:31 +00:00
/**
* @brief FourCC representation used within HECL's database
*
* FourCCs are efficient, mnemonic four-char-sequences used to represent types
* while fitting comfortably in a 32-bit word. HECL uses a four-char array
* to remain endian-independent.
*/
2018-12-08 05:18:42 +00:00
class FourCC {
2017-12-29 07:56:31 +00:00
protected:
2018-12-08 05:18:42 +00:00
union {
char fcc[4];
uint32_t num = 0;
2018-12-08 05:18:42 +00:00
};
2017-12-29 07:56:31 +00:00
public:
// Sentinel FourCC
constexpr FourCC() noexcept = default;
constexpr FourCC(const FourCC& other) noexcept = default;
constexpr FourCC(FourCC&& other) noexcept = default;
constexpr FourCC(const char* name) noexcept : fcc{name[0], name[1], name[2], name[3]} {}
constexpr FourCC(uint32_t n) noexcept : num(n) {}
constexpr FourCC& operator=(const FourCC&) noexcept = default;
constexpr FourCC& operator=(FourCC&&) noexcept = default;
constexpr bool operator==(const FourCC& other) const noexcept { return num == other.num; }
constexpr bool operator!=(const FourCC& other) const noexcept { return !operator==(other); }
constexpr bool operator==(const char* other) const noexcept {
return other[0] == fcc[0] && other[1] == fcc[1] && other[2] == fcc[2] && other[3] == fcc[3];
}
constexpr bool operator!=(const char* other) const noexcept { return !operator==(other); }
constexpr bool operator==(int32_t other) const noexcept { return num == uint32_t(other); }
constexpr bool operator!=(int32_t other) const noexcept { return !operator==(other); }
constexpr bool operator==(uint32_t other) const noexcept { return num == other; }
constexpr bool operator!=(uint32_t other) const noexcept { return !operator==(other); }
std::string toString() const { return std::string(std::begin(fcc), std::end(fcc)); }
constexpr std::string_view toStringView() const { return std::string_view(fcc, std::size(fcc)); }
constexpr uint32_t toUint32() const noexcept { return num; }
constexpr const char* getChars() const noexcept { return fcc; }
constexpr char* getChars() noexcept { return fcc; }
constexpr bool IsValid() const noexcept { return num != 0; }
2017-12-29 07:56:31 +00:00
};
#define FOURCC(chars) FourCC(SBIG(chars))
using BigDNA = athena::io::DNA<athena::Endian::Big>;
2018-10-22 08:14:32 +00:00
/** FourCC with DNA read/write */
2018-12-08 05:18:42 +00:00
class DNAFourCC final : public BigDNA, public FourCC {
2018-10-22 08:14:32 +00:00
public:
constexpr DNAFourCC() noexcept : FourCC() {}
constexpr DNAFourCC(const FourCC& other) noexcept : FourCC(other) {}
constexpr DNAFourCC(const char* name) noexcept : FourCC(name) {}
constexpr DNAFourCC(uint32_t n) noexcept : FourCC(n) {}
DNAFourCC(athena::io::IStreamReader& r) { read(r); }
2018-12-08 05:18:42 +00:00
AT_DECL_EXPLICIT_DNA_YAML
2018-10-22 08:14:32 +00:00
};
2018-12-08 05:18:42 +00:00
template <>
inline void DNAFourCC::Enumerate<BigDNA::Read>(Read::StreamT& r) {
r.readUBytesToBuf(fcc, std::size(fcc));
2017-12-29 07:56:31 +00:00
}
2018-12-08 05:18:42 +00:00
template <>
inline void DNAFourCC::Enumerate<BigDNA::Write>(Write::StreamT& w) {
w.writeBytes(fcc, std::size(fcc));
2018-12-08 05:18:42 +00:00
}
template <>
inline void DNAFourCC::Enumerate<BigDNA::ReadYaml>(ReadYaml::StreamT& r) {
2019-10-01 07:23:35 +00:00
const std::string rs = r.readString();
rs.copy(fcc, std::size(fcc));
2018-12-08 05:18:42 +00:00
}
template <>
inline void DNAFourCC::Enumerate<BigDNA::WriteYaml>(WriteYaml::StreamT& w) {
2019-10-01 07:23:35 +00:00
w.writeString(std::string_view{fcc, std::size(fcc)});
2018-12-08 05:18:42 +00:00
}
template <>
inline void DNAFourCC::Enumerate<BigDNA::BinarySize>(BinarySize::StreamT& s) {
s += std::size(fcc);
2017-12-29 07:56:31 +00:00
}
2018-12-08 05:18:42 +00:00
} // namespace hecl
namespace std {
template <>
struct hash<hecl::FourCC> {
size_t operator()(const hecl::FourCC& val) const noexcept { return val.toUint32(); }
};
} // namespace std
2019-07-20 04:22:58 +00:00
FMT_CUSTOM_FORMATTER(hecl::FourCC, "{:c}{:c}{:c}{:c}", obj.getChars()[0], obj.getChars()[1], obj.getChars()[2],
obj.getChars()[3])
FMT_CUSTOM_FORMATTER(hecl::DNAFourCC, "{:c}{:c}{:c}{:c}", obj.getChars()[0], obj.getChars()[1], obj.getChars()[2],
obj.getChars()[3])