diff --git a/include/blt/math/math.h b/include/blt/math/math.h index e544ea4..7c2ff50 100755 --- a/include/blt/math/math.h +++ b/include/blt/math/math.h @@ -19,7 +19,9 @@ namespace blt { seed = (seed << 13) ^ seed; return ((seed * (seed * seed * 15731 + 789221) + 1376312589) & 0x7fffffff); } - + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-aliasing" /** * fast inverse sqrt */ @@ -35,6 +37,8 @@ namespace blt { y = y * (1.5f - (x * y * y)); return y; } + +#pragma GCC diagnostic pop static inline constexpr double pow(int b, int p) { diff --git a/include/blt/nbt/nbt.h b/include/blt/nbt/nbt.h index e41a4cd..d609280 100755 --- a/include/blt/nbt/nbt.h +++ b/include/blt/nbt/nbt.h @@ -17,6 +17,15 @@ namespace blt::nbt { std::string readUTF8String(std::fstream& stream); + // Used to grab the byte-data of any T element. Defaults to Big Endian, however can be configured to use little endian + template + int toBytes(const T& in, char* out); + + // Used to cast the binary data of any T object, into a T object. + template + int fromBytes(const char* in, T* out); + + enum class nbt_tag : char { END = 0, BYTE = 1, @@ -33,8 +42,48 @@ namespace blt::nbt { LONG_ARRAY = 12 }; - void writeName(std::fstream& out, const std::string& name); - std::string readName(std::fstream& in); + class tag_t { + protected: + nbt_tag type; + std::string name; + public: + explicit tag_t(nbt_tag type): type(type) {}; + explicit tag_t(nbt_tag type, std::string name): type(type), name(std::move(name)) {} + virtual void writePayload(std::fstream& out) = 0; + virtual void readPayload(std::fstream& in) = 0; + void writeName(std::fstream& out); + void readName(std::fstream& in); + }; + + template + class tag : public tag_t { + protected: + T t; + public: + explicit tag(nbt_tag type): tag_t(type) {}; + explicit tag(nbt_tag type, std::string name): tag_t(type, std::move(name)) {} + [[nodiscard]] inline const T& get() const {return t;} + inline T& get() {return t;} + }; + + class tag_end : public tag { + public: + void writePayload(std::fstream& out) final; + // nothing to read + void readPayload(std::fstream&) final {} + }; + + class tag_byte : public tag { + public: + void writePayload(std::fstream& out) final; + void readPayload(std::fstream& in) final; + }; + + class tag_short : public tag { + public: + void writePayload(std::fstream& out) final; + void readPayload(std::fstream& in) final; + }; class NBTDecoder { private: diff --git a/include/blt/std/logging.h b/include/blt/std/logging.h index 995c8a4..c835b46 100755 --- a/include/blt/std/logging.h +++ b/include/blt/std/logging.h @@ -522,6 +522,11 @@ namespace blt::logging { applyCFormatting(withoutLn, out, args); + if (level == log_level::NONE){ + std::cout << out << std::endl; + return; + } + std::string finalFormattedOutput = applyFormatString(out, level, file, line); if (loggingFormat.logToConsole) diff --git a/src/blt/nbt/nbt.cpp b/src/blt/nbt/nbt.cpp index 0a38e03..6ef144d 100755 --- a/src/blt/nbt/nbt.cpp +++ b/src/blt/nbt/nbt.cpp @@ -4,6 +4,9 @@ * See LICENSE file for license detail */ #include +#include +#include +#include namespace blt::nbt { void writeUTF8String(std::fstream& stream, const std::string& str) { @@ -28,15 +31,60 @@ namespace blt::nbt { return strOut; } - void writeName(std::fstream& out, const std::string& name) { + template + int toBytes(const T& in, char* const out) { + std::memcpy(out, (void*) &in, sizeof(T)); + + if constexpr (std::endian::native == std::endian::little) { + for (size_t i = 0; i < sizeof(T) / 2; i++) + std::swap(out[i], out[sizeof(T) - 1 - i]); + } + + return 0; + } + + template + int fromBytes(const char* const in, T* const out) { + memcpy(out, in, sizeof(T)); + + if constexpr (std::endian::native == std::endian::little) { + for (size_t i = 0; i < sizeof(T) / 2; i++) + std::swap(((char*) (out))[i], ((char*) (out))[sizeof(T) - 1 - i]); + } + + return 0; + } + + void tag_t::writeName(std::fstream& out) { writeUTF8String(out, name); } - std::string readName(std::fstream& in) { - return readUTF8String(in); + void tag_t::readName(std::fstream& in) { + name = readUTF8String(in); } - void writePayload(std::fstream& out) { + void tag_end::writePayload(std::fstream& out) { out.put('\0'); } + + void tag_byte::writePayload(std::fstream& out) { + // single byte no need for conversion + out.put(t); + } + + void tag_byte::readPayload(std::fstream& in) { + in.read(&t, 1); + } + + void tag_short::writePayload(std::fstream& out) { + char data[sizeof(t)]; + toBytes(t, data); + out.write(data, sizeof(t)); + } + + void tag_short::readPayload(std::fstream& in) { + char data[sizeof(t)]; + in.read(data, sizeof(t)); + fromBytes(data, &t); + } } \ No newline at end of file