Make Serialize accept argument SerializeFormat format

Rename `const char* GetString()` to GetCString and add `std::string GetString()`
WIP on serializers/msgpack.h
This commit is contained in:
Fangrui Song 2018-01-06 18:01:32 -08:00
parent 76a3fe8400
commit 5809d0c436
9 changed files with 110 additions and 64 deletions

View File

@ -31,7 +31,7 @@ struct RealCacheManager : ICacheManager {
WriteToFile(cache_path, file.file_contents_);
}
std::string indexed_content = Serialize(file);
std::string indexed_content = Serialize(config_->cacheFormat, file);
WriteToFile(AppendSerializationFormat(cache_path), indexed_content);
}

View File

@ -479,7 +479,7 @@ IndexVar* IndexFile::Resolve(IndexVarId id) {
}
std::string IndexFile::ToString() {
return Serialize(*this);
return Serialize(SerializeFormat::Json, *this);
}
IndexType::IndexType(IndexTypeId id, const std::string& usr)

View File

@ -154,7 +154,7 @@ inline bool operator!=(const IndexFuncRef& a, const IndexFuncRef& b) {
}
inline void Reflect(Reader& visitor, IndexFuncRef& value) {
const char* str_value = visitor.GetString();
const char* str_value = visitor.GetCString();
if (str_value[0] == '~') {
value.is_implicit = true;
++str_value;

View File

@ -149,7 +149,7 @@ void Reflect(Reader& visitor, Position& value) {
if (!visitor.IsString())
value = Position();
else
value = Position(visitor.GetString());
value = Position(visitor.GetCString());
}
void Reflect(Writer& visitor, Position& value) {
std::string output = value.ToString();
@ -161,7 +161,7 @@ void Reflect(Reader& visitor, Range& value) {
if (!visitor.IsString())
value = Range();
else
value = Range(visitor.GetString());
value = Range(visitor.GetCString());
}
void Reflect(Writer& visitor, Range& value) {
std::string output = value.ToString();

View File

@ -1,6 +1,5 @@
#include "serializer.h"
// TODO Move Json* to serializers/json.cc
#include "serializers/json.h"
#include "serializers/msgpack.h"
@ -192,23 +191,37 @@ void Reflect(TVisitor& visitor, IndexFile& value) {
REFLECT_MEMBER_END();
}
std::string Serialize(IndexFile& file) {
std::string Serialize(SerializeFormat format, IndexFile& file) {
switch (format) {
case SerializeFormat::Json: {
rapidjson::StringBuffer output;
rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(output);
writer.SetFormatOptions(
rapidjson::PrettyFormatOptions::kFormatSingleLineArray);
writer.SetIndent(' ', 2);
JsonWriter json_writer(&writer);
Reflect(json_writer, file);
return output.GetString();
}
case SerializeFormat::MessagePack: {
msgpack::sbuffer buf;
msgpack::packer<msgpack::sbuffer> pk(&buf);
MessagePackWriter msgpack_writer(&pk);
Reflect(msgpack_writer, file);
return std::string(buf.data(), buf.size());
}
}
return "";
}
std::unique_ptr<IndexFile> Deserialize(SerializeFormat format,
std::string path,
std::string serialized,
optional<int> expected_version) {
std::unique_ptr<IndexFile> file;
switch (format) {
case SerializeFormat::Json: {
rapidjson::Document reader;
reader.Parse(serialized.c_str());
if (reader.HasParseError())
@ -224,11 +237,18 @@ std::unique_ptr<IndexFile> Deserialize(SerializeFormat format,
}
}
// TODO msgpack
(void)format;
auto file = MakeUnique<IndexFile>(path);
file = MakeUnique<IndexFile>(path);
JsonReader json_reader{&reader};
Reflect(json_reader, *file);
break;
}
case SerializeFormat::MessagePack: {
msgpack::object_handle oh = msgpack::unpack(serialized.data(), serialized.size());
(void)oh;
break;
}
}
// Restore non-serialized state.
file->path = path;

View File

@ -27,7 +27,8 @@ class Reader {
virtual int GetInt() = 0;
virtual int64_t GetInt64() = 0;
virtual uint64_t GetUint64() = 0;
virtual const char* GetString() = 0;
virtual const char* GetCString() = 0;
virtual std::string GetString() { return GetCString(); }
virtual bool HasMember(const char* x) = 0;
virtual std::unique_ptr<Reader> operator[](const char* x) = 0;
@ -245,7 +246,7 @@ void ReflectMember(Reader& visitor, const char* name, T& value) {
visitor.DoMember(name, [&](Reader& child) { Reflect(child, value); });
}
std::string Serialize(IndexFile& file);
std::string Serialize(SerializeFormat format, IndexFile& file);
std::unique_ptr<IndexFile> Deserialize(SerializeFormat format,
std::string path,
std::string serialized,

View File

@ -24,7 +24,7 @@ class JsonReader : public Reader {
int GetInt() override { return m_->GetInt(); }
int64_t GetInt64() override { return m_->GetInt64(); }
uint64_t GetUint64() override { return m_->GetUint64(); }
const char* GetString() override { return m_->GetString(); }
const char* GetCString() override { return m_->GetString(); }
bool HasMember(const char* x) override { return m_->HasMember(x); }
std::unique_ptr<Reader> operator[](const char* x) override {

View File

@ -5,37 +5,61 @@
#include <msgpack.hpp>
class MessagePackReader : public Reader {
msgpack::object_handle* m_;
msgpack::unpacker* m_;
msgpack::object_handle oh_;
void next() { m_->next(oh_); }
public:
MessagePackReader(msgpack::object_handle* m) : m_(m) {}
MessagePackReader(msgpack::unpacker* m) : m_(m) { next(); }
SerializeFormat Format() const override { return SerializeFormat::MessagePack; }
//bool GetBool() override { return m_->GetBool(); }
//int GetInt() override { return m_->GetInt(); }
//int64_t GetInt64() override { return m_->GetInt64(); }
//uint64_t GetUint64() override { return m_->GetUint64(); }
//const char* GetString() override { return m_->GetString(); }
bool IsNull() override { return oh_.get().is_nil(); }
bool IsArray() override { return oh_.get().type == msgpack::type::ARRAY; }
bool IsInt() override {
return oh_.get().type == msgpack::type::POSITIVE_INTEGER ||
oh_.get().type == msgpack::type::NEGATIVE_INTEGER;
}
bool IsString() override { return oh_.get().type == msgpack::type::STR; }
//bool HasMember(const char* x) override { return m_->HasMember(x); }
//std::unique_ptr<Reader> operator[](const char* x) override {
// auto& sub = (*m_)[x];
// return std::unique_ptr<JsonReader>(new JsonReader(&sub));
//}
bool GetBool() override {
auto ret = oh_.get().as<bool>();
next();
return ret;
}
int GetInt() override {
auto ret = oh_.get().as<int>();
next();
return ret;
}
int64_t GetInt64() override {
auto ret = oh_.get().as<int64_t>();
next();
return ret;
}
uint64_t GetUint64() override {
auto ret = oh_.get().as<uint64_t>();
next();
return ret;
}
const char* GetCString() override {
auto ret = oh_.get().as<char*>();
next();
return ret;
}
//void IterArray(std::function<void(Reader&)> fn) override {
// for (auto& entry : m_->GetArray()) {
// MessagePackReader sub(&entry);
// fn(sub);
// }
//}
bool HasMember(const char* x) override { return true; }
std::unique_ptr<Reader> operator[](const char* x) override {
return {};
}
//void DoMember(const char* name, std::function<void(Reader&)> fn) override {
// auto it = m_->FindMember(name);
// if (it != m_->MemberEnd()) {
// MessagePackReader sub(&it->value);
// fn(sub);
// }
//}
void IterArray(std::function<void(Reader&)> fn) override {
}
void DoMember(const char* name, std::function<void(Reader&)> fn) override {
const char* key = GetCString();
fn(*this);
}
};
class MessagePackWriter : public Writer {
@ -43,6 +67,7 @@ class MessagePackWriter : public Writer {
public:
MessagePackWriter(msgpack::packer<msgpack::sbuffer>* m) : m_(m) {}
SerializeFormat Format() const override { return SerializeFormat::MessagePack; }
void Null() override { m_->pack_nil(); }
void Bool(bool x) override { m_->pack(x); }

View File

@ -75,8 +75,8 @@ void DiffDocuments(std::string path,
void VerifySerializeToFrom(IndexFile* file) {
std::string expected = file->ToString();
std::unique_ptr<IndexFile> result =
Deserialize(SerializeFormat::Json, "--.cc", Serialize(*file),
std::unique_ptr<IndexFile> result = Deserialize(
SerializeFormat::Json, "--.cc", Serialize(SerializeFormat::Json, *file),
nullopt /*expected_version*/);
std::string actual = result->ToString();
if (expected != actual) {