New JSON serialization
This commit is contained in:
parent
640efb3e15
commit
257a2bf339
17 changed files with 2248 additions and 2 deletions
|
@ -31,9 +31,9 @@ else()
|
|||
else()
|
||||
set(ARCH_FLAG "-march=${ARCH}")
|
||||
endif()
|
||||
set(WARNINGS "-Wall -Wextra -Wpointer-arith -Wundef -Wvla -Wwrite-strings -Werror -Wno-error=extra -Wno-error=deprecated-declarations -Wno-error=sign-compare -Wno-error=strict-aliasing -Wno-error=type-limits -Wno-unused-parameter -Wno-error=unused-variable -Wno-error=undef -Wno-error=uninitialized")
|
||||
set(WARNINGS "-Wall -Wextra -Wpointer-arith -Wundef -Wvla -Wwrite-strings -Werror -Wno-error=extra -Wno-error=deprecated-declarations -Wno-error=sign-compare -Wno-error=strict-aliasing -Wno-error=type-limits -Wno-unused-parameter -Wno-error=unused-variable -Wno-error=undef -Wno-error=uninitialized -Wno-error=unused-result")
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
||||
set(WARNINGS "${WARNINGS} -Wno-error=mismatched-tags -Wno-error=null-conversion -Wno-overloaded-shift-op-parentheses -Wno-error=shift-count-overflow -Wno-error=tautological-constant-out-of-range-compare -Wno-error=unused-private-field -Wno-error=unneeded-internal-declaration")
|
||||
set(WARNINGS "${WARNINGS} -Wno-error=mismatched-tags -Wno-error=null-conversion -Wno-overloaded-shift-op-parentheses -Wno-error=shift-count-overflow -Wno-error=tautological-constant-out-of-range-compare -Wno-error=unused-private-field -Wno-error=unneeded-internal-declaration -Wno-error=unused-function")
|
||||
else()
|
||||
set(WARNINGS "${WARNINGS} -Wlogical-op -Wno-error=maybe-uninitialized")
|
||||
endif()
|
||||
|
|
242
src/serialization/BinaryInputStreamSerializer.cpp
Normal file
242
src/serialization/BinaryInputStreamSerializer.cpp
Normal file
|
@ -0,0 +1,242 @@
|
|||
// Copyright (c) 2012-2014, The CryptoNote developers, The Bytecoin developers
|
||||
//
|
||||
// This file is part of Bytecoin.
|
||||
//
|
||||
// Bytecoin is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Bytecoin is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with Bytecoin. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "BinaryInputStreamSerializer.h"
|
||||
#include "SerializationOverloads.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace {
|
||||
|
||||
void deserialize(std::istream& stream, uint8_t& v) {
|
||||
char c;
|
||||
stream.get(c);
|
||||
v = static_cast<uint8_t>(c);
|
||||
}
|
||||
|
||||
void deserialize(std::istream& stream, int8_t& v) {
|
||||
uint8_t val;
|
||||
deserialize(stream, val);
|
||||
v = val;
|
||||
}
|
||||
|
||||
void deserialize(std::istream& stream, bool& v) {
|
||||
uint8_t val;
|
||||
deserialize(stream, val);
|
||||
|
||||
v = val;
|
||||
}
|
||||
|
||||
void deserialize(std::istream& stream, uint32_t& v) {
|
||||
char c;
|
||||
|
||||
stream.get(c);
|
||||
v = static_cast<uint8_t>(c);
|
||||
|
||||
stream.get(c);
|
||||
v += static_cast<uint8_t>(c) << 8;
|
||||
|
||||
stream.get(c);
|
||||
v += static_cast<uint8_t>(c) << 16;
|
||||
|
||||
stream.get(c);
|
||||
v += static_cast<uint8_t>(c) << 24;
|
||||
}
|
||||
|
||||
void deserialize(std::istream& stream, int32_t& v) {
|
||||
uint32_t val;
|
||||
deserialize(stream, val);
|
||||
v = val;
|
||||
}
|
||||
|
||||
void deserialize(std::istream& stream, uint64_t& v) {
|
||||
char c;
|
||||
uint64_t uc;
|
||||
|
||||
stream.get(c);
|
||||
uc = static_cast<unsigned char>(c);
|
||||
v = uc;
|
||||
|
||||
stream.get(c);
|
||||
uc = static_cast<unsigned char>(c);
|
||||
v += (uc << 8);
|
||||
|
||||
stream.get(c);
|
||||
uc = static_cast<unsigned char>(c);
|
||||
v += (uc << 16);
|
||||
|
||||
stream.get(c);
|
||||
uc = static_cast<unsigned char>(c);
|
||||
v += (uc << 24);
|
||||
|
||||
stream.get(c);
|
||||
uc = static_cast<unsigned char>(c);
|
||||
v += (uc << 32);
|
||||
|
||||
stream.get(c);
|
||||
uc = static_cast<unsigned char>(c);
|
||||
v += (uc << 40);
|
||||
|
||||
stream.get(c);
|
||||
uc = static_cast<unsigned char>(c);
|
||||
v += (uc << 48);
|
||||
|
||||
stream.get(c);
|
||||
uc = static_cast<unsigned char>(c);
|
||||
v += (uc << 56);
|
||||
}
|
||||
|
||||
void deserialize(std::istream& stream, int64_t& v) {
|
||||
uint64_t val;
|
||||
deserialize(stream, val);
|
||||
v = val;
|
||||
}
|
||||
|
||||
void deserialize(std::istream& stream, char* buf, size_t len) {
|
||||
const size_t chunk = 1000;
|
||||
|
||||
// stream.read(buf, len);
|
||||
|
||||
// looks redundant, but i had a bug with it
|
||||
while (len && stream) {
|
||||
size_t toRead = std::min(len, chunk);
|
||||
stream.read(buf, toRead);
|
||||
len -= toRead;
|
||||
buf += toRead;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace cryptonote {
|
||||
|
||||
ISerializer::SerializerType BinaryInputStreamSerializer::type() const {
|
||||
return ISerializer::INPUT;
|
||||
}
|
||||
|
||||
ISerializer& BinaryInputStreamSerializer::beginObject(const std::string& name) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& BinaryInputStreamSerializer::endObject() {
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& BinaryInputStreamSerializer::beginArray(std::size_t& size, const std::string& name) {
|
||||
uint64_t val;
|
||||
serializeVarint(val, name, *this);
|
||||
size = val;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& BinaryInputStreamSerializer::endArray() {
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& BinaryInputStreamSerializer::operator()(uint8_t& value, const std::string& name) {
|
||||
deserialize(stream, value);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& BinaryInputStreamSerializer::operator()(uint32_t& value, const std::string& name) {
|
||||
deserialize(stream, value);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& BinaryInputStreamSerializer::operator()(int32_t& value, const std::string& name) {
|
||||
uint32_t v;
|
||||
operator()(v, name);
|
||||
value = v;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& BinaryInputStreamSerializer::operator()(int64_t& value, const std::string& name) {
|
||||
deserialize(stream, value);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& BinaryInputStreamSerializer::operator()(uint64_t& value, const std::string& name) {
|
||||
deserialize(stream, value);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& BinaryInputStreamSerializer::operator()(bool& value, const std::string& name) {
|
||||
deserialize(stream, value);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& BinaryInputStreamSerializer::operator()(std::string& value, const std::string& name) {
|
||||
uint64_t size;
|
||||
serializeVarint(size, name, *this);
|
||||
|
||||
std::vector<char> temp;
|
||||
temp.resize(size);
|
||||
|
||||
deserialize(stream, &temp[0], size);
|
||||
|
||||
value.reserve(size);
|
||||
value.assign(&temp[0], size);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& BinaryInputStreamSerializer::operator()(char* value, std::size_t size, const std::string& name) {
|
||||
stream.read(value, size);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& BinaryInputStreamSerializer::tag(const std::string& name) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& BinaryInputStreamSerializer::untagged(uint8_t& value) {
|
||||
char v;
|
||||
stream.get(v);
|
||||
value = v;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& BinaryInputStreamSerializer::endTag() {
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool BinaryInputStreamSerializer::hasObject(const std::string& name) {
|
||||
assert(false); //the method is not supported for this type of serialization
|
||||
throw std::runtime_error("hasObject method is not supported in BinaryInputStreamSerializer");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
ISerializer& BinaryInputStreamSerializer::operator()(double& value, const std::string& name) {
|
||||
assert(false); //the method is not supported for this type of serialization
|
||||
throw std::runtime_error("double serialization is not supported in BinaryInputStreamSerializer");
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
}
|
66
src/serialization/BinaryInputStreamSerializer.h
Normal file
66
src/serialization/BinaryInputStreamSerializer.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
// Copyright (c) 2012-2014, The CryptoNote developers, The Bytecoin developers
|
||||
//
|
||||
// This file is part of Bytecoin.
|
||||
//
|
||||
// Bytecoin is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Bytecoin is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with Bytecoin. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ISerializer.h"
|
||||
#include "SerializationOverloads.h"
|
||||
|
||||
#include <istream>
|
||||
|
||||
namespace cryptonote {
|
||||
|
||||
class BinaryInputStreamSerializer : public ISerializer {
|
||||
public:
|
||||
BinaryInputStreamSerializer(std::istream& strm) : stream(strm) {}
|
||||
virtual ~BinaryInputStreamSerializer() {}
|
||||
|
||||
virtual ISerializer::SerializerType type() const;
|
||||
|
||||
virtual ISerializer& beginObject(const std::string& name) override;
|
||||
virtual ISerializer& endObject() override;
|
||||
|
||||
virtual ISerializer& beginArray(std::size_t& size, const std::string& name) override;
|
||||
virtual ISerializer& endArray() override;
|
||||
|
||||
virtual ISerializer& operator()(uint8_t& value, const std::string& name) override;
|
||||
virtual ISerializer& operator()(int32_t& value, const std::string& name) override;
|
||||
|
||||
virtual ISerializer& operator()(uint32_t& value, const std::string& name) override;
|
||||
virtual ISerializer& operator()(int64_t& value, const std::string& name) override;
|
||||
virtual ISerializer& operator()(uint64_t& value, const std::string& name) override;
|
||||
virtual ISerializer& operator()(double& value, const std::string& name) override;
|
||||
virtual ISerializer& operator()(bool& value, const std::string& name) override;
|
||||
virtual ISerializer& operator()(std::string& value, const std::string& name) override;
|
||||
virtual ISerializer& operator()(char* value, std::size_t size, const std::string& name);
|
||||
|
||||
virtual ISerializer& tag(const std::string& name) override;
|
||||
virtual ISerializer& untagged(uint8_t& value) override;
|
||||
virtual ISerializer& endTag() override;
|
||||
|
||||
virtual bool hasObject(const std::string& name) override;
|
||||
|
||||
template<typename T>
|
||||
ISerializer& operator()(T& value, const std::string& name) {
|
||||
return ISerializer::operator()(value, name);
|
||||
}
|
||||
|
||||
private:
|
||||
std::istream& stream;
|
||||
};
|
||||
|
||||
}
|
185
src/serialization/BinaryOutputStreamSerializer.cpp
Normal file
185
src/serialization/BinaryOutputStreamSerializer.cpp
Normal file
|
@ -0,0 +1,185 @@
|
|||
// Copyright (c) 2012-2014, The CryptoNote developers, The Bytecoin developers
|
||||
//
|
||||
// This file is part of Bytecoin.
|
||||
//
|
||||
// Bytecoin is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Bytecoin is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with Bytecoin. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "BinaryOutputStreamSerializer.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace {
|
||||
|
||||
void serializeInteger(std::ostream& stream, uint8_t v) {
|
||||
stream.put(static_cast<char>(v));
|
||||
}
|
||||
|
||||
void serializeBool(std::ostream& stream, bool v) {
|
||||
serializeInteger(stream, static_cast<uint8_t>(v));
|
||||
}
|
||||
|
||||
void serializeInteger(std::ostream& stream, uint32_t v) {
|
||||
stream.put(static_cast<char>(v & 0xff));
|
||||
v >>= 8;
|
||||
|
||||
stream.put(static_cast<char>(v & 0xff));
|
||||
v >>= 8;
|
||||
|
||||
stream.put(static_cast<char>(v & 0xff));
|
||||
v >>= 8;
|
||||
|
||||
stream.put(static_cast<char>(v & 0xff));
|
||||
}
|
||||
|
||||
void serializeInteger(std::ostream& stream, uint64_t v) {
|
||||
stream.put(static_cast<unsigned char>(v & 0xff));
|
||||
v >>= 8;
|
||||
|
||||
stream.put(static_cast<unsigned char>(v & 0xff));
|
||||
v >>= 8;
|
||||
|
||||
stream.put(static_cast<unsigned char>(v & 0xff));
|
||||
v >>= 8;
|
||||
|
||||
stream.put(static_cast<unsigned char>(v & 0xff));
|
||||
v >>= 8;
|
||||
|
||||
stream.put(static_cast<unsigned char>(v & 0xff));
|
||||
v >>= 8;
|
||||
|
||||
stream.put(static_cast<unsigned char>(v & 0xff));
|
||||
v >>= 8;
|
||||
|
||||
stream.put(static_cast<unsigned char>(v & 0xff));
|
||||
v >>= 8;
|
||||
|
||||
stream.put(static_cast<unsigned char>(v & 0xff));
|
||||
}
|
||||
|
||||
void serializeInteger(std::ostream& stream, int64_t v) {
|
||||
serializeInteger(stream, static_cast<uint64_t>(v));
|
||||
}
|
||||
|
||||
void serializeData(std::ostream& stream, const char* buf, size_t len) {
|
||||
stream.write(buf, len);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace cryptonote {
|
||||
|
||||
ISerializer::SerializerType BinaryOutputStreamSerializer::type() const {
|
||||
return ISerializer::OUTPUT;
|
||||
}
|
||||
|
||||
ISerializer& BinaryOutputStreamSerializer::beginObject(const std::string& name) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& BinaryOutputStreamSerializer::endObject() {
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& BinaryOutputStreamSerializer::beginArray(std::size_t& size, const std::string& name) {
|
||||
uint64_t size64 = size;
|
||||
serializeVarint(size64, name, *this);
|
||||
size = size64;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& BinaryOutputStreamSerializer::endArray() {
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& BinaryOutputStreamSerializer::operator()(uint8_t& value, const std::string& name) {
|
||||
serializeInteger(stream, value);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& BinaryOutputStreamSerializer::operator()(uint32_t& value, const std::string& name) {
|
||||
serializeInteger(stream, value);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& BinaryOutputStreamSerializer::operator()(int32_t& value, const std::string& name) {
|
||||
uint32_t v = value;
|
||||
operator()(v, name);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& BinaryOutputStreamSerializer::operator()(int64_t& value, const std::string& name) {
|
||||
serializeInteger(stream, value);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& BinaryOutputStreamSerializer::operator()(uint64_t& value, const std::string& name) {
|
||||
serializeInteger(stream, value);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& BinaryOutputStreamSerializer::operator()(bool& value, const std::string& name) {
|
||||
serializeBool(stream, value);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& BinaryOutputStreamSerializer::operator()(std::string& value, const std::string& name) {
|
||||
uint64_t size = value.size();
|
||||
serializeVarint(size, name, *this);
|
||||
serializeData(stream, value.c_str(), value.size());
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& BinaryOutputStreamSerializer::operator()(char* value, std::size_t size, const std::string& name) {
|
||||
serializeData(stream, value, size);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& BinaryOutputStreamSerializer::tag(const std::string& name) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& BinaryOutputStreamSerializer::untagged(uint8_t& value) {
|
||||
stream.put(value);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& BinaryOutputStreamSerializer::endTag() {
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool BinaryOutputStreamSerializer::hasObject(const std::string& name) {
|
||||
assert(false); //the method is not supported for this type of serialization
|
||||
throw std::runtime_error("hasObject method is not supported in BinaryOutputStreamSerializer");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
ISerializer& BinaryOutputStreamSerializer::operator()(double& value, const std::string& name) {
|
||||
assert(false); //the method is not supported for this type of serialization
|
||||
throw std::runtime_error("double serialization is not supported in BinaryOutputStreamSerializer");
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
}
|
65
src/serialization/BinaryOutputStreamSerializer.h
Normal file
65
src/serialization/BinaryOutputStreamSerializer.h
Normal file
|
@ -0,0 +1,65 @@
|
|||
// Copyright (c) 2012-2014, The CryptoNote developers, The Bytecoin developers
|
||||
//
|
||||
// This file is part of Bytecoin.
|
||||
//
|
||||
// Bytecoin is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Bytecoin is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with Bytecoin. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ISerializer.h"
|
||||
#include "SerializationOverloads.h"
|
||||
|
||||
#include <ostream>
|
||||
|
||||
namespace cryptonote {
|
||||
|
||||
class BinaryOutputStreamSerializer : public ISerializer {
|
||||
public:
|
||||
BinaryOutputStreamSerializer(std::ostream& strm) : stream(strm) {}
|
||||
virtual ~BinaryOutputStreamSerializer() {}
|
||||
|
||||
virtual ISerializer::SerializerType type() const;
|
||||
|
||||
virtual ISerializer& beginObject(const std::string& name) override;
|
||||
virtual ISerializer& endObject() override;
|
||||
|
||||
virtual ISerializer& beginArray(std::size_t& size, const std::string& name) override;
|
||||
virtual ISerializer& endArray() override;
|
||||
|
||||
virtual ISerializer& operator()(uint8_t& value, const std::string& name) override;
|
||||
virtual ISerializer& operator()(int32_t& value, const std::string& name) override;
|
||||
virtual ISerializer& operator()(uint32_t& value, const std::string& name) override;
|
||||
virtual ISerializer& operator()(int64_t& value, const std::string& name) override;
|
||||
virtual ISerializer& operator()(uint64_t& value, const std::string& name) override;
|
||||
virtual ISerializer& operator()(double& value, const std::string& name) override;
|
||||
virtual ISerializer& operator()(bool& value, const std::string& name) override;
|
||||
virtual ISerializer& operator()(std::string& value, const std::string& name) override;
|
||||
virtual ISerializer& operator()(char* value, std::size_t size, const std::string& name) override;
|
||||
|
||||
virtual ISerializer& tag(const std::string& name) override;
|
||||
virtual ISerializer& untagged(uint8_t& value) override;
|
||||
virtual ISerializer& endTag() override;
|
||||
|
||||
virtual bool hasObject(const std::string& name) override;
|
||||
|
||||
template<typename T>
|
||||
ISerializer& operator()(T& value, const std::string& name) {
|
||||
return ISerializer::operator()(value, name);
|
||||
}
|
||||
|
||||
private:
|
||||
std::ostream& stream;
|
||||
};
|
||||
|
||||
}
|
135
src/serialization/ISerializer.h
Normal file
135
src/serialization/ISerializer.h
Normal file
|
@ -0,0 +1,135 @@
|
|||
// Copyright (c) 2012-2014, The CryptoNote developers, The Bytecoin developers
|
||||
//
|
||||
// This file is part of Bytecoin.
|
||||
//
|
||||
// Bytecoin is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Bytecoin is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with Bytecoin. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
|
||||
namespace cryptonote {
|
||||
|
||||
class ISerializer {
|
||||
public:
|
||||
|
||||
enum SerializerType {
|
||||
INPUT,
|
||||
OUTPUT
|
||||
};
|
||||
|
||||
virtual ~ISerializer() {}
|
||||
|
||||
virtual SerializerType type() const = 0;
|
||||
|
||||
virtual ISerializer& beginObject(const std::string& name) = 0;
|
||||
virtual ISerializer& endObject() = 0;
|
||||
virtual ISerializer& beginArray(std::size_t& size, const std::string& name) = 0;
|
||||
virtual ISerializer& endArray() = 0;
|
||||
|
||||
virtual ISerializer& operator()(uint8_t& value, const std::string& name) = 0;
|
||||
virtual ISerializer& operator()(int32_t& value, const std::string& name) = 0;
|
||||
virtual ISerializer& operator()(uint32_t& value, const std::string& name) = 0;
|
||||
virtual ISerializer& operator()(int64_t& value, const std::string& name) = 0;
|
||||
virtual ISerializer& operator()(uint64_t& value, const std::string& name) = 0;
|
||||
virtual ISerializer& operator()(double& value, const std::string& name) = 0;
|
||||
virtual ISerializer& operator()(bool& value, const std::string& name) = 0;
|
||||
virtual ISerializer& operator()(char* value, std::size_t size, const std::string& name) = 0;
|
||||
virtual ISerializer& operator()(std::string& value, const std::string& name) = 0;
|
||||
|
||||
virtual ISerializer& tag(const std::string& name) = 0;
|
||||
virtual ISerializer& untagged(uint8_t& value) = 0;
|
||||
virtual ISerializer& endTag() = 0;
|
||||
|
||||
virtual bool hasObject(const std::string& name) = 0;
|
||||
|
||||
template<typename T>
|
||||
ISerializer& operator()(T& value, const std::string& name);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
ISerializer& ISerializer::operator()(T& value, const std::string& name) {
|
||||
serialize(value, name, *this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void serialize(T& value, const std::string& name, ISerializer& serializer) {
|
||||
value.serialize(serializer, name);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
template<typename T>
|
||||
void serialize(std::vector<T>& value, const std::string& name);
|
||||
|
||||
template<typename K, typename V>
|
||||
void serialize(std::unordered_map<K, V>& value, const std::string& name);
|
||||
|
||||
|
||||
|
||||
template<typename T>
|
||||
void ISerializer::serialize(std::vector<T>& value, const std::string& name) {
|
||||
std::size_t size = value.size();
|
||||
beginArray(size, name);
|
||||
value.resize(size);
|
||||
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
serialize(value[i], "");
|
||||
}
|
||||
|
||||
endArray();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename K, typename V>
|
||||
void ISerializer::serialize(std::unordered_map<K, V>& value, const std::string& name) {
|
||||
std::size_t size;
|
||||
size = value.size();
|
||||
|
||||
beginArray(size, name);
|
||||
|
||||
if (type() == INPUT) {
|
||||
value.reserve(size);
|
||||
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
K key;
|
||||
V v;
|
||||
beginObject("");
|
||||
serialize(key, "");
|
||||
serialize(v, "");
|
||||
endObject();
|
||||
|
||||
value[key] = v;
|
||||
}
|
||||
} else {
|
||||
for (auto kv: value) {
|
||||
K key;
|
||||
key = kv.first;
|
||||
beginObject("");
|
||||
serialize(key, "");
|
||||
serialize(kv.second, "");
|
||||
endObject();
|
||||
}
|
||||
}
|
||||
|
||||
endArray();
|
||||
|
||||
return *this;
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
33
src/serialization/JsonInputStreamSerializer.cpp
Normal file
33
src/serialization/JsonInputStreamSerializer.cpp
Normal file
|
@ -0,0 +1,33 @@
|
|||
// Copyright (c) 2012-2014, The CryptoNote developers, The Bytecoin developers
|
||||
//
|
||||
// This file is part of Bytecoin.
|
||||
//
|
||||
// Bytecoin is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Bytecoin is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with Bytecoin. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "serialization/JsonInputStreamSerializer.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <exception>
|
||||
|
||||
namespace cryptonote {
|
||||
|
||||
JsonInputStreamSerializer::JsonInputStreamSerializer(std::istream& stream) {
|
||||
stream >> root;
|
||||
JsonInputValueSerializer::setJsonValue(&root);
|
||||
}
|
||||
|
||||
JsonInputStreamSerializer::~JsonInputStreamSerializer() {
|
||||
}
|
||||
|
||||
} //namespace cryptonote
|
40
src/serialization/JsonInputStreamSerializer.h
Normal file
40
src/serialization/JsonInputStreamSerializer.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
// Copyright (c) 2012-2014, The CryptoNote developers, The Bytecoin developers
|
||||
//
|
||||
// This file is part of Bytecoin.
|
||||
//
|
||||
// Bytecoin is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Bytecoin is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with Bytecoin. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
//#include "serialization/Enumerator.h"
|
||||
#include "serialization/JsonInputValueSerializer.h"
|
||||
#include "serialization/JsonValue.h"
|
||||
|
||||
namespace cryptonote {
|
||||
|
||||
//deserialization
|
||||
class JsonInputStreamSerializer : public JsonInputValueSerializer {
|
||||
public:
|
||||
JsonInputStreamSerializer(std::istream& stream);
|
||||
virtual ~JsonInputStreamSerializer();
|
||||
|
||||
private:
|
||||
JsonValue root;
|
||||
};
|
||||
|
||||
}
|
216
src/serialization/JsonInputValueSerializer.cpp
Normal file
216
src/serialization/JsonInputValueSerializer.cpp
Normal file
|
@ -0,0 +1,216 @@
|
|||
// Copyright (c) 2012-2014, The CryptoNote developers, The Bytecoin developers
|
||||
//
|
||||
// This file is part of Bytecoin.
|
||||
//
|
||||
// Bytecoin is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Bytecoin is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with Bytecoin. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "serialization/JsonInputValueSerializer.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace cryptonote {
|
||||
|
||||
JsonInputValueSerializer::JsonInputValueSerializer() : root(nullptr) {
|
||||
}
|
||||
|
||||
JsonInputValueSerializer::~JsonInputValueSerializer() {
|
||||
}
|
||||
|
||||
void JsonInputValueSerializer::setJsonValue(const JsonValue* value) {
|
||||
root = value;
|
||||
}
|
||||
|
||||
ISerializer::SerializerType JsonInputValueSerializer::type() const {
|
||||
return ISerializer::INPUT;
|
||||
}
|
||||
|
||||
ISerializer& JsonInputValueSerializer::beginObject(const std::string& name) {
|
||||
assert(root);
|
||||
|
||||
if (chain.size() == 0) {
|
||||
chain.push_back(root);
|
||||
return *this;
|
||||
}
|
||||
|
||||
const JsonValue* parent = chain.back();
|
||||
if (parent->isArray()) {
|
||||
const JsonValue& v = (*parent)[idxs.back()++];
|
||||
chain.push_back(&v);
|
||||
} else {
|
||||
const JsonValue& v = (*parent)(name);
|
||||
chain.push_back(&v);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& JsonInputValueSerializer::endObject() {
|
||||
assert(root);
|
||||
|
||||
chain.pop_back();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& JsonInputValueSerializer::beginArray(std::size_t& size, const std::string& name) {
|
||||
assert(root);
|
||||
|
||||
const JsonValue* parent = chain.back();
|
||||
|
||||
const JsonValue& arr = (*parent)(name);
|
||||
size = arr.size();
|
||||
|
||||
chain.push_back(&arr);
|
||||
idxs.push_back(0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& JsonInputValueSerializer::endArray() {
|
||||
assert(root);
|
||||
|
||||
chain.pop_back();
|
||||
idxs.pop_back();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& JsonInputValueSerializer::operator()(uint32_t& value, const std::string& name) {
|
||||
assert(root);
|
||||
|
||||
int64_t v = static_cast<int64_t>(value);
|
||||
operator()(v, name);
|
||||
value = static_cast<uint64_t>(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& JsonInputValueSerializer::operator()(int32_t& value, const std::string& name) {
|
||||
assert(root);
|
||||
|
||||
int64_t v = static_cast<int64_t>(value);
|
||||
operator()(v, name);
|
||||
value = static_cast<uint64_t>(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& JsonInputValueSerializer::operator()(int64_t& value, const std::string& name) {
|
||||
assert(root);
|
||||
|
||||
const JsonValue* val = chain.back();
|
||||
|
||||
if (val->isArray()) {
|
||||
const JsonValue& v = (*val)[idxs.back()++];
|
||||
value = v.getNumber();
|
||||
} else {
|
||||
const JsonValue& v = (*val)(name);
|
||||
value = v.getNumber();
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& JsonInputValueSerializer::operator()(uint64_t& value, const std::string& name) {
|
||||
assert(root);
|
||||
|
||||
int64_t v = static_cast<int64_t>(value);
|
||||
operator()(v, name);
|
||||
value = static_cast<uint64_t>(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& JsonInputValueSerializer::operator()(double& value, const std::string& name) {
|
||||
assert(root);
|
||||
|
||||
const JsonValue* val = chain.back();
|
||||
|
||||
if (val->isArray()) {
|
||||
value = (*val)[idxs.back()++].getDouble();
|
||||
} else {
|
||||
value = (*val)(name).getDouble();
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& JsonInputValueSerializer::operator()(std::string& value, const std::string& name) {
|
||||
assert(root);
|
||||
|
||||
const JsonValue* val = chain.back();
|
||||
|
||||
if (val->isArray()) {
|
||||
value = (*val)[idxs.back()++].getString();
|
||||
} else {
|
||||
value = (*val)(name).getString();
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& JsonInputValueSerializer::operator()(uint8_t& value, const std::string& name) {
|
||||
assert(root);
|
||||
|
||||
uint64_t v = static_cast<uint64_t>(value);
|
||||
operator()(v, name);
|
||||
value = static_cast<uint8_t>(value);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& JsonInputValueSerializer::operator()(bool& value, const std::string& name) {
|
||||
assert(root);
|
||||
|
||||
const JsonValue* val = chain.back();
|
||||
|
||||
if (val->isArray()) {
|
||||
value = (*val)[idxs.back()++].getBool();
|
||||
} else {
|
||||
value = (*val)(name).getBool();
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool JsonInputValueSerializer::hasObject(const std::string& name) {
|
||||
const JsonValue* val = chain.back();
|
||||
|
||||
return val->count(name) != 0;
|
||||
}
|
||||
|
||||
ISerializer& JsonInputValueSerializer::operator()(char* value, std::size_t size, const std::string& name) {
|
||||
assert(false);
|
||||
throw std::runtime_error("JsonInputValueSerializer doesn't support this type of serialization");
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& JsonInputValueSerializer::tag(const std::string& name) {
|
||||
assert(false);
|
||||
throw std::runtime_error("JsonInputValueSerializer doesn't support this type of serialization");
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& JsonInputValueSerializer::untagged(uint8_t& value) {
|
||||
assert(false);
|
||||
throw std::runtime_error("JsonInputValueSerializer doesn't support this type of serialization");
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& JsonInputValueSerializer::endTag() {
|
||||
assert(false);
|
||||
throw std::runtime_error("JsonInputValueSerializer doesn't support this type of serialization");
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
}
|
67
src/serialization/JsonInputValueSerializer.h
Normal file
67
src/serialization/JsonInputValueSerializer.h
Normal file
|
@ -0,0 +1,67 @@
|
|||
// Copyright (c) 2012-2014, The CryptoNote developers, The Bytecoin developers
|
||||
//
|
||||
// This file is part of Bytecoin.
|
||||
//
|
||||
// Bytecoin is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Bytecoin is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with Bytecoin. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "serialization/ISerializer.h"
|
||||
#include "serialization/JsonValue.h"
|
||||
|
||||
namespace cryptonote {
|
||||
|
||||
//deserialization
|
||||
class JsonInputValueSerializer : public ISerializer {
|
||||
public:
|
||||
JsonInputValueSerializer();
|
||||
virtual ~JsonInputValueSerializer();
|
||||
|
||||
void setJsonValue(const JsonValue* value);
|
||||
SerializerType type() const;
|
||||
|
||||
virtual ISerializer& beginObject(const std::string& name) override;
|
||||
virtual ISerializer& endObject() override;
|
||||
|
||||
virtual ISerializer& beginArray(std::size_t& size, const std::string& name) override;
|
||||
virtual ISerializer& endArray() override;
|
||||
|
||||
virtual ISerializer& operator()(int32_t& value, const std::string& name) override;
|
||||
virtual ISerializer& operator()(uint32_t& value, const std::string& name) override;
|
||||
virtual ISerializer& operator()(int64_t& value, const std::string& name) override;
|
||||
virtual ISerializer& operator()(uint64_t& value, const std::string& name) override;
|
||||
virtual ISerializer& operator()(double& value, const std::string& name) override;
|
||||
virtual ISerializer& operator()(std::string& value, const std::string& name) override;
|
||||
virtual ISerializer& operator()(uint8_t& value, const std::string& name) override;
|
||||
virtual ISerializer& operator()(bool& value, const std::string& name) override;
|
||||
virtual ISerializer& operator()(char* value, std::size_t size, const std::string& name) override;
|
||||
|
||||
virtual ISerializer& tag(const std::string& name) override;
|
||||
virtual ISerializer& untagged(uint8_t& value) override;
|
||||
virtual ISerializer& endTag() override;
|
||||
|
||||
virtual bool hasObject(const std::string& name) override;
|
||||
|
||||
template<typename T>
|
||||
ISerializer& operator()(T& value, const std::string& name) {
|
||||
return ISerializer::operator()(value, name);
|
||||
}
|
||||
|
||||
private:
|
||||
const JsonValue* root;
|
||||
std::vector<const JsonValue*> chain;
|
||||
std::vector<size_t> idxs;
|
||||
};
|
||||
|
||||
}
|
189
src/serialization/JsonOutputStreamSerializer.cpp
Normal file
189
src/serialization/JsonOutputStreamSerializer.cpp
Normal file
|
@ -0,0 +1,189 @@
|
|||
// Copyright (c) 2012-2014, The CryptoNote developers, The Bytecoin developers
|
||||
//
|
||||
// This file is part of Bytecoin.
|
||||
//
|
||||
// Bytecoin is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Bytecoin is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with Bytecoin. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "serialization/JsonOutputStreamSerializer.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace cryptonote {
|
||||
|
||||
JsonOutputStreamSerializer::JsonOutputStreamSerializer() : root(JsonValue::OBJECT) {
|
||||
}
|
||||
|
||||
JsonOutputStreamSerializer::~JsonOutputStreamSerializer() {
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, const JsonOutputStreamSerializer& enumerator) {
|
||||
out << enumerator.root;
|
||||
return out;
|
||||
}
|
||||
|
||||
JsonValue JsonOutputStreamSerializer::getJsonValue() const {
|
||||
return root;
|
||||
}
|
||||
|
||||
ISerializer::SerializerType JsonOutputStreamSerializer::type() const {
|
||||
return ISerializer::OUTPUT;
|
||||
}
|
||||
|
||||
ISerializer& JsonOutputStreamSerializer::beginObject(const std::string& name) {
|
||||
if (chain.size() == 0) {
|
||||
chain.push_back(&root);
|
||||
return *this;
|
||||
}
|
||||
|
||||
JsonValue* parent = chain.back();
|
||||
JsonValue obj(JsonValue::OBJECT);
|
||||
|
||||
if (parent->isObject()) {
|
||||
JsonValue& res = parent->insert(name, obj);
|
||||
chain.push_back(&res);
|
||||
} else {
|
||||
JsonValue& res = parent->pushBack(obj);
|
||||
chain.push_back(&res);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& JsonOutputStreamSerializer::endObject() {
|
||||
chain.pop_back();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& JsonOutputStreamSerializer::beginArray(std::size_t& size, const std::string& name) {
|
||||
JsonValue val(JsonValue::ARRAY);
|
||||
JsonValue& res = chain.back()->insert(name, val);
|
||||
chain.push_back(&res);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& JsonOutputStreamSerializer::endArray() {
|
||||
chain.pop_back();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& JsonOutputStreamSerializer::operator()(uint64_t& value, const std::string& name) {
|
||||
int64_t v = static_cast<int64_t>(value);
|
||||
return operator()(v, name);
|
||||
}
|
||||
|
||||
ISerializer& JsonOutputStreamSerializer::operator()(uint32_t& value, const std::string& name) {
|
||||
uint64_t v = static_cast<uint64_t>(value);
|
||||
return operator()(v, name);
|
||||
}
|
||||
|
||||
ISerializer& JsonOutputStreamSerializer::operator()(int32_t& value, const std::string& name) {
|
||||
int64_t v = static_cast<int64_t>(value);
|
||||
return operator()(v, name);
|
||||
}
|
||||
|
||||
ISerializer& JsonOutputStreamSerializer::operator()(int64_t& value, const std::string& name) {
|
||||
JsonValue* val = chain.back();
|
||||
JsonValue v;
|
||||
v = static_cast<int64_t>(value);
|
||||
if (val->isArray()) {
|
||||
val->pushBack(v);
|
||||
} else {
|
||||
val->insert(name, v);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& JsonOutputStreamSerializer::operator()(double& value, const std::string& name) {
|
||||
JsonValue* val = chain.back();
|
||||
JsonValue v;
|
||||
v = static_cast<double>(value);
|
||||
|
||||
if (val->isArray()) {
|
||||
val->pushBack(v);
|
||||
} else {
|
||||
val->insert(name, v);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& JsonOutputStreamSerializer::operator()(std::string& value, const std::string& name) {
|
||||
JsonValue* val = chain.back();
|
||||
JsonValue v;
|
||||
v = value;
|
||||
|
||||
if (val->isArray()) {
|
||||
val->pushBack(v);
|
||||
} else {
|
||||
val->insert(name, v);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& JsonOutputStreamSerializer::operator()(uint8_t& value, const std::string& name) {
|
||||
uint64_t v = static_cast<uint64_t>(value);
|
||||
return operator()(v, name);
|
||||
}
|
||||
|
||||
ISerializer& JsonOutputStreamSerializer::operator()(bool& value, const std::string& name) {
|
||||
JsonValue* val = chain.back();
|
||||
JsonValue v;
|
||||
v = static_cast<bool>(value);
|
||||
if (val->isArray()) {
|
||||
val->pushBack(v);
|
||||
} else {
|
||||
val->insert(name, v);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& JsonOutputStreamSerializer::operator()(char* value, std::size_t size, const std::string& name) {
|
||||
assert(false);
|
||||
throw std::runtime_error("JsonOutputStreamSerializer doesn't support \"char *\" type of serialization");
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& JsonOutputStreamSerializer::tag(const std::string& name) {
|
||||
assert(false);
|
||||
throw std::runtime_error("JsonOutputStreamSerializer doesn't support this type of serialization");
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& JsonOutputStreamSerializer::untagged(uint8_t& value) {
|
||||
assert(false);
|
||||
throw std::runtime_error("JsonOutputStreamSerializer doesn't support this type of serialization");
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ISerializer& JsonOutputStreamSerializer::endTag() {
|
||||
assert(false);
|
||||
throw std::runtime_error("JsonOutputStreamSerializer doesn't support this type of serialization");
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool JsonOutputStreamSerializer::hasObject(const std::string& name) {
|
||||
assert(false);
|
||||
throw std::runtime_error("JsonOutputStreamSerializer doesn't support this type of serialization");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
69
src/serialization/JsonOutputStreamSerializer.h
Normal file
69
src/serialization/JsonOutputStreamSerializer.h
Normal file
|
@ -0,0 +1,69 @@
|
|||
// Copyright (c) 2012-2014, The CryptoNote developers, The Bytecoin developers
|
||||
//
|
||||
// This file is part of Bytecoin.
|
||||
//
|
||||
// Bytecoin is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Bytecoin is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with Bytecoin. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "serialization/ISerializer.h"
|
||||
#include "serialization/JsonValue.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace cryptonote {
|
||||
|
||||
class JsonOutputStreamSerializer : public ISerializer {
|
||||
public:
|
||||
JsonOutputStreamSerializer();
|
||||
virtual ~JsonOutputStreamSerializer();
|
||||
|
||||
JsonValue getJsonValue() const;
|
||||
SerializerType type() const;
|
||||
|
||||
virtual ISerializer& beginObject(const std::string& name) override;
|
||||
virtual ISerializer& endObject() override;
|
||||
|
||||
virtual ISerializer& beginArray(std::size_t& size, const std::string& name) override;
|
||||
virtual ISerializer& endArray() override;
|
||||
|
||||
virtual ISerializer& operator()(int32_t& value, const std::string& name) override;
|
||||
virtual ISerializer& operator()(uint32_t& value, const std::string& name) override;
|
||||
virtual ISerializer& operator()(int64_t& value, const std::string& name) override;
|
||||
virtual ISerializer& operator()(uint64_t& value, const std::string& name) override;
|
||||
virtual ISerializer& operator()(double& value, const std::string& name) override;
|
||||
virtual ISerializer& operator()(std::string& value, const std::string& name) override;
|
||||
virtual ISerializer& operator()(uint8_t& value, const std::string& name) override;
|
||||
virtual ISerializer& operator()(bool& value, const std::string& name) override;
|
||||
virtual ISerializer& operator()(char* value, std::size_t size, const std::string& name) override;
|
||||
|
||||
virtual ISerializer& tag(const std::string& name) override;
|
||||
virtual ISerializer& untagged(uint8_t& value) override;
|
||||
virtual ISerializer& endTag() override;
|
||||
|
||||
virtual bool hasObject(const std::string& name) override;
|
||||
|
||||
template<typename T>
|
||||
ISerializer& operator()(T& value, const std::string& name) {
|
||||
return ISerializer::operator()(value, name);
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& out, const JsonOutputStreamSerializer& enumerator);
|
||||
|
||||
private:
|
||||
JsonValue root;
|
||||
std::vector<JsonValue*> chain;
|
||||
};
|
||||
|
||||
} // namespace cryptonote
|
65
src/serialization/JsonSerializationDispatcher.h
Normal file
65
src/serialization/JsonSerializationDispatcher.h
Normal file
|
@ -0,0 +1,65 @@
|
|||
// Copyright (c) 2012-2014, The CryptoNote developers, The Bytecoin developers
|
||||
//
|
||||
// This file is part of Bytecoin.
|
||||
//
|
||||
// Bytecoin is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Bytecoin is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with Bytecoin. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <sstream>
|
||||
#include <type_traits>
|
||||
#include <boost/tti/has_member_function.hpp>
|
||||
|
||||
#include "serialization/JsonOutputStreamSerializer.h"
|
||||
#include "serialization/JsonInputStreamSerializer.h"
|
||||
#include "storages/portable_storage_template_helper.h"
|
||||
|
||||
namespace {
|
||||
BOOST_TTI_HAS_MEMBER_FUNCTION(serialize)
|
||||
} //namespace
|
||||
|
||||
namespace cryptonote {
|
||||
|
||||
template<class T>
|
||||
inline typename std::enable_if<has_member_function_serialize<void (T::*)(ISerializer&, const std::string&)>::value, void>::type SerializeToJson(T& obj, std::string& jsonBuff) {
|
||||
std::stringstream stream;
|
||||
JsonOutputStreamSerializer serializer;
|
||||
|
||||
obj.serialize(serializer, "");
|
||||
|
||||
stream << serializer;
|
||||
jsonBuff = stream.str();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline typename std::enable_if<has_member_function_serialize<void (T::*)(ISerializer&, const std::string&)>::value, void>::type LoadFromJson(T& obj, const std::string& jsonBuff) {
|
||||
std::stringstream stream(jsonBuff);
|
||||
JsonInputStreamSerializer serializer(stream);
|
||||
|
||||
obj.serialize(serializer, "");
|
||||
}
|
||||
|
||||
//old epee serialization
|
||||
|
||||
template<class T>
|
||||
inline typename std::enable_if<!has_member_function_serialize<void (T::*)(ISerializer&, const std::string&)>::value, void>::type SerializeToJson(T& obj, std::string& jsonBuff) {
|
||||
epee::serialization::store_t_to_json(obj, jsonBuff);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline typename std::enable_if<!has_member_function_serialize<void (T::*)(ISerializer&, const std::string&)>::value, void>::type LoadFromJson(T& obj, const std::string& jsonBuff) {
|
||||
epee::serialization::load_t_from_json(obj, jsonBuff);
|
||||
}
|
||||
|
||||
} //namespace cryptonote
|
612
src/serialization/JsonValue.cpp
Normal file
612
src/serialization/JsonValue.cpp
Normal file
|
@ -0,0 +1,612 @@
|
|||
// Copyright (c) 2012-2014, The CryptoNote developers, The Bytecoin developers
|
||||
//
|
||||
// This file is part of Bytecoin.
|
||||
//
|
||||
// Bytecoin is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Bytecoin is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with Bytecoin. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "JsonValue.h"
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <assert.h>
|
||||
|
||||
namespace cryptonote {
|
||||
|
||||
JsonValue::JsonValue() : d_type(NIL) {
|
||||
}
|
||||
|
||||
JsonValue::JsonValue(JsonValue::Type type) {
|
||||
switch(type) {
|
||||
case OBJECT:
|
||||
new(d_valueObject)JsonValue::Object();
|
||||
break;
|
||||
case ARRAY:
|
||||
new(d_valueArray)JsonValue::Array();
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error("Wrong JsonValue type. Object or Array are possible only");
|
||||
}
|
||||
|
||||
d_type = type;
|
||||
}
|
||||
|
||||
JsonValue::JsonValue(const JsonValue& other) : d_type(other.d_type) {
|
||||
switch (d_type) {
|
||||
case ARRAY:
|
||||
new(d_valueArray)JsonValue::Array(*reinterpret_cast<const Array*>(other.d_valueArray));
|
||||
break;
|
||||
case BOOL:
|
||||
d_valueBool = other.d_valueBool;
|
||||
break;
|
||||
case INT64:
|
||||
d_valueInt64 = other.d_valueInt64;
|
||||
break;
|
||||
case NIL:
|
||||
break;
|
||||
case OBJECT:
|
||||
new(d_valueObject)JsonValue::Object(*reinterpret_cast<const Object*>(other.d_valueObject));
|
||||
break;
|
||||
case DOUBLE:
|
||||
d_valueDouble = other.d_valueDouble;
|
||||
break;
|
||||
case STRING:
|
||||
new(d_valueString)std::string(*reinterpret_cast<const std::string*>(other.d_valueString));
|
||||
break;
|
||||
default:
|
||||
throw(std::runtime_error("Invalid type"));
|
||||
}
|
||||
}
|
||||
|
||||
JsonValue::~JsonValue() {
|
||||
destructValue();
|
||||
}
|
||||
|
||||
bool JsonValue::isArray() const {
|
||||
return d_type == ARRAY;
|
||||
}
|
||||
|
||||
bool JsonValue::isBool() const {
|
||||
return d_type == BOOL;
|
||||
}
|
||||
|
||||
bool JsonValue::isInt64() const {
|
||||
return d_type == INT64;
|
||||
}
|
||||
|
||||
bool JsonValue::isNil() const {
|
||||
return d_type == NIL;
|
||||
}
|
||||
|
||||
bool JsonValue::isObject() const {
|
||||
return d_type == OBJECT;
|
||||
}
|
||||
|
||||
bool JsonValue::isDouble() const {
|
||||
return d_type == DOUBLE;
|
||||
}
|
||||
|
||||
bool JsonValue::isString() const {
|
||||
return d_type == STRING;
|
||||
}
|
||||
|
||||
bool JsonValue::getBool() const {
|
||||
assert(d_type == BOOL);
|
||||
if (d_type != BOOL) {
|
||||
throw(std::runtime_error("Value type is not BOOL"));
|
||||
}
|
||||
|
||||
return d_valueBool;
|
||||
}
|
||||
|
||||
int64_t JsonValue::getNumber() const {
|
||||
assert(d_type == INT64);
|
||||
if (d_type != INT64) {
|
||||
throw(std::runtime_error("Value type is not INT64"));
|
||||
}
|
||||
|
||||
return d_valueInt64;
|
||||
}
|
||||
|
||||
const JsonValue::Object& JsonValue::getObject() const {
|
||||
assert(d_type == OBJECT);
|
||||
if (d_type != OBJECT) {
|
||||
throw(std::runtime_error("Value type is not OBJECT"));
|
||||
}
|
||||
|
||||
return *reinterpret_cast<const Object*>(d_valueObject);
|
||||
}
|
||||
|
||||
double JsonValue::getDouble() const {
|
||||
assert(d_type == DOUBLE);
|
||||
if (d_type != DOUBLE) {
|
||||
throw(std::runtime_error("Value type is not DOUBLE"));
|
||||
}
|
||||
|
||||
return d_valueDouble;
|
||||
}
|
||||
|
||||
std::string JsonValue::getString() const {
|
||||
assert(d_type == STRING);
|
||||
if (d_type != STRING) {
|
||||
throw(std::runtime_error("Value type is not STRING"));
|
||||
}
|
||||
|
||||
return *reinterpret_cast<const std::string*>(d_valueString);
|
||||
}
|
||||
|
||||
const JsonValue& JsonValue::operator()(const std::string& name) const {
|
||||
assert(d_type == OBJECT);
|
||||
assert(reinterpret_cast<const Object*>(d_valueObject)->count(name) > 0);
|
||||
if (d_type != OBJECT) {
|
||||
throw(std::runtime_error("Value type is not OBJECT"));
|
||||
}
|
||||
|
||||
return reinterpret_cast<const Object*>(d_valueObject)->at(name);
|
||||
}
|
||||
|
||||
size_t JsonValue::count(const std::string& name) const {
|
||||
assert(d_type == OBJECT);
|
||||
if (d_type != OBJECT) {
|
||||
throw(std::runtime_error("Value type is not OBJECT"));
|
||||
}
|
||||
|
||||
return reinterpret_cast<const Object*>(d_valueObject)->count(name);
|
||||
}
|
||||
|
||||
const JsonValue& JsonValue::operator[](size_t index) const {
|
||||
assert(d_type == ARRAY);
|
||||
if (d_type != ARRAY) {
|
||||
throw(std::runtime_error("Value type is not ARRAY"));
|
||||
}
|
||||
|
||||
return reinterpret_cast<const Array*>(d_valueArray)->at(index);
|
||||
}
|
||||
|
||||
size_t JsonValue::size() const {
|
||||
assert(d_type == ARRAY || d_type == OBJECT);
|
||||
switch (d_type) {
|
||||
case OBJECT:
|
||||
return reinterpret_cast<const Object*>(d_valueString)->size();
|
||||
case ARRAY:
|
||||
return reinterpret_cast<const Array*>(d_valueString)->size();
|
||||
default:
|
||||
throw(std::runtime_error("Value type is not ARRAY or OBJECT"));
|
||||
}
|
||||
}
|
||||
|
||||
JsonValue::Array::const_iterator JsonValue::begin() const {
|
||||
assert(d_type == ARRAY);
|
||||
if (d_type != ARRAY) {
|
||||
throw(std::runtime_error("Value type is not ARRAY"));
|
||||
}
|
||||
|
||||
return reinterpret_cast<const Array*>(d_valueArray)->begin();
|
||||
}
|
||||
|
||||
JsonValue::Array::const_iterator JsonValue::end() const {
|
||||
assert(d_type == ARRAY);
|
||||
if (d_type != ARRAY) {
|
||||
throw(std::runtime_error("Value type is not ARRAY"));
|
||||
}
|
||||
|
||||
return reinterpret_cast<const Array*>(d_valueArray)->end();
|
||||
}
|
||||
|
||||
void JsonValue::readArray(std::istream& in) {
|
||||
char c;
|
||||
JsonValue::Array value;
|
||||
|
||||
c = in.peek();
|
||||
while (true) {
|
||||
if (!isspace(in.peek())) break;
|
||||
in.read(&c, 1);
|
||||
}
|
||||
|
||||
if (c != ']') {
|
||||
for (;;) {
|
||||
value.resize(value.size() + 1);
|
||||
in >> value.back();
|
||||
in >> c;
|
||||
while (isspace(c)) in >> c;
|
||||
if (c == ']') {
|
||||
break;
|
||||
}
|
||||
|
||||
if (c != ',') {
|
||||
throw(std::runtime_error("Unable to parse"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (d_type != JsonValue::ARRAY) {
|
||||
destructValue();
|
||||
d_type = JsonValue::NIL;
|
||||
new(d_valueArray)JsonValue::Array;
|
||||
d_type = JsonValue::ARRAY;
|
||||
}
|
||||
|
||||
reinterpret_cast<JsonValue::Array*>(d_valueArray)->swap(value);
|
||||
}
|
||||
|
||||
void JsonValue::readTrue(std::istream& in) {
|
||||
char data[3];
|
||||
in.read(data, 3);
|
||||
if (data[0] != 'r' || data[1] != 'u' || data[2] != 'e') {
|
||||
throw(std::runtime_error("Unable to parse"));
|
||||
}
|
||||
|
||||
if (d_type != JsonValue::BOOL) {
|
||||
destructValue();
|
||||
d_type = JsonValue::BOOL;
|
||||
}
|
||||
|
||||
d_valueBool = true;
|
||||
}
|
||||
|
||||
void JsonValue::readFalse(std::istream& in) {
|
||||
char data[4];
|
||||
in.read(data, 4);
|
||||
if (data[0] != 'a' || data[1] != 'l' || data[2] != 's' || data[3] != 'e') {
|
||||
throw(std::runtime_error("Unable to parse"));
|
||||
}
|
||||
|
||||
if (d_type != JsonValue::BOOL) {
|
||||
destructValue();
|
||||
d_type = JsonValue::BOOL;
|
||||
}
|
||||
|
||||
d_valueBool = false;
|
||||
}
|
||||
|
||||
void JsonValue::readNumber(std::istream& in, char c) {
|
||||
std::string text;
|
||||
text += c;
|
||||
size_t dots = 0;
|
||||
for (;;) {
|
||||
int i = in.peek();
|
||||
if (i >= '0' && i <= '9') {
|
||||
in.read(&c, 1);
|
||||
text += c;
|
||||
} else if (i == '.') {
|
||||
in.read(&c, 1);
|
||||
text += '.';
|
||||
++dots;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (dots > 0) {
|
||||
if (dots > 1) {
|
||||
throw(std::runtime_error("Unable to parse"));
|
||||
}
|
||||
|
||||
int i = in.peek();
|
||||
if (in.peek() == 'e') {
|
||||
in.read(&c, 1);
|
||||
text += c;
|
||||
i = in.peek();
|
||||
if (i == '+') {
|
||||
in.read(&c, 1);
|
||||
text += c;
|
||||
i = in.peek();
|
||||
} else if (i == '-') {
|
||||
in.read(&c, 1);
|
||||
text += c;
|
||||
i = in.peek();
|
||||
}
|
||||
|
||||
if (i < '0' || i > '9') {
|
||||
throw(std::runtime_error("Unable to parse"));
|
||||
}
|
||||
|
||||
do {
|
||||
in.read(&c, 1);
|
||||
text += c;
|
||||
i = in.peek();
|
||||
} while (i >= '0' && i <= '9');
|
||||
}
|
||||
|
||||
double value;
|
||||
std::istringstream(text) >> value;
|
||||
if (d_type != JsonValue::DOUBLE) {
|
||||
destructValue();
|
||||
d_type = JsonValue::DOUBLE;
|
||||
}
|
||||
|
||||
d_valueDouble = value;
|
||||
} else {
|
||||
if (text.size() > 1 && ((text[0] == '0') || (text[0] == '-' && text[1] == '0'))) {
|
||||
throw(std::runtime_error("Unable to parse"));
|
||||
}
|
||||
|
||||
int64_t value;
|
||||
std::istringstream(text) >> value;
|
||||
if (d_type != JsonValue::INT64) {
|
||||
destructValue();
|
||||
d_type = JsonValue::INT64;
|
||||
}
|
||||
|
||||
d_valueInt64 = value;
|
||||
}
|
||||
}
|
||||
|
||||
void JsonValue::readNull(std::istream& in) {
|
||||
char data[3];
|
||||
in.read(data, 3);
|
||||
if (data[0] != 'u' || data[1] != 'l' || data[2] != 'l') {
|
||||
throw(std::runtime_error("Unable to parse"));
|
||||
}
|
||||
|
||||
if (d_type != JsonValue::NIL) {
|
||||
destructValue();
|
||||
d_type = JsonValue::NIL;
|
||||
}
|
||||
}
|
||||
|
||||
void JsonValue::readObject(std::istream& in) {
|
||||
char c;
|
||||
JsonValue::Object value;
|
||||
in >> c;
|
||||
while (isspace(c)) in >> c;
|
||||
|
||||
if (c != '}') {
|
||||
std::string name;
|
||||
for (;;) {
|
||||
if (c != '"') {
|
||||
throw(std::runtime_error("Unable to parse"));
|
||||
}
|
||||
|
||||
name.clear();
|
||||
for (;;) {
|
||||
in >> c;
|
||||
if (c == '"') {
|
||||
break;
|
||||
}
|
||||
|
||||
if (c == '\\') {
|
||||
name += c;
|
||||
in >> c;
|
||||
}
|
||||
|
||||
name += c;
|
||||
}
|
||||
|
||||
in >> c;
|
||||
while (isspace(c)) in >> c;
|
||||
if (c != ':') {
|
||||
throw(std::runtime_error("Unable to parse"));
|
||||
}
|
||||
|
||||
in >> value[name];
|
||||
in >> c;
|
||||
while (isspace(c)) in >> c;
|
||||
if (c == '}') {
|
||||
break;
|
||||
}
|
||||
|
||||
if (c != ',') {
|
||||
throw(std::runtime_error("Unable to parse"));
|
||||
}
|
||||
in >> c;
|
||||
while (isspace(c)) in >> c;
|
||||
}
|
||||
}
|
||||
|
||||
if (d_type != JsonValue::OBJECT) {
|
||||
destructValue();
|
||||
d_type = JsonValue::NIL;
|
||||
new(d_valueObject)JsonValue::Object;
|
||||
d_type = JsonValue::OBJECT;
|
||||
}
|
||||
|
||||
reinterpret_cast<JsonValue::Object*>(d_valueObject)->swap(value);
|
||||
}
|
||||
|
||||
void JsonValue::readString(std::istream& in) {
|
||||
char c;
|
||||
std::string value;
|
||||
|
||||
for (;;) {
|
||||
in.read(&c, 1);
|
||||
if (c == '"') {
|
||||
break;
|
||||
}
|
||||
|
||||
if (c == '\\') {
|
||||
value += c;
|
||||
in >> c;
|
||||
}
|
||||
|
||||
value += c;
|
||||
}
|
||||
|
||||
if (d_type != JsonValue::STRING) {
|
||||
destructValue();
|
||||
d_type = JsonValue::NIL;
|
||||
new(d_valueString)std::string;
|
||||
d_type = JsonValue::STRING;
|
||||
}
|
||||
|
||||
reinterpret_cast<std::string*>(d_valueString)->swap(value);
|
||||
}
|
||||
|
||||
std::istream& operator>>(std::istream& in, JsonValue& jsonValue) {
|
||||
char c;
|
||||
in >> c;
|
||||
while (isspace(c)) in >> c;
|
||||
if (c == '[') {
|
||||
jsonValue.readArray(in);
|
||||
} else if (c == 't') {
|
||||
jsonValue.readTrue(in);
|
||||
} else if (c == 'f') {
|
||||
jsonValue.readFalse(in);
|
||||
} else if ((c == '-') || (c >= '0' && c <= '9')) {
|
||||
jsonValue.readNumber(in, c);
|
||||
} else if (c == 'n') {
|
||||
jsonValue.readNull(in);
|
||||
} else if (c == '{') {
|
||||
jsonValue.readObject(in);
|
||||
} else if (c == '"') {
|
||||
jsonValue.readString(in);
|
||||
} else {
|
||||
throw(std::runtime_error("Unable to parse"));
|
||||
}
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, const JsonValue& jsonValue) {
|
||||
if (jsonValue.d_type == JsonValue::ARRAY) {
|
||||
const JsonValue::Array& array = *reinterpret_cast<const JsonValue::Array*>(jsonValue.d_valueArray);
|
||||
out << '[';
|
||||
if (array.size() > 0) {
|
||||
out << array[0];
|
||||
for (size_t i = 1; i < array.size(); ++i) {
|
||||
out << ',' << array[i];
|
||||
}
|
||||
}
|
||||
|
||||
out << ']';
|
||||
} else if (jsonValue.d_type == JsonValue::BOOL) {
|
||||
out << (jsonValue.d_valueBool ? "true" : "false");
|
||||
} else if (jsonValue.d_type == JsonValue::INT64) {
|
||||
out << jsonValue.d_valueInt64;
|
||||
} else if (jsonValue.d_type == JsonValue::NIL) {
|
||||
out << "null";
|
||||
} else if (jsonValue.d_type == JsonValue::OBJECT) {
|
||||
const JsonValue::Object& object = *reinterpret_cast<const JsonValue::Object*>(jsonValue.d_valueObject);
|
||||
out << '{';
|
||||
auto iter = object.begin();
|
||||
if (iter != object.end()) {
|
||||
out << '"' << iter->first << "\":" << iter->second;
|
||||
++iter;
|
||||
for (; iter != object.end(); ++iter) {
|
||||
out << ",\"" << iter->first << "\":" << iter->second;
|
||||
}
|
||||
}
|
||||
|
||||
out << '}';
|
||||
} else if (jsonValue.d_type == JsonValue::DOUBLE) {
|
||||
std::ostringstream stream;
|
||||
stream << std::fixed << std::setprecision(11) << jsonValue.d_valueDouble;
|
||||
std::string value = stream.str();
|
||||
while (value.size() > 1 && value[value.size() - 2] != '.' && value[value.size() - 1] == '0') {
|
||||
value.resize(value.size() - 1);
|
||||
}
|
||||
|
||||
out << value;
|
||||
} else if (jsonValue.d_type == JsonValue::STRING) {
|
||||
out << '"' << *reinterpret_cast<const std::string*>(jsonValue.d_valueString) << '"';
|
||||
} else {
|
||||
throw(std::runtime_error("Invalid type"));
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
void JsonValue::destructValue() {
|
||||
switch (d_type) {
|
||||
case ARRAY:
|
||||
reinterpret_cast<Array*>(d_valueArray)->~Array();
|
||||
break;
|
||||
case OBJECT:
|
||||
reinterpret_cast<Object*>(d_valueObject)->~Object();
|
||||
break;
|
||||
case STRING:
|
||||
reinterpret_cast<std::string*>(d_valueString)->~basic_string();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
JsonValue& JsonValue::pushBack(const JsonValue& val) {
|
||||
if (d_type != ARRAY) {
|
||||
throw std::runtime_error("JsonValue error. pushBack is only possible for arrays");
|
||||
}
|
||||
|
||||
Array* array = reinterpret_cast<Array*>(d_valueArray);
|
||||
array->push_back(val);
|
||||
|
||||
return array->back();
|
||||
}
|
||||
|
||||
JsonValue& JsonValue::insert(const std::string key, const JsonValue& value) {
|
||||
if (d_type != OBJECT) {
|
||||
throw std::runtime_error("JsonValue error. insert is only possible for objects");
|
||||
}
|
||||
|
||||
Object* obj = reinterpret_cast<Object*>(d_valueObject);
|
||||
|
||||
auto res = obj->insert(std::make_pair(key, value));
|
||||
return res.first->second;
|
||||
}
|
||||
|
||||
JsonValue& JsonValue::operator=(bool value) {
|
||||
if (d_type != BOOL) {
|
||||
destructValue();
|
||||
d_type = BOOL;
|
||||
}
|
||||
|
||||
d_valueBool = value;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
JsonValue& JsonValue::operator=(int64_t value) {
|
||||
if (d_type != INT64) {
|
||||
destructValue();
|
||||
d_type = INT64;
|
||||
}
|
||||
|
||||
d_valueInt64 = value;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//JsonValue& JsonValue::operator=(NilType value) {
|
||||
// if (d_type != NIL) {
|
||||
// destructValue();
|
||||
// d_type = NIL;
|
||||
// }
|
||||
//}
|
||||
|
||||
JsonValue& JsonValue::operator=(double value) {
|
||||
if (d_type != DOUBLE) {
|
||||
destructValue();
|
||||
d_type = DOUBLE;
|
||||
}
|
||||
|
||||
d_valueDouble = value;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
JsonValue& JsonValue::operator=(const std::string& value) {
|
||||
if (d_type != STRING) {
|
||||
destructValue();
|
||||
new(d_valueString)std::string;
|
||||
d_type = STRING;
|
||||
}
|
||||
|
||||
reinterpret_cast<std::string*>(d_valueString)->assign(value.data(), value.size());
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
JsonValue& JsonValue::operator=(const char* value) {
|
||||
return operator=(std::string(value));
|
||||
}
|
||||
|
||||
} //namespace cryptonote
|
103
src/serialization/JsonValue.h
Normal file
103
src/serialization/JsonValue.h
Normal file
|
@ -0,0 +1,103 @@
|
|||
// Copyright (c) 2012-2014, The CryptoNote developers, The Bytecoin developers
|
||||
//
|
||||
// This file is part of Bytecoin.
|
||||
//
|
||||
// Bytecoin is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Bytecoin is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with Bytecoin. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace cryptonote {
|
||||
|
||||
class JsonValue {
|
||||
public:
|
||||
typedef std::vector<JsonValue> Array;
|
||||
typedef std::map<std::string, JsonValue> Object;
|
||||
|
||||
enum Type {
|
||||
ARRAY,
|
||||
BOOL,
|
||||
INT64,
|
||||
NIL,
|
||||
OBJECT,
|
||||
DOUBLE,
|
||||
STRING
|
||||
};
|
||||
|
||||
JsonValue();
|
||||
JsonValue(Type type);
|
||||
JsonValue(const JsonValue& other);
|
||||
~JsonValue();
|
||||
JsonValue& operator=(const JsonValue& other) = delete;
|
||||
bool isArray() const;
|
||||
bool isBool() const;
|
||||
bool isInt64() const;
|
||||
bool isNil() const;
|
||||
bool isObject() const;
|
||||
bool isDouble() const;
|
||||
bool isString() const;
|
||||
bool getBool() const;
|
||||
int64_t getNumber() const;
|
||||
const Object& getObject() const;
|
||||
double getDouble() const;
|
||||
std::string getString() const;
|
||||
const JsonValue& operator()(const std::string& name) const;
|
||||
size_t count(const std::string& name) const;
|
||||
const JsonValue& operator[](size_t index) const;
|
||||
size_t size() const;
|
||||
Array::const_iterator begin() const;
|
||||
Array::const_iterator end() const;
|
||||
|
||||
JsonValue& pushBack(const JsonValue& val);
|
||||
JsonValue& insert(const std::string key, const JsonValue& value);
|
||||
|
||||
JsonValue& operator=(bool value);
|
||||
JsonValue& operator=(int64_t value);
|
||||
// JsonValue& operator=(NilType value);
|
||||
JsonValue& operator=(double value);
|
||||
JsonValue& operator=(const std::string& value);
|
||||
JsonValue& operator=(const char* value);
|
||||
|
||||
|
||||
friend std::istream& operator>>(std::istream& in, JsonValue& jsonValue);
|
||||
friend std::ostream& operator<<(std::ostream& out, const JsonValue& jsonValue);
|
||||
|
||||
private:
|
||||
size_t d_type;
|
||||
union {
|
||||
uint8_t d_valueArray[sizeof(Array)];
|
||||
bool d_valueBool;
|
||||
int64_t d_valueInt64;
|
||||
uint8_t d_valueObject[sizeof(Object)];
|
||||
double d_valueDouble;
|
||||
uint8_t d_valueString[sizeof(std::string)];
|
||||
};
|
||||
|
||||
void destructValue();
|
||||
|
||||
void readArray(std::istream& in);
|
||||
void readTrue(std::istream& in);
|
||||
void readFalse(std::istream& in);
|
||||
void readNumber(std::istream& in, char c);
|
||||
void readNull(std::istream& in);
|
||||
void readObject(std::istream& in);
|
||||
void readString(std::istream& in);
|
||||
};
|
||||
|
||||
} //namespace cryptonote
|
81
src/serialization/SerializationOverloads.cpp
Normal file
81
src/serialization/SerializationOverloads.cpp
Normal file
|
@ -0,0 +1,81 @@
|
|||
// Copyright (c) 2012-2014, The CryptoNote developers, The Bytecoin developers
|
||||
//
|
||||
// This file is part of Bytecoin.
|
||||
//
|
||||
// Bytecoin is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Bytecoin is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with Bytecoin. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "SerializationOverloads.h"
|
||||
|
||||
#include <limits>
|
||||
|
||||
namespace cryptonote {
|
||||
|
||||
void readVarint(uint64_t& value, cryptonote::ISerializer& serializer) {
|
||||
const int bits = std::numeric_limits<uint64_t>::digits;
|
||||
|
||||
uint64_t v = 0;
|
||||
for (int shift = 0;; shift += 7) {
|
||||
uint8_t b;
|
||||
serializer.untagged(b);
|
||||
|
||||
if (shift + 7 >= bits && b >= 1 << (bits - shift)) {
|
||||
throw std::runtime_error("Varint overflow");
|
||||
}
|
||||
|
||||
if (b == 0 && shift != 0) {
|
||||
throw std::runtime_error("Non-canonical varint representation");
|
||||
}
|
||||
|
||||
v |= static_cast<uint64_t>(b & 0x7f) << shift;
|
||||
if ((b & 0x80) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
value = v;
|
||||
}
|
||||
|
||||
void writeVarint(uint64_t& value, cryptonote::ISerializer& serializer) {
|
||||
uint64_t v = value;
|
||||
|
||||
while (v >= 0x80) {
|
||||
uint8_t b = (static_cast<uint8_t>(v) & 0x7f) | 0x80;
|
||||
serializer.untagged(b);
|
||||
v >>= 7;
|
||||
}
|
||||
|
||||
uint8_t b = static_cast<uint8_t>(v);
|
||||
serializer.untagged(b);
|
||||
}
|
||||
|
||||
|
||||
void serializeVarint(uint64_t& value, const std::string& name, cryptonote::ISerializer& serializer) {
|
||||
serializer.tag(name);
|
||||
|
||||
if (serializer.type() == cryptonote::ISerializer::INPUT) {
|
||||
readVarint(value, serializer);
|
||||
} else {
|
||||
writeVarint(value, serializer);
|
||||
}
|
||||
|
||||
serializer.endTag();
|
||||
}
|
||||
|
||||
void serializeVarint(uint32_t& value, const std::string& name, cryptonote::ISerializer& serializer) {
|
||||
uint64_t v = value;
|
||||
serializeVarint(v, name, serializer);
|
||||
value = static_cast<uint32_t>(v);
|
||||
}
|
||||
|
||||
}
|
78
src/serialization/SerializationOverloads.h
Normal file
78
src/serialization/SerializationOverloads.h
Normal file
|
@ -0,0 +1,78 @@
|
|||
// Copyright (c) 2012-2014, The CryptoNote developers, The Bytecoin developers
|
||||
//
|
||||
// This file is part of Bytecoin.
|
||||
//
|
||||
// Bytecoin is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Bytecoin is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with Bytecoin. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ISerializer.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace cryptonote {
|
||||
|
||||
void serializeVarint(uint64_t& value, const std::string& name, cryptonote::ISerializer& serializer);
|
||||
void serializeVarint(uint32_t& value, const std::string& name, cryptonote::ISerializer& serializer);
|
||||
|
||||
template<typename T>
|
||||
void serialize(std::vector<T>& value, const std::string& name, cryptonote::ISerializer& serializer) {
|
||||
std::size_t size = value.size();
|
||||
serializer.beginArray(size, name);
|
||||
value.resize(size);
|
||||
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
serializer(value[i], "");
|
||||
}
|
||||
|
||||
serializer.endArray();
|
||||
}
|
||||
|
||||
template<typename K, typename V>
|
||||
void serialize(std::unordered_map<K, V>& value, const std::string& name, cryptonote::ISerializer& serializer) {
|
||||
std::size_t size;
|
||||
size = value.size();
|
||||
|
||||
serializer.beginArray(size, name);
|
||||
|
||||
if (serializer.type() == cryptonote::ISerializer::INPUT) {
|
||||
value.reserve(size);
|
||||
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
K key;
|
||||
V v;
|
||||
serializer.beginObject("");
|
||||
serializer(key, "");
|
||||
serializer(v, "");
|
||||
serializer.endObject();
|
||||
|
||||
value[key] = v;
|
||||
}
|
||||
} else {
|
||||
for (auto kv: value) {
|
||||
K key;
|
||||
key = kv.first;
|
||||
serializer.beginObject("");
|
||||
serializer(key, "");
|
||||
serializer(kv.second, "");
|
||||
serializer.endObject();
|
||||
}
|
||||
}
|
||||
|
||||
serializer.endArray();
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue