made toAppendDelim better
[folly.git] / folly / json.cpp
index cd83b5adffb68209b8edb695a93ce14986f1aa92..f51b038b4f186891b6be8614bbc467eeded69a68 100644 (file)
@@ -256,26 +256,6 @@ private:
   serialization_opts const& opts_;
 };
 
-//////////////////////////////////////////////////////////////////////
-
-struct ParseError : std::runtime_error {
-  explicit ParseError(int line)
-    : std::runtime_error(to<std::string>("json parse error on line ", line))
-  {}
-
-  explicit ParseError(int line, std::string const& context,
-      std::string const& expected)
-    : std::runtime_error(to<std::string>("json parse error on line ", line,
-        !context.empty() ? to<std::string>(" near `", context, '\'')
-                        : "",
-        ": ", expected))
-  {}
-
-  explicit ParseError(std::string const& what)
-    : std::runtime_error("json parse error: " + what)
-  {}
-};
-
 // Wraps our input buffer with some helper functions.
 struct Input {
   explicit Input(StringPiece range, json::serialization_opts const* opts)
@@ -704,6 +684,62 @@ void escapeString(StringPiece input,
   out.push_back('\"');
 }
 
+fbstring stripComments(StringPiece jsonC) {
+  fbstring result;
+  enum class State {
+    None,
+    InString,
+    InlineComment,
+    LineComment
+  } state = State::None;
+
+  for (size_t i = 0; i < jsonC.size(); ++i) {
+    auto s = jsonC.subpiece(i);
+    switch (state) {
+      case State::None:
+        if (s.startsWith("/*")) {
+          state = State::InlineComment;
+          ++i;
+          continue;
+        } else if (s.startsWith("//")) {
+          state = State::LineComment;
+          ++i;
+          continue;
+        } else if (s.startsWith("\"")) {
+          state = State::InString;
+        }
+        result.push_back(s[0]);
+        break;
+      case State::InString:
+        if (s.startsWith("\\\"")) {
+          result.push_back(s[0]);
+          result.push_back(s[1]);
+          ++i;
+          continue;
+        } else if (s.startsWith("\"")) {
+          state = State::None;
+        }
+        result.push_back(s[0]);
+        break;
+      case State::InlineComment:
+        if (s.startsWith("*/")) {
+          state = State::None;
+          ++i;
+        }
+        break;
+      case State::LineComment:
+        if (s.startsWith("\n")) {
+          // skip the line break. It doesn't matter.
+          state = State::None;
+        }
+        break;
+      default:
+        throw std::logic_error("Unknown comment state");
+    }
+  }
+  return result;
+}
+
 }
 
 //////////////////////////////////////////////////////////////////////