mirror of
https://github.com/pocoproject/poco.git
synced 2025-10-23 16:48:06 +02:00
JSON fixes/refactoring
This commit is contained in:
@@ -129,7 +129,76 @@ const int Parser::_stateTransitionTable[NR_STATES][NR_CLASSES] = {
|
||||
};
|
||||
|
||||
|
||||
Parser::Parser(const Handler::Ptr& pHandler) :
|
||||
// Source
|
||||
|
||||
class Source
|
||||
{
|
||||
public:
|
||||
Source()
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~Source()
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool nextChar(int& c) = 0;
|
||||
};
|
||||
|
||||
|
||||
class StreamSource : public Source
|
||||
{
|
||||
public:
|
||||
StreamSource(std::istream& in) : _in(in)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~StreamSource()
|
||||
{
|
||||
}
|
||||
|
||||
bool nextChar(int& c)
|
||||
{
|
||||
if ( _in.good() )
|
||||
{
|
||||
c = _in.get();
|
||||
return _in.good();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
std::istream& _in;
|
||||
};
|
||||
|
||||
|
||||
class StringSource : public Source
|
||||
{
|
||||
public:
|
||||
StringSource(std::string::const_iterator begin, std::string::const_iterator end) : _it(begin), _end(end)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~StringSource()
|
||||
{
|
||||
}
|
||||
|
||||
bool nextChar(int& c)
|
||||
{
|
||||
if ( _it == _end ) return false;
|
||||
|
||||
c = *_it++;
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string::const_iterator _it;
|
||||
std::string::const_iterator _end;
|
||||
};
|
||||
|
||||
|
||||
// Parser
|
||||
Parser::Parser(const Handler::Ptr& pHandler, std::size_t bufSize) :
|
||||
_pHandler(pHandler),
|
||||
_state(GO),
|
||||
_beforeCommentState(0),
|
||||
@@ -137,38 +206,50 @@ Parser::Parser(const Handler::Ptr& pHandler) :
|
||||
_escaped(0),
|
||||
_comment(0),
|
||||
_utf16HighSurrogate(0),
|
||||
//_depth(config.parseDepth() ? config.parseDepth() : -1),
|
||||
_depth(-1),
|
||||
_depth(UNLIMITED_DEPTH),
|
||||
_top(-1),
|
||||
_stack(PARSER_STACK_SIZE),
|
||||
_parseBuffer(PARSE_BUFFER_SIZE),
|
||||
_parseBuffer(bufSize),
|
||||
_parseBufferCount(0),
|
||||
_commentBeginOffset(0),
|
||||
_decimalPoint(0),
|
||||
_decimalPoint('.'),
|
||||
_allowNullByte(true),
|
||||
_allowComments(false)
|
||||
{
|
||||
_stack.clear();
|
||||
_parseBuffer.clear();
|
||||
push(MODE_DONE);
|
||||
_decimalPoint = *std::localeconv()->decimal_point;
|
||||
clearBuffer();
|
||||
}
|
||||
|
||||
|
||||
Parser::~Parser()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Parser::reset()
|
||||
{
|
||||
_state = GO;
|
||||
_beforeCommentState = 0;
|
||||
_type = JSON_T_NONE;
|
||||
_escaped = 0;
|
||||
_comment = 0;
|
||||
_utf16HighSurrogate = 0;
|
||||
_top = -1;
|
||||
_parseBufferCount = 0;
|
||||
|
||||
_stack.clear();
|
||||
_parseBuffer.clear();
|
||||
push(MODE_DONE);
|
||||
clearBuffer();
|
||||
}
|
||||
|
||||
|
||||
Dynamic::Var Parser::parse(const std::string& json)
|
||||
{
|
||||
feeder = new StringCharacterFeeder(json.begin(), json.end());
|
||||
StringSource source(json.begin(), json.end());
|
||||
|
||||
int c = 0;
|
||||
while(feeder->nextChar(c))
|
||||
while(source.nextChar(c))
|
||||
{
|
||||
if (0 == parseChar(c)) throw SyntaxException("JSON syntax error");
|
||||
if (0 == parseChar(c, source)) throw SyntaxException("JSON syntax error");
|
||||
}
|
||||
|
||||
if (!done())
|
||||
@@ -180,12 +261,12 @@ Dynamic::Var Parser::parse(const std::string& json)
|
||||
|
||||
Dynamic::Var Parser::parse(std::istream& in)
|
||||
{
|
||||
feeder = new StreamCharacterFeeder(in);
|
||||
StreamSource source(in);
|
||||
|
||||
int c = 0;
|
||||
while(feeder->nextChar(c))
|
||||
while(source.nextChar(c))
|
||||
{
|
||||
if (0 == parseChar(c)) throw JSONException("JSON syntax error");
|
||||
if (0 == parseChar(c, source)) throw JSONException("JSON syntax error");
|
||||
}
|
||||
|
||||
if (!done())
|
||||
@@ -222,6 +303,7 @@ bool Parser::pop(int mode)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Parser::clearBuffer()
|
||||
{
|
||||
_parseBufferCount = 0;
|
||||
@@ -305,7 +387,7 @@ void Parser::addCharToParseBuffer(int nextChar, int nextClass)
|
||||
}
|
||||
|
||||
|
||||
bool Parser::parseChar(int nextChar)
|
||||
bool Parser::parseChar(int nextChar, Source& source)
|
||||
{
|
||||
int nextClass, nextState;
|
||||
|
||||
@@ -325,7 +407,7 @@ bool Parser::parseChar(int nextChar)
|
||||
for(int i = 1; i < count; ++i)
|
||||
{
|
||||
int c = 0;
|
||||
if ( !feeder->nextChar(c) ) throw JSONException("Invalid UTF8 character found");
|
||||
if (!source.nextChar(c)) throw JSONException("Invalid UTF8 character found");
|
||||
buffer[i] = c;
|
||||
}
|
||||
|
||||
@@ -702,8 +784,8 @@ void Parser::parseBuffer()
|
||||
{
|
||||
Int64 value = NumberParser::parse64(_parseBuffer.begin());
|
||||
// if number is 32-bit, then handle as such
|
||||
if ( value > std::numeric_limits<int>::max()
|
||||
|| value < std::numeric_limits<int>::min() )
|
||||
if (value > std::numeric_limits<int>::max()
|
||||
|| value < std::numeric_limits<int>::min() )
|
||||
{
|
||||
_pHandler->value(value);
|
||||
}
|
||||
|
@@ -46,7 +46,8 @@ namespace JSON {
|
||||
PrintHandler::PrintHandler(unsigned indent):
|
||||
_out(std::cout),
|
||||
_indent(indent),
|
||||
_array(false)
|
||||
_array(false),
|
||||
_value(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -54,7 +55,8 @@ PrintHandler::PrintHandler(unsigned indent):
|
||||
PrintHandler::PrintHandler(std::ostream& out, unsigned indent):
|
||||
_out(out),
|
||||
_indent(indent),
|
||||
_array(false)
|
||||
_array(false),
|
||||
_value(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -107,6 +109,7 @@ void PrintHandler::startArray()
|
||||
_out << '[' << endLine();
|
||||
_tab.append(indent(), ' ');
|
||||
_array = true;
|
||||
_value = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -115,11 +118,17 @@ void PrintHandler::endArray()
|
||||
_tab.erase(_tab.length() - indent());
|
||||
_out << endLine() << _tab << ']';
|
||||
_array = false;
|
||||
_value = false;
|
||||
}
|
||||
|
||||
|
||||
void PrintHandler::key(const std::string& k)
|
||||
{
|
||||
if (_value)
|
||||
{
|
||||
comma();
|
||||
_value = false;
|
||||
}
|
||||
_out << _tab << '"' << k << '"';
|
||||
if (!printFlat()) _out << ' ';
|
||||
_out << ':';
|
||||
@@ -129,60 +138,68 @@ void PrintHandler::key(const std::string& k)
|
||||
|
||||
void PrintHandler::null()
|
||||
{
|
||||
if (_array) _out << _tab;
|
||||
arrayValue();
|
||||
_out << "null";
|
||||
_value = true;
|
||||
}
|
||||
|
||||
|
||||
void PrintHandler::value(int v)
|
||||
{
|
||||
if (_array) _out << _tab;
|
||||
arrayValue();
|
||||
_out << v;
|
||||
_value = true;
|
||||
}
|
||||
|
||||
|
||||
void PrintHandler::value(unsigned v)
|
||||
{
|
||||
if (_array) _out << _tab;
|
||||
arrayValue();
|
||||
_out << v;
|
||||
_value = true;
|
||||
}
|
||||
|
||||
|
||||
#if defined(POCO_HAVE_INT64)
|
||||
void PrintHandler::value(Int64 v)
|
||||
{
|
||||
if (_array) _out << _tab;
|
||||
arrayValue();
|
||||
_out << v;
|
||||
_value = true;
|
||||
}
|
||||
|
||||
|
||||
void PrintHandler::value(UInt64 v)
|
||||
{
|
||||
if (_array) _out << _tab;
|
||||
arrayValue();
|
||||
_out << v;
|
||||
_value = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void PrintHandler::value(const std::string& value)
|
||||
{
|
||||
if (_array) _out << _tab;
|
||||
arrayValue();
|
||||
Stringifier::formatString(value, _out);
|
||||
_value = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PrintHandler::value(double d)
|
||||
{
|
||||
if (_array) _out << _tab;
|
||||
arrayValue();
|
||||
_out << d;
|
||||
_value = true;
|
||||
}
|
||||
|
||||
|
||||
void PrintHandler::value(bool b)
|
||||
{
|
||||
if (_array) _out << _tab;
|
||||
arrayValue();
|
||||
_out << b;
|
||||
_value = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -192,4 +209,12 @@ void PrintHandler::comma()
|
||||
}
|
||||
|
||||
|
||||
void PrintHandler::arrayValue()
|
||||
{
|
||||
if (_array)
|
||||
{
|
||||
if (_value) comma();
|
||||
_out << _tab;
|
||||
}
|
||||
}
|
||||
} } // namespace Poco::JSON
|
||||
|
Reference in New Issue
Block a user