|
@@ -16,6 +16,7 @@
|
|
|
|
|
|
#include <cc/data.h>
|
|
|
|
|
|
+#include <cstring>
|
|
|
#include <cassert>
|
|
|
#include <climits>
|
|
|
#include <map>
|
|
@@ -31,7 +32,7 @@
|
|
|
using namespace std;
|
|
|
|
|
|
namespace {
|
|
|
-const char* WHITESPACE = " \b\f\n\r\t";
|
|
|
+const char* const WHITESPACE = " \b\f\n\r\t";
|
|
|
} // end anonymous namespace
|
|
|
|
|
|
namespace isc {
|
|
@@ -183,7 +184,7 @@ throwJSONError(const std::string& error, const std::string& file, int line,
|
|
|
}
|
|
|
|
|
|
std::ostream&
|
|
|
-operator<<(std::ostream &out, const Element& e) {
|
|
|
+operator<<(std::ostream& out, const Element& e) {
|
|
|
return (out << e.str());
|
|
|
}
|
|
|
|
|
@@ -240,8 +241,9 @@ Element::createMap() {
|
|
|
//
|
|
|
namespace {
|
|
|
bool
|
|
|
-char_in(const char c, const char *chars) {
|
|
|
- for (size_t i = 0; i < strlen(chars); ++i) {
|
|
|
+charIn(const int c, const char* chars) {
|
|
|
+ const size_t chars_len = std::strlen(chars);
|
|
|
+ for (size_t i = 0; i < chars_len; ++i) {
|
|
|
if (chars[i] == c) {
|
|
|
return (true);
|
|
|
}
|
|
@@ -250,9 +252,9 @@ char_in(const char c, const char *chars) {
|
|
|
}
|
|
|
|
|
|
void
|
|
|
-skip_chars(std::istream &in, const char *chars, int& line, int& pos) {
|
|
|
- char c = in.peek();
|
|
|
- while (char_in(c, chars) && c != EOF) {
|
|
|
+skipChars(std::istream& in, const char* chars, int& line, int& pos) {
|
|
|
+ int c = in.peek();
|
|
|
+ while (charIn(c, chars) && c != EOF) {
|
|
|
if (c == '\n') {
|
|
|
++line;
|
|
|
pos = 1;
|
|
@@ -270,21 +272,21 @@ skip_chars(std::istream &in, const char *chars, int& line, int& pos) {
|
|
|
//
|
|
|
// the character found is left on the stream
|
|
|
void
|
|
|
-skip_to(std::istream &in, const std::string& file, int& line,
|
|
|
- int& pos, const char* chars, const char* may_skip="")
|
|
|
+skipTo(std::istream& in, const std::string& file, int& line,
|
|
|
+ int& pos, const char* chars, const char* may_skip="")
|
|
|
{
|
|
|
- char c = in.get();
|
|
|
+ int c = in.get();
|
|
|
++pos;
|
|
|
while (c != EOF) {
|
|
|
if (c == '\n') {
|
|
|
pos = 1;
|
|
|
++line;
|
|
|
}
|
|
|
- if (char_in(c, may_skip)) {
|
|
|
+ if (charIn(c, may_skip)) {
|
|
|
c = in.get();
|
|
|
++pos;
|
|
|
- } else if (char_in(c, chars)) {
|
|
|
- while(char_in(in.peek(), may_skip)) {
|
|
|
+ } else if (charIn(c, chars)) {
|
|
|
+ while (charIn(in.peek(), may_skip)) {
|
|
|
if (in.peek() == '\n') {
|
|
|
pos = 1;
|
|
|
++line;
|
|
@@ -296,7 +298,7 @@ skip_to(std::istream &in, const std::string& file, int& line,
|
|
|
--pos;
|
|
|
return;
|
|
|
} else {
|
|
|
- throwJSONError(std::string("'") + c + "' read, one of \"" + chars + "\" expected", file, line, pos);
|
|
|
+ throwJSONError(std::string("'") + std::string(1, c) + "' read, one of \"" + chars + "\" expected", file, line, pos);
|
|
|
}
|
|
|
}
|
|
|
throwJSONError(std::string("EOF read, one of \"") + chars + "\" expected", file, line, pos);
|
|
@@ -305,12 +307,11 @@ skip_to(std::istream &in, const std::string& file, int& line,
|
|
|
// TODO: Should we check for all other official escapes here (and
|
|
|
// error on the rest)?
|
|
|
std::string
|
|
|
-str_from_stringstream(std::istream &in, const std::string& file, const int line,
|
|
|
- int& pos) throw (JSONError)
|
|
|
+strFromStringstream(std::istream& in, const std::string& file,
|
|
|
+ const int line, int& pos) throw (JSONError)
|
|
|
{
|
|
|
- char c;
|
|
|
std::stringstream ss;
|
|
|
- c = in.get();
|
|
|
+ int c = in.get();
|
|
|
++pos;
|
|
|
if (c == '"') {
|
|
|
c = in.get();
|
|
@@ -354,7 +355,7 @@ str_from_stringstream(std::istream &in, const std::string& file, const int line,
|
|
|
in.get();
|
|
|
++pos;
|
|
|
}
|
|
|
- ss << c;
|
|
|
+ ss.put(c);
|
|
|
c = in.get();
|
|
|
++pos;
|
|
|
}
|
|
@@ -365,7 +366,7 @@ str_from_stringstream(std::istream &in, const std::string& file, const int line,
|
|
|
}
|
|
|
|
|
|
std::string
|
|
|
-word_from_stringstream(std::istream &in, int& pos) {
|
|
|
+wordFromStringstream(std::istream& in, int& pos) {
|
|
|
std::stringstream ss;
|
|
|
while (isalpha(in.peek())) {
|
|
|
ss << (char) in.get();
|
|
@@ -374,8 +375,8 @@ word_from_stringstream(std::istream &in, int& pos) {
|
|
|
return (ss.str());
|
|
|
}
|
|
|
|
|
|
-static std::string
|
|
|
-number_from_stringstream(std::istream &in, int& pos) {
|
|
|
+std::string
|
|
|
+numberFromStringstream(std::istream& in, int& pos) {
|
|
|
std::stringstream ss;
|
|
|
while (isdigit(in.peek()) || in.peek() == '+' || in.peek() == '-' ||
|
|
|
in.peek() == '.' || in.peek() == 'e' || in.peek() == 'E') {
|
|
@@ -389,13 +390,13 @@ number_from_stringstream(std::istream &in, int& pos) {
|
|
|
// that can also hold an e value? (and have specific getters if the
|
|
|
// value is larger than an int can handle)
|
|
|
ElementPtr
|
|
|
-from_stringstream_number(std::istream &in, int &pos) {
|
|
|
+fromStringstreamNumber(std::istream& in, int& pos) {
|
|
|
long int i;
|
|
|
double d = 0.0;
|
|
|
bool is_double = false;
|
|
|
- char *endptr;
|
|
|
+ char* endptr;
|
|
|
|
|
|
- std::string number = number_from_stringstream(in, pos);
|
|
|
+ std::string number = numberFromStringstream(in, pos);
|
|
|
|
|
|
i = strtol(number.c_str(), &endptr, 10);
|
|
|
if (*endptr != '\0') {
|
|
@@ -422,10 +423,10 @@ from_stringstream_number(std::istream &in, int &pos) {
|
|
|
}
|
|
|
|
|
|
ElementPtr
|
|
|
-from_stringstream_bool(std::istream &in, const std::string& file,
|
|
|
- const int line, int& pos)
|
|
|
+fromStringstreamBool(std::istream& in, const std::string& file,
|
|
|
+ const int line, int& pos)
|
|
|
{
|
|
|
- const std::string word = word_from_stringstream(in, pos);
|
|
|
+ const std::string word = wordFromStringstream(in, pos);
|
|
|
if (boost::iequals(word, "True")) {
|
|
|
return (Element::create(true));
|
|
|
} else if (boost::iequals(word, "False")) {
|
|
@@ -438,10 +439,10 @@ from_stringstream_bool(std::istream &in, const std::string& file,
|
|
|
}
|
|
|
|
|
|
ElementPtr
|
|
|
-from_stringstream_null(std::istream &in, const std::string& file,
|
|
|
- const int line, int& pos)
|
|
|
+fromStringstreamNull(std::istream& in, const std::string& file,
|
|
|
+ const int line, int& pos)
|
|
|
{
|
|
|
- const std::string word = word_from_stringstream(in, pos);
|
|
|
+ const std::string word = wordFromStringstream(in, pos);
|
|
|
if (boost::iequals(word, "null")) {
|
|
|
return (Element::create());
|
|
|
} else {
|
|
@@ -451,26 +452,26 @@ from_stringstream_null(std::istream &in, const std::string& file,
|
|
|
}
|
|
|
|
|
|
ElementPtr
|
|
|
-from_stringstream_string(std::istream& in, const std::string& file, int& line,
|
|
|
- int& pos)
|
|
|
+fromStringstreamString(std::istream& in, const std::string& file, int& line,
|
|
|
+ int& pos)
|
|
|
{
|
|
|
- return (Element::create(str_from_stringstream(in, file, line, pos)));
|
|
|
+ return (Element::create(strFromStringstream(in, file, line, pos)));
|
|
|
}
|
|
|
|
|
|
ElementPtr
|
|
|
-from_stringstream_list(std::istream &in, const std::string& file, int& line,
|
|
|
- int& pos)
|
|
|
+fromStringstreamList(std::istream& in, const std::string& file, int& line,
|
|
|
+ int& pos)
|
|
|
{
|
|
|
- char c = 0;
|
|
|
+ int c = 0;
|
|
|
ElementPtr list = Element::createList();
|
|
|
ConstElementPtr cur_list_element;
|
|
|
|
|
|
- skip_chars(in, WHITESPACE, line, pos);
|
|
|
+ skipChars(in, WHITESPACE, line, pos);
|
|
|
while (c != EOF && c != ']') {
|
|
|
if (in.peek() != ']') {
|
|
|
cur_list_element = Element::fromJSON(in, file, line, pos);
|
|
|
list->add(cur_list_element);
|
|
|
- skip_to(in, file, line, pos, ",]", WHITESPACE);
|
|
|
+ skipTo(in, file, line, pos, ",]", WHITESPACE);
|
|
|
}
|
|
|
c = in.get();
|
|
|
pos++;
|
|
@@ -479,12 +480,12 @@ from_stringstream_list(std::istream &in, const std::string& file, int& line,
|
|
|
}
|
|
|
|
|
|
ElementPtr
|
|
|
-from_stringstream_map(std::istream &in, const std::string& file, int& line,
|
|
|
- int& pos)
|
|
|
+fromStringstreamMap(std::istream& in, const std::string& file, int& line,
|
|
|
+ int& pos)
|
|
|
{
|
|
|
ElementPtr map = Element::createMap();
|
|
|
- skip_chars(in, WHITESPACE, line, pos);
|
|
|
- char c = in.peek();
|
|
|
+ skipChars(in, WHITESPACE, line, pos);
|
|
|
+ int c = in.peek();
|
|
|
if (c == EOF) {
|
|
|
throwJSONError(std::string("Unterminated map, <string> or } expected"), file, line, pos);
|
|
|
} else if (c == '}') {
|
|
@@ -492,9 +493,9 @@ from_stringstream_map(std::istream &in, const std::string& file, int& line,
|
|
|
c = in.get();
|
|
|
} else {
|
|
|
while (c != EOF && c != '}') {
|
|
|
- std::string key = str_from_stringstream(in, file, line, pos);
|
|
|
+ std::string key = strFromStringstream(in, file, line, pos);
|
|
|
|
|
|
- skip_to(in, file, line, pos, ":", WHITESPACE);
|
|
|
+ skipTo(in, file, line, pos, ":", WHITESPACE);
|
|
|
// skip the :
|
|
|
in.get();
|
|
|
pos++;
|
|
@@ -502,14 +503,14 @@ from_stringstream_map(std::istream &in, const std::string& file, int& line,
|
|
|
ConstElementPtr value = Element::fromJSON(in, file, line, pos);
|
|
|
map->set(key, value);
|
|
|
|
|
|
- skip_to(in, file, line, pos, ",}", WHITESPACE);
|
|
|
+ skipTo(in, file, line, pos, ",}", WHITESPACE);
|
|
|
c = in.get();
|
|
|
pos++;
|
|
|
}
|
|
|
}
|
|
|
return (map);
|
|
|
}
|
|
|
-}
|
|
|
+} // unnamed namespace
|
|
|
|
|
|
std::string
|
|
|
Element::typeToName(Element::types type) {
|
|
@@ -575,13 +576,13 @@ Element::fromJSON(std::istream& in, const std::string& file_name)
|
|
|
}
|
|
|
|
|
|
ElementPtr
|
|
|
-Element::fromJSON(std::istream &in, const std::string& file, int& line,
|
|
|
+Element::fromJSON(std::istream& in, const std::string& file, int& line,
|
|
|
int& pos) throw(JSONError)
|
|
|
{
|
|
|
- char c = 0;
|
|
|
+ int c = 0;
|
|
|
ElementPtr element;
|
|
|
bool el_read = false;
|
|
|
- skip_chars(in, WHITESPACE, line, pos);
|
|
|
+ skipChars(in, WHITESPACE, line, pos);
|
|
|
while (c != EOF && !el_read) {
|
|
|
c = in.get();
|
|
|
pos++;
|
|
@@ -600,7 +601,7 @@ Element::fromJSON(std::istream &in, const std::string& file, int& line,
|
|
|
case '+':
|
|
|
case '.':
|
|
|
in.putback(c);
|
|
|
- element = from_stringstream_number(in, pos);
|
|
|
+ element = fromStringstreamNumber(in, pos);
|
|
|
el_read = true;
|
|
|
break;
|
|
|
case 't':
|
|
@@ -608,32 +609,32 @@ Element::fromJSON(std::istream &in, const std::string& file, int& line,
|
|
|
case 'f':
|
|
|
case 'F':
|
|
|
in.putback(c);
|
|
|
- element = from_stringstream_bool(in, file, line, pos);
|
|
|
+ element = fromStringstreamBool(in, file, line, pos);
|
|
|
el_read = true;
|
|
|
break;
|
|
|
case 'n':
|
|
|
case 'N':
|
|
|
in.putback(c);
|
|
|
- element = from_stringstream_null(in, file, line, pos);
|
|
|
+ element = fromStringstreamNull(in, file, line, pos);
|
|
|
el_read = true;
|
|
|
break;
|
|
|
case '"':
|
|
|
in.putback('"');
|
|
|
- element = from_stringstream_string(in, file, line, pos);
|
|
|
+ element = fromStringstreamString(in, file, line, pos);
|
|
|
el_read = true;
|
|
|
break;
|
|
|
case '[':
|
|
|
- element = from_stringstream_list(in, file, line, pos);
|
|
|
+ element = fromStringstreamList(in, file, line, pos);
|
|
|
el_read = true;
|
|
|
break;
|
|
|
case '{':
|
|
|
- element = from_stringstream_map(in, file, line, pos);
|
|
|
+ element = fromStringstreamMap(in, file, line, pos);
|
|
|
el_read = true;
|
|
|
break;
|
|
|
case EOF:
|
|
|
break;
|
|
|
default:
|
|
|
- throwJSONError(std::string("error: unexpected character ") + c, file, line, pos);
|
|
|
+ throwJSONError(std::string("error: unexpected character ") + std::string(1, c), file, line, pos);
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
@@ -645,12 +646,12 @@ Element::fromJSON(std::istream &in, const std::string& file, int& line,
|
|
|
}
|
|
|
|
|
|
ElementPtr
|
|
|
-Element::fromJSON(const std::string &in) {
|
|
|
+Element::fromJSON(const std::string& in) {
|
|
|
std::stringstream ss;
|
|
|
ss << in;
|
|
|
int line = 1, pos = 1;
|
|
|
ElementPtr result(fromJSON(ss, "<string>", line, pos));
|
|
|
- skip_chars(ss, WHITESPACE, line, pos);
|
|
|
+ skipChars(ss, WHITESPACE, line, pos);
|
|
|
// ss must now be at end
|
|
|
if (ss.peek() != EOF) {
|
|
|
throwJSONError("Extra data", "<string>", line, pos);
|