Commit e4e97de8 authored by Norby, Tom's avatar Norby, Tom

Template and test updates.

parent c56b5004
Pipeline #95949 passed with stages
in 20 minutes and 22 seconds
......@@ -8,18 +8,19 @@
#include <sstream>
#include <vector>
#include "radixcore/value.hh"
#include "radixcore/visibility.hh"
//-----------------------------------------------------------------------------
// see www.json.org for parsing grammar
namespace radix
{
template <class JsonType>
class RADIX_PUBLIC JSONParser
template <class value_type, class array_type, class object_type>
class RADIX_PUBLIC JSONParserImpl
{
public:
//-------------------------------------------------------------------------
JSONParser()
JSONParserImpl()
{
literals[0] = "false";
literals[1] = "null";
......@@ -29,7 +30,7 @@ class RADIX_PUBLIC JSONParser
}
//-------------------------------------------------------------------------
JsonType& root() { return m_root; }
value_type& root() { return m_root; }
//-------------------------------------------------------------------------
std::string last_error()
......@@ -136,7 +137,7 @@ class RADIX_PUBLIC JSONParser
}
//-------------------------------------------------------------------------
JsonType parse_array()
value_type parse_array()
{
if (m_po >= m_text.size()) return nullptr;
if (m_text[m_po] != '[') return nullptr;
......@@ -146,11 +147,11 @@ class RADIX_PUBLIC JSONParser
size_t col_prev = m_col;
bool trailing_comma = false;
JsonType parent = JsonType(DataArray());
value_type parent = array_type();
for (; m_po < m_text.size(); m_po++, m_col++)
{
skip_whitespace();
JsonType child = parse_value();
value_type child = parse_value();
if (child.is_null())
{
if (m_last_error != "")
......@@ -168,7 +169,7 @@ class RADIX_PUBLIC JSONParser
}
else if (m_text[m_po] == ']')
break;
return JsonType();
return value_type();
}
else
{
......@@ -191,13 +192,13 @@ class RADIX_PUBLIC JSONParser
m_last_error = "invalid character '";
m_last_error += ch;
m_last_error += "' in array";
return JsonType();
return value_type();
}
}
if (m_po >= m_text.size() || m_text[m_po] != ']')
{
m_last_error = "no closing bracket ']' for array";
return JsonType();
return value_type();
}
m_po++;
m_col++;
......@@ -211,9 +212,9 @@ class RADIX_PUBLIC JSONParser
// (0|([1-9][0-9]*))
// (\.[0-9]+)?
// ([Ee][+-]?[0-9]+)?
JsonType parse_number()
value_type parse_number()
{
if (m_po >= m_text.size()) return JsonType();
if (m_po >= m_text.size()) return value_type();
size_t len = 0;
......@@ -226,7 +227,7 @@ class RADIX_PUBLIC JSONParser
if (m_po >= m_text.size())
{
m_last_error = "invalid number (no digits after -)";
return JsonType();
return value_type();
}
}
......@@ -235,7 +236,7 @@ class RADIX_PUBLIC JSONParser
if (m_po >= m_text.size() || !(ch >= '0' && m_text[m_po] <= '9'))
{
m_last_error = "invalid number (no digits)";
return JsonType();
return value_type();
}
m_po++;
m_col++;
......@@ -254,13 +255,13 @@ class RADIX_PUBLIC JSONParser
{
try
{
JsonType node =
JsonType(std::stod(std::string(&m_text[m_po - len], len)));
value_type node =
value_type(std::stod(std::string(&m_text[m_po - len], len)));
return node;
}
catch (...)
{
return JsonType();
return value_type();
}
}
ch = m_text[m_po];
......@@ -274,7 +275,7 @@ class RADIX_PUBLIC JSONParser
if (m_po >= m_text.size())
{
m_last_error = "invalid number (no digits after decimal)";
return JsonType();
return value_type();
}
ch = m_text[m_po];
size_t n_digits = 0;
......@@ -287,7 +288,7 @@ class RADIX_PUBLIC JSONParser
if (n_digits == 0)
{
m_last_error = "invalid number (no digits after decimal)";
return JsonType();
return value_type();
}
}
......@@ -300,7 +301,7 @@ class RADIX_PUBLIC JSONParser
if (m_po >= m_text.size())
{
m_last_error = "invalid number (no digits for exponent)";
return JsonType();
return value_type();
}
ch = m_text[m_po];
// [+-]?
......@@ -313,7 +314,7 @@ class RADIX_PUBLIC JSONParser
if (m_po >= m_text.size())
{
m_last_error = "invalid number (no digits for exponent)";
return JsonType();
return value_type();
}
size_t n_digits = 0;
......@@ -326,19 +327,19 @@ class RADIX_PUBLIC JSONParser
if (n_digits == 0)
{
m_last_error = "invalid number (no digits after decimal)";
return JsonType();
return value_type();
}
}
try
{
JsonType node =
JsonType(std::stod(std::string(&m_text[m_po - len], len)));
value_type node =
value_type(std::stod(std::string(&m_text[m_po - len], len)));
return node;
}
catch (...)
{
return JsonType();
return value_type();
}
}
......@@ -359,7 +360,7 @@ class RADIX_PUBLIC JSONParser
// only 3 valid literals all in lower case: false, null, true
// TODO: need to refactor code to support null return (currently it is
// treated as an error)
JsonType parse_literal()
value_type parse_literal()
{
size_t len = 0;
for (; m_po + len < m_text.size(); len++)
......@@ -375,32 +376,32 @@ class RADIX_PUBLIC JSONParser
m_col += len;
if (std::string("true") == literals[i])
{
return JsonType(true);
return value_type(true);
}
else if (std::string("false") == literals[i])
{
return JsonType(false);
return value_type(false);
}
// default to null
return JsonType();
return value_type();
}
}
m_last_error = "invalid literal";
return JsonType();
return value_type();
}
//-------------------------------------------------------------------------
JsonType parse_object()
value_type parse_object()
{
if (m_po >= m_text.size()) return JsonType();
if (m_text[m_po] != '{') return JsonType();
if (m_po >= m_text.size()) return value_type();
if (m_text[m_po] != '{') return value_type();
m_po++;
m_col++;
size_t line_prev = m_line;
size_t col_prev = m_col;
bool trailing_comma = false;
JsonType parent = JsonType(DataObject());
value_type parent = object_type();
for (; m_po < m_text.size(); m_po++, m_col++)
{
skip_whitespace();
......@@ -412,7 +413,7 @@ class RADIX_PUBLIC JSONParser
m_last_error = "trailing comma in object";
m_line = line_prev;
m_col = col_prev;
return JsonType();
return value_type();
}
break;
}
......@@ -427,7 +428,7 @@ class RADIX_PUBLIC JSONParser
m_line = line_prev;
m_col = col_prev;
}
return JsonType();
return value_type();
}
skip_whitespace();
......@@ -435,13 +436,13 @@ class RADIX_PUBLIC JSONParser
if (m_po >= m_text.size() || m_text[m_po] != ':')
{
m_last_error = "no ':' following key in object";
return JsonType();
return value_type();
}
m_po++;
m_col++;
// parse value
JsonType child = parse_value();
value_type child = parse_value();
if (child.is_null())
{
if (m_last_error == "")
......@@ -454,7 +455,7 @@ class RADIX_PUBLIC JSONParser
m_line = line_prev;
m_col = col_prev;
}
return JsonType();
return value_type();
}
else
{
......@@ -476,13 +477,13 @@ class RADIX_PUBLIC JSONParser
else
{
m_last_error = "invalid character in object";
return JsonType();
return value_type();
}
}
if (m_po >= m_text.size() || m_text[m_po] != '}')
{
m_last_error = "no closing curly bracket '}' for object";
return JsonType();
return value_type();
}
m_po++;
m_col++;
......@@ -586,19 +587,19 @@ class RADIX_PUBLIC JSONParser
}
//-------------------------------------------------------------------------
JsonType parse_string()
value_type parse_string()
{
std::string str = parse_string_contents();
if (m_last_error != "") return JsonType();
return JsonType(str);
if (m_last_error != "") return value_type();
return value_type(str);
}
//-------------------------------------------------------------------------
JsonType parse_value()
value_type parse_value()
{
skip_whitespace();
char ch = m_text[m_po];
JsonType node;
value_type node;
if (ch == '"')
node = parse_string();
else if (ch == '[')
......@@ -619,7 +620,7 @@ class RADIX_PUBLIC JSONParser
const char* literals[N_LITERALS];
size_t literal_lens[N_LITERALS];
JsonType m_root;
value_type m_root;
std::string m_text = "";
......@@ -630,5 +631,8 @@ class RADIX_PUBLIC JSONParser
std::string m_last_error = "";
};
typedef JSONParserImpl<Value, DataArray, DataObject> JSONParser;
} // namespace radix
#endif /** RADIX_RADIXCORE_JSON_HH_ */
#include "gtest/gtest.h"
#include "radixcore/json.hh"
#include "radixcore/value.hh"
#include <QDir>
using namespace radix;
......@@ -15,12 +12,10 @@ using namespace radix;
TEST(JSONParser, parse_from_file)
{
QDir workingDir(".");
{
JSONParser<Value> sunnyDay;
std::string filename =
workingDir.absoluteFilePath("testfiles/wellformed.json").toStdString();
bool success = sunnyDay.parse_from_file(filename);
JSONParser sunnyDay;
std::string filename = "testfiles/wellformed.json";
bool success = sunnyDay.parse_from_file(filename);
EXPECT_TRUE(success);
// not really an error just the null terminating at eof
......@@ -53,11 +48,9 @@ TEST(JSONParser, parse_from_file)
EXPECT_TRUE(array.at(3).to_bool());
}
{
JSONParser<Value> noFile;
std::string filename =
workingDir.absoluteFilePath("wrong_path/file_doesn't_exist.json")
.toStdString();
bool success = noFile.parse_from_file(filename);
JSONParser noFile;
std::string filename = "wrong_path/file_doesn't_exist.json";
bool success = noFile.parse_from_file(filename);
EXPECT_FALSE(success);
std::string errorMsg = noFile.last_error();
EXPECT_EQ("could not open file at line 1 column 1", errorMsg);
......@@ -68,7 +61,7 @@ TEST(JSONParser, parse_from_stream)
{
// check code paths in JSONParser class
{
JSONParser<Value> jp;
JSONParser jp;
std::string errorMsg = "";
// trailing junk
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment