Skip to content

Commit

Permalink
update src/main.cc example, include snippet in README.md
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielSchuette committed May 23, 2021
1 parent 3243bb6 commit 815d949
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 15 deletions.
48 changes: 39 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<p align="center">
<a href="https://github.com/DanielSchuette/SJP" alt="Contributors">
<a href="https://github.com/DanielSchuette/sjp" alt="Contributors">
<img src="https://img.shields.io/badge/version-0.1-blue" /></a>
</p>

# 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
Expand Down Expand Up @@ -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<double> 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<sjp::JsonNumber&>(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!

Expand Down
2 changes: 1 addition & 1 deletion data/test.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
}
}
}
25 changes: 20 additions & 5 deletions src/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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<double> 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<double> v;
for (size_t i = 0; i < array.size(); i++) {
sjp::JsonNumber& n = static_cast<sjp::JsonNumber&>(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<sjp::JsonNumber&>(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);

Expand Down

0 comments on commit 815d949

Please sign in to comment.