aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr
diff options
context:
space:
mode:
Diffstat (limited to 'src/libexpr')
-rw-r--r--src/libexpr/value-to-json.cc55
-rw-r--r--src/libexpr/value-to-json.hh71
-rw-r--r--src/libexpr/value.hh3
3 files changed, 30 insertions, 99 deletions
diff --git a/src/libexpr/value-to-json.cc b/src/libexpr/value-to-json.cc
index 47ee324a6..72e413e44 100644
--- a/src/libexpr/value-to-json.cc
+++ b/src/libexpr/value-to-json.cc
@@ -1,4 +1,5 @@
#include "value-to-json.hh"
+#include "json.hh"
#include "eval-inline.hh"
#include "util.hh"
@@ -8,24 +9,8 @@
namespace nix {
-
-void escapeJSON(std::ostream & str, const string & s)
-{
- str << "\"";
- for (auto & i : s)
- if (i == '\"' || i == '\\') str << "\\" << i;
- else if (i == '\n') str << "\\n";
- else if (i == '\r') str << "\\r";
- else if (i == '\t') str << "\\t";
- else if (i >= 0 && i < 32)
- str << "\\u" << std::setfill('0') << std::setw(4) << std::hex << (uint16_t) i << std::dec;
- else str << i;
- str << "\"";
-}
-
-
void printValueAsJSON(EvalState & state, bool strict,
- Value & v, std::ostream & str, PathSet & context)
+ Value & v, JSONPlaceholder & out, PathSet & context)
{
checkInterrupt();
@@ -34,58 +19,58 @@ void printValueAsJSON(EvalState & state, bool strict,
switch (v.type) {
case tInt:
- str << v.integer;
+ out.write(v.integer);
break;
case tBool:
- str << (v.boolean ? "true" : "false");
+ out.write(v.boolean);
break;
case tString:
copyContext(v, context);
- escapeJSON(str, v.string.s);
+ out.write(v.string.s);
break;
case tPath:
- escapeJSON(str, state.copyPathToStore(context, v.path));
+ out.write(state.copyPathToStore(context, v.path));
break;
case tNull:
- str << "null";
+ out.write(nullptr);
break;
case tAttrs: {
Bindings::iterator i = v.attrs->find(state.sOutPath);
if (i == v.attrs->end()) {
- JSONObject json(str);
+ auto obj(out.object());
StringSet names;
for (auto & j : *v.attrs)
names.insert(j.name);
for (auto & j : names) {
Attr & a(*v.attrs->find(state.symbols.create(j)));
- json.attr(j);
- printValueAsJSON(state, strict, *a.value, str, context);
+ auto placeholder(obj.placeholder(j));
+ printValueAsJSON(state, strict, *a.value, placeholder, context);
}
} else
- printValueAsJSON(state, strict, *i->value, str, context);
+ printValueAsJSON(state, strict, *i->value, out, context);
break;
}
case tList1: case tList2: case tListN: {
- JSONList json(str);
+ auto list(out.list());
for (unsigned int n = 0; n < v.listSize(); ++n) {
- json.elem();
- printValueAsJSON(state, strict, *v.listElems()[n], str, context);
+ auto placeholder(list.placeholder());
+ printValueAsJSON(state, strict, *v.listElems()[n], placeholder, context);
}
break;
}
case tExternal:
- v.external->printValueAsJSON(state, strict, str, context);
+ v.external->printValueAsJSON(state, strict, out, context);
break;
case tFloat:
- str << v.fpoint;
+ out.write(v.fpoint);
break;
default:
@@ -93,9 +78,15 @@ void printValueAsJSON(EvalState & state, bool strict,
}
}
+void printValueAsJSON(EvalState & state, bool strict,
+ Value & v, std::ostream & str, PathSet & context)
+{
+ JSONPlaceholder out(str);
+ printValueAsJSON(state, strict, v, out, context);
+}
void ExternalValueBase::printValueAsJSON(EvalState & state, bool strict,
- std::ostream & str, PathSet & context) const
+ JSONPlaceholder & out, PathSet & context) const
{
throw TypeError(format("cannot convert %1% to JSON") % showType());
}
diff --git a/src/libexpr/value-to-json.hh b/src/libexpr/value-to-json.hh
index c59caf564..67fed6487 100644
--- a/src/libexpr/value-to-json.hh
+++ b/src/libexpr/value-to-json.hh
@@ -8,73 +8,12 @@
namespace nix {
-void printValueAsJSON(EvalState & state, bool strict,
- Value & v, std::ostream & out, PathSet & context);
-
-void escapeJSON(std::ostream & str, const string & s);
+class JSONPlaceholder;
-struct JSONObject
-{
- std::ostream & str;
- bool first;
- JSONObject(std::ostream & str) : str(str), first(true)
- {
- str << "{";
- }
- ~JSONObject()
- {
- str << "}";
- }
- void attr(const string & s)
- {
- if (!first) str << ","; else first = false;
- escapeJSON(str, s);
- str << ":";
- }
- void attr(const string & s, const string & t)
- {
- attr(s);
- escapeJSON(str, t);
- }
- void attr(const string & s, const char * t)
- {
- attr(s);
- escapeJSON(str, t);
- }
- void attr(const string & s, bool b)
- {
- attr(s);
- str << (b ? "true" : "false");
- }
- template<typename T>
- void attr(const string & s, const T & n)
- {
- attr(s);
- str << n;
- }
-};
+void printValueAsJSON(EvalState & state, bool strict,
+ Value & v, JSONPlaceholder & out, PathSet & context);
-struct JSONList
-{
- std::ostream & str;
- bool first;
- JSONList(std::ostream & str) : str(str), first(true)
- {
- str << "[";
- }
- ~JSONList()
- {
- str << "]";
- }
- void elem()
- {
- if (!first) str << ","; else first = false;
- }
- void elem(const string & s)
- {
- elem();
- escapeJSON(str, s);
- }
-};
+void printValueAsJSON(EvalState & state, bool strict,
+ Value & v, std::ostream & str, PathSet & context);
}
diff --git a/src/libexpr/value.hh b/src/libexpr/value.hh
index 62bdd9281..f5e485748 100644
--- a/src/libexpr/value.hh
+++ b/src/libexpr/value.hh
@@ -36,6 +36,7 @@ class Symbol;
struct Pos;
class EvalState;
class XMLWriter;
+class JSONPlaceholder;
typedef long NixInt;
@@ -73,7 +74,7 @@ class ExternalValueBase
/* Print the value as JSON. Defaults to unconvertable, i.e. throws an error */
virtual void printValueAsJSON(EvalState & state, bool strict,
- std::ostream & str, PathSet & context) const;
+ JSONPlaceholder & out, PathSet & context) const;
/* Print the value as XML. Defaults to unevaluated */
virtual void printValueAsXML(EvalState & state, bool strict, bool location,