diff options
Diffstat (limited to 'src/serialise.cpp')
-rw-r--r-- | src/serialise.cpp | 186 |
1 files changed, 173 insertions, 13 deletions
diff --git a/src/serialise.cpp b/src/serialise.cpp index 65a2ea78..88b323f9 100644 --- a/src/serialise.cpp +++ b/src/serialise.cpp @@ -2,6 +2,7 @@ */ #include <serialise.hpp> #include <serialiser_texttree.hpp> +#include "common.hpp" Serialiser& Serialiser::operator<<(const Serialisable& subobj) { @@ -11,16 +12,33 @@ Serialiser& Serialiser::operator<<(const Serialisable& subobj) return *this; } +void Deserialiser::item(Serialisable& s) +{ + DEBUG("Deserialise - '"<<s.serialise_tag()<<"'"); + start_object(s.serialise_tag()); + s.deserialise(*this); + end_object(s.serialise_tag()); +} +::std::string Deserialiser::start_object() +{ + ::std::string s = read_tag(); + DEBUG("tag = '" << s << "'"); + start_object(nullptr); + return s; +} + +// -------------------------------------------------------------------- Serialiser_TextTree::Serialiser_TextTree(::std::ostream& os): m_os(os), - m_indent_level(0) + m_indent_level(0), + m_array_was_empty(false) { } void Serialiser_TextTree::start_object(const char *tag) { print_indent(); - m_os << tag << "{\n"; + m_os << tag << " {\n"; indent(); } void Serialiser_TextTree::end_object(const char *_tag) { @@ -30,31 +48,39 @@ void Serialiser_TextTree::end_object(const char *_tag) { } void Serialiser_TextTree::start_array(unsigned int size) { print_indent(); - if( size == 0 ) - m_os << "["; - else - m_os << "[\n"; - indent(); + if( size == 0 ) { + m_os << "[]\n"; + m_array_was_empty = true; + } + else { + m_os << "[" << size << "\n"; + indent(); + } } void Serialiser_TextTree::end_array() { - unindent(); - print_indent(); - m_os << "]\n"; + if( m_array_was_empty ) { + m_array_was_empty = false; + } + else { + unindent(); + print_indent(); + m_os << "]\n"; + } } Serialiser& Serialiser_TextTree::operator<<(bool val) { print_indent(); - m_os << (val ? "true" : "false") << "\n"; + m_os << (val ? "T" : "F") << "\n"; return *this; } -Serialiser& Serialiser_TextTree::operator<<(unsigned int val) +Serialiser& Serialiser_TextTree::operator<<(uint64_t val) { print_indent(); m_os << val << "\n"; return *this; } -Serialiser& Serialiser_TextTree::operator<<(const ::std::string& s) +Serialiser& Serialiser_TextTree::operator<<(const char* s) { print_indent(); m_os << "\"" << s << "\"\n"; @@ -74,4 +100,138 @@ void Serialiser_TextTree::print_indent() m_os << " "; } +// -------------------------------------------------------------------- +Deserialiser_TextTree::Deserialiser_TextTree(::std::istream& is): + m_is(is) +{ +} +bool Deserialiser_TextTree::is_ws(char c) +{ + return c == ' ' || c == '\t' || c == '\n' || c == '\r'; +} +char Deserialiser_TextTree::getc() +{ + char c; + m_is.get(c); + return c; +} +char Deserialiser_TextTree::peekc() +{ + return m_is.peek(); +} +void Deserialiser_TextTree::eat_ws() +{ + char c; + do { + m_is.get(c); + } while( is_ws(c) ); + m_is.putback(c); +} +size_t Deserialiser_TextTree::start_array() +{ + eat_ws(); + char c = getc(); + if( c != '[' ) + throw ::std::runtime_error("TODO: Less shit exception, start_array"); + + eat_ws(); + if( peekc() == ']' ) { + DEBUG("len = 0"); + return 0; + } + + size_t len; + m_is >> len; + if( !m_is.good() ) + throw ::std::runtime_error("TODO: Less shit exception, start_array"); + DEBUG("len = "<<len); + return len; +} +void Deserialiser_TextTree::end_array() +{ + eat_ws(); + char c = getc(); + DEBUG("c = '"<<c<<"'"); + if( c != ']' ) + throw ::std::runtime_error("TODO: Less shit exception, end_array"); +} +::std::string Deserialiser_TextTree::read_tag() +{ + ::std::string tag; + eat_ws(); + char c; + do { + m_is.get(c); + tag.push_back(c); + } while( !is_ws(c) ); + tag.pop_back(); + if( tag.size() == 0 ) + throw ::std::runtime_error("TODO: Less shit exception, read_tag"); + return tag; +} +void Deserialiser_TextTree::item(bool& b) +{ + eat_ws(); + switch( getc() ) + { + case 'T': DEBUG("true"); b = true; break; + case 'F': DEBUG("false"); b = false; break; + default: + throw ::std::runtime_error("TODO: Less shit exception, item(bool)"); + } +} +void Deserialiser_TextTree::item(uint64_t& v) +{ + eat_ws(); + m_is >> v; + if( !m_is.good() ) + throw ::std::runtime_error("TODO: Less shit exception, item(uint64_t)"); +} +void Deserialiser_TextTree::item(::std::string& s) +{ + eat_ws(); + + ::std::string rv; + char c = getc(); + DEBUG("c = '"<<c<<"'"); + if( c != '"' ) + throw ::std::runtime_error("TODO: Less shit exception, item(::std::string)"); + + while(peekc() != '"') + { + char c = getc(); + if( c == '\\' ) + c = getc(); + rv.push_back(c); + } + getc(); // eat " + + DEBUG("rv = '"<<rv<<"'"); + s = rv; +} + +void Deserialiser_TextTree::start_object(const char *tag) +{ + eat_ws(); + if( tag != nullptr ) { + ::std::string s = read_tag(); + DEBUG("s == " << s); + if( s != tag ) + throw ::std::runtime_error("TODO: Less shit exception, start_object"); + } + eat_ws(); + char c = getc(); + DEBUG("c = '" << c << "' (tag = " << (tag ? tag : "-NUL-")); + if( c != '{' ) + throw ::std::runtime_error("TODO: Less shit exception, start_object"); +} +void Deserialiser_TextTree::end_object(const char *tag) +{ + eat_ws(); + char c = getc(); + DEBUG("c = '"<<c<<"'"); + if( c != '}' ) { + throw ::std::runtime_error("TODO: Less shit exception, end_object"); + } +} |