Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions src/Store/Json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,18 @@

namespace ToolFramework {

bool json_encode(std::ostream& output, const std::string& datum) {
bool json_encode(std::ostream& output, const char* datum) {
output << '"';
for (char c : datum) {
if (c == '"' || c == '\\') output << '\\';
output << c;
while (*datum) {
if (*datum == '"' || *datum == '\\') output << '\\';
output << *datum;
};
output << '"';
return true;
}
};

bool json_encode(std::ostream& output, const std::string& datum) {
return json_encode(output, datum.c_str());
};

}
83 changes: 75 additions & 8 deletions src/Store/Json.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,29 +10,48 @@

namespace ToolFramework {

template <typename T, size_t N>
bool json_encode(std::ostream&, const std::array<T, N>&);

template <typename T>
bool json_encode(std::ostream&, const std::vector<T>&);

template <typename T>
bool json_encode(std::ostream&, const std::map<std::string, T>&);

template <typename T>
typename std::enable_if<std::is_arithmetic<T>::value, bool>::type
json_encode(std::ostream& output, T datum) {
output << datum;
return true;
}

bool json_encode(std::ostream& output, const char* datum);
bool json_encode(std::ostream& output, const std::string& datum);

template <typename T>
bool json_encode(std::ostream& output, const std::vector<T>& data) {
bool json_encode(std::ostream& output, const T* data, size_t size) {
output << '[';
bool comma = false;
for (const T& datum : data) {
for (size_t i = 0; i < size; ++i) {
if (comma)
output << ',';
else
comma = true;
json_encode(output, datum);
comma = true;
if (!json_encode(output, data[i])) return false;
};
output << ']';
return true;
}
};

template <typename T, size_t N>
bool json_encode(std::ostream& output, const std::array<T, N>& array) {
return json_encode(output, array.data(), array.size());
};

template <typename T>
bool json_encode(std::ostream& output, const std::vector<T>& vector) {
return json_encode(output, vector.data(), vector.size());
};

template <typename T>
bool json_encode(std::ostream& output, const std::map<std::string, T>& data) {
Expand All @@ -43,9 +62,9 @@ bool json_encode(std::ostream& output, const std::map<std::string, T>& data) {
output << ',';
else
comma = true;
json_encode(output, datum.first);
if (!json_encode(output, datum.first)) return false;
output << ':';
json_encode(output, datum.second);
if (!json_encode(output, datum.second)) return false;
};
output << '}';
return true;
Expand All @@ -59,6 +78,54 @@ bool json_encode(std::string& output, T data) {
return true;
}

namespace json_internal {

inline bool json_encode_object_slots(std::ostream& output, bool& comma) {
return true;
};

template <typename Slot, typename... Rest>
bool json_encode_object_slots(
std::ostream& output,
bool& comma,
const char* name,
const Slot& slot,
Rest... rest
) {
if (comma) output << ',';
comma = true;
output << '"' << name << '"' << ':';
if (!json_encode(output, slot)) return false;
return json_encode_object_slots(output, comma, rest...);
};

template <typename Slot, typename... Rest>
bool json_encode_object_slots(
std::ostream& output,
bool& comma,
const std::string& name,
const Slot& slot,
Rest... rest
) {
return json_encode_object_slots(output, comma, name.c_str(), slot, rest...);
};

}; // json_internal


// A helper function to write fixed-size objects
// Example: call `json_encode_object(output, "x", 42, "a", false)`
// to produce `{"x":42,"a":false}`
template <typename... Args>
bool json_encode_object(std::ostream& output, Args... args) {
output << '{';
bool comma = false;
if (!json_internal::json_encode_object_slots(output, comma, args...))
return false;
output << '}';
return true;
}

}; // ToolFramework

#endif
Loading