diff --git a/space/space.cpp b/space/space.cpp index a0ca225..4a4fef2 100644 --- a/space/space.cpp +++ b/space/space.cpp @@ -748,35 +748,35 @@ std::wstring Space::to_wstr() const } -std::string Space::serialize_to_space_str() const +std::string Space::serialize_to_space_str(bool pretty_print) const { std::string str; - serialize_to_space_to(str); + serialize_to_space_to(str, pretty_print); return str; } -std::wstring Space::serialize_to_space_wstr() const +std::wstring Space::serialize_to_space_wstr(bool pretty_print) const { std::wstring str; - serialize_to_space_to(str); + serialize_to_space_to(str, pretty_print); return str; } -void Space::serialize_to_space_to(std::string & str) const +void Space::serialize_to_space_to(std::string & str, bool pretty_print) const { PT::TextStream stream; - serialize_to_space_stream(stream); + serialize_to_space_stream(stream, pretty_print); stream.to_string(str); } -void Space::serialize_to_space_to(std::wstring & str) const +void Space::serialize_to_space_to(std::wstring & str, bool pretty_print) const { PT::WTextStream stream; - serialize_to_space_stream(stream); + serialize_to_space_stream(stream, pretty_print); stream.to_string(str); } diff --git a/space/space.h b/space/space.h index 340813d..c19e7f3 100644 --- a/space/space.h +++ b/space/space.h @@ -330,52 +330,50 @@ public: - std::string serialize_to_space_str() const; - std::wstring serialize_to_space_wstr() const; - void serialize_to_space_to(std::string & str) const; - void serialize_to_space_to(std::wstring & str) const; + std::string serialize_to_space_str(bool pretty_print = false) const; + std::wstring serialize_to_space_wstr(bool pretty_print = false) const; + void serialize_to_space_to(std::string & str, bool pretty_print = false) const; + void serialize_to_space_to(std::wstring & str, bool pretty_print = false) const; template - void serialize_to_space_stream(StreamType & str) const + void serialize_to_space_stream(StreamType & str, bool pretty_print = false, bool is_main_object = true) const { - // IMPROVEME - switch(type) { case type_null: - //serialize_null(str, escape); + serialize_space_null(str); break; case type_bool: - //serialize_bool(str, escape); + serialize_space_bool(str); break; case type_long: - //serialize_long(str, escape); + serialize_space_long(str); break; case type_float: - //serialize_float(str, escape); + serialize_space_float(str); break; case type_double: - //serialize_double(str, escape); + serialize_space_double(str); break; case type_string: - //serialize_string(str, escape); + serialize_space_string(str); break; case type_wstring: - //serialize_wstring(str, escape); + serialize_space_wstring(str); break; case type_object: - //serialize_object(str, escape); + serialize_space_object(str, pretty_print, is_main_object); break; case type_table: - //serialize_table(str, escape); + serialize_space_table(str, pretty_print); break; } } @@ -387,7 +385,6 @@ public: void serialize_to_json_to(std::wstring & str) const; - template void serialize_to_json_stream(StreamType & str) const { @@ -494,6 +491,7 @@ protected: void escape_to_space_format(int c, StreamType & out) const { // IMPLEMENT ME + escape_to_json_format(c, out); } @@ -594,6 +592,183 @@ protected: } + + + template + void serialize_space_null(StreamType & str) const + { + serialize_string_buffer(L"null", str, Escape::escape_space); + } + + template + void serialize_space_bool(StreamType & str) const + { + if( value.value_bool ) + { + serialize_string_buffer(L"true", str, Escape::escape_space); + } + else + { + serialize_string_buffer(L"false", str, Escape::escape_space); + } + } + + + template + void serialize_space_long(StreamType & str) const + { + wchar_t buffer[50]; + size_t buffer_len = sizeof(buffer) / sizeof(char); + + PT::Toa(value.value_long, buffer, buffer_len); + serialize_string_buffer(buffer, str, Escape::escape_space); + } + + template + void serialize_space_float(StreamType & str) const + { + wchar_t buffer[100]; + size_t buffer_len = sizeof(buffer) / sizeof(char); + + int chars_written = std::swprintf(buffer, buffer_len, L"%e", static_cast(value.value_float)); + + if( errno == EOVERFLOW || chars_written < 0 ) + buffer[0] = 0; + + serialize_string_buffer(buffer, str, Escape::escape_space); + } + + template + void serialize_space_double(StreamType & str) const + { + wchar_t buffer[100]; + size_t buffer_len = sizeof(buffer) / sizeof(wchar_t); + + int chars_written = std::swprintf(buffer, buffer_len, L"%e", value.value_double); + + if( errno == EOVERFLOW || chars_written < 0 ) + buffer[0] = 0; + + serialize_string_buffer(buffer, str, Escape::escape_space); + } + + template + void serialize_space_string(StreamType & str) const + { + str << '"'; + serialize_string_buffer(value.value_string.c_str(), str, Escape::escape_space); + str << '"'; + } + + template + void serialize_space_wstring(StreamType & str) const + { + str << '"'; + serialize_string_buffer(value.value_wstring.c_str(), str, Escape::escape_space); + str << '"'; + } + + template + void serialize_space_object(StreamType & str, bool pretty_print, bool is_main_object) const + { + if( !is_main_object ) + { + str << '{'; + print_if(pretty_print, str, '\n'); + } + + bool is_first = true; + + for(auto & map_item : value.value_object) + { + if( !is_first ) + print_if(pretty_print, str, '\n', ','); + + bool quote_field = should_field_be_quoted(map_item.first); + + print_if(quote_field, str, '"'); + serialize_string_buffer(map_item.first.c_str(), str, Escape::escape_space); + print_if(quote_field, str, '"'); + + print_if(pretty_print, str, ' '); + str << '='; + print_if(pretty_print, str, ' '); + + map_item.second->serialize_to_space_stream(str, pretty_print, false); + is_first = false; + } + + print_if(!is_first && pretty_print, str, '\n'); + serialize_child_spaces(str, pretty_print); + + if( !is_main_object ) + { + str << '}'; + print_if(pretty_print, str, '\n'); + } + } + + + template + void serialize_child_spaces(StreamType & str, bool pretty_print) const + { + if( child_spaces && !child_spaces->empty() ) + { + print_if(pretty_print, str, '\n'); + + for(Space * child_space : *child_spaces) + { + print_if(!pretty_print, str, ' '); + + if( child_space->name && !child_space->name->empty() ) + { + bool quote_field = should_field_be_quoted(*child_space->name); + + print_if(quote_field, str, '"'); + serialize_string_buffer(child_space->name->c_str(), str, Escape::escape_space); + print_if(quote_field, str, '"'); + + str << ' '; + } + + child_space->serialize_to_space_stream(str, pretty_print, false); + print_if(pretty_print, str, '\n'); + } + } + } + + + template + void serialize_space_table(StreamType & str, bool pretty_print) const + { + bool multivalue_table = false; + bool is_first = true; + + if( value.value_table.size() > 1 ) + { + multivalue_table = true; + } + + str << '('; + print_if(pretty_print && multivalue_table, str, '\n'); + + for(Space * space : value.value_table) + { + if( !is_first ) + print_if(pretty_print, str, '\n', ','); + + space->serialize_to_space_stream(str, pretty_print, false); + is_first = false; + } + + print_if(pretty_print && multivalue_table, str, '\n'); + str << ')'; + } + + + + + template void serialize_json_null(StreamType & str) const { @@ -719,6 +894,7 @@ public: ///////////////////////////// remove me + template void Serialize(Stream & out, bool use_indents = false, bool use_comments = false, int level = 0) const { @@ -748,6 +924,44 @@ public: protected: + template + bool should_field_be_quoted(StringType & str) const + { + if( str.empty() ) + return true; + + for(size_t i = 0 ; i < str.size() ; ++i) + { + int c = str[i]; + + // '{' is used when child spaces begin + + if( c == '\n' || c == '#' || c == '=' || c == '{' || c == '}' ) + return true; + } + + return false; + } + + + + + template + void print_if(bool condition, StreamType & str, wchar_t c) const + { + if( condition ) + str << c; + } + + template + void print_if(bool condition, StreamType & str, wchar_t c1, wchar_t c2) const + { + if( condition ) + str << c1; + else + str << c2; + } + void copy_value_from(const Space & space); void copy_child_spaces_from(const Space & space);