diff --git a/include/ircd/json.h b/include/ircd/json.h index f2757c221..636e58b35 100644 --- a/include/ircd/json.h +++ b/include/ircd/json.h @@ -32,10 +32,10 @@ namespace ircd::json IRCD_EXCEPTION(error, type_error); IRCD_EXCEPTION(error, not_found); - struct array; - struct object; struct value; struct member; + struct object; + struct array; struct iov; enum type @@ -169,12 +169,16 @@ ircd::json::string(T&&... t) std::string ret(size, char{}); const auto buf{const_cast(ret.data())}; const auto max{ret.size() + 1}; - const auto printed { print(buf, max, std::forward(t)...) }; + #ifdef RB_DEBUG + if(unlikely(printed != ret.size())) + std::cerr << printed << " != " << ret.size() << std::endl << ret << std::endl; + #endif + assert(printed == ret.size()); return ret; } diff --git a/include/ircd/json/tuple.h b/include/ircd/json/tuple.h index ca02752ca..f247ed49c 100644 --- a/include/ircd/json/tuple.h +++ b/include/ircd/json/tuple.h @@ -914,7 +914,7 @@ template typename std::enable_if(), bool>::type defined(T&& t) { - return t != T{}; + return t != T{0}; } template @@ -926,24 +926,26 @@ serialized(const tuple &t) tuple::size() }; - std::array sizes; + std::array sizes {0}; const auto e{_member_transform_if(t, begin(sizes), end(sizes), [] - (auto&& ret, const string_view &key, auto&& val) + (auto &ret, const string_view &key, auto&& val) { if(!defined(val)) return false; - // " " : , + // " " : , ret = 1 + key.size() + 1 + 1 + serialized(val) + 1; return true; })}; // Subtract one to get the final size when an extra comma is // accumulated on non-empty objects. - const size_t overhead{2}; - auto ret{std::accumulate(begin(sizes), e, overhead)}; - ret -= e != begin(sizes); - return ret; + const auto overhead + { + 1 + std::all_of(begin(sizes), e, is_zero{}) + }; + + return std::accumulate(begin(sizes), e, size_t(overhead)); } template @@ -952,8 +954,14 @@ stringify(mutable_buffer &buf, const tuple &tuple) { std::array members; + std::sort(begin(members), end(members), [] + (const auto &a, const auto &b) + { + return a.first < b.first; + }); + const auto e{_member_transform_if(tuple, begin(members), end(members), [] - (auto&& ret, const string_view &key, auto&& val) + (auto &ret, const string_view &key, auto&& val) { if(!defined(val)) return false;