diff --git a/README.md b/README.md
index a2c9bb9..06ae2fb 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,10 @@
-
+
-# Simple-JSON-Parser (SJP)
-`SJP` is a minimal JSON parser that (almost) fully implements the JSON spec at
+# Simple-JSON-Parser (sjp)
+`sjp` is a minimal JSON parser that (almost) fully implements the JSON spec at
[www.json.org](https://www.json.org/json-en.html). It is written in fairly
clean C++ and the interface is designed to make data from a JSON file easily
accessible without a complicated API or any extra dependencies. The following
@@ -54,16 +54,46 @@ requirement. You can verify the fact that we don't leak any allocations with
`make leak-test` (requires `valgrind`).
# Usage Example
-Take a look at `main.cc` for an example of how to use `SJP`. A
-[Makefile](./src/Makefile) is provided (again, my setup with `gcc` as the
-compiler). Run the following in the repository's base directory:
+Take a look at [`src/main.cc`](./src/main.cc) for an example of how to use
+`sjp`. A [Makefile](./src/Makefile) is provided (again, my setup with `gcc` as
+the compiler). Run `make test` to see what `sjp` can do for you.
-```bash
-make test
+Here's a snippet, taken from that file:
+
+```c++
+{
+ FILE* stream = fopen("some/file.json", "r");
+ auto logger = io::SjpLogger(*argv, stderr);
+ auto parser = sjp::Parser(stream, &logger);
+
+ sjp::Json json = parser.parse();
+ json.print(stderr); // pretty-prints the parsed JSON to a FILE*
+
+ /* Now, we can read data from the SJP::JSON object.
+ * JSONOBJECTs are accessed via OPERATOR[] and string keys.
+ */
+ sjp::JsonValue& array = json["data"]["deeply"]["nested"];
+ assert(array.get_type() == sjp::Type::Array);
+
+ std::vector v;
+ for (size_t i = 0; i < array.size(); i++) {
+ /* JSONARRAYs are accessed via OPERATOR[] and integer keys.
+ * We get a JSONVALUE&, which we must cast to the actual type before
+ * the VALUE member (that every primitive type has) can be accessed.
+ * As seen above, we can always check JSONVALUE.GET_TYPE() to
+ * dynamically validate what kind of data we've got.
+ */
+ sjp::JsonNumber& n = static_cast(array[i]);
+ v.push_back(n.value);
+ }
+}
```
+`sjp` only has a few API functions you need to know about and those are pretty
+much all demonstrated in [`src/main.cc`](./src/main.cc).
+
Since we don't link any external dependencies in, any IDE should be easily able
-to compile the code, too. When you use `SJP` as a library, simply copy `src/*`
+to compile the code, too. When you use `sjp` as a library, simply copy `src/*`
into your project and include `sjp.hh` and `io.hh` where you need the parser
and/or the `JSON` object. Yes, It is honestly __that__ easy!
diff --git a/data/test.json b/data/test.json
index d73bdfa..a6f5ed3 100644
--- a/data/test.json
+++ b/data/test.json
@@ -21,7 +21,7 @@
},
"data": {
"deeply": {
- "nested": [-0.124, 4230.0, 3.1415, 0, 1, 2, 3, 4]
+ "nested": [-0.124, 4230.0, 3.1415, 0, 1, 2, 3, 4, "a string, not a number"]
}
}
}
diff --git a/src/main.cc b/src/main.cc
index 660cc0d..7e33389 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -33,20 +33,35 @@ int main(int /*argc*/, char** argv)
auto parser = sjp::Parser(stream, &logger);
sjp::Json json = parser.parse();
- json.print(stderr);
+ json.print(stderr); // pretty-prints the parsed JSON to a FILE*
- std::vector v;
+ /* Now, we can read data from the SJP::JSON object.
+ * JSONOBJECTs are accessed via OPERATOR[] and string keys.
+ */
sjp::JsonValue& array = json["data"]["deeply"]["nested"];
assert(array.get_type() == sjp::Type::Array);
+ std::vector v;
for (size_t i = 0; i < array.size(); i++) {
- sjp::JsonNumber& n = static_cast(array[i]);
- v.push_back(n.value);
+ /* JSONARRAYs are accessed via OPERATOR[] and integer keys.
+ * We get a JSONVALUE&, which we must cast to the actual type before
+ * the VALUE member (that every primitive type has) can be accessed.
+ * As seen above, we can always check JSONVALUE.GET_TYPE() to
+ * dynamically validate what kind of data we've got.
+ */
+ sjp::JsonValue& item = array[i];
+ if (item.get_type() == sjp::Type::Number) {
+ sjp::JsonNumber& n = static_cast(item);
+ v.push_back(n.value);
+ } else {
+ logger.warn("ignoring non-number item of type `%s'",
+ item.type_to_string().c_str());
+ }
}
double s = 0.0;
std::for_each(v.begin(), v.end(), [&s](const double&d) { s += d; });
- fprintf(stderr, "%g\n", s);
+ logger.log("sum over all number items in the array: %g", s);
fclose(stream);