mirror of https://github.com/aria2/aria2
Removed unused code
parent
e83b03b2cd
commit
dc74ebeced
427
src/json.cc
427
src/json.cc
|
@ -37,441 +37,14 @@
|
|||
#include <sstream>
|
||||
|
||||
#include "array_fun.h"
|
||||
#include "DlAbortEx.h"
|
||||
#include "error_code.h"
|
||||
#include "a2functional.h"
|
||||
#include "util.h"
|
||||
#include "fmt.h"
|
||||
#include "base64.h"
|
||||
|
||||
namespace aria2 {
|
||||
|
||||
namespace json {
|
||||
|
||||
// Function prototype declaration
|
||||
namespace {
|
||||
template<typename InputIterator>
|
||||
std::pair<SharedHandle<ValueBase>, InputIterator>
|
||||
decode(InputIterator first, InputIterator last, size_t depth);
|
||||
} // namespace
|
||||
|
||||
namespace {
|
||||
const char WS[] = { 0x20, 0x09, 0x0a, 0x0d };
|
||||
const char ESCAPE_CHARS[] = { '"', '\\', '/', '\b', '\f', '\n', '\r', '\t' };
|
||||
const size_t MAX_STRUCTURE_DEPTH = 100;
|
||||
} // namespace
|
||||
|
||||
namespace {
|
||||
template<typename InputIterator>
|
||||
InputIterator skipWs(InputIterator first, InputIterator last)
|
||||
{
|
||||
while(first != last && std::find(vbegin(WS), vend(WS), *first) != vend(WS)) {
|
||||
++first;
|
||||
}
|
||||
return first;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace {
|
||||
template<typename InputIterator>
|
||||
void checkEof(InputIterator first, InputIterator last)
|
||||
{
|
||||
if(first == last) {
|
||||
throw DL_ABORT_EX2("JSON decoding failed: unexpected EOF",
|
||||
error_code::JSON_PARSE_ERROR);
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace {
|
||||
template<typename InputIterator>
|
||||
InputIterator
|
||||
decodeKeyword(InputIterator first, InputIterator last,
|
||||
const std::string& keyword)
|
||||
{
|
||||
size_t len = keyword.size();
|
||||
for(size_t i = 0; i < len; ++i) {
|
||||
checkEof(first, last);
|
||||
if(*first != keyword[i]) {
|
||||
throw DL_ABORT_EX2(fmt("JSON decoding failed: %s not found.",
|
||||
keyword.c_str()),
|
||||
error_code::JSON_PARSE_ERROR);
|
||||
}
|
||||
++first;
|
||||
}
|
||||
return first;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace {
|
||||
template<typename InputIterator>
|
||||
std::pair<SharedHandle<ValueBase>, InputIterator>
|
||||
decodeTrue(InputIterator first, InputIterator last)
|
||||
{
|
||||
first = decodeKeyword(first, last, "true");
|
||||
return std::make_pair(Bool::gTrue(), first);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace {
|
||||
template<typename InputIterator>
|
||||
std::pair<SharedHandle<ValueBase>, InputIterator>
|
||||
decodeFalse(InputIterator first, InputIterator last)
|
||||
{
|
||||
first = decodeKeyword(first, last, "false");
|
||||
return std::make_pair(Bool::gFalse(), first);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace {
|
||||
template<typename InputIterator>
|
||||
std::pair<SharedHandle<ValueBase>, InputIterator>
|
||||
decodeNull(InputIterator first, InputIterator last)
|
||||
{
|
||||
first = decodeKeyword(first, last, "null");
|
||||
return std::make_pair(Null::g(), first);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace {
|
||||
template<typename InputIterator>
|
||||
std::pair<SharedHandle<ValueBase>, InputIterator>
|
||||
decodeString(InputIterator first, InputIterator last)
|
||||
{
|
||||
// Consume first char, assuming it is '"'.
|
||||
++first;
|
||||
std::string s;
|
||||
InputIterator offset = first;
|
||||
while(first != last) {
|
||||
if(*first == '"') {
|
||||
break;
|
||||
}
|
||||
if(*first == '\\') {
|
||||
s.append(offset, first);
|
||||
++first;
|
||||
checkEof(first, last);
|
||||
if(*first == 'u') {
|
||||
++first;
|
||||
InputIterator uchars = first;
|
||||
for(int i = 0; i < 4; ++i, ++first) {
|
||||
checkEof(first, last);
|
||||
}
|
||||
checkEof(first, last);
|
||||
uint16_t codepoint = util::parseUInt(std::string(uchars, first), 16);
|
||||
if(codepoint <= 0x007fu) {
|
||||
unsigned char temp[1];
|
||||
temp[0] = static_cast<char>(codepoint);
|
||||
s.append(&temp[0], &temp[sizeof(temp)]);
|
||||
} else if(codepoint <= 0x07ffu) {
|
||||
unsigned char temp[2];
|
||||
temp[0] = 0xC0u | (codepoint >> 6);
|
||||
temp[1] = 0x80u | (codepoint & 0x003fu);
|
||||
s.append(&temp[0], &temp[sizeof(temp)]);
|
||||
} else if(in(codepoint, 0xD800u, 0xDBFFu)) {
|
||||
// surrogate pair
|
||||
if(*first != '\\' || first+1 == last ||
|
||||
*(first+1) != 'u') {
|
||||
throw DL_ABORT_EX2("JSON decoding failed: bad UTF-8 sequence.",
|
||||
error_code::JSON_PARSE_ERROR);
|
||||
}
|
||||
first += 2;
|
||||
InputIterator uchars = first;
|
||||
for(int i = 0; i < 4; ++i, ++first) {
|
||||
checkEof(first, last);
|
||||
}
|
||||
checkEof(first, last);
|
||||
uint16_t codepoint2 = util::parseUInt(std::string(uchars, first), 16);
|
||||
if(!in(codepoint2, 0xDC00u, 0xDFFFu)) {
|
||||
throw DL_ABORT_EX2("JSON decoding failed: bad UTF-8 sequence.",
|
||||
error_code::JSON_PARSE_ERROR);
|
||||
}
|
||||
uint32_t fullcodepoint = 0x010000u;
|
||||
fullcodepoint += (codepoint & 0x03FFu) << 10;
|
||||
fullcodepoint += (codepoint2 & 0x03FFu);
|
||||
unsigned char temp[4];
|
||||
temp[0] = 0xf0u | (fullcodepoint >> 18);
|
||||
temp[1] = 0x80u | ((fullcodepoint >> 12) & 0x003Fu);
|
||||
temp[2] = 0x80u | ((fullcodepoint >> 6) & 0x003Fu);
|
||||
temp[3] = 0x80u | (fullcodepoint & 0x003Fu);
|
||||
s.append(&temp[0], &temp[sizeof(temp)]);
|
||||
} else {
|
||||
unsigned char temp[3];
|
||||
temp[0] = 0xE0u | (codepoint >> 12);
|
||||
temp[1] = 0x80u | ((codepoint >> 6) & 0x003Fu);
|
||||
temp[2] = 0x80u | (codepoint & 0x003Fu);
|
||||
s.append(&temp[0], &temp[sizeof(temp)]);
|
||||
}
|
||||
offset = first;
|
||||
} else {
|
||||
if(*first == 'b') {
|
||||
s += "\b";
|
||||
} else if(*first == 'f') {
|
||||
s += "\f";
|
||||
} else if(*first == 'n') {
|
||||
s += "\n";
|
||||
} else if(*first == 'r') {
|
||||
s += "\r";
|
||||
} else if(*first == 't') {
|
||||
s += "\t";
|
||||
} else {
|
||||
s.append(first, first+1);
|
||||
}
|
||||
++first;
|
||||
offset = first;
|
||||
}
|
||||
} else {
|
||||
++first;
|
||||
}
|
||||
}
|
||||
checkEof(first, last);
|
||||
if(std::distance(offset, first) > 0) {
|
||||
s.append(offset, first);
|
||||
}
|
||||
if(!util::isUtf8(s)) {
|
||||
throw DL_ABORT_EX2("JSON decoding failed: Non UTF-8 string.",
|
||||
error_code::JSON_PARSE_ERROR);
|
||||
}
|
||||
++first;
|
||||
return std::make_pair(String::g(s), first);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace {
|
||||
template<typename InputIterator>
|
||||
void checkEmptyDigit(InputIterator first, InputIterator last)
|
||||
{
|
||||
if(std::distance(first, last) == 0) {
|
||||
throw DL_ABORT_EX2("JSON decoding failed: zero DIGIT.",
|
||||
error_code::JSON_PARSE_ERROR);
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace {
|
||||
template<typename InputIterator>
|
||||
void checkLeadingZero(InputIterator first, InputIterator last)
|
||||
{
|
||||
if(std::distance(first, last) > 2 && *first == '0') {
|
||||
throw DL_ABORT_EX2("JSON decoding failed: leading zero.",
|
||||
error_code::JSON_PARSE_ERROR);
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace {
|
||||
template<typename InputIterator>
|
||||
std::pair<SharedHandle<ValueBase>, InputIterator>
|
||||
decodeNumber(InputIterator first, InputIterator last)
|
||||
{
|
||||
std::string s;
|
||||
if(*first == '-') {
|
||||
s.append(first, first+1);
|
||||
++first;
|
||||
}
|
||||
InputIterator offset = first;
|
||||
while(first != last && in(*first, '0', '9')) {
|
||||
++first;
|
||||
}
|
||||
checkEof(first, last);
|
||||
checkEmptyDigit(offset, first);
|
||||
checkLeadingZero(offset, first);
|
||||
s.append(offset, first);
|
||||
bool fp = false;
|
||||
if(*first == '.') {
|
||||
fp = true;
|
||||
s.append(first, first+1);
|
||||
++first;
|
||||
offset = first;
|
||||
while(first != last && in(*first, '0', '9')) {
|
||||
++first;
|
||||
}
|
||||
checkEof(first, last);
|
||||
checkEmptyDigit(offset, first);
|
||||
s.append(offset, first);
|
||||
}
|
||||
if(*first == 'e') {
|
||||
fp = true;
|
||||
s.append(first, first+1);
|
||||
++first;
|
||||
checkEof(first, last);
|
||||
if(*first == '+' || *first == '-') {
|
||||
s.append(first, first+1);
|
||||
++first;
|
||||
}
|
||||
offset = first;
|
||||
while(first != last && in(*first, '0', '9')) {
|
||||
++first;
|
||||
}
|
||||
checkEof(first, last);
|
||||
checkEmptyDigit(offset, first);
|
||||
s.append(offset, first);
|
||||
}
|
||||
if(fp) {
|
||||
// Since we don't have floating point coutner part in ValueBase,
|
||||
// we just treat it as string.
|
||||
return std::make_pair(String::g(s), first);
|
||||
} else {
|
||||
Integer::ValueType val = util::parseLLInt(s);
|
||||
return std::make_pair(Integer::g(val), first);
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace {
|
||||
void checkDepth(size_t depth)
|
||||
{
|
||||
if(depth >= MAX_STRUCTURE_DEPTH) {
|
||||
throw DL_ABORT_EX2("JSON decoding failed: Structure is too deep.",
|
||||
error_code::JSON_PARSE_ERROR);
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace {
|
||||
template<typename InputIterator>
|
||||
std::pair<SharedHandle<ValueBase>, InputIterator>
|
||||
decodeArray(InputIterator first, InputIterator last, size_t depth)
|
||||
{
|
||||
checkDepth(depth);
|
||||
SharedHandle<List> list = List::g();
|
||||
// Consume first char, assuming it is '['.
|
||||
++first;
|
||||
first = skipWs(first, last);
|
||||
checkEof(first, last);
|
||||
if(*first != ']') {
|
||||
while(1) {
|
||||
std::pair<SharedHandle<ValueBase>, InputIterator>
|
||||
r = decode(first, last, depth);
|
||||
list->append(r.first);
|
||||
first = r.second;
|
||||
first = skipWs(first, last);
|
||||
if(first == last || (*first != ',' && *first != ']')) {
|
||||
throw DL_ABORT_EX2("JSON decoding failed:"
|
||||
" value-separator ',' or ']' is not found.",
|
||||
error_code::JSON_PARSE_ERROR);
|
||||
}
|
||||
if(*first == ']') {
|
||||
break;
|
||||
}
|
||||
++first;
|
||||
}
|
||||
}
|
||||
++first;
|
||||
return std::make_pair(list, first);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace {
|
||||
template<typename InputIterator>
|
||||
std::pair<SharedHandle<ValueBase>, InputIterator>
|
||||
decodeObject(InputIterator first, InputIterator last, size_t depth)
|
||||
{
|
||||
checkDepth(depth);
|
||||
SharedHandle<Dict> dict = Dict::g();
|
||||
// Consume first char, assuming it is '{'
|
||||
++first;
|
||||
first = skipWs(first, last);
|
||||
checkEof(first, last);
|
||||
if(*first != '}') {
|
||||
while(1) {
|
||||
std::pair<SharedHandle<ValueBase>, InputIterator>
|
||||
keyRet = decodeString(first, last);
|
||||
first = keyRet.second;
|
||||
first = skipWs(first, last);
|
||||
if(first == last || *first != ':') {
|
||||
throw DL_ABORT_EX2("JSON decoding failed:"
|
||||
" name-separator ':' is not found.",
|
||||
error_code::JSON_PARSE_ERROR);
|
||||
}
|
||||
++first;
|
||||
std::pair<SharedHandle<ValueBase>, InputIterator>
|
||||
valueRet = decode(first, last, depth);
|
||||
dict->put(downcast<String>(keyRet.first)->s(), valueRet.first);
|
||||
first = valueRet.second;
|
||||
first = skipWs(first, last);
|
||||
if(first == last || (*first != ',' && *first != '}')) {
|
||||
throw DL_ABORT_EX2("JSON decoding failed:"
|
||||
" value-separator ',' or '}' is not found.",
|
||||
error_code::JSON_PARSE_ERROR);
|
||||
}
|
||||
if(*first == '}') {
|
||||
break;
|
||||
}
|
||||
++first;
|
||||
first = skipWs(first, last);
|
||||
checkEof(first, last);
|
||||
}
|
||||
}
|
||||
++first;
|
||||
return std::make_pair(dict, first);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace {
|
||||
template<typename InputIterator>
|
||||
std::pair<SharedHandle<ValueBase>, InputIterator>
|
||||
decode(InputIterator first, InputIterator last, size_t depth)
|
||||
{
|
||||
first = skipWs(first, last);
|
||||
if(first == last) {
|
||||
throw DL_ABORT_EX2("JSON decoding failed:"
|
||||
" Unexpected EOF in term context.",
|
||||
error_code::JSON_PARSE_ERROR);
|
||||
}
|
||||
if(*first == '[') {
|
||||
return decodeArray(first, last, depth+1);
|
||||
} else if(*first == '{') {
|
||||
return decodeObject(first, last, depth+1);
|
||||
} else if(*first == '"') {
|
||||
return decodeString(first, last);
|
||||
} else if(*first == '-' || in(*first, '0', '9')) {
|
||||
return decodeNumber(first, last);
|
||||
} else if(*first == 't') {
|
||||
return decodeTrue(first, last);
|
||||
} else if(*first == 'f') {
|
||||
return decodeFalse(first, last);
|
||||
} else if(*first == 'n') {
|
||||
return decodeNull(first, last);
|
||||
} else {
|
||||
throw DL_ABORT_EX2("JSON decoding failed:"
|
||||
" Unexpected character in term context.",
|
||||
error_code::JSON_PARSE_ERROR);
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
template<typename InputIterator>
|
||||
SharedHandle<ValueBase> decode(InputIterator first, InputIterator last)
|
||||
{
|
||||
first = skipWs(first, last);
|
||||
if(first == last) {
|
||||
throw DL_ABORT_EX2("JSON decoding failed:"
|
||||
" Unexpected EOF in term context.",
|
||||
error_code::JSON_PARSE_ERROR);
|
||||
}
|
||||
std::pair<SharedHandle<ValueBase>, InputIterator> r;
|
||||
if(*first == '[') {
|
||||
r = decodeArray(first, last, 1);
|
||||
} else if(*first == '{') {
|
||||
r = decodeObject(first, last, 1);
|
||||
} else {
|
||||
throw DL_ABORT_EX2("JSON decoding failed:"
|
||||
" Unexpected EOF in term context.",
|
||||
error_code::JSON_PARSE_ERROR);
|
||||
}
|
||||
return r.first;
|
||||
}
|
||||
|
||||
SharedHandle<ValueBase> decode(const std::string& json)
|
||||
{
|
||||
return decode(json.begin(), json.end());
|
||||
}
|
||||
|
||||
SharedHandle<ValueBase> decode(const unsigned char* json, size_t len)
|
||||
{
|
||||
return decode(json, json+len);
|
||||
}
|
||||
|
||||
std::string jsonEscape(const std::string& s)
|
||||
{
|
||||
std::string t;
|
||||
|
|
|
@ -42,11 +42,6 @@ namespace aria2 {
|
|||
|
||||
namespace json {
|
||||
|
||||
// Parses JSON text defined in RFC4627.
|
||||
SharedHandle<ValueBase> decode(const std::string& json);
|
||||
|
||||
SharedHandle<ValueBase> decode(const unsigned char* json, size_t len);
|
||||
|
||||
std::string jsonEscape(const std::string& s);
|
||||
|
||||
template<typename OutputStream>
|
||||
|
|
396
test/JsonTest.cc
396
test/JsonTest.cc
|
@ -12,414 +12,18 @@ namespace aria2 {
|
|||
class JsonTest:public CppUnit::TestFixture {
|
||||
|
||||
CPPUNIT_TEST_SUITE(JsonTest);
|
||||
CPPUNIT_TEST(testDecode);
|
||||
CPPUNIT_TEST(testDecode_error);
|
||||
CPPUNIT_TEST(testEncode);
|
||||
CPPUNIT_TEST(testDecodeGetParams);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
private:
|
||||
|
||||
public:
|
||||
void testDecode();
|
||||
void testDecode_error();
|
||||
void testEncode();
|
||||
void testDecodeGetParams();
|
||||
};
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION( JsonTest );
|
||||
|
||||
void JsonTest::testDecode()
|
||||
{
|
||||
{
|
||||
// empty object
|
||||
SharedHandle<ValueBase> r = json::decode("{}");
|
||||
const Dict* dict = downcast<Dict>(r);
|
||||
CPPUNIT_ASSERT(dict);
|
||||
}
|
||||
{
|
||||
// empty object
|
||||
SharedHandle<ValueBase> r = json::decode("{ }");
|
||||
const Dict* dict = downcast<Dict>(r);
|
||||
CPPUNIT_ASSERT(dict);
|
||||
}
|
||||
{
|
||||
// empty array
|
||||
SharedHandle<ValueBase> r = json::decode("[]");
|
||||
const List* list = downcast<List>(r);
|
||||
CPPUNIT_ASSERT(list);
|
||||
}
|
||||
{
|
||||
// empty array
|
||||
SharedHandle<ValueBase> r = json::decode("[ ]");
|
||||
const List* list = downcast<List>(r);
|
||||
CPPUNIT_ASSERT(list);
|
||||
}
|
||||
{
|
||||
// empty string
|
||||
SharedHandle<ValueBase> r = json::decode("[\"\"]");
|
||||
const List* list = downcast<List>(r);
|
||||
CPPUNIT_ASSERT(list);
|
||||
const String* s = downcast<String>(list->get(0));
|
||||
CPPUNIT_ASSERT_EQUAL(std::string(), s->s());
|
||||
}
|
||||
{
|
||||
// string
|
||||
SharedHandle<ValueBase> r = json::decode("[\"foobar\"]");
|
||||
const List* list = downcast<List>(r);
|
||||
CPPUNIT_ASSERT(list);
|
||||
const String* s = downcast<String>(list->get(0));
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("foobar"), s->s());
|
||||
}
|
||||
{
|
||||
// string with escape
|
||||
SharedHandle<ValueBase> r = json::decode("[\"\\\\foo\\\"\\\"bar\"]");
|
||||
const List* list = downcast<List>(r);
|
||||
CPPUNIT_ASSERT(list);
|
||||
const String* s = downcast<String>(list->get(0));
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("\\foo\"\"bar"), s->s());
|
||||
}
|
||||
{
|
||||
// string with escape
|
||||
SharedHandle<ValueBase> r = json::decode("[\"foo\\\"\"]");
|
||||
const List* list = downcast<List>(r);
|
||||
CPPUNIT_ASSERT(list);
|
||||
const String* s = downcast<String>(list->get(0));
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("foo\""), s->s());
|
||||
}
|
||||
{
|
||||
// string: utf-8 1 to 3 bytes.
|
||||
SharedHandle<ValueBase> r = json::decode("[\"\\u0024\\u00A2\\u20AC\"]");
|
||||
const List* list = downcast<List>(r);
|
||||
CPPUNIT_ASSERT(list);
|
||||
const String* s = downcast<String>(list->get(0));
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("$¢€"), s->s());
|
||||
}
|
||||
{
|
||||
// string: utf-8 4 bytes
|
||||
SharedHandle<ValueBase> r = json::decode("[\"\\uD852\\uDF62\"]");
|
||||
const List* list = downcast<List>(r);
|
||||
CPPUNIT_ASSERT(list);
|
||||
const String* s = downcast<String>(list->get(0));
|
||||
const unsigned char arr[] = { 0xF0u, 0xA4u, 0xADu, 0xA2u };
|
||||
CPPUNIT_ASSERT_EQUAL(std::string(vbegin(arr), vend(arr)), s->s());
|
||||
}
|
||||
{
|
||||
// null
|
||||
SharedHandle<ValueBase> r = json::decode("[null]");
|
||||
const List* list = downcast<List>(r);
|
||||
CPPUNIT_ASSERT(list);
|
||||
const Null* s = downcast<Null>(list->get(0));
|
||||
CPPUNIT_ASSERT(s);
|
||||
}
|
||||
{
|
||||
// true, false
|
||||
SharedHandle<ValueBase> r = json::decode("[true, false]");
|
||||
const List* list = downcast<List>(r);
|
||||
CPPUNIT_ASSERT(list);
|
||||
const Bool* trueValue = downcast<Bool>(list->get(0));
|
||||
CPPUNIT_ASSERT(trueValue);
|
||||
CPPUNIT_ASSERT(trueValue->val());
|
||||
const Bool* falseValue = downcast<Bool>(list->get(1));
|
||||
CPPUNIT_ASSERT(falseValue);
|
||||
CPPUNIT_ASSERT(!falseValue->val());
|
||||
}
|
||||
{
|
||||
// object: 1 member
|
||||
SharedHandle<ValueBase> r = json::decode("{\"foo\":[\"bar\"]}");
|
||||
const Dict* dict = downcast<Dict>(r);
|
||||
CPPUNIT_ASSERT(dict);
|
||||
const List* list = downcast<List>(dict->get("foo"));
|
||||
CPPUNIT_ASSERT(list);
|
||||
const String* s = downcast<String>(list->get(0));
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("bar"), s->s());
|
||||
}
|
||||
{
|
||||
// object: 2 members
|
||||
SharedHandle<ValueBase> r = json::decode("{\"\":[\"bar\"], "
|
||||
"\"alpha\" : \"bravo\"}");
|
||||
const Dict* dict = downcast<Dict>(r);
|
||||
CPPUNIT_ASSERT(dict);
|
||||
const List* list = downcast<List>(dict->get(""));
|
||||
CPPUNIT_ASSERT(list);
|
||||
const String* s = downcast<String>(list->get(0));
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("bar"), s->s());
|
||||
const String* str = downcast<String>(dict->get("alpha"));
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("bravo"), str->s());
|
||||
}
|
||||
{
|
||||
// array: 2 values
|
||||
SharedHandle<ValueBase> r = json::decode("[\"foo\", {}]");
|
||||
const List* list = downcast<List>(r);
|
||||
CPPUNIT_ASSERT(list);
|
||||
const String* s = downcast<String>(list->get(0));
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("foo"), s->s());
|
||||
const Dict* dict = downcast<Dict>(list->get(1));
|
||||
CPPUNIT_ASSERT(dict);
|
||||
}
|
||||
{
|
||||
// Number: currently we handle floating point number as string
|
||||
SharedHandle<ValueBase> r = json::decode("[0,-1,1.2,-1.2e-10,-1e10]");
|
||||
const List* list = downcast<List>(r);
|
||||
CPPUNIT_ASSERT(list);
|
||||
const Integer* i = downcast<Integer>(list->get(0));
|
||||
CPPUNIT_ASSERT_EQUAL((Integer::ValueType)0, i->i());
|
||||
const Integer* i1 = downcast<Integer>(list->get(1));
|
||||
CPPUNIT_ASSERT_EQUAL((Integer::ValueType)-1, i1->i());
|
||||
const String* s2 = downcast<String>(list->get(2));
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("1.2"), s2->s());
|
||||
const String* s3 = downcast<String>(list->get(3));
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("-1.2e-10"), s3->s());
|
||||
const String* s4 = downcast<String>(list->get(4));
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("-1e10"), s4->s());
|
||||
}
|
||||
{
|
||||
// escape chars: ", \, /, \b, \f, \n, \r, \t
|
||||
SharedHandle<ValueBase> r =json::decode("[\"\\\"\\\\\\/\\b\\f\\n\\r\\t\"]");
|
||||
const List* list = downcast<List>(r);
|
||||
const String* s = downcast<String>(list->get(0));
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("\"\\/\b\f\n\r\t"), s->s());
|
||||
}
|
||||
{
|
||||
// string: literal + escaped chars.
|
||||
SharedHandle<ValueBase> r =
|
||||
json::decode("[\"foo\\u0024b\\u00A2\\u20ACbaz\"]");
|
||||
const List* list = downcast<List>(r);
|
||||
CPPUNIT_ASSERT(list);
|
||||
const String* s = downcast<String>(list->get(0));
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("foo$b¢€baz"), s->s());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void JsonTest::testDecode_error()
|
||||
{
|
||||
{
|
||||
try {
|
||||
// object
|
||||
SharedHandle<ValueBase> r = json::decode("{");
|
||||
CPPUNIT_FAIL("exception must be thrown.");
|
||||
} catch(RecoverableException& e) {
|
||||
// success
|
||||
}
|
||||
}
|
||||
{
|
||||
try {
|
||||
// object
|
||||
SharedHandle<ValueBase> r = json::decode("}");
|
||||
CPPUNIT_FAIL("exception must be thrown.");
|
||||
} catch(RecoverableException& e) {
|
||||
// success
|
||||
}
|
||||
}
|
||||
{
|
||||
try {
|
||||
// object
|
||||
SharedHandle<ValueBase> r = json::decode("{\"\":");
|
||||
CPPUNIT_FAIL("exception must be thrown.");
|
||||
} catch(RecoverableException& e) {
|
||||
// success
|
||||
}
|
||||
}
|
||||
{
|
||||
try {
|
||||
// object
|
||||
SharedHandle<ValueBase> r = json::decode("{\"\":\"\",");
|
||||
CPPUNIT_FAIL("exception must be thrown.");
|
||||
} catch(RecoverableException& e) {
|
||||
// success
|
||||
}
|
||||
}
|
||||
{
|
||||
try {
|
||||
// array
|
||||
SharedHandle<ValueBase> r = json::decode("[");
|
||||
CPPUNIT_FAIL("exception must be thrown.");
|
||||
} catch(RecoverableException& e) {
|
||||
// success
|
||||
}
|
||||
}
|
||||
{
|
||||
try {
|
||||
// array
|
||||
SharedHandle<ValueBase> r = json::decode("]");
|
||||
CPPUNIT_FAIL("exception must be thrown.");
|
||||
} catch(RecoverableException& e) {
|
||||
// success
|
||||
}
|
||||
}
|
||||
{
|
||||
try {
|
||||
// array
|
||||
SharedHandle<ValueBase> r = json::decode("[\"\"");
|
||||
CPPUNIT_FAIL("exception must be thrown.");
|
||||
} catch(RecoverableException& e) {
|
||||
// success
|
||||
}
|
||||
}
|
||||
{
|
||||
try {
|
||||
// array
|
||||
SharedHandle<ValueBase> r = json::decode("[\"\",");
|
||||
CPPUNIT_FAIL("exception must be thrown.");
|
||||
} catch(RecoverableException& e) {
|
||||
// success
|
||||
}
|
||||
}
|
||||
{
|
||||
try {
|
||||
// string
|
||||
SharedHandle<ValueBase> r = json::decode("[\"foo]");
|
||||
CPPUNIT_FAIL("exception must be thrown.");
|
||||
} catch(RecoverableException& e) {
|
||||
// success
|
||||
}
|
||||
}
|
||||
{
|
||||
try {
|
||||
// string
|
||||
SharedHandle<ValueBase> r = json::decode("[\"\\u\"]");
|
||||
CPPUNIT_FAIL("exception must be thrown.");
|
||||
} catch(RecoverableException& e) {
|
||||
// success
|
||||
}
|
||||
}
|
||||
{
|
||||
try {
|
||||
// string
|
||||
SharedHandle<ValueBase> r = json::decode("[\"\\u");
|
||||
CPPUNIT_FAIL("exception must be thrown.");
|
||||
} catch(RecoverableException& e) {
|
||||
// success
|
||||
}
|
||||
}
|
||||
{
|
||||
try {
|
||||
// string
|
||||
SharedHandle<ValueBase> r = json::decode("[\"\\u000\"]");
|
||||
CPPUNIT_FAIL("exception must be thrown.");
|
||||
} catch(RecoverableException& e) {
|
||||
// success
|
||||
}
|
||||
}
|
||||
{
|
||||
try {
|
||||
// string
|
||||
SharedHandle<ValueBase> r = json::decode("[\"\\u000");
|
||||
CPPUNIT_FAIL("exception must be thrown.");
|
||||
} catch(RecoverableException& e) {
|
||||
// success
|
||||
}
|
||||
}
|
||||
{
|
||||
try {
|
||||
// string
|
||||
SharedHandle<ValueBase> r = json::decode("[\"\\uD852foo\"]");
|
||||
CPPUNIT_FAIL("exception must be thrown.");
|
||||
} catch(RecoverableException& e) {
|
||||
// success
|
||||
}
|
||||
}
|
||||
{
|
||||
try {
|
||||
// string
|
||||
SharedHandle<ValueBase> r = json::decode("[\"\\uD852");
|
||||
CPPUNIT_FAIL("exception must be thrown.");
|
||||
} catch(RecoverableException& e) {
|
||||
// success
|
||||
}
|
||||
}
|
||||
{
|
||||
try {
|
||||
// string
|
||||
SharedHandle<ValueBase> r = json::decode("[\"\\uD852\\u\"]");
|
||||
CPPUNIT_FAIL("exception must be thrown.");
|
||||
} catch(RecoverableException& e) {
|
||||
// success
|
||||
}
|
||||
}
|
||||
{
|
||||
try {
|
||||
// string
|
||||
SharedHandle<ValueBase> r = json::decode("[\"\\uD852\\u");
|
||||
CPPUNIT_FAIL("exception must be thrown.");
|
||||
} catch(RecoverableException& e) {
|
||||
// success
|
||||
}
|
||||
}
|
||||
{
|
||||
try {
|
||||
// string
|
||||
SharedHandle<ValueBase> r = json::decode("[\"\\uD852\\u0000\"]");
|
||||
CPPUNIT_FAIL("exception must be thrown.");
|
||||
} catch(RecoverableException& e) {
|
||||
// success
|
||||
}
|
||||
}
|
||||
{
|
||||
try {
|
||||
// string
|
||||
SharedHandle<ValueBase> r = json::decode("[\"\\uD852\\uDF62");
|
||||
CPPUNIT_FAIL("exception must be thrown.");
|
||||
} catch(RecoverableException& e) {
|
||||
// success
|
||||
}
|
||||
}
|
||||
{
|
||||
try {
|
||||
// object
|
||||
SharedHandle<ValueBase> r = json::decode("{:\"\"}");
|
||||
CPPUNIT_FAIL("exception must be thrown.");
|
||||
} catch(RecoverableException& e) {
|
||||
// success
|
||||
}
|
||||
}
|
||||
{
|
||||
try {
|
||||
// object
|
||||
SharedHandle<ValueBase> r = json::decode("{\"foo\":}");
|
||||
CPPUNIT_FAIL("exception must be thrown.");
|
||||
} catch(RecoverableException& e) {
|
||||
// success
|
||||
}
|
||||
}
|
||||
{
|
||||
try {
|
||||
// number
|
||||
SharedHandle<ValueBase> r = json::decode("{00}");
|
||||
CPPUNIT_FAIL("exception must be thrown.");
|
||||
} catch(RecoverableException& e) {
|
||||
// success
|
||||
}
|
||||
}
|
||||
{
|
||||
try {
|
||||
// number
|
||||
SharedHandle<ValueBase> r = json::decode("{1.}");
|
||||
CPPUNIT_FAIL("exception must be thrown.");
|
||||
} catch(RecoverableException& e) {
|
||||
// success
|
||||
}
|
||||
}
|
||||
{
|
||||
try {
|
||||
// number
|
||||
SharedHandle<ValueBase> r = json::decode("{1.1e}");
|
||||
CPPUNIT_FAIL("exception must be thrown.");
|
||||
} catch(RecoverableException& e) {
|
||||
// success
|
||||
}
|
||||
}
|
||||
{
|
||||
try {
|
||||
// bool
|
||||
SharedHandle<ValueBase> r = json::decode("{t");
|
||||
CPPUNIT_FAIL("exception must be thrown.");
|
||||
} catch(RecoverableException& e) {
|
||||
// success
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JsonTest::testEncode()
|
||||
{
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue