0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-11-29 10:12:39 +01:00

ircd::json: All output through the generator.

This commit is contained in:
Jason Volk 2018-03-20 14:51:58 -07:00
parent 84ede3ceac
commit 7a9bb89506
2 changed files with 70 additions and 76 deletions

View file

@ -19,11 +19,13 @@ namespace ircd::json
bool operator!(const array &); bool operator!(const array &);
size_t size(const array &); size_t size(const array &);
string_view stringify(mutable_buffer &buf, const string_view *const &begin, const string_view *const &end);
string_view stringify(mutable_buffer &buf, const std::string *const &begin, const std::string *const &end);
size_t serialized(const string_view *const &begin, const string_view *const &end); size_t serialized(const string_view *const &begin, const string_view *const &end);
size_t serialized(const std::string *const &begin, const std::string *const &end); size_t serialized(const std::string *const &begin, const std::string *const &end);
size_t serialized(const array &);
string_view stringify(mutable_buffer &buf, const string_view *const &begin, const string_view *const &end);
string_view stringify(mutable_buffer &buf, const std::string *const &begin, const std::string *const &end);
string_view stringify(mutable_buffer &, const array &);
} }
/// Lightweight interface to a JSON array string. /// Lightweight interface to a JSON array string.
@ -66,8 +68,8 @@ struct ircd::json::array
using string_view::string_view; using string_view::string_view;
template<class it> static size_t serialized(const it &b, const it &e);
template<class it> static string_view stringify(mutable_buffer &, const it &b, const it &e); template<class it> static string_view stringify(mutable_buffer &, const it &b, const it &e);
friend string_view stringify(mutable_buffer &, const array &);
friend std::ostream &operator<<(std::ostream &, const array &); friend std::ostream &operator<<(std::ostream &, const array &);
}; };

View file

@ -1044,9 +1044,8 @@ ircd::json::stringify(mutable_buffer &buf,
const object::member &member) const object::member &member)
{ {
char *const start(begin(buf)); char *const start(begin(buf));
printer(buf, printer.name, member.first); printer(buf, printer.name << printer.name_sep, member.first);
printer(buf, printer.name_sep); stringify(buf, member.second);
consume(buf, copy(buf, member.second));
return string_view { start, begin(buf) }; return string_view { start, begin(buf) };
} }
@ -1198,8 +1197,16 @@ ircd::json::stringify(mutable_buffer &buf,
return empty_array; return empty_array;
} }
consume(buf, copy(buf, string_view{v})); return array::stringify(buf, begin(v), end(v));
return string_view{v}; }
size_t
ircd::json::serialized(const array &v)
{
if(string_view{v}.empty())
return size(empty_array);
return array::serialized(begin(v), end(v));
} }
ircd::string_view ircd::string_view
@ -1214,24 +1221,22 @@ size_t
ircd::json::serialized(const std::string *const &b, ircd::json::serialized(const std::string *const &b,
const std::string *const &e) const std::string *const &e)
{ {
const size_t ret(1 + !std::distance(b, e)); return array::serialized(b, e);
return std::accumulate(b, e, ret, [] }
(auto ret, const auto &value)
{ ircd::string_view
return ret += serialized(string_view{value}) + 1; ircd::json::stringify(mutable_buffer &buf,
}); const string_view *const &b,
const string_view *const &e)
{
return array::stringify(buf, b, e);
} }
size_t size_t
ircd::json::serialized(const string_view *const &b, ircd::json::serialized(const string_view *const &b,
const string_view *const &e) const string_view *const &e)
{ {
const size_t ret(1 + !std::distance(b, e)); return array::serialized(b, e);
return std::accumulate(b, e, ret, []
(auto ret, const auto &value)
{
return ret += serialized(value) + 1;
});
} }
template<class it> template<class it>
@ -1244,11 +1249,7 @@ ircd::json::array::stringify(mutable_buffer &buf,
{ {
[](mutable_buffer &buf, const string_view &element) [](mutable_buffer &buf, const string_view &element)
{ {
if(!consume(buf, ircd::buffer::copy(buf, element))) json::stringify(buf, element);
throw print_error
{
"The JSON generator ran out of space in supplied buffer"
};
} }
}; };
@ -1259,6 +1260,19 @@ ircd::json::array::stringify(mutable_buffer &buf,
return { start, std::begin(buf) }; return { start, std::begin(buf) };
} }
template<class it>
size_t
ircd::json::array::serialized(const it &b,
const it &e)
{
const size_t ret(1 + !std::distance(b, e));
return std::accumulate(b, e, ret, []
(auto ret, const string_view &value)
{
return ret += json::serialized(value) + 1;
});
}
std::ostream & std::ostream &
ircd::json::operator<<(std::ostream &s, const array &a) ircd::json::operator<<(std::ostream &s, const array &a)
{ {
@ -1404,7 +1418,7 @@ ircd::json::stringify(mutable_buffer &buf,
case LITERAL: case LITERAL:
{ {
consume(buf, copy(buf, string_view{v})); printer(buf, printer.literal, string_view{v});
break; break;
} }
@ -1412,7 +1426,7 @@ ircd::json::stringify(mutable_buffer &buf,
{ {
if(v.serial) if(v.serial)
{ {
consume(buf, copy(buf, string_view{v})); stringify(buf, json::object{string_view{v}});
break; break;
} }
@ -1422,7 +1436,6 @@ ircd::json::stringify(mutable_buffer &buf,
break; break;
} }
//consume(buf, copy(buf, literal_null));
consume(buf, copy(buf, empty_object)); consume(buf, copy(buf, empty_object));
break; break;
} }
@ -1431,7 +1444,7 @@ ircd::json::stringify(mutable_buffer &buf,
{ {
if(v.serial) if(v.serial)
{ {
consume(buf, copy(buf, string_view{v})); stringify(buf, json::array{string_view{v}});
break; break;
} }
@ -1441,7 +1454,6 @@ ircd::json::stringify(mutable_buffer &buf,
break; break;
} }
//consume(buf, copy(buf, literal_null));
consume(buf, copy(buf, empty_array)); consume(buf, copy(buf, empty_array));
break; break;
} }
@ -1449,15 +1461,11 @@ ircd::json::stringify(mutable_buffer &buf,
case NUMBER: case NUMBER:
{ {
if(v.serial) if(v.serial)
{ printer(buf, printer.number, string_view{v});
consume(buf, copy(buf, string_view{v})); else if(v.floats)
break; consume(buf, copy(buf, lex_cast(v.floating)));
}
if(v.floats)
printer(buf, double_, v.floating);
else else
printer(buf, long_, v.integer); consume(buf, copy(buf, lex_cast(v.integer)));
break; break;
} }
@ -1491,28 +1499,27 @@ ircd::json::serialized(const value &v)
switch(v.type) switch(v.type)
{ {
case OBJECT: case OBJECT:
return v.serial? v.len : serialized(v.object, v.object + v.len); return v.serial? serialized(json::object{v}) : serialized(v.object, v.object + v.len);
case ARRAY: case ARRAY:
return v.serial? v.len : serialized(v.array, v.array + v.len); return v.serial? serialized(json::array{v}) : serialized(v.array, v.array + v.len);
case LITERAL: case LITERAL:
{
return v.serial? v.len : serialized(bool(v.integer)); return v.serial? v.len : serialized(bool(v.integer));
}
case NUMBER: case NUMBER:
{ {
thread_local char test_buffer[256];
mutable_buffer buf{test_buffer};
if(v.serial) if(v.serial)
return v.len; printer(buf, printer.number, string_view{v});
else if(v.floats)
return size(lex_cast(v.floating));
else
return size(lex_cast(v.integer));
static thread_local char test_buffer[4096]; return begin(buf) - test_buffer;
const auto test
{
stringify(mutable_buffer{test_buffer}, v)
};
return test.size();
} }
case STRING: case STRING:
@ -1563,7 +1570,7 @@ ircd::json::value::value(const value &other)
create_string(len, [&other] create_string(len, [&other]
(mutable_buffer &buffer) (mutable_buffer &buffer)
{ {
consume(buffer, copy(buffer, string_view{other})); json::stringify(buffer, string_view{other});
}); });
} }
else switch(type) else switch(type)
@ -1601,10 +1608,10 @@ ircd::json::value::value(const value &other)
if(!string) if(!string)
break; break;
create_string(len, [&other] create_string(serialized(other), [&other]
(mutable_buffer &buffer) (mutable_buffer &buffer)
{ {
copy(buffer, const_buffer{other.string, other.len}); json::stringify(buffer, other);
}); });
break; break;
} }
@ -1992,33 +1999,18 @@ ircd::json::stringify(mutable_buffer &buf,
return empty_string; return empty_string;
} }
consume(buf, copy(buf, string_view{v})); const json::value value{v};
return string_view{v}; return stringify(buf, value);
} }
size_t size_t
ircd::json::serialized(const string_view &s) ircd::json::serialized(const string_view &v)
{ {
size_t ret if(v.empty() && defined(v))
{ return 2;
s.size()
};
switch(type(s, std::nothrow)) const json::value value{v};
{ return serialized(value);
case NUMBER:
case OBJECT:
case ARRAY:
case LITERAL:
break;
case STRING:
ret += !startswith(s, '"');
ret += !endswith(s, '"');
break;
}
return ret;
} }
enum ircd::json::type enum ircd::json::type