- fixed bugs and added test cases
This commit is contained in:
parent
ac6ced6fb8
commit
206e15dff7
2 changed files with 123 additions and 25 deletions
101
src/JSON.cc
101
src/JSON.cc
|
@ -93,28 +93,70 @@ JSON& JSON::operator=(JSON o) {
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
JSON& JSON::operator=(const JSON& o) {
|
JSON& JSON::operator=(const JSON& o) {
|
||||||
|
// check for self-assignment
|
||||||
|
if (&o == this) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (_type) {
|
||||||
|
case (array): {
|
||||||
|
delete static_cast<std::vector<JSON>*>(_payload);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (object): {
|
||||||
|
delete static_cast<std::map<std::string, JSON>*>(_payload);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (string): {
|
||||||
|
delete static_cast<std::string*>(_payload);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (boolean): {
|
||||||
|
delete static_cast<bool*>(_payload);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (number_int): {
|
||||||
|
delete static_cast<int*>(_payload);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (number_float): {
|
||||||
|
delete static_cast<double*>(_payload);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (null): {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_type = o._type;
|
_type = o._type;
|
||||||
switch (_type) {
|
switch (_type) {
|
||||||
case (array):
|
case (array): {
|
||||||
_payload = new std::vector<JSON>(*static_cast<std::vector<JSON>*>(o._payload));
|
_payload = new std::vector<JSON>(*static_cast<std::vector<JSON>*>(o._payload));
|
||||||
break;
|
break;
|
||||||
case (object):
|
}
|
||||||
|
case (object): {
|
||||||
_payload = new std::map<std::string, JSON>(*static_cast<std::map<std::string, JSON>*>(o._payload));
|
_payload = new std::map<std::string, JSON>(*static_cast<std::map<std::string, JSON>*>(o._payload));
|
||||||
break;
|
break;
|
||||||
case (string):
|
}
|
||||||
|
case (string): {
|
||||||
_payload = new std::string(*static_cast<std::string*>(o._payload));
|
_payload = new std::string(*static_cast<std::string*>(o._payload));
|
||||||
break;
|
break;
|
||||||
case (boolean):
|
}
|
||||||
|
case (boolean): {
|
||||||
_payload = new bool(*static_cast<bool*>(o._payload));
|
_payload = new bool(*static_cast<bool*>(o._payload));
|
||||||
break;
|
break;
|
||||||
case (number_int):
|
}
|
||||||
|
case (number_int): {
|
||||||
_payload = new int(*static_cast<int*>(o._payload));
|
_payload = new int(*static_cast<int*>(o._payload));
|
||||||
break;
|
break;
|
||||||
case (number_float):
|
}
|
||||||
|
case (number_float): {
|
||||||
_payload = new double(*static_cast<double*>(o._payload));
|
_payload = new double(*static_cast<double*>(o._payload));
|
||||||
break;
|
break;
|
||||||
case (null):
|
}
|
||||||
|
case (null): {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -124,26 +166,33 @@ JSON& JSON::operator=(const JSON& o) {
|
||||||
/// destructor
|
/// destructor
|
||||||
JSON::~JSON() {
|
JSON::~JSON() {
|
||||||
switch (_type) {
|
switch (_type) {
|
||||||
case (array):
|
case (array): {
|
||||||
delete static_cast<std::vector<JSON>*>(_payload);
|
delete static_cast<std::vector<JSON>*>(_payload);
|
||||||
break;
|
break;
|
||||||
case (object):
|
}
|
||||||
|
case (object): {
|
||||||
delete static_cast<std::map<std::string, JSON>*>(_payload);
|
delete static_cast<std::map<std::string, JSON>*>(_payload);
|
||||||
break;
|
break;
|
||||||
case (string):
|
}
|
||||||
|
case (string): {
|
||||||
delete static_cast<std::string*>(_payload);
|
delete static_cast<std::string*>(_payload);
|
||||||
break;
|
break;
|
||||||
case (boolean):
|
}
|
||||||
|
case (boolean): {
|
||||||
delete static_cast<bool*>(_payload);
|
delete static_cast<bool*>(_payload);
|
||||||
break;
|
break;
|
||||||
case (number_int):
|
}
|
||||||
|
case (number_int): {
|
||||||
delete static_cast<int*>(_payload);
|
delete static_cast<int*>(_payload);
|
||||||
break;
|
break;
|
||||||
case (number_float):
|
}
|
||||||
|
case (number_float): {
|
||||||
delete static_cast<double*>(_payload);
|
delete static_cast<double*>(_payload);
|
||||||
break;
|
break;
|
||||||
case (null):
|
}
|
||||||
|
case (null): {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -567,10 +616,6 @@ void JSON::parser::error(std::string msg) {
|
||||||
bool JSON::parser::next() {
|
bool JSON::parser::next() {
|
||||||
_current = _buffer[_pos++];
|
_current = _buffer[_pos++];
|
||||||
|
|
||||||
if (_buffer == nullptr) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// skip trailing whitespace
|
// skip trailing whitespace
|
||||||
while (std::isspace(_current)) {
|
while (std::isspace(_current)) {
|
||||||
_current = _buffer[_pos++];
|
_current = _buffer[_pos++];
|
||||||
|
@ -579,13 +624,21 @@ bool JSON::parser::next() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \todo: escaped strings
|
|
||||||
std::string JSON::parser::parseString() {
|
std::string JSON::parser::parseString() {
|
||||||
// get position of closing quote
|
// get position of closing quotes
|
||||||
const char* p = strchr(_buffer + _pos, '\"');
|
char* p = strchr(_buffer + _pos, '\"');
|
||||||
|
|
||||||
// check if quotes were found
|
// if the closing quotes are escaped (viz. *(p-1) is '\\'),
|
||||||
if (!p) {
|
// we continue looking for the "right" quotes
|
||||||
|
while (p != nullptr and * (p - 1) == '\\') {
|
||||||
|
// length of the string so far
|
||||||
|
const size_t length = p - _buffer - _pos;
|
||||||
|
// continue checking after escaped quote
|
||||||
|
p = strchr(_buffer + _pos + length + 1, '\"');
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if closing quotes were found
|
||||||
|
if (p == nullptr) {
|
||||||
error("expected '\"'");
|
error("expected '\"'");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -654,8 +707,6 @@ void JSON::parser::parse(JSON& result) {
|
||||||
error("unexpected end of file");
|
error("unexpected end of file");
|
||||||
}
|
}
|
||||||
|
|
||||||
//JSON result;
|
|
||||||
|
|
||||||
switch (_current) {
|
switch (_current) {
|
||||||
case ('{'): {
|
case ('{'): {
|
||||||
// explicitly set result to object to cope with {}
|
// explicitly set result to object to cope with {}
|
||||||
|
|
|
@ -74,6 +74,14 @@ void test_null() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void test_bool() {
|
||||||
|
JSON True = true;
|
||||||
|
JSON False = false;
|
||||||
|
|
||||||
|
bool x = True;
|
||||||
|
}
|
||||||
|
|
||||||
void test_string() {
|
void test_string() {
|
||||||
/* a string object */
|
/* a string object */
|
||||||
|
|
||||||
|
@ -135,6 +143,13 @@ void test_string() {
|
||||||
} catch (const std::exception& ex) {
|
} catch (const std::exception& ex) {
|
||||||
assert(ex.what() == std::string("cannot cast string to JSON Boolean"));
|
assert(ex.what() == std::string("cannot cast string to JSON Boolean"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// get payload
|
||||||
|
std::string* s1 = static_cast<std::string*>(a.data());
|
||||||
|
std::string s2 = a;
|
||||||
|
assert(*s1 == s2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_array() {
|
void test_array() {
|
||||||
|
@ -200,6 +215,13 @@ void test_array() {
|
||||||
std::cerr << element << '\n';
|
std::cerr << element << '\n';
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
{
|
||||||
|
// get payload
|
||||||
|
std::vector<JSON>* array = static_cast<std::vector<JSON>*>(a.data());
|
||||||
|
assert(array->size() == a.size());
|
||||||
|
assert(array->empty() == a.empty());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_streaming() {
|
void test_streaming() {
|
||||||
|
@ -224,10 +246,35 @@ void test_streaming() {
|
||||||
o >> k;
|
o >> k;
|
||||||
assert(j.toString() == k.toString());
|
assert(j.toString() == k.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check numbers
|
||||||
|
{
|
||||||
|
std::stringstream number_stream;
|
||||||
|
number_stream << "[0, -1, 1, 1.0, -1.0, 1.0e+1, 1.0e-1, 1.0E+1, 1.0E-1, -1.2345678e-12345678]";
|
||||||
|
JSON j;
|
||||||
|
j << number_stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check Unicode
|
||||||
|
{
|
||||||
|
std::stringstream unicode_stream;
|
||||||
|
unicode_stream << "[\"öäüÖÄÜß\", \"ÀÁÂÃĀĂȦ\", \"★☆→➠♥︎♦︎☁︎\"]";
|
||||||
|
JSON j;
|
||||||
|
j << unicode_stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check escaped strings
|
||||||
|
{
|
||||||
|
std::stringstream escaped_stream;
|
||||||
|
escaped_stream << "[\"\\\"Hallo\\\"\", \"\u0123\"]";
|
||||||
|
JSON j;
|
||||||
|
j << escaped_stream;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
test_null();
|
test_null();
|
||||||
|
test_bool();
|
||||||
test_string();
|
test_string();
|
||||||
test_array();
|
test_array();
|
||||||
test_streaming();
|
test_streaming();
|
||||||
|
|
Loading…
Reference in a new issue