JSON: Migrated to Common

This commit is contained in:
Paul Beckingham 2016-03-01 01:38:13 -05:00
parent fbbf1e8860
commit b6ad3c741c
27 changed files with 1 additions and 1581 deletions

View file

@ -8,7 +8,6 @@ set (timew_SRCS Database.cpp Database.h
Extensions.cpp Extensions.h
Grammar.cpp Grammar.h
Interval.cpp Interval.h
JSON.cpp JSON.h
Lexer.cpp Lexer.h
LR0.cpp LR0.h
Rules.cpp Rules.h)

View file

@ -1,490 +0,0 @@
////////////////////////////////////////////////////////////////////////////////
//
// Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// http://www.opensource.org/licenses/mit-license.php
//
////////////////////////////////////////////////////////////////////////////////
#include <cmake.h>
#include <JSON.h>
#include <common.h>
#include <format.h>
#include <utf8.h>
const char *json_encode[] = {
"\x00", "\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07",
"\\b", "\\t", "\\n", "\x0b", "\\f", "\\r", "\x0e", "\x0f",
"\x10", "\x11", "\x12", "\x13", "\x14", "\x15", "\x16", "\x17",
"\x18", "\x19", "\x1a", "\x1b", "\x1c", "\x1d", "\x1e", "\x1f",
"\x20", "\x21", "\\\"", "\x23", "\x24", "\x25", "\x26", "\x27",
"\x28", "\x29", "\x2a", "\x2b", "\x2c", "\x2d", "\x2e", "\\/",
"\x30", "\x31", "\x32", "\x33", "\x34", "\x35", "\x36", "\x37",
"\x38", "\x39", "\x3a", "\x3b", "\x3c", "\x3d", "\x3e", "\x3f",
"\x40", "\x41", "\x42", "\x43", "\x44", "\x45", "\x46", "\x47",
"\x48", "\x49", "\x4a", "\x4b", "\x4c", "\x4d", "\x4e", "\x4f",
"\x50", "\x51", "\x52", "\x53", "\x54", "\x55", "\x56", "\x57",
"\x58", "\x59", "\x5a", "\x5b", "\\\\", "\x5d", "\x5e", "\x5f",
"\x60", "\x61", "\x62", "\x63", "\x64", "\x65", "\x66", "\x67",
"\x68", "\x69", "\x6a", "\x6b", "\x6c", "\x6d", "\x6e", "\x6f",
"\x70", "\x71", "\x72", "\x73", "\x74", "\x75", "\x76", "\x77",
"\x78", "\x79", "\x7a", "\x7b", "\x7c", "\x7d", "\x7e", "\x7f",
"\x80", "\x81", "\x82", "\x83", "\x84", "\x85", "\x86", "\x87",
"\x88", "\x89", "\x8a", "\x8b", "\x8c", "\x8d", "\x8e", "\x8f",
"\x90", "\x91", "\x92", "\x93", "\x94", "\x95", "\x96", "\x97",
"\x98", "\x99", "\x9a", "\x9b", "\x9c", "\x9d", "\x9e", "\x9f",
"\xa0", "\xa1", "\xa2", "\xa3", "\xa4", "\xa5", "\xa6", "\xa7",
"\xa8", "\xa9", "\xaa", "\xab", "\xac", "\xad", "\xae", "\xaf",
"\xb0", "\xb1", "\xb2", "\xb3", "\xb4", "\xb5", "\xb6", "\xb7",
"\xb8", "\xb9", "\xba", "\xbb", "\xbc", "\xbd", "\xbe", "\xbf",
"\xc0", "\xc1", "\xc2", "\xc3", "\xc4", "\xc5", "\xc6", "\xc7",
"\xc8", "\xc9", "\xca", "\xcb", "\xcc", "\xcd", "\xce", "\xcf",
"\xd0", "\xd1", "\xd2", "\xd3", "\xd4", "\xd5", "\xd6", "\xd7",
"\xd8", "\xd9", "\xda", "\xdb", "\xdc", "\xdd", "\xde", "\xdf",
"\xe0", "\xe1", "\xe2", "\xe3", "\xe4", "\xe5", "\xe6", "\xe7",
"\xe8", "\xe9", "\xea", "\xeb", "\xec", "\xed", "\xee", "\xef",
"\xf0", "\xf1", "\xf2", "\xf3", "\xf4", "\xf5", "\xf6", "\xf7",
"\xf8", "\xf9", "\xfa", "\xfb", "\xfc", "\xfd", "\xfe", "\xff"
};
////////////////////////////////////////////////////////////////////////////////
json::value* json::value::parse (Pig& pig)
{
json::value* v;
if ((v = json::object::parse (pig)) ||
(v = json::array::parse (pig)) ||
(v = json::string::parse (pig)) ||
(v = json::number::parse (pig)) ||
(v = json::literal::parse (pig)))
return v;
return NULL;
}
////////////////////////////////////////////////////////////////////////////////
json::jtype json::value::type ()
{
return json::j_value;
}
////////////////////////////////////////////////////////////////////////////////
std::string json::value::dump () const
{
return "<value>";
}
////////////////////////////////////////////////////////////////////////////////
json::string::string (const std::string& other)
{
_data = other;
}
////////////////////////////////////////////////////////////////////////////////
json::string* json::string::parse (Pig& pig)
{
std::string value;
if (pig.getQuoted ('"', value))
{
json::string* s = new json::string ();
s->_data = value;
return s;
}
return NULL;
}
////////////////////////////////////////////////////////////////////////////////
json::jtype json::string::type ()
{
return json::j_string;
}
////////////////////////////////////////////////////////////////////////////////
std::string json::string::dump () const
{
return std::string ("\"") + _data + "\"";
}
////////////////////////////////////////////////////////////////////////////////
json::number* json::number::parse (Pig& pig)
{
double d;
if (pig.getNumber (d))
{
json::number* s = new json::number ();
s->_dvalue = d;
return s;
}
return NULL;
}
////////////////////////////////////////////////////////////////////////////////
json::jtype json::number::type ()
{
return json::j_number;
}
////////////////////////////////////////////////////////////////////////////////
std::string json::number::dump () const
{
return format (_dvalue);
}
////////////////////////////////////////////////////////////////////////////////
json::number::operator double () const
{
return _dvalue;
}
////////////////////////////////////////////////////////////////////////////////
json::literal* json::literal::parse (Pig& pig)
{
if (pig.skipLiteral ("null"))
{
json::literal* s = new json::literal ();
s->_lvalue = nullvalue;
return s;
}
else if (pig.skipLiteral ("false"))
{
json::literal* s = new json::literal ();
s->_lvalue = falsevalue;
return s;
}
else if (pig.skipLiteral ("true"))
{
json::literal* s = new json::literal ();
s->_lvalue = truevalue;
return s;
}
return NULL;
}
////////////////////////////////////////////////////////////////////////////////
json::jtype json::literal::type ()
{
return json::j_literal;
}
////////////////////////////////////////////////////////////////////////////////
std::string json::literal::dump () const
{
if (_lvalue == nullvalue) return "null";
else if (_lvalue == falsevalue) return "false";
else return "true";
}
////////////////////////////////////////////////////////////////////////////////
json::array::~array ()
{
for (auto& i : _data)
delete i;
}
////////////////////////////////////////////////////////////////////////////////
json::array* json::array::parse (Pig& pig)
{
auto checkpoint = pig.cursor ();
pig.skipWS ();
if (pig.skip ('['))
{
pig.skipWS ();
json::array* arr = new json::array ();
json::value* value;
if ((value = json::value::parse (pig)))
{
arr->_data.push_back (value);
value = NULL; // Not a leak. Looks like a leak.
pig.skipWS ();
while (pig.skip (','))
{
pig.skipWS ();
if ((value = json::value::parse (pig)))
{
arr->_data.push_back (value);
pig.skipWS ();
}
else
{
delete arr;
throw format ("Error: missing value after ',' at position {1}", (int) pig.cursor ());
}
}
}
if (pig.skip (']'))
return arr;
else
throw format ("Error: missing ']' at position {1}", (int) pig.cursor ());
delete arr;
}
pig.restoreTo (checkpoint);
return NULL;
}
////////////////////////////////////////////////////////////////////////////////
json::jtype json::array::type ()
{
return json::j_array;
}
////////////////////////////////////////////////////////////////////////////////
std::string json::array::dump () const
{
std::string output;
output += "[";
for (auto i = _data.begin (); i != _data.end (); ++i)
{
if (i != _data.begin ())
output += ",";
output += (*i)->dump ();
}
output += "]";
return output;
}
////////////////////////////////////////////////////////////////////////////////
json::object::~object ()
{
for (auto& i : _data)
delete i.second;
}
////////////////////////////////////////////////////////////////////////////////
json::object* json::object::parse (Pig& pig)
{
auto checkpoint = pig.cursor ();
pig.skipWS ();
if (pig.skip ('{'))
{
pig.skipWS ();
json::object* obj = new json::object ();
std::string name;
json::value* value;
if (json::object::parse_pair (pig, name, value))
{
obj->_data.insert (std::pair <std::string, json::value*> (name, value));
value = NULL; // Not a leak. Looks like a leak.
pig.skipWS ();
while (pig.skip (','))
{
pig.skipWS ();
if (json::object::parse_pair (pig, name, value))
{
obj->_data.insert (std::pair <std::string, json::value*> (name, value));
pig.skipWS ();
}
else
{
delete obj;
throw format ("Error: missing value after ',' at position {1}", (int) pig.cursor ());
}
}
}
if (pig.skip ('}'))
return obj;
else
throw format ("Error: missing '}' at position {1}", (int) pig.cursor ());
delete obj;
}
pig.restoreTo (checkpoint);
return NULL;
}
////////////////////////////////////////////////////////////////////////////////
bool json::object::parse_pair (
Pig& pig,
std::string& name,
json::value*& val)
{
auto checkpoint = pig.cursor ();
if (pig.getQuoted ('"', name))
{
pig.skipWS ();
if (pig.skip (':'))
{
pig.skipWS ();
if ((val = json::value::parse (pig)))
return true;
else
throw format ("Error: missing value at position {1}", (int) pig.cursor ());
}
else
throw format ("Error: missing ':' at position {1}", (int) pig.cursor ());
}
pig.restoreTo (checkpoint);
return false;
}
////////////////////////////////////////////////////////////////////////////////
json::jtype json::object::type ()
{
return json::j_object;
}
////////////////////////////////////////////////////////////////////////////////
std::string json::object::dump () const
{
std::string output;
output += "{";
for (auto i = _data.begin (); i != _data.end (); ++i)
{
if (i != _data.begin ())
output += ",";
output += "\"" + i->first + "\":";
output += i->second->dump ();
}
output += "}";
return output;
}
////////////////////////////////////////////////////////////////////////////////
json::value* json::parse (const std::string& input)
{
json::value* root = NULL;
Pig n (input);
n.skipWS ();
if (n.peek () == '{') root = json::object::parse (n);
else if (n.peek () == '[') root = json::array::parse (n);
else
throw format ("Error: expected '{' or '[' at position {1}", (int) n.cursor ());
// Check for end condition.
n.skipWS ();
if (!n.eos ())
{
delete root;
throw format ("Error: extra characters found at position {1}", (int) n.cursor ());
}
return root;
}
////////////////////////////////////////////////////////////////////////////////
std::string json::encode (const std::string& input)
{
std::string output;
output.reserve ((input.size () * 6) / 5); // 20% increase.
auto last = input.begin ();
for (auto i = input.begin (); i != input.end (); ++i)
{
switch (*i)
{
// Simple translations.
case '"':
case '\\':
case '/':
case '\b':
case '\f':
case '\n':
case '\r':
case '\t':
output.append (last, i);
output += json_encode[(unsigned char)(*i)];
last = i + 1;
// Default NOP.
}
}
output.append (last, input.end ());
return output;
}
////////////////////////////////////////////////////////////////////////////////
std::string json::decode (const std::string& input)
{
std::string output;
output.reserve (input.size ()); // Same size.
size_t pos = 0;
while (pos < input.length ())
{
if (input[pos] == '\\')
{
++pos;
switch (input[pos])
{
// Simple translations.
case '"': output += '"'; break;
case '\\': output += '\\'; break;
case '/': output += '/'; break;
case 'b': output += '\b'; break;
case 'f': output += '\f'; break;
case 'n': output += '\n'; break;
case 'r': output += '\r'; break;
case 't': output += '\t'; break;
// Compose a UTF8 unicode character.
case 'u':
output += utf8_character (utf8_codepoint (input.substr (++pos)));
pos += 3;
break;
// If it is an unrecognized sequence, do nothing.
default:
output += '\\';
output += input[pos];
break;
}
++pos;
}
else
{
size_t next_backslash = input.find ('\\', pos);
output.append (input, pos, next_backslash - pos);
pos = next_backslash;
}
}
return output;
}
////////////////////////////////////////////////////////////////////////////////

View file

@ -1,135 +0,0 @@
////////////////////////////////////////////////////////////////////////////////
//
// Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// http://www.opensource.org/licenses/mit-license.php
//
////////////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_JSON
#define INCLUDED_JSON
#include <map>
#include <vector>
#include <string>
#include <Pig.h>
namespace json
{
enum jtype
{
j_value, // 0
j_object, // 1
j_array, // 2
j_string, // 3
j_number, // 4
j_literal // 5
};
class value
{
public:
value () {}
virtual ~value () {}
static value* parse (Pig&);
virtual jtype type ();
virtual std::string dump () const;
};
class string : public value
{
public:
string () {}
string (const std::string&);
~string () {}
static string* parse (Pig&);
jtype type ();
std::string dump () const;
public:
std::string _data;
};
class number : public value
{
public:
number () : _dvalue (0.0) {}
~number () {}
static number* parse (Pig&);
jtype type ();
std::string dump () const;
operator double () const;
public:
double _dvalue;
};
class literal : public value
{
public:
literal () : _lvalue (none) {}
~literal () {}
static literal* parse (Pig&);
jtype type ();
std::string dump () const;
public:
enum literal_value {none, nullvalue, falsevalue, truevalue};
literal_value _lvalue;
};
class array : public value
{
public:
array () {}
~array ();
static array* parse (Pig&);
jtype type ();
std::string dump () const;
public:
std::vector <value*> _data;
};
class object : public value
{
public:
object () {}
~object ();
static object* parse (Pig&);
static bool parse_pair (Pig&, std::string&, value*&);
jtype type ();
std::string dump () const;
public:
std::map <std::string, value*> _data;
};
// Parser entry point.
value* parse (const std::string&);
// Encode/decode for JSON entities.
std::string encode (const std::string&);
std::string decode (const std::string&);
}
#endif
////////////////////////////////////////////////////////////////////////////////

2
test/.gitignore vendored
View file

@ -4,5 +4,3 @@ grammar.t
lexer.t
lr0.t
rules.t
json.t
json_test

View file

@ -10,7 +10,7 @@ include_directories (${CMAKE_SOURCE_DIR}
include_directories (${CMAKE_INSTALL_PREFIX}/include)
link_directories(${CMAKE_INSTALL_PREFIX}/lib)
set (test_SRCS grammar.t json.t json_test lexer.t lr0.t rules.t)
set (test_SRCS grammar.t lexer.t lr0.t rules.t)
add_custom_target (test ./run_all --verbose
DEPENDS ${test_SRCS}

View file

@ -1,186 +0,0 @@
////////////////////////////////////////////////////////////////////////////////
//
// Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// http://www.opensource.org/licenses/mit-license.php
//
////////////////////////////////////////////////////////////////////////////////
#include <cmake.h>
#include <iostream>
#include <stdlib.h>
#include <JSON.h>
#include <test.h>
const char *positive_tests[] =
{
"{}",
" { } ",
"[]",
"{\"one\":1}",
"{\n\"one\"\n:\n1\n}\n",
" { \"one\" : 1 } ",
"{\"name\":123, \"array\":[1,2,3.4], \"object\":{\"m1\":\"v1\", \"m2\":\"v2\"}}",
"{\"name\":\"value\",\"array\":[\"one\",\"two\"],\"object\":{\"name2\":123,\"literal\":false}}",
"{\n"
"\"ticket\": { \"type\":\"add\", \"client\":\"taskwarrior 2.x\"},\n"
"\"auth\": { \"user\":\"paul\", \"org\":\"gbf\", \"key\":\".........\",\n"
" \"locale\":\"en-US\" },\n"
"\n"
"\"add\": { \"description\":\"Wash the dog\",\n"
" \"project\":\"home\",\n"
" \"due\":\"20101101T000000Z\" }\n"
"}",
"{"
"\"ticket\":{"
"\"type\":\"synch\","
"\"client\":\"taskd-test-suite 1.0\""
"},"
"\"synch\":{"
"\"user\":{"
"\"data\":["
"{"
"\"uuid\":\"11111111-1111-1111-1111-111111111111\","
"\"status\":\"pending\","
"\"description\":\"This is a test\","
"\"entry\":\"20110111T124000Z\""
"}"
"],"
"\"synch\":\"key\""
"}"
"},"
"\"auth\":{"
"\"org\":\"gbf\","
"\"user\":\"Paul Beckingham\","
"\"key\":\"K\","
"\"locale\":\"en-US\""
"}"
"}"
};
#define NUM_POSITIVE_TESTS (sizeof (positive_tests) / sizeof (positive_tests[0]))
const char *negative_tests[] =
{
"",
"{",
"}",
"[",
"]",
"foo",
"[?]"
};
#define NUM_NEGATIVE_TESTS (sizeof (negative_tests) / sizeof (negative_tests[0]))
////////////////////////////////////////////////////////////////////////////////
int main (int, char**)
{
UnitTest t (NUM_POSITIVE_TESTS + NUM_NEGATIVE_TESTS + 22);
// Ensure environment has no influence.
unsetenv ("TASKDATA");
unsetenv ("TASKRC");
// Positive tests.
for (unsigned int i = 0; i < NUM_POSITIVE_TESTS; ++i)
{
try
{
json::value* root = json::parse (positive_tests[i]);
t.ok (root, std::string ("positive: ") + positive_tests[i]);
if (root)
{
t.diag (root->dump ());
delete root;
}
}
catch (const std::string& e) { t.diag (e); }
catch (...) { t.diag ("Unknown error"); }
}
// Negative tests.
for (unsigned int i = 0; i < NUM_NEGATIVE_TESTS; ++i)
{
try
{
json::value* root = json::parse (negative_tests[i]);
t.is ((const char*) root, (const char*) NULL,
std::string ("negative: ") + negative_tests[i]);
}
catch (const std::string& e) { t.pass (e); }
catch (...) { t.fail ("Unknown error"); }
}
// Other tests.
try
{
// Regular unit tests.
t.is (json::encode ("1\b2"), "1\\b2", "json::encode slashslashb -> slashslashslashslashb");
t.is (json::decode ("1\\b2"), "1\b2", "json::decode slashslashslashslashb -> slashslashb");
t.is (json::encode ("1\n2"), "1\\n2", "json::encode slashslashn -> slashslashslashslashn");
t.is (json::decode ("1\\n2"), "1\n2", "json::decode slashslashslashslashn -> slashslashn");
t.is (json::encode ("1\r2"), "1\\r2", "json::encode slashslashr -> slashslashslashslashr");
t.is (json::decode ("1\\r2"), "1\r2", "json::decode slashslashslashslashr -> slashslashr");
t.is (json::encode ("1\t2"), "1\\t2", "json::encode slashslasht -> slashslashslashslasht");
t.is (json::decode ("1\\t2"), "1\t2", "json::decode slashslashslashslasht -> slashslasht");
t.is (json::encode ("1\\2"), "1\\\\2", "json::encode slashslash -> slashslashslashslash");
t.is (json::decode ("1\\\\2"), "1\\2", "json::decode slashslashslashslash -> slashslash");
t.is (json::encode ("1\x2"), "1\x2", "json::encode slashslashx -> slashslashx(NOP)");
t.is (json::decode ("1\x2"), "1\x2", "json::decode slashslashx -> slashslashx(NOP)");
t.is (json::encode ("1€2"), "1€2", "json::encode € -> €");
t.is (json::decode ("1\\u20ac2"), "1€2", "json::decode slashslashu20ac -> €");
std::string encoded = json::encode ("one\\");
t.is (encoded, "one\\\\", "json::encode oneslashslashslashslash -> oneslashslashslashslashslashslashslashslash");
t.is ((int)encoded.length (), 5, "json::encode oneslashslashslashslash -> length 5");
t.is (encoded[0], 'o', "json::encode oneslashslashslashslash[0] -> o");
t.is (encoded[1], 'n', "json::encode oneslashslashslashslash[1] -> n");
t.is (encoded[2], 'e', "json::encode oneslashslashslashslash[2] -> e");
t.is (encoded[3], '\\', "json::encode oneslashslashslashslash[3] -> slashslash");
t.is (encoded[4], '\\', "json::encode oneslashslashslashslash[4] -> slashslash");
t.is (json::decode (encoded), "one\\", "json::decode oneslashslashslashslashslashslashslashslash -> oneslashslashslashslash");
}
catch (const std::string& e) {t.diag (e);}
return 0;
}
////////////////////////////////////////////////////////////////////////////////

View file

@ -1,23 +0,0 @@
{
"glossary": {
"title": "example glossary",
"GlossDiv": {
"title": "S",
"GlossList": {
"GlossEntry": {
"ID": "SGML",
"SortAs": "SGML",
"GlossTerm": "Standard Generalized Markup Language",
"Acronym": "SGML",
"Abbrev": "ISO 8879:1986",
"GlossDef": {
"para": "A meta-markup language, used to create markup languages such as DocBook.",
"GlossSeeAlso": ["GML", "XML"]
},
"GlossSee": "markup"
}
}
}
}
}

View file

@ -1,11 +0,0 @@
{"menu": {
"id": "file",
"value": "File",
"popup": {
"menuitem": [
{"value": "New", "onclick": "CreateNewDoc()"},
{"value": "Open", "onclick": "OpenDoc()"},
{"value": "Close", "onclick": "CloseDoc()"}
]
}
}}

View file

@ -1,26 +0,0 @@
{"widget": {
"debug": "on",
"window": {
"title": "Sample Konfabulator Widget",
"name": "main_window",
"width": 500,
"height": 500
},
"image": {
"src": "Images/Sun.png",
"name": "sun1",
"hOffset": 250,
"vOffset": 250,
"alignment": "center"
},
"text": {
"data": "Click Here",
"size": 36,
"style": "bold",
"name": "text1",
"hOffset": 250,
"vOffset": 100,
"alignment": "center",
"onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;"
}
}}

View file

@ -1,88 +0,0 @@
{"web-app": {
"servlet": [
{
"servlet-name": "cofaxCDS",
"servlet-class": "org.cofax.cds.CDSServlet",
"init-param": {
"configGlossary:installationAt": "Philadelphia, PA",
"configGlossary:adminEmail": "ksm@pobox.com",
"configGlossary:poweredBy": "Cofax",
"configGlossary:poweredByIcon": "/images/cofax.gif",
"configGlossary:staticPath": "/content/static",
"templateProcessorClass": "org.cofax.WysiwygTemplate",
"templateLoaderClass": "org.cofax.FilesTemplateLoader",
"templatePath": "templates",
"templateOverridePath": "",
"defaultListTemplate": "listTemplate.htm",
"defaultFileTemplate": "articleTemplate.htm",
"useJSP": false,
"jspListTemplate": "listTemplate.jsp",
"jspFileTemplate": "articleTemplate.jsp",
"cachePackageTagsTrack": 200,
"cachePackageTagsStore": 200,
"cachePackageTagsRefresh": 60,
"cacheTemplatesTrack": 100,
"cacheTemplatesStore": 50,
"cacheTemplatesRefresh": 15,
"cachePagesTrack": 200,
"cachePagesStore": 100,
"cachePagesRefresh": 10,
"cachePagesDirtyRead": 10,
"searchEngineListTemplate": "forSearchEnginesList.htm",
"searchEngineFileTemplate": "forSearchEngines.htm",
"searchEngineRobotsDb": "WEB-INF/robots.db",
"useDataStore": true,
"dataStoreClass": "org.cofax.SqlDataStore",
"redirectionClass": "org.cofax.SqlRedirection",
"dataStoreName": "cofax",
"dataStoreDriver": "com.microsoft.jdbc.sqlserver.SQLServerDriver",
"dataStoreUrl": "jdbc:microsoft:sqlserver://LOCALHOST:1433;DatabaseName=goon",
"dataStoreUser": "sa",
"dataStorePassword": "dataStoreTestQuery",
"dataStoreTestQuery": "SET NOCOUNT ON;select test='test';",
"dataStoreLogFile": "/usr/local/tomcat/logs/datastore.log",
"dataStoreInitConns": 10,
"dataStoreMaxConns": 100,
"dataStoreConnUsageLimit": 100,
"dataStoreLogLevel": "debug",
"maxUrlLength": 500}},
{
"servlet-name": "cofaxEmail",
"servlet-class": "org.cofax.cds.EmailServlet",
"init-param": {
"mailHost": "mail1",
"mailHostOverride": "mail2"}},
{
"servlet-name": "cofaxAdmin",
"servlet-class": "org.cofax.cds.AdminServlet"},
{
"servlet-name": "fileServlet",
"servlet-class": "org.cofax.cds.FileServlet"},
{
"servlet-name": "cofaxTools",
"servlet-class": "org.cofax.cms.CofaxToolsServlet",
"init-param": {
"templatePath": "toolstemplates/",
"log": 1,
"logLocation": "/usr/local/tomcat/logs/CofaxTools.log",
"logMaxSize": "",
"dataLog": 1,
"dataLogLocation": "/usr/local/tomcat/logs/dataLog.log",
"dataLogMaxSize": "",
"removePageCache": "/content/admin/remove?cache=pages&id=",
"removeTemplateCache": "/content/admin/remove?cache=templates&id=",
"fileTransferFolder": "/usr/local/tomcat/webapps/content/fileTransferFolder",
"lookInContext": 1,
"adminGroupID": 4,
"betaServer": true}}],
"servlet-mapping": {
"cofaxCDS": "/",
"cofaxEmail": "/cofaxutil/aemail/*",
"cofaxAdmin": "/admin/*",
"fileServlet": "/static/*",
"cofaxTools": "/tools/*"},
"taglib": {
"taglib-uri": "cofax.tld",
"taglib-location": "/WEB-INF/tlds/cofax.tld"}}}

View file

@ -1,27 +0,0 @@
{"menu": {
"header": "SVG Viewer",
"items": [
{"id": "Open"},
{"id": "OpenNew", "label": "Open New"},
null,
{"id": "ZoomIn", "label": "Zoom In"},
{"id": "ZoomOut", "label": "Zoom Out"},
{"id": "OriginalView", "label": "Original View"},
null,
{"id": "Quality"},
{"id": "Pause"},
{"id": "Mute"},
null,
{"id": "Find", "label": "Find..."},
{"id": "FindAgain", "label": "Find Again"},
{"id": "Copy"},
{"id": "CopyAgain", "label": "Copy Again"},
{"id": "CopySVG", "label": "Copy SVG"},
{"id": "ViewSVG", "label": "View SVG"},
{"id": "ViewSource", "label": "View Source"},
{"id": "SaveAs", "label": "Save As"},
null,
{"id": "Help"},
{"id": "About", "label": "About Adobe CVG Viewer..."}
]
}}

View file

@ -1,2 +0,0 @@
[{"styleFocus":"GROWTH","creationTime":"2008-01-21","preferences":{"kfe.elite-rankings":"hide","guitarPromoClosed":"1","kfe.last_viewed_feature":"1"},"nickName":"Pascal-Louis Perez","showFlag":true,"firstName":"Pascal-Louis","points":0,"id":8,"industryFocus":"TECHNOLOGY","externalIds":[{"platform":"FACEBOOK","id":219948}],"useRealName":true,"shard":8,"concentrationFocus":"LESS_THAN_10","passwordSalt":3567830610840546163,"validatedEmails":["pascal.louis.perez@gmail.com","pascal@kaching.com","pascal@cs.stanford.edu"],"city":"Geneve","rankLevel":"BASIC","experiences":["KACHING","DEVELOPMENT","LOGIN_SYSTEM","ADMIN","RESEARCH","RANKINGS"],"marketCapFocus":"LARGE","picture":"sqr8.jpg","interests":{"MY_WALL":["EMAIL"]},"nonValidatedEmails":["pascal.loui-s.perez@gmail.com"],"showPicture":true,"lastName":"Perez","tradingFrequencyFocus":"BUY_AND_HOLD","validatedPrimaryEmail":"pascal.louis.perez@gmail.com","country":"CH","sessions":[{"d":"p","parameters":{"facebookSessionKey":"a9f133eed207196a563b0ca7-219948","facebookUserId":"219948"},"k":"qOtXSepsfrc=","platform":"FACEBOOK"},{"d":"s","k":"O7p3i91IXa8="},{"d":"s","k":"fexhG/MSXr0="},{"d":"s","k":"YUkWZMK4ors="},{"d":"s","k":"ETfFsm0svdg="}],"primaryEmail":"pascal.louis.perez@gmail.com","investmentStrategy":"Hire people who can manage my assets for me. I'm lousy.","lastLogin":"2008-12-17 12:45:25.000","portfolioId":219948}]

View file

@ -1 +0,0 @@
[ 100, 500, 300, 200, 400 ]

View file

@ -1,30 +0,0 @@
[
{
"color": "red",
"value": "#f00"
},
{
"color": "green",
"value": "#0f0"
},
{
"color": "blue",
"value": "#00f"
},
{
"color": "cyan",
"value": "#0ff"
},
{
"color": "magenta",
"value": "#f0f"
},
{
"color": "yellow",
"value": "#ff0"
},
{
"color": "black",
"value": "#000"
}
]

View file

@ -1,4 +0,0 @@
{
"color": "red",
"value": "#f00"
}

View file

@ -1,26 +0,0 @@
{
"id": "0001",
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"batters":
{
"batter":
[
{ "id": "1001", "type": "Regular" },
{ "id": "1002", "type": "Chocolate" },
{ "id": "1003", "type": "Blueberry" },
{ "id": "1004", "type": "Devil's Food" }
]
},
"topping":
[
{ "id": "5001", "type": "None" },
{ "id": "5002", "type": "Glazed" },
{ "id": "5005", "type": "Sugar" },
{ "id": "5007", "type": "Powdered Sugar" },
{ "id": "5006", "type": "Chocolate with Sprinkles" },
{ "id": "5003", "type": "Chocolate" },
{ "id": "5004", "type": "Maple" }
]
}

View file

@ -1,70 +0,0 @@
[
{
"id": "0001",
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"batters":
{
"batter":
[
{ "id": "1001", "type": "Regular" },
{ "id": "1002", "type": "Chocolate" },
{ "id": "1003", "type": "Blueberry" },
{ "id": "1004", "type": "Devil's Food" }
]
},
"topping":
[
{ "id": "5001", "type": "None" },
{ "id": "5002", "type": "Glazed" },
{ "id": "5005", "type": "Sugar" },
{ "id": "5007", "type": "Powdered Sugar" },
{ "id": "5006", "type": "Chocolate with Sprinkles" },
{ "id": "5003", "type": "Chocolate" },
{ "id": "5004", "type": "Maple" }
]
},
{
"id": "0002",
"type": "donut",
"name": "Raised",
"ppu": 0.55,
"batters":
{
"batter":
[
{ "id": "1001", "type": "Regular" }
]
},
"topping":
[
{ "id": "5001", "type": "None" },
{ "id": "5002", "type": "Glazed" },
{ "id": "5005", "type": "Sugar" },
{ "id": "5003", "type": "Chocolate" },
{ "id": "5004", "type": "Maple" }
]
},
{
"id": "0003",
"type": "donut",
"name": "Old Fashioned",
"ppu": 0.55,
"batters":
{
"batter":
[
{ "id": "1001", "type": "Regular" },
{ "id": "1002", "type": "Chocolate" }
]
},
"topping":
[
{ "id": "5001", "type": "None" },
{ "id": "5002", "type": "Glazed" },
{ "id": "5003", "type": "Chocolate" },
{ "id": "5004", "type": "Maple" }
]
}
]

View file

@ -1,17 +0,0 @@
{
"id": "0001",
"type": "donut",
"name": "Cake",
"image":
{
"url": "images/0001.jpg",
"width": 200,
"height": 200
},
"thumbnail":
{
"url": "images/thumbnails/0001.jpg",
"width": 32,
"height": 32
}
}

View file

@ -1,34 +0,0 @@
{
"items":
{
"item":
[
{
"id": "0001",
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"batters":
{
"batter":
[
{ "id": "1001", "type": "Regular" },
{ "id": "1002", "type": "Chocolate" },
{ "id": "1003", "type": "Blueberry" },
{ "id": "1004", "type": "Devil's Food" }
]
},
"topping":
[
{ "id": "5001", "type": "None" },
{ "id": "5002", "type": "Glazed" },
{ "id": "5005", "type": "Sugar" },
{ "id": "5007", "type": "Powdered Sugar" },
{ "id": "5006", "type": "Chocolate with Sprinkles" },
{ "id": "5003", "type": "Chocolate" },
{ "id": "5004", "type": "Maple" }
]
}
]
}
}

View file

@ -1,36 +0,0 @@
{
"items":
{
"item":
[
{
"id": "0001",
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"batters":
{
"batter":
[
{ "id": "1001", "type": "Regular" },
{ "id": "1002", "type": "Chocolate" },
{ "id": "1003", "type": "Blueberry" },
{ "id": "1004", "type": "Devil's Food" }
]
},
"topping":
[
{ "id": "5001", "type": "None" },
{ "id": "5002", "type": "Glazed" },
{ "id": "5005", "type": "Sugar" },
{ "id": "5007", "type": "Powdered Sugar" },
{ "id": "5006", "type": "Chocolate with Sprinkles" },
{ "id": "5003", "type": "Chocolate" },
{ "id": "5004", "type": "Maple" }
]
}
]
}
}

View file

@ -1,44 +0,0 @@
{
"data": [
{
"id": "X999_Y999",
"from": {
"name": "Tom Brady", "id": "X12"
},
"message": "Looking forward to 2010!",
"actions": [
{
"name": "Comment",
"link": "http://www.facebook.com/X999/posts/Y999"
},
{
"name": "Like",
"link": "http://www.facebook.com/X999/posts/Y999"
}
],
"type": "status",
"created_time": "2010-08-02T21:27:44+0000",
"updated_time": "2010-08-02T21:27:44+0000"
},
{
"id": "X998_Y998",
"from": {
"name": "Peyton Manning", "id": "X18"
},
"message": "Where's my contract?",
"actions": [
{
"name": "Comment",
"link": "http://www.facebook.com/X998/posts/Y998"
},
{
"name": "Like",
"link": "http://www.facebook.com/X998/posts/Y998"
}
],
"type": "status",
"created_time": "2010-08-02T21:27:44+0000",
"updated_time": "2010-08-02T21:27:44+0000"
}
]
}

View file

@ -1,21 +0,0 @@
{
"title": "Talk On Travel Pool",
"link": "http://www.flickr.com/groups/talkontravel/pool/",
"description": "Travel and vacation photos from around the world.",
"modified": "2009-02-02T11:10:27Z",
"generator": "http://www.flickr.com/",
"items": [
{
"title": "View from the hotel",
"link": "http://www.flickr.com/photos/33112458@N08/3081564649/in/pool-998875@N22",
"media": {"m":"http://farm4.static.flickr.com/3037/3081564649_4a6569750c_m.jpg"},
"date_taken": "2008-12-04T04:43:03-08:00",
"description": "<p><a href=\"http://www.flickr.com/people/33112458@N08/\"> Talk On Travel<\/a> has added a photo to the pool:<\/p> <p><a href=\"http:// www.flickr.com/photos/33112458@N08/3081564649/\" title=\"View from the hotel\"> <img src=\"http://farm4.static.flickr.com/3037/3081564649_4a6569750c_m.jpg\" width=\"240\" height=\"180\" alt=\"View from the hotel\" /><\/a><\/p> ",
"published": "2008-12-04T12:43:03Z",
"author": "nobody@flickr.com (Talk On Travel)",
"author_id": "33112458@N08",
"tags": "spain dolphins tenerife canaries lagomera aqualand playadelasamericas junglepark losgigantos loscristines talkontravel"
}
]
}

View file

@ -1,41 +0,0 @@
{
"ResultSet": {
"totalResultsAvailable": "1827221",
"totalResultsReturned": 2,
"firstResultPosition": 1,
"Result": [
{
"Title": "potato jpg",
"Summary": "Kentang Si bungsu dari keluarga Solanum tuberosum L ini ternyata memiliki khasiat untuk mengurangi kerutan jerawat bintik hitam dan kemerahan pada kulit Gunakan seminggu sekali sebagai",
"Url": "http:\/\/www.mediaindonesia.com\/spaw\/uploads\/images\/potato.jpg",
"ClickUrl": "http:\/\/www.mediaindonesia.com\/spaw\/uploads\/images\/potato.jpg",
"RefererUrl": "http:\/\/www.mediaindonesia.com\/mediaperempuan\/index.php?ar_id=Nzkw",
"FileSize": 22630,
"FileFormat": "jpeg",
"Height": "362",
"Width": "532",
"Thumbnail": {
"Url": "http:\/\/thm-a01.yimg.com\/nimage\/557094559c18f16a",
"Height": "98",
"Width": "145"
}
},
{
"Title": "potato jpg",
"Summary": "Introduction of puneri aloo This is a traditional potato preparation flavoured with curry leaves and peanuts and can be eaten on fasting day Preparation time 10 min",
"Url": "http:\/\/www.infovisual.info\/01\/photo\/potato.jpg",
"ClickUrl": "http:\/\/www.infovisual.info\/01\/photo\/potato.jpg",
"RefererUrl": "http:\/\/sundayfood.com\/puneri-aloo-indian-%20recipe",
"FileSize": 119398,
"FileFormat": "jpeg",
"Height": "685",
"Width": "1024",
"Thumbnail": {
"Url": "http:\/\/thm-a01.yimg.com\/nimage\/7fa23212efe84b64",
"Height": "107",
"Width": "160"
}
}
]
}
}

View file

@ -1,77 +0,0 @@
{
"menu": {
"header": "xProgress SVG Viewer",
"items": [
{
"id": "Open"
},
{
"id": "OpenNew",
"label": "Open New"
},
null,
{
"id": "ZoomIn",
"label": "Zoom In"
},
{
"id": "ZoomOut",
"label": "Zoom Out"
},
{
"id": "OriginalView",
"label": "Original View"
},
null,
{
"id": "Quality"
},
{
"id": "Pause"
},
{
"id": "Mute"
},
null,
{
"id": "Find",
"label": "Find..."
},
{
"id": "FindAgain",
"label": "Find Again"
},
{
"id": "Copy"
},
{
"id": "CopyAgain",
"label": "Copy Again"
},
{
"id": "CopySVG",
"label": "Copy SVG"
},
{
"id": "ViewSVG",
"label": "View SVG"
},
{
"id": "ViewSource",
"label": "View Source"
},
{
"id": "SaveAs",
"label": "Save As"
},
null,
{
"id": "Help"
},
{
"id": "About",
"label": "About xProgress CVG Viewer..."
}
]
}
}

View file

@ -1,50 +0,0 @@
{"results":[
{"text":"@twitterapi http:\/\/tinyurl.com\/ctrefg",
"to_user_id":396524,
"to_user":"TwitterAPI",
"from_user":"jkoum",
"metadata":
{
"result_type":"popular",
"recent_retweets": 109
},
"id":1478555574,
"from_user_id":1833773,
"iso_language_code":"nl",
"source":"<a href=\"http:\/\/twitter.com\/\">twitter<\/a>",
"profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/118412707\/2522215727_a5f07da155_b_normal.jpg",
"created_at":"Wed, 08 Apr 2009 19:22:10 +0000"}
],
"since_id":0,
"max_id":1480307926,
"refresh_url":"?since_id=1480307926&q=%40twitterapi",
"results_per_page":15,
"next_page":"?page=2&max_id=1480307926&q=%40twitterapi",
"completed_in":0.031704,
"page":1,
"query":"%40twitterapi"
}

View file

@ -1,53 +0,0 @@
{"apiVersion":"2.0",
"data":{
"updated":"2010-01-07T19:58:42.949Z",
"totalItems":800,
"startIndex":1,
"itemsPerPage":1,
"items":[
{"id":"hYB0mn5zh2c",
"uploaded":"2007-06-05T22:07:03.000Z",
"updated":"2010-01-07T13:26:50.000Z",
"uploader":"GoogleDeveloperDay",
"category":"News",
"title":"Google Developers Day US - Maps API Introduction",
"description":"Google Maps API Introduction ...",
"tags":[
"GDD07","GDD07US","Maps"
],
"thumbnail":{
"default":"http://i.ytimg.com/vi/hYB0mn5zh2c/default.jpg",
"hqDefault":"http://i.ytimg.com/vi/hYB0mn5zh2c/hqdefault.jpg"
},
"player":{
"default":"http://www.youtube.com/watch?v\u003dhYB0mn5zh2c"
},
"content":{
"1":"rtsp://v5.cache3.c.youtube.com/CiILENy.../0/0/0/video.3gp",
"5":"http://www.youtube.com/v/hYB0mn5zh2c?f...",
"6":"rtsp://v1.cache1.c.youtube.com/CiILENy.../0/0/0/video.3gp"
},
"duration":2840,
"aspectRatio":"widescreen",
"rating":4.63,
"ratingCount":68,
"viewCount":220101,
"favoriteCount":201,
"commentCount":22,
"status":{
"value":"restricted",
"reason":"limitedSyndication"
},
"accessControl":{
"syndicate":"allowed",
"commentVote":"allowed",
"rate":"allowed",
"list":"allowed",
"comment":"allowed",
"embed":"allowed",
"videoRespond":"moderated"
}
}
]
}
}

View file

@ -1,85 +0,0 @@
////////////////////////////////////////////////////////////////////////////////
//
// Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// http://www.opensource.org/licenses/mit-license.php
//
////////////////////////////////////////////////////////////////////////////////
#include <cmake.h>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <FS.h>
#include <JSON.h>
////////////////////////////////////////////////////////////////////////////////
int main (int argc, char** argv)
{
if (argc == 1)
{
std::cout << "\nUsage: json_test [-q] <file | JSON> ...\n"
<< "\n"
<< " -q quiet, no JSON dump\n"
<< " <file> file containing JSON\n"
<< " <JSON> JSON string, may need to be quoted\n"
<< "\n";
return 0;
}
bool quiet = false;
for (int i = 1; i < argc; ++i)
if (!strcmp (argv[i], "-q"))
quiet = true;
for (int i = 1; i < argc; ++i)
{
if (strcmp (argv[i], "-q"))
{
try
{
json::value* root;
File file (argv[i]);
if (file.exists ())
{
std::string contents;
file.read (contents);
root = json::parse (contents);
}
else
root = json::parse (argv[i]);
if (root && !quiet)
std::cout << root->dump () << "\n";
delete root;
}
catch (const std::string& e) { std::cout << e << "\n"; }
catch (...) { std::cout << "Unknown error\n"; }
}
}
return 0;
}
////////////////////////////////////////////////////////////////////////////////