diff --git a/demboyz/base/jsonfile.cpp b/demboyz/base/jsonfile.cpp new file mode 100644 index 0000000..a7a4b4b --- /dev/null +++ b/demboyz/base/jsonfile.cpp @@ -0,0 +1,154 @@ + +#include "jsonfile.h" +#include "b64/encode.h" +#include + +namespace base +{ + JsonWriterFile::JsonWriterFile(FILE* fp, char* buffer, std::size_t length): + m_fileStream(fp, buffer, length), + m_writer(m_fileStream), + m_fp(fp) + { + } + + FILE* JsonWriterFile::GetFp() const + { + return m_fp; + } + + void JsonWriterFile::Flush() + { + m_fileStream.Flush(); + } + + bool JsonWriterFile::IsComplete() const + { + return m_writer.IsComplete(); + } + + void JsonWriterFile::StartObject(const char* name /*= nullptr*/) + { + auto& writer = m_writer; + if (name) + { + writer.String(name); + } + writer.StartObject(); + } + + void JsonWriterFile::EndObject() + { + m_writer.EndObject(); + } + + void JsonWriterFile::StartArray(const char* name /*= nullptr*/) + { + auto& writer = m_writer; + if (name) + { + writer.String(name); + } + writer.StartArray(); + } + + void JsonWriterFile::EndArray() + { + m_writer.EndArray(); + } + + void JsonWriterFile::WriteBool(const char* name, bool value) + { + auto& writer = m_writer; + writer.String(name); + writer.Bool(value); + } + + void JsonWriterFile::WriteInt32(const char* name, std::int32_t value) + { + auto& writer = m_writer; + writer.String(name); + writer.Int(value); + } + + void JsonWriterFile::WriteInt64(const char* name, std::int64_t value) + { + auto& writer = m_writer; + writer.String(name); + writer.Int64(value); + } + + void JsonWriterFile::WriteUInt32(const char* name, std::uint32_t value) + { + auto& writer = m_writer; + writer.String(name); + writer.Uint(value); + } + + void JsonWriterFile::WriteUint64(const char* name, std::uint64_t value) + { + auto& writer = m_writer; + writer.String(name); + writer.Uint64(value); + } + + void JsonWriterFile::WriteString(const char* name, const char* value) + { + auto& writer = m_writer; + writer.String(name); + writer.String(value); + } + + void JsonWriterFile::WriteString(const char* name, const char* value, std::int32_t length) + { + auto& writer = m_writer; + writer.String(name); + writer.String(value, length); + } + + void JsonWriterFile::WriteFloat(const char* name, const double value) + { + auto& writer = m_writer; + writer.String(name); + writer.Double(value); + } + + void JsonWriterFile::WriteBits(const char* name, const unsigned char* data, std::size_t numBits) + { + auto& writer = m_writer; + writer.String(name); + + base64::base64_encodestate state; + base64::base64_init_encodestate(&state); + state.flags = base64::BASE64_ENC_NO_NEWLINE_TERM; + + const std::size_t numBytes = ((numBits + 7) >> 3); + const int encodedLenMax = base64::base64_calc_buffer_length(numBytes, &state); + + char* const encoded = (char*)calloc(encodedLenMax, 1); + char* encodedCurOut = encoded; + + const std::size_t numTrailingBits = (numBits & 7); + if (numTrailingBits > 0) + { + const std::size_t numBytesWithoutBits = (numBits >> 3); + encodedCurOut += base64::base64_encode_block((const char*)data, numBytesWithoutBits, encodedCurOut, &state); + const char lastByteClean = data[numBytesWithoutBits] & ~(0xFF >> numTrailingBits); + encodedCurOut += base64::base64_encode_block(&lastByteClean, 1, encodedCurOut, &state); + } + else + { + encodedCurOut += base64::base64_encode_block((const char*)data, numBytes, encodedCurOut, &state); + } + encodedCurOut += base64::base64_encode_blockend(encodedCurOut, &state); + + writer.String(encoded, encodedCurOut - encoded); + free(encoded); + return; + } + + void JsonWriterFile::WriteBytes(const char* name, const unsigned char* data, std::size_t numBytes) + { + JsonWriterFile::WriteBits(name, data, numBytes * 8); + } +} diff --git a/demboyz/base/jsonfile.h b/demboyz/base/jsonfile.h new file mode 100644 index 0000000..5164bd9 --- /dev/null +++ b/demboyz/base/jsonfile.h @@ -0,0 +1,45 @@ + +#pragma once + +#include +#include +#include +#include +#include + +namespace base +{ + class JsonWriterFile + { + public: + JsonWriterFile(FILE* fp, char* buffer, std::size_t length); + + FILE* GetFp() const; + void Flush(); + bool IsComplete() const; + + void StartObject(const char* name = nullptr); + void EndObject(); + + void StartArray(const char* name = nullptr); + void EndArray(); + + void WriteNull(const char* name); + void WriteBool(const char* name, bool value); + void WriteInt32(const char* name, std::int32_t value); + void WriteInt64(const char* name, std::int64_t value); + void WriteUInt32(const char* name, std::uint32_t value); + void WriteUint64(const char* name, std::uint64_t value); + void WriteString(const char* name, const char* value); + void WriteString(const char* name, const char* value, std::int32_t length); + void WriteFloat(const char* name, const double value); + + void WriteBits(const char* name, const unsigned char* data, std::size_t numBits); + void WriteBytes(const char* name, const unsigned char* data, std::size_t numBytes); + + private: + rapidjson::FileWriteStream m_fileStream; + rapidjson::Writer m_writer; + FILE* m_fp; + }; +}