binary json format introduced + specification
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
#include "WorldFiles.h"
|
||||
|
||||
#include "rle.h"
|
||||
#include "binary_io.h"
|
||||
#include "../window/Camera.h"
|
||||
#include "../content/Content.h"
|
||||
#include "../objects/Player.h"
|
||||
@@ -477,7 +476,7 @@ void WorldFiles::writeIndices(const ContentIndices* indices) {
|
||||
items.put(def->name);
|
||||
}
|
||||
|
||||
files::write_string(getIndicesFile(), json::stringify(&root, true, " "));
|
||||
files::write_json(getIndicesFile(), &root);
|
||||
}
|
||||
|
||||
void WorldFiles::writeWorldInfo(const World* world) {
|
||||
@@ -494,7 +493,7 @@ void WorldFiles::writeWorldInfo(const World* world) {
|
||||
timeobj.put("day-time", world->daytime);
|
||||
timeobj.put("day-time-speed", world->daytimeSpeed);
|
||||
|
||||
files::write_string(getWorldFile(), json::stringify(&root, true, " "));
|
||||
files::write_json(getWorldFile(), &root);
|
||||
}
|
||||
|
||||
bool WorldFiles::readWorldInfo(World* world) {
|
||||
@@ -540,7 +539,7 @@ void WorldFiles::writePlayer(Player* player){
|
||||
root.put("flight", player->flight);
|
||||
root.put("noclip", player->noclip);
|
||||
|
||||
files::write_string(getPlayerFile(), json::stringify(&root, true, " "));
|
||||
files::write_json(getPlayerFile(), &root);
|
||||
}
|
||||
|
||||
bool WorldFiles::readPlayer(Player* player) {
|
||||
|
||||
@@ -1,165 +0,0 @@
|
||||
#include "binary_io.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
|
||||
void BinaryWriter::put(ubyte b) {
|
||||
buffer.push_back(b);
|
||||
}
|
||||
|
||||
void BinaryWriter::putCStr(const char* str) {
|
||||
size_t size = strlen(str)+1;
|
||||
buffer.reserve(buffer.size() + size);
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
buffer.push_back(str[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void BinaryWriter::put(const std::string& s) {
|
||||
size_t len = s.length();
|
||||
if (len > INT16_MAX) {
|
||||
throw std::domain_error("length > INT16_MAX");
|
||||
}
|
||||
putInt16(len);
|
||||
put((const ubyte*)s.data(), len);
|
||||
}
|
||||
|
||||
void BinaryWriter::putShortStr(const std::string& s) {
|
||||
size_t len = s.length();
|
||||
if (len > 255) {
|
||||
throw std::domain_error("length > 255");
|
||||
}
|
||||
put(len);
|
||||
put((const ubyte*)s.data(), len);
|
||||
}
|
||||
|
||||
void BinaryWriter::put(const ubyte* arr, size_t size) {
|
||||
buffer.reserve(buffer.size() + size);
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
buffer.push_back(arr[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void BinaryWriter::putInt16(int16_t val) {
|
||||
buffer.push_back((char) (val >> 8 & 255));
|
||||
buffer.push_back((char) (val >> 0 & 255));
|
||||
}
|
||||
|
||||
void BinaryWriter::putInt32(int32_t val) {
|
||||
buffer.reserve(buffer.size() + 4);
|
||||
buffer.push_back((char) (val >> 24 & 255));
|
||||
buffer.push_back((char) (val >> 16 & 255));
|
||||
buffer.push_back((char) (val >> 8 & 255));
|
||||
buffer.push_back((char) (val >> 0 & 255));
|
||||
}
|
||||
|
||||
void BinaryWriter::putInt64(int64_t val) {
|
||||
buffer.reserve(buffer.size() + 8);
|
||||
buffer.push_back((char) (val >> 56 & 255));
|
||||
buffer.push_back((char) (val >> 48 & 255));
|
||||
buffer.push_back((char) (val >> 40 & 255));
|
||||
buffer.push_back((char) (val >> 32 & 255));
|
||||
buffer.push_back((char) (val >> 24 & 255));
|
||||
buffer.push_back((char) (val >> 16 & 255));
|
||||
buffer.push_back((char) (val >> 8 & 255));
|
||||
buffer.push_back((char) (val >> 0 & 255));
|
||||
}
|
||||
|
||||
void BinaryWriter::putFloat32(float val) {
|
||||
union {
|
||||
int32_t vali32;
|
||||
float valfloat;
|
||||
} value;
|
||||
value.valfloat = val;
|
||||
putInt32(value.vali32);
|
||||
}
|
||||
|
||||
BinaryReader::BinaryReader(const ubyte* data, size_t size)
|
||||
: data(data), size(size), pos(0) {
|
||||
}
|
||||
|
||||
void BinaryReader::checkMagic(const char* data, size_t size) {
|
||||
if (pos + size >= this->size) {
|
||||
throw std::runtime_error("invalid magic number");
|
||||
}
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
if (this->data[pos + i] != (ubyte)data[i]){
|
||||
throw std::runtime_error("invalid magic number");
|
||||
}
|
||||
}
|
||||
pos += size;
|
||||
}
|
||||
|
||||
ubyte BinaryReader::get() {
|
||||
if (pos == size) {
|
||||
throw std::underflow_error("buffer underflow");
|
||||
}
|
||||
return data[pos++];
|
||||
}
|
||||
|
||||
int16_t BinaryReader::getInt16() {
|
||||
if (pos+2 > size) {
|
||||
throw std::underflow_error("unexpected end");
|
||||
}
|
||||
pos += 2;
|
||||
return (data[pos - 2] << 8) |
|
||||
(data[pos - 1]);
|
||||
}
|
||||
|
||||
int32_t BinaryReader::getInt32() {
|
||||
if (pos+4 > size) {
|
||||
throw std::underflow_error("unexpected end");
|
||||
}
|
||||
pos += 4;
|
||||
return (data[pos - 4] << 24) |
|
||||
(data[pos - 3] << 16) |
|
||||
(data[pos - 2] << 8) |
|
||||
(data[pos - 1]);
|
||||
}
|
||||
|
||||
int64_t BinaryReader::getInt64() {
|
||||
if (pos+8 > size) {
|
||||
throw std::underflow_error("unexpected end");
|
||||
}
|
||||
pos += 8;
|
||||
return ((int64_t)data[pos - 8] << 56) |
|
||||
((int64_t)data[pos - 7] << 48) |
|
||||
((int64_t)data[pos - 6] << 40) |
|
||||
((int64_t)data[pos - 5] << 32) |
|
||||
((int64_t)data[pos - 4] << 24) |
|
||||
((int64_t)data[pos - 3] << 16) |
|
||||
((int64_t)data[pos - 2] << 8) |
|
||||
((int64_t)data[pos - 1]);
|
||||
}
|
||||
|
||||
float BinaryReader::getFloat32() {
|
||||
union {
|
||||
int32_t vali32;
|
||||
float valfloat;
|
||||
} value;
|
||||
value.vali32 = getInt32();
|
||||
return value.valfloat;
|
||||
}
|
||||
|
||||
std::string BinaryReader::getString() {
|
||||
uint16_t length = (uint16_t)getInt16();
|
||||
if (pos+length > size) {
|
||||
throw std::underflow_error("unexpected end");
|
||||
}
|
||||
pos += length;
|
||||
return std::string((const char*)(data+pos-length), length);
|
||||
}
|
||||
|
||||
std::string BinaryReader::getShortString() {
|
||||
ubyte length = get();
|
||||
if (pos+length > size) {
|
||||
throw std::underflow_error("unexpected end");
|
||||
}
|
||||
pos += length;
|
||||
return std::string((const char*)(data+pos-length), length);
|
||||
}
|
||||
|
||||
bool BinaryReader::hasNext() const {
|
||||
return pos < size;
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
#ifndef FILES_BINARY_WRITER_H_
|
||||
#define FILES_BINARY_WRITER_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "../typedefs.h"
|
||||
|
||||
class BinaryWriter {
|
||||
std::vector<ubyte> buffer;
|
||||
public:
|
||||
void put(ubyte b);
|
||||
void putCStr(const char* str);
|
||||
void putInt16(int16_t val);
|
||||
void putInt32(int32_t val);
|
||||
void putInt64(int64_t val);
|
||||
void putFloat32(float val);
|
||||
void put(const std::string& s);
|
||||
void put(const ubyte* arr, size_t size);
|
||||
void putShortStr(const std::string& s);
|
||||
|
||||
inline size_t size() const {
|
||||
return buffer.size();
|
||||
}
|
||||
inline const ubyte* data() const {
|
||||
return buffer.data();
|
||||
}
|
||||
};
|
||||
|
||||
class BinaryReader {
|
||||
const ubyte* data;
|
||||
size_t size;
|
||||
size_t pos;
|
||||
public:
|
||||
BinaryReader(const ubyte* data, size_t size);
|
||||
|
||||
void checkMagic(const char* data, size_t size);
|
||||
ubyte get();
|
||||
int16_t getInt16();
|
||||
int32_t getInt32();
|
||||
int64_t getInt64();
|
||||
float getFloat32();
|
||||
std::string getString();
|
||||
std::string getShortString();
|
||||
bool hasNext() const;
|
||||
};
|
||||
|
||||
#endif // FILES_BINARY_WRITER_H_
|
||||
+29
-4
@@ -92,16 +92,41 @@ bool files::write_string(fs::path filename, const std::string content) {
|
||||
return true;
|
||||
}
|
||||
|
||||
json::JObject* files::read_json(fs::path file) {
|
||||
std::string text = files::read_string(file);
|
||||
bool files::write_json(fs::path filename, const json::JObject* obj, bool nice) {
|
||||
// -- binary json tests
|
||||
//return write_binary_json(fs::path(filename.u8string()+".bin"), obj);
|
||||
return files::write_string(filename, json::stringify(obj, nice, " "));
|
||||
}
|
||||
|
||||
bool files::write_binary_json(fs::path filename, const json::JObject* obj) {
|
||||
std::vector<ubyte> bytes = json::to_binary(obj);
|
||||
return files::write_bytes(filename, (const char*)bytes.data(), bytes.size());
|
||||
}
|
||||
|
||||
json::JObject* files::read_json(fs::path filename) {
|
||||
// binary json tests
|
||||
// fs::path binfile = fs::path(filename.u8string()+".bin");
|
||||
// if (fs::is_regular_file(binfile)){
|
||||
// return read_binary_json(binfile);
|
||||
// }
|
||||
|
||||
std::string text = files::read_string(filename);
|
||||
try {
|
||||
return json::parse(file.string(), text);
|
||||
auto obj = json::parse(filename.string(), text);
|
||||
//write_binary_json(binfile, obj);
|
||||
return obj;
|
||||
} catch (const parsing_error& error) {
|
||||
std::cerr << error.errorLog() << std::endl;
|
||||
throw std::runtime_error("could not to parse "+file.string());
|
||||
throw std::runtime_error("could not to parse "+filename.string());
|
||||
}
|
||||
}
|
||||
|
||||
json::JObject* files::read_binary_json(fs::path file) {
|
||||
size_t size;
|
||||
std::unique_ptr<char[]> bytes (files::read_bytes(file, size));
|
||||
return json::from_binary((const ubyte*)bytes.get(), size);
|
||||
}
|
||||
|
||||
std::vector<std::string> files::read_list(fs::path filename) {
|
||||
std::ifstream file(filename);
|
||||
if (!file) {
|
||||
|
||||
+14
-8
@@ -7,6 +7,8 @@
|
||||
#include <filesystem>
|
||||
#include "../typedefs.h"
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
namespace json {
|
||||
class JObject;
|
||||
}
|
||||
@@ -25,14 +27,18 @@ namespace files {
|
||||
};
|
||||
|
||||
|
||||
extern bool write_bytes(std::filesystem::path, const char* data, size_t size);
|
||||
extern uint append_bytes(std::filesystem::path, const char* data, size_t size);
|
||||
extern bool read(std::filesystem::path, char* data, size_t size);
|
||||
extern char* read_bytes(std::filesystem::path, size_t& length);
|
||||
extern std::string read_string(std::filesystem::path filename);
|
||||
extern bool write_string(std::filesystem::path filename, const std::string content);
|
||||
extern json::JObject* read_json(std::filesystem::path file);
|
||||
extern std::vector<std::string> read_list(std::filesystem::path file);
|
||||
extern bool write_bytes(fs::path, const char* data, size_t size);
|
||||
extern uint append_bytes(fs::path, const char* data, size_t size);
|
||||
extern bool write_string(fs::path filename, const std::string content);
|
||||
extern bool write_json(fs::path filename, const json::JObject* obj, bool nice=true);
|
||||
extern bool write_binary_json(fs::path filename, const json::JObject* obj);
|
||||
|
||||
extern bool read(fs::path, char* data, size_t size);
|
||||
extern char* read_bytes(fs::path, size_t& length);
|
||||
extern std::string read_string(fs::path filename);
|
||||
extern json::JObject* read_json(fs::path file);
|
||||
extern json::JObject* read_binary_json(fs::path file);
|
||||
extern std::vector<std::string> read_list(fs::path file);
|
||||
}
|
||||
|
||||
#endif /* FILES_FILES_H_ */
|
||||
Reference in New Issue
Block a user