aboutsummaryrefslogtreecommitdiffstats
path: root/libtests
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2022-05-01 20:06:31 +0200
committerJay Berkenbilt <ejb@ql.org>2022-05-02 01:55:52 +0200
commit8d2a0eda5a76a341ae6b597f58e874d9e3bd571c (patch)
treeef5a23b3eb9115db14f37235f6b353eed50b6335 /libtests
parentf5dd63819d9f0cab89d8558b3b9c596e5056c9b7 (diff)
downloadqpdf-8d2a0eda5a76a341ae6b597f58e874d9e3bd571c.tar.zst
Add reactors to the JSON parser
Diffstat (limited to 'libtests')
-rw-r--r--libtests/json_parse.cc98
-rw-r--r--libtests/qtest/json_parse.test9
-rw-r--r--libtests/qtest/json_parse/good-01-react.out21
-rw-r--r--libtests/qtest/json_parse/good-02-react.out3
-rw-r--r--libtests/qtest/json_parse/good-03-react.out3
-rw-r--r--libtests/qtest/json_parse/good-04-react.out18
-rw-r--r--libtests/qtest/json_parse/good-05-react.out2
-rw-r--r--libtests/qtest/json_parse/good-06-react.out2
-rw-r--r--libtests/qtest/json_parse/good-07-react.out2
-rw-r--r--libtests/qtest/json_parse/good-08-react.out11
-rw-r--r--libtests/qtest/json_parse/good-09-react.out8
-rw-r--r--libtests/qtest/json_parse/good-10-react.out47
-rw-r--r--libtests/qtest/json_parse/good-10.json4
-rw-r--r--libtests/qtest/json_parse/save-10.json27
14 files changed, 250 insertions, 5 deletions
diff --git a/libtests/json_parse.cc b/libtests/json_parse.cc
index 77692eab..7f894c8d 100644
--- a/libtests/json_parse.cc
+++ b/libtests/json_parse.cc
@@ -1,21 +1,113 @@
#include <qpdf/JSON.hh>
#include <qpdf/QUtil.hh>
+#include <cstdlib>
+#include <cstring>
#include <iostream>
+#include <memory>
+
+namespace
+{
+ class Reactor: public JSON::Reactor
+ {
+ public:
+ virtual ~Reactor() = default;
+ virtual void dictionaryStart() override;
+ virtual void arrayStart() override;
+ virtual void containerEnd(JSON const& value) override;
+ virtual void topLevelScalar() override;
+ virtual bool
+ dictionaryItem(std::string const& key, JSON const& value) override;
+ virtual bool arrayItem(JSON const& value) override;
+
+ private:
+ void printItem(JSON const&);
+ };
+} // namespace
+
+void
+Reactor::dictionaryStart()
+{
+ std::cout << "dictionary start" << std::endl;
+}
+
+void
+Reactor::arrayStart()
+{
+ std::cout << "array start" << std::endl;
+}
+
+void
+Reactor::containerEnd(JSON const& value)
+{
+ std::cout << "container end: ";
+ printItem(value);
+}
+
+void
+Reactor::topLevelScalar()
+{
+ std::cout << "top-level scalar" << std::endl;
+}
+
+bool
+Reactor::dictionaryItem(std::string const& key, JSON const& value)
+{
+ std::cout << "dictionary item: " << key << " -> ";
+ printItem(value);
+ if (key == "keep") {
+ return false;
+ }
+ return true;
+}
+
+bool
+Reactor::arrayItem(JSON const& value)
+{
+ std::cout << "array item: ";
+ printItem(value);
+ std::string n;
+ if (value.getString(n) && n == "keep") {
+ return false;
+ }
+ return true;
+}
+
+void
+Reactor::printItem(JSON const& j)
+{
+ std::cout << "[" << j.getStart() << ", " << j.getEnd()
+ << "): " << j.unparse() << std::endl;
+}
+
+static void
+usage()
+{
+ std::cerr << "Usage: json_parse file [--react]" << std::endl;
+ exit(2);
+}
int
main(int argc, char* argv[])
{
- if (argc != 2) {
- std::cerr << "Usage: json_parse file" << std::endl;
+ if ((argc < 2) || (argc > 3)) {
+ usage();
return 2;
}
char const* filename = argv[1];
+ std::shared_ptr<Reactor> reactor;
+ if (argc == 3) {
+ if (strcmp(argv[2], "--react") == 0) {
+ reactor = std::make_shared<Reactor>();
+ } else {
+ usage();
+ }
+ }
try {
std::shared_ptr<char> buf;
size_t size;
QUtil::read_file_into_memory(filename, buf, size);
std::string s(buf.get(), size);
- std::cout << JSON::parse(s).unparse() << std::endl;
+ std::cout << JSON::parse(s, reactor.get()).unparse() << std::endl;
} catch (std::exception& e) {
std::cerr << "exception: " << filename << ": " << e.what() << std::endl;
return 2;
diff --git a/libtests/qtest/json_parse.test b/libtests/qtest/json_parse.test
index cdafb506..15b251cc 100644
--- a/libtests/qtest/json_parse.test
+++ b/libtests/qtest/json_parse.test
@@ -32,7 +32,7 @@ if ($^O ne 'msys')
cleanup();
-my $good = 9;
+my $good = 10;
for (my $i = 1; $i <= $good; ++$i)
{
@@ -73,6 +73,11 @@ for (my $i = 1; $i <= $good; ++$i)
{$td->FILE => "out.json"},
{$td->STRING => ""});
}
+
+ $td->runtest("good $n reactor",
+ {$td->COMMAND => "json_parse good-$n.json --react"},
+ {$td->FILE => "good-$n-react.out", $td->EXIT_STATUS => 0},
+ $td->NORMALIZE_NEWLINES);
}
my @bad = (
@@ -127,7 +132,7 @@ foreach my $d (@bad)
cleanup();
-$td->report((2 * $good) + scalar(@bad));
+$td->report((3 * $good) + scalar(@bad));
sub cleanup
{
diff --git a/libtests/qtest/json_parse/good-01-react.out b/libtests/qtest/json_parse/good-01-react.out
new file mode 100644
index 00000000..d6167a6b
--- /dev/null
+++ b/libtests/qtest/json_parse/good-01-react.out
@@ -0,0 +1,21 @@
+dictionary start
+dictionary item: a -> [6, 11): "bcd"
+array start
+dictionary item: e -> [18, 0): []
+array item: [19, 20): 1
+array item: [41, 42): 2
+array item: [44, 45): 3
+array item: [46, 47): 4
+array item: [48, 54): "five"
+dictionary start
+array item: [56, 0): {}
+dictionary item: six -> [64, 65): 7
+dictionary item: 8 -> [72, 73): 9
+container end: [56, 74): {}
+array item: [76, 80): null
+array item: [82, 86): true
+array item: [107, 112): false
+array item: [114, 134): "a\b\f\n\r\t\\\"/z"
+container end: [18, 135): []
+container end: [0, 136): {}
+{}
diff --git a/libtests/qtest/json_parse/good-02-react.out b/libtests/qtest/json_parse/good-02-react.out
new file mode 100644
index 00000000..12d1931a
--- /dev/null
+++ b/libtests/qtest/json_parse/good-02-react.out
@@ -0,0 +1,3 @@
+dictionary start
+container end: [0, 2): {}
+{}
diff --git a/libtests/qtest/json_parse/good-03-react.out b/libtests/qtest/json_parse/good-03-react.out
new file mode 100644
index 00000000..02e632b7
--- /dev/null
+++ b/libtests/qtest/json_parse/good-03-react.out
@@ -0,0 +1,3 @@
+array start
+container end: [0, 2): []
+[]
diff --git a/libtests/qtest/json_parse/good-04-react.out b/libtests/qtest/json_parse/good-04-react.out
new file mode 100644
index 00000000..bd18ccfc
--- /dev/null
+++ b/libtests/qtest/json_parse/good-04-react.out
@@ -0,0 +1,18 @@
+array start
+array start
+array item: [1, 0): []
+array start
+array item: [2, 0): []
+dictionary start
+array item: [3, 0): {}
+container end: [3, 5): {}
+container end: [2, 6): []
+dictionary start
+array item: [8, 0): {}
+dictionary start
+dictionary item: -> [13, 0): {}
+container end: [13, 15): {}
+container end: [8, 16): {}
+container end: [1, 17): []
+container end: [0, 18): []
+[]
diff --git a/libtests/qtest/json_parse/good-05-react.out b/libtests/qtest/json_parse/good-05-react.out
new file mode 100644
index 00000000..daa37173
--- /dev/null
+++ b/libtests/qtest/json_parse/good-05-react.out
@@ -0,0 +1,2 @@
+top-level scalar
+"x"
diff --git a/libtests/qtest/json_parse/good-06-react.out b/libtests/qtest/json_parse/good-06-react.out
new file mode 100644
index 00000000..adec78ee
--- /dev/null
+++ b/libtests/qtest/json_parse/good-06-react.out
@@ -0,0 +1,2 @@
+top-level scalar
+123
diff --git a/libtests/qtest/json_parse/good-07-react.out b/libtests/qtest/json_parse/good-07-react.out
new file mode 100644
index 00000000..e08bca41
--- /dev/null
+++ b/libtests/qtest/json_parse/good-07-react.out
@@ -0,0 +1,2 @@
+top-level scalar
+-123
diff --git a/libtests/qtest/json_parse/good-08-react.out b/libtests/qtest/json_parse/good-08-react.out
new file mode 100644
index 00000000..c773d585
--- /dev/null
+++ b/libtests/qtest/json_parse/good-08-react.out
@@ -0,0 +1,11 @@
+array start
+array item: [1, 2): 1
+array item: [4, 6): -2
+array item: [8, 11): 3.4
+array item: [13, 17): -5.6
+array item: [19, 23): -9e1
+array item: [25, 29): 10e2
+array item: [31, 37): 12.3e5
+array item: [39, 46): 12.6e-7
+container end: [0, 47): []
+[]
diff --git a/libtests/qtest/json_parse/good-09-react.out b/libtests/qtest/json_parse/good-09-react.out
new file mode 100644
index 00000000..edbf869b
--- /dev/null
+++ b/libtests/qtest/json_parse/good-09-react.out
@@ -0,0 +1,8 @@
+array start
+array item: [1, 7): "aπb"
+array item: [9, 23): "a\b\f\n\r\tc"
+array item: [25, 42): "aπbπc"
+array item: [44, 52): "π"
+array item: [54, 71): "a\u0018bʬc"
+container end: [0, 72): []
+[]
diff --git a/libtests/qtest/json_parse/good-10-react.out b/libtests/qtest/json_parse/good-10-react.out
new file mode 100644
index 00000000..142d95d0
--- /dev/null
+++ b/libtests/qtest/json_parse/good-10-react.out
@@ -0,0 +1,47 @@
+dictionary start
+array start
+dictionary item: a -> [9, 0): []
+array item: [10, 11): 1
+array item: [13, 14): 2
+dictionary start
+array item: [16, 0): {}
+dictionary item: x -> [22, 25): "y"
+container end: [16, 26): {}
+array item: [28, 29): 3
+dictionary start
+array item: [31, 0): {}
+dictionary item: keep -> [40, 61): "not in final output"
+container end: [31, 62): {
+ "keep": "not in final output"
+}
+container end: [9, 63): []
+array start
+dictionary item: keep -> [75, 0): []
+array item: [76, 77): 1
+array item: [79, 83): null
+array item: [85, 86): 2
+array item: [88, 93): false
+array item: [95, 101): "keep"
+array item: [103, 104): 3
+array start
+array item: [106, 0): []
+array item: [107, 113): "this"
+array item: [115, 121): "keep"
+array item: [123, 128): "not"
+array item: [130, 137): "final"
+container end: [106, 138): [
+ "keep"
+]
+container end: [75, 139): [
+ "keep"
+]
+container end: [0, 141): {
+ "keep": [
+ "keep"
+ ]
+}
+{
+ "keep": [
+ "keep"
+ ]
+}
diff --git a/libtests/qtest/json_parse/good-10.json b/libtests/qtest/json_parse/good-10.json
new file mode 100644
index 00000000..8f2d46b3
--- /dev/null
+++ b/libtests/qtest/json_parse/good-10.json
@@ -0,0 +1,4 @@
+{
+ "a": [1, 2, {"x": "y"}, 3, {"keep": "not in final output"}],
+ "keep": [1, null, 2, false, "keep", 3, ["this", "keep", "not", "final"]]
+}
diff --git a/libtests/qtest/json_parse/save-10.json b/libtests/qtest/json_parse/save-10.json
new file mode 100644
index 00000000..1b111dbd
--- /dev/null
+++ b/libtests/qtest/json_parse/save-10.json
@@ -0,0 +1,27 @@
+{
+ "a": [
+ 1,
+ 2,
+ {
+ "x": "y"
+ },
+ 3,
+ {
+ "keep": "not in final output"
+ }
+ ],
+ "keep": [
+ 1,
+ null,
+ 2,
+ false,
+ "keep",
+ 3,
+ [
+ "this",
+ "keep",
+ "not",
+ "final"
+ ]
+ ]
+}