mirror of
https://github.com/qpdf/qpdf.git
synced 2024-12-22 10:58:58 +00:00
3440ea7d3c
Unparse is admittedly strange, but I'd rather be strange and consistent, and everything else in the qpdf library uses unparse to serialize. (If you're reading this, the convention of using "unparse" comes from the "clu" programming language.)
156 lines
4.3 KiB
C++
156 lines
4.3 KiB
C++
#include <qpdf/JSON.hh>
|
|
#include <qpdf/QPDFObjectHandle.hh>
|
|
#include <iostream>
|
|
#include <assert.h>
|
|
|
|
static void check(JSON& j, std::string const& exp)
|
|
{
|
|
if (exp != j.unparse())
|
|
{
|
|
std::cout << "Got " << j.unparse() << "; wanted " << exp << "\n";
|
|
}
|
|
}
|
|
|
|
static void test_main()
|
|
{
|
|
JSON jstr = JSON::makeString(
|
|
"<1>\xcf\x80<2>\xf0\x9f\xa5\x94\\\"<3>\x03\t\b\r\n<4>");
|
|
check(jstr,
|
|
"\"<1>\xcf\x80<2>\xf0\x9f\xa5\x94\\\\\\\"<3>"
|
|
"\\u0003\\t\\b\\r\\n<4>\"");
|
|
JSON jnull = JSON::makeNull();
|
|
check(jnull, "null");
|
|
JSON jarr = JSON::makeArray();
|
|
check(jarr, "[]");
|
|
JSON jstr2 = JSON::makeString("a\tb");
|
|
JSON jint = JSON::makeInt(16059);
|
|
JSON jdouble = JSON::makeReal(3.14159);
|
|
JSON jexp = JSON::makeNumber("2.1e5");
|
|
jarr.addArrayElement(jstr2);
|
|
jarr.addArrayElement(jnull);
|
|
jarr.addArrayElement(jint);
|
|
jarr.addArrayElement(jdouble);
|
|
jarr.addArrayElement(jexp);
|
|
check(jarr,
|
|
"[\n"
|
|
" \"a\\tb\",\n"
|
|
" null,\n"
|
|
" 16059,\n"
|
|
" 3.141590,\n"
|
|
" 2.1e5\n"
|
|
"]");
|
|
JSON jmap = JSON::makeDictionary();
|
|
check(jmap, "{}");
|
|
jmap.addDictionaryMember("b", jstr2);
|
|
jmap.addDictionaryMember("a", jarr);
|
|
jmap.addDictionaryMember("c\r\nd", jnull);
|
|
jmap.addDictionaryMember("yes", JSON::makeBool(false));
|
|
jmap.addDictionaryMember("no", JSON::makeBool(true));
|
|
jmap.addDictionaryMember("empty_dict", JSON::makeDictionary());
|
|
jmap.addDictionaryMember("empty_list", JSON::makeArray());
|
|
jmap.addDictionaryMember("single", JSON::makeArray()).
|
|
addArrayElement(JSON::makeInt(12));
|
|
check(jmap,
|
|
"{\n"
|
|
" \"a\": [\n"
|
|
" \"a\\tb\",\n"
|
|
" null,\n"
|
|
" 16059,\n"
|
|
" 3.141590,\n"
|
|
" 2.1e5\n"
|
|
" ],\n"
|
|
" \"b\": \"a\\tb\",\n"
|
|
" \"c\\r\\nd\": null,\n"
|
|
" \"empty_dict\": {},\n"
|
|
" \"empty_list\": [],\n"
|
|
" \"no\": true,\n"
|
|
" \"single\": [\n"
|
|
" 12\n"
|
|
" ],\n"
|
|
" \"yes\": false\n"
|
|
"}");
|
|
}
|
|
|
|
static void check_schema(JSON& obj, JSON& schema, bool exp,
|
|
std::string const& description)
|
|
{
|
|
std::list<std::string> errors;
|
|
std::cout << "--- " << description << std::endl;
|
|
assert(exp == obj.checkSchema(schema, errors));
|
|
for (std::list<std::string>::iterator iter = errors.begin();
|
|
iter != errors.end(); ++iter)
|
|
{
|
|
std::cout << *iter << std::endl;
|
|
}
|
|
std::cout << "---" << std::endl;
|
|
}
|
|
|
|
static void test_schema()
|
|
{
|
|
// Since we don't have a JSON parser, use the PDF parser as a
|
|
// shortcut for creating a complex JSON structure.
|
|
JSON schema = QPDFObjectHandle::parse(
|
|
"<<"
|
|
" /one <<"
|
|
" /a <<"
|
|
" /q (queue)"
|
|
" /r <<"
|
|
" /x (ecks)"
|
|
" /y (why)"
|
|
" >>"
|
|
" /s [ (esses) ]"
|
|
" >>"
|
|
" >>"
|
|
" /two ["
|
|
" <<"
|
|
" /goose (gander)"
|
|
" /glarp (enspliel)"
|
|
" >>"
|
|
" ]"
|
|
">>").getJSON();
|
|
JSON a = QPDFObjectHandle::parse("[(not a) (dictionary)]").getJSON();
|
|
check_schema(a, schema, false, "top-level type mismatch");
|
|
JSON b = QPDFObjectHandle::parse(
|
|
"<<"
|
|
" /one <<"
|
|
" /a <<"
|
|
" /t (oops)"
|
|
" /r ["
|
|
" /x (ecks)"
|
|
" /y (why)"
|
|
" ]"
|
|
" /s << /z (esses) >>"
|
|
" >>"
|
|
" >>"
|
|
" /two ["
|
|
" <<"
|
|
" /goose (0 gander)"
|
|
" /glarp (0 enspliel)"
|
|
" >>"
|
|
" <<"
|
|
" /goose (1 gander)"
|
|
" /flarp (1 enspliel)"
|
|
" >>"
|
|
" 2"
|
|
" [ (three) ]"
|
|
" <<"
|
|
" /goose (4 gander)"
|
|
" /glarp (4 enspliel)"
|
|
" >>"
|
|
" ]"
|
|
">>").getJSON();
|
|
check_schema(b, schema, false, "top-level type mismatch");
|
|
check_schema(a, a, false, "top-level schema array error");
|
|
check_schema(b, b, false, "lower-level schema array error");
|
|
check_schema(schema, schema, true, "pass");
|
|
}
|
|
|
|
int main()
|
|
{
|
|
test_main();
|
|
test_schema();
|
|
|
|
std::cout << "end of json tests\n";
|
|
return 0;
|
|
}
|