JSON Parser : code style corrections

This commit is contained in:
Andrew Lindesay
2017-05-16 00:21:15 +12:00
parent 795c2826bb
commit 55f5f25940
6 changed files with 126 additions and 60 deletions
+70 -34
View File
@@ -4,6 +4,8 @@
* Copyright 2014, Stephan Aßmus <[email protected]> * Copyright 2014, Stephan Aßmus <[email protected]>
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#include "Json.h" #include "Json.h"
#include <cstdio> #include <cstdio>
@@ -25,7 +27,8 @@ namespace BPrivate {
static bool static bool
b_jsonparse_is_hex(char c) { b_jsonparse_is_hex(char c)
{
return isdigit(c) return isdigit(c)
|| (c > 0x41 && c <= 0x46) || (c > 0x41 && c <= 0x46)
|| (c > 0x61 && c <= 0x66); || (c > 0x61 && c <= 0x66);
@@ -33,7 +36,8 @@ b_jsonparse_is_hex(char c) {
static bool static bool
b_jsonparse_all_hex(const char* c) { b_jsonparse_all_hex(const char* c)
{
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
if (!b_jsonparse_is_hex(c[i])) if (!b_jsonparse_is_hex(c[i]))
return false; return false;
@@ -57,27 +61,37 @@ public:
{ {
} }
BJsonEventListener* Listener() const {
BJsonEventListener* Listener() const
{
return fListener; return fListener;
} }
BDataIO* Data() const {
BDataIO* Data() const
{
return fData; return fData;
} }
int LineNumber() const {
int LineNumber() const
{
return fLineNumber; return fLineNumber;
} }
int IncrementLineNumber() {
return fLineNumber++; void IncrementLineNumber()
{
fLineNumber++;
} }
// TODO; there is considerable opportunity for performance improvements // TODO; there is considerable opportunity for performance improvements
// here by buffering the input and then feeding it into the parse // here by buffering the input and then feeding it into the parse
// algorithm character by character. // algorithm character by character.
status_t NextChar(char* buffer) { status_t NextChar(char* buffer)
{
if (fHasPushbackChar) { if (fHasPushbackChar) {
buffer[0] = fPushbackChar; buffer[0] = fPushbackChar;
@@ -88,7 +102,9 @@ public:
return Data()->ReadExactly(buffer, 1); return Data()->ReadExactly(buffer, 1);
} }
void PushbackChar(char c) {
void PushbackChar(char c)
{
fPushbackChar = c; fPushbackChar = c;
fHasPushbackChar = true; fHasPushbackChar = true;
} }
@@ -156,14 +172,18 @@ BJson::NextChar(JsonParseContext& jsonParseContext, char* c)
return true; return true;
case B_PARTIAL_READ: case B_PARTIAL_READ:
{
jsonParseContext.Listener()->HandleError(B_BAD_DATA, jsonParseContext.Listener()->HandleError(B_BAD_DATA,
jsonParseContext.LineNumber(), "unexpected end of input"); jsonParseContext.LineNumber(), "unexpected end of input");
return false; return false;
}
default: default:
{
jsonParseContext.Listener()->HandleError(result, -1, jsonParseContext.Listener()->HandleError(result, -1,
"io related read error"); "io related read error");
return false; return false;
}
} }
} }
@@ -272,10 +292,8 @@ BJson::ParseObjectNameValuePair(JsonParseContext& jsonParseContext)
case '\"': // name of the object case '\"': // name of the object
{ {
if (!didParseName) { if (!didParseName) {
if (!ParseString(jsonParseContext, if (!ParseString(jsonParseContext, B_JSON_OBJECT_NAME))
B_JSON_OBJECT_NAME)) {
return false; return false;
}
didParseName = true; didParseName = true;
} else { } else {
@@ -323,7 +341,7 @@ bool
BJson::ParseObject(JsonParseContext& jsonParseContext) BJson::ParseObject(JsonParseContext& jsonParseContext)
{ {
if (!jsonParseContext.Listener()->Handle( if (!jsonParseContext.Listener()->Handle(
BJsonEvent(B_JSON_OBJECT_START))) { BJsonEvent(B_JSON_OBJECT_START))) {
return false; return false;
} }
@@ -336,13 +354,16 @@ BJson::ParseObject(JsonParseContext& jsonParseContext)
switch (c) { switch (c) {
case '}': // terminate the object case '}': // terminate the object
{
if (!jsonParseContext.Listener()->Handle( if (!jsonParseContext.Listener()->Handle(
BJsonEvent(B_JSON_OBJECT_END))) { BJsonEvent(B_JSON_OBJECT_END))) {
return false; return false;
} }
return true; return true;
}
case ',': // next value. case ',': // next value.
{
if (firstItem) { if (firstItem) {
jsonParseContext.Listener()->HandleError(B_BAD_DATA, jsonParseContext.Listener()->HandleError(B_BAD_DATA,
jsonParseContext.LineNumber(), "unexpected" jsonParseContext.LineNumber(), "unexpected"
@@ -354,6 +375,7 @@ BJson::ParseObject(JsonParseContext& jsonParseContext)
if (!ParseObjectNameValuePair(jsonParseContext)) if (!ParseObjectNameValuePair(jsonParseContext))
return false; return false;
break; break;
}
default: default:
{ {
@@ -379,7 +401,7 @@ bool
BJson::ParseArray(JsonParseContext& jsonParseContext) BJson::ParseArray(JsonParseContext& jsonParseContext)
{ {
if (!jsonParseContext.Listener()->Handle( if (!jsonParseContext.Listener()->Handle(
BJsonEvent(B_JSON_ARRAY_START))) { BJsonEvent(B_JSON_ARRAY_START))) {
return false; return false;
} }
@@ -392,13 +414,16 @@ BJson::ParseArray(JsonParseContext& jsonParseContext)
switch (c) { switch (c) {
case ']': // terminate the array case ']': // terminate the array
{
if (!jsonParseContext.Listener()->Handle( if (!jsonParseContext.Listener()->Handle(
BJsonEvent(B_JSON_ARRAY_END))) { BJsonEvent(B_JSON_ARRAY_END))) {
return false; return false;
} }
return true; return true;
}
case ',': // next value. case ',': // next value.
{
if (firstItem) { if (firstItem) {
jsonParseContext.Listener()->HandleError(B_BAD_DATA, jsonParseContext.Listener()->HandleError(B_BAD_DATA,
jsonParseContext.LineNumber(), "unexpected" jsonParseContext.LineNumber(), "unexpected"
@@ -409,6 +434,7 @@ BJson::ParseArray(JsonParseContext& jsonParseContext)
if (!ParseAny(jsonParseContext)) if (!ParseAny(jsonParseContext))
return false; return false;
break; break;
}
default: default:
{ {
@@ -445,25 +471,25 @@ BJson::ParseEscapeUnicodeSequence(JsonParseContext& jsonParseContext,
} }
if (!b_jsonparse_all_hex(buffer)) { if (!b_jsonparse_all_hex(buffer)) {
BString errorMessage; BString errorMessage;
errorMessage.SetToFormat( errorMessage.SetToFormat(
"malformed unicode sequence [%s] in string parsing", "malformed unicode sequence [%s] in string parsing",
buffer); buffer);
jsonParseContext.Listener()->HandleError(B_BAD_DATA, jsonParseContext.Listener()->HandleError(B_BAD_DATA,
jsonParseContext.LineNumber(), errorMessage.String()); jsonParseContext.LineNumber(), errorMessage.String());
return false; return false;
} }
uint intValue; uint intValue;
if (sscanf(buffer, "%4x", &intValue) != 1) { if (sscanf(buffer, "%4x", &intValue) != 1) {
BString errorMessage; BString errorMessage;
errorMessage.SetToFormat( errorMessage.SetToFormat(
"unable to process unicode sequence [%s] in string " "unable to process unicode sequence [%s] in string "
" parsing", buffer); " parsing", buffer);
jsonParseContext.Listener()->HandleError(B_BAD_DATA, jsonParseContext.Listener()->HandleError(B_BAD_DATA,
jsonParseContext.LineNumber(), errorMessage.String()); jsonParseContext.LineNumber(), errorMessage.String());
return false; return false;
} }
char character[7]; char character[7];
@@ -511,12 +537,14 @@ BJson::ParseStringEscapeSequence(JsonParseContext& jsonParseContext,
stringResult += "\""; stringResult += "\"";
break; break;
case 'u': case 'u':
{
// unicode escape sequence. // unicode escape sequence.
if (!ParseEscapeUnicodeSequence(jsonParseContext, if (!ParseEscapeUnicodeSequence(jsonParseContext,
stringResult)) { stringResult)) {
return false; return false;
} }
break; break;
}
default: default:
{ {
BString errorMessage; BString errorMessage;
@@ -546,19 +574,24 @@ BJson::ParseString(JsonParseContext& jsonParseContext,
switch (c) { switch (c) {
case '"': case '"':
{
// terminates the string assembled so far. // terminates the string assembled so far.
jsonParseContext.Listener()->Handle( jsonParseContext.Listener()->Handle(
BJsonEvent(eventType, stringResult.String())); BJsonEvent(eventType, stringResult.String()));
return true; return true;
}
case '\\': case '\\':
{
if (!ParseStringEscapeSequence(jsonParseContext, if (!ParseStringEscapeSequence(jsonParseContext,
stringResult)) { stringResult)) {
return false; return false;
} }
break; break;
}
default: default:
{
uint8 uc = static_cast<uint8>(c); uint8 uc = static_cast<uint8>(c);
if(uc < 0x20) { // control characters are not allowed if(uc < 0x20) { // control characters are not allowed
@@ -573,6 +606,7 @@ BJson::ParseString(JsonParseContext& jsonParseContext,
stringResult.Append(&c, 1); stringResult.Append(&c, 1);
break; break;
}
} }
} }
} }
@@ -585,7 +619,7 @@ BJson::ParseExpectedVerbatimStringAndRaiseEvent(
json_event_type jsonEventType) json_event_type jsonEventType)
{ {
if (ParseExpectedVerbatimString(jsonParseContext, expectedString, if (ParseExpectedVerbatimString(jsonParseContext, expectedString,
expectedStringLength, leadingChar)) { expectedStringLength, leadingChar)) {
if (!jsonParseContext.Listener()->Handle(BJsonEvent(jsonEventType))) if (!jsonParseContext.Listener()->Handle(BJsonEvent(jsonEventType)))
return false; return false;
} }
@@ -695,6 +729,7 @@ BJson::ParseNumber(JsonParseContext& jsonParseContext)
switch (result) { switch (result) {
case B_OK: case B_OK:
{
if (isdigit(c)) { if (isdigit(c)) {
value += c; value += c;
break; break;
@@ -707,7 +742,7 @@ BJson::ParseNumber(JsonParseContext& jsonParseContext)
jsonParseContext.PushbackChar(c); jsonParseContext.PushbackChar(c);
// intentional fall through // intentional fall through
}
case B_PARTIAL_READ: case B_PARTIAL_READ:
{ {
errno = 0; errno = 0;
@@ -723,11 +758,12 @@ BJson::ParseNumber(JsonParseContext& jsonParseContext)
return true; return true;
} }
default: default:
{
jsonParseContext.Listener()->HandleError(result, -1, jsonParseContext.Listener()->HandleError(result, -1,
"io related read error"); "io related read error");
return false; return false;
}
} }
} }
} }
+2
View File
@@ -2,6 +2,8 @@
* Copyright 2017, Andrew Lindesay <[email protected]> * Copyright 2017, Andrew Lindesay <[email protected]>
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#include "JsonEvent.h" #include "JsonEvent.h"
#include <stdlib.h> #include <stdlib.h>
+1
View File
@@ -3,6 +3,7 @@
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#include "JsonEventListener.h" #include "JsonEventListener.h"
+27 -9
View File
@@ -3,9 +3,8 @@
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#include "JsonMessageWriter.h"
#include <stdio.h> #include "JsonMessageWriter.h"
namespace BPrivate { namespace BPrivate {
@@ -179,19 +178,25 @@ BStackedMessageEventListener::Handle(const BJsonEvent& event)
break; break;
case B_JSON_OBJECT_START: case B_JSON_OBJECT_START:
{
SetStackedListenerOnWriter(new BStackedObjectMessageEventListener( SetStackedListenerOnWriter(new BStackedObjectMessageEventListener(
fWriter, this)); fWriter, this));
break; break;
}
case B_JSON_ARRAY_START: case B_JSON_ARRAY_START:
{
SetStackedListenerOnWriter(new BStackedArrayMessageEventListener( SetStackedListenerOnWriter(new BStackedArrayMessageEventListener(
fWriter, this)); fWriter, this));
break; break;
}
default: default:
{
HandleError(B_NOT_ALLOWED, JSON_EVENT_LISTENER_ANY_LINE, HandleError(B_NOT_ALLOWED, JSON_EVENT_LISTENER_ANY_LINE,
"unexpected type of json item to add to container"); "unexpected type of json item to add to container");
return false; return false;
}
} }
return ErrorStatus() == B_OK; return ErrorStatus() == B_OK;
@@ -304,7 +309,8 @@ BStackedMessageEventListener::SetStackedListenerOnWriter(
BStackedArrayMessageEventListener::BStackedArrayMessageEventListener( BStackedArrayMessageEventListener::BStackedArrayMessageEventListener(
BJsonMessageWriter* writer, BJsonMessageWriter* writer,
BStackedMessageEventListener* parent) BStackedMessageEventListener* parent)
: BStackedMessageEventListener(writer, parent, B_JSON_MESSAGE_WHAT_ARRAY) :
BStackedMessageEventListener(writer, parent, B_JSON_MESSAGE_WHAT_ARRAY)
{ {
fCount = 0; fCount = 0;
} }
@@ -314,7 +320,8 @@ BStackedArrayMessageEventListener::BStackedArrayMessageEventListener(
BJsonMessageWriter* writer, BJsonMessageWriter* writer,
BStackedMessageEventListener* parent, BStackedMessageEventListener* parent,
BMessage* message) BMessage* message)
: BStackedMessageEventListener(writer, parent, message) :
BStackedMessageEventListener(writer, parent, message)
{ {
message->what = B_JSON_MESSAGE_WHAT_ARRAY; message->what = B_JSON_MESSAGE_WHAT_ARRAY;
fCount = 0; fCount = 0;
@@ -334,11 +341,13 @@ BStackedArrayMessageEventListener::Handle(const BJsonEvent& event)
switch (event.EventType()) { switch (event.EventType()) {
case B_JSON_ARRAY_END: case B_JSON_ARRAY_END:
{
if (fParent != NULL) if (fParent != NULL)
fParent->AddMessage(fMessage); fParent->AddMessage(fMessage);
SetStackedListenerOnWriter(fParent); SetStackedListenerOnWriter(fParent);
delete this; delete this;
break; break;
}
default: default:
return BStackedMessageEventListener::Handle(event); return BStackedMessageEventListener::Handle(event);
@@ -370,7 +379,8 @@ BStackedArrayMessageEventListener::DidAdd()
BStackedObjectMessageEventListener::BStackedObjectMessageEventListener( BStackedObjectMessageEventListener::BStackedObjectMessageEventListener(
BJsonMessageWriter* writer, BJsonMessageWriter* writer,
BStackedMessageEventListener* parent) BStackedMessageEventListener* parent)
: BStackedMessageEventListener(writer, parent, B_JSON_MESSAGE_WHAT_OBJECT) :
BStackedMessageEventListener(writer, parent, B_JSON_MESSAGE_WHAT_OBJECT)
{ {
} }
@@ -379,7 +389,8 @@ BStackedObjectMessageEventListener::BStackedObjectMessageEventListener(
BJsonMessageWriter* writer, BJsonMessageWriter* writer,
BStackedMessageEventListener* parent, BStackedMessageEventListener* parent,
BMessage* message) BMessage* message)
: BStackedMessageEventListener(writer, parent, message) :
BStackedMessageEventListener(writer, parent, message)
{ {
message->what = B_JSON_MESSAGE_WHAT_OBJECT; message->what = B_JSON_MESSAGE_WHAT_OBJECT;
} }
@@ -398,11 +409,13 @@ BStackedObjectMessageEventListener::Handle(const BJsonEvent& event)
switch (event.EventType()) { switch (event.EventType()) {
case B_JSON_OBJECT_END: case B_JSON_OBJECT_END:
{
if (fParent != NULL) if (fParent != NULL)
fParent->AddMessage(fMessage); fParent->AddMessage(fMessage);
SetStackedListenerOnWriter(fParent); SetStackedListenerOnWriter(fParent);
delete this; delete this;
break; break;
}
case B_JSON_OBJECT_NAME: case B_JSON_OBJECT_NAME:
fNextItemName.SetTo(event.Content()); fNextItemName.SetTo(event.Content());
@@ -479,22 +492,27 @@ BJsonMessageWriter::Handle(const BJsonEvent& event)
else { else {
switch(event.EventType()) { switch(event.EventType()) {
case B_JSON_OBJECT_START: case B_JSON_OBJECT_START:
{
SetStackedListener(new BStackedObjectMessageEventListener( SetStackedListener(new BStackedObjectMessageEventListener(
this, NULL, fTopLevelMessage)); this, NULL, fTopLevelMessage));
break; break;
}
case B_JSON_ARRAY_START: case B_JSON_ARRAY_START:
{
fTopLevelMessage->what = B_JSON_MESSAGE_WHAT_ARRAY; fTopLevelMessage->what = B_JSON_MESSAGE_WHAT_ARRAY;
SetStackedListener(new BStackedArrayMessageEventListener( SetStackedListener(new BStackedArrayMessageEventListener(
this, NULL, fTopLevelMessage)); this, NULL, fTopLevelMessage));
break; break;
}
default: default:
{
HandleError(B_NOT_ALLOWED, JSON_EVENT_LISTENER_ANY_LINE, HandleError(B_NOT_ALLOWED, JSON_EVENT_LISTENER_ANY_LINE,
"a message object can only handle an object or an array" "a message object can only handle an object or an array"
"at the top level"); "at the top level");
return false; return false;
}
} }
} }
+25 -16
View File
@@ -3,6 +3,7 @@
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#include "JsonTextWriter.h" #include "JsonTextWriter.h"
#include <stdio.h> #include <stdio.h>
@@ -22,7 +23,8 @@ b_json_is_7bit_clean(uint8 c)
static bool static bool
b_json_is_illegal(uint8 c) { b_json_is_illegal(uint8 c)
{
return c < 0x20 || c == 0x7f; return c < 0x20 || c == 0x7f;
} }
@@ -210,27 +212,35 @@ BJsonTextWriterStackedEventListener::Handle(const BJsonEvent& event)
break; break;
case B_JSON_OBJECT_START: case B_JSON_OBJECT_START:
{
writeResult = StreamChar('{'); writeResult = StreamChar('{');
if (writeResult == B_OK) { if (writeResult == B_OK) {
SetStackedListenerOnWriter( SetStackedListenerOnWriter(
new BJsonTextWriterObjectStackedEventListener(fWriter, this)); new BJsonTextWriterObjectStackedEventListener(
fWriter, this));
} }
break; break;
}
case B_JSON_ARRAY_START: case B_JSON_ARRAY_START:
{
writeResult = StreamChar('['); writeResult = StreamChar('[');
if (writeResult == B_OK) { if (writeResult == B_OK) {
SetStackedListenerOnWriter( SetStackedListenerOnWriter(
new BJsonTextWriterArrayStackedEventListener(fWriter, this)); new BJsonTextWriterArrayStackedEventListener(
fWriter, this));
} }
break; break;
}
default: default:
{
HandleError(B_NOT_ALLOWED, JSON_EVENT_LISTENER_ANY_LINE, HandleError(B_NOT_ALLOWED, JSON_EVENT_LISTENER_ANY_LINE,
"unexpected type of json item to add to container"); "unexpected type of json item to add to container");
return false; return false;
}
} }
if (writeResult == B_OK) if (writeResult == B_OK)
@@ -313,15 +323,16 @@ BJsonTextWriterStackedEventListener::StreamStringEncoded(const char* string,
status_t status_t
BJsonTextWriterStackedEventListener::StreamQuotedEncodedString(const char* string) BJsonTextWriterStackedEventListener::StreamQuotedEncodedString(
const char* string)
{ {
return fWriter->StreamQuotedEncodedString(string); return fWriter->StreamQuotedEncodedString(string);
} }
status_t status_t
BJsonTextWriterStackedEventListener::StreamQuotedEncodedString(const char* string, BJsonTextWriterStackedEventListener::StreamQuotedEncodedString(
off_t offset, size_t length) const char* string, off_t offset, size_t length)
{ {
return fWriter->StreamQuotedEncodedString(string, offset, length); return fWriter->StreamQuotedEncodedString(string, offset, length);
} }
@@ -362,7 +373,8 @@ BJsonTextWriterStackedEventListener::SetStackedListenerOnWriter(
BJsonTextWriterArrayStackedEventListener::BJsonTextWriterArrayStackedEventListener( BJsonTextWriterArrayStackedEventListener::BJsonTextWriterArrayStackedEventListener(
BJsonTextWriter* writer, BJsonTextWriter* writer,
BJsonTextWriterStackedEventListener* parent) BJsonTextWriterStackedEventListener* parent)
: BJsonTextWriterStackedEventListener(writer, parent) :
BJsonTextWriterStackedEventListener(writer, parent)
{ {
} }
@@ -431,7 +443,8 @@ BJsonTextWriterArrayStackedEventListener::WillAdd()
BJsonTextWriterObjectStackedEventListener::BJsonTextWriterObjectStackedEventListener( BJsonTextWriterObjectStackedEventListener::BJsonTextWriterObjectStackedEventListener(
BJsonTextWriter* writer, BJsonTextWriter* writer,
BJsonTextWriterStackedEventListener* parent) BJsonTextWriterStackedEventListener* parent)
: BJsonTextWriterStackedEventListener(writer, parent) :
BJsonTextWriterStackedEventListener(writer, parent)
{ {
} }
@@ -591,7 +604,7 @@ BJsonTextWriter::StreamStringEncoded(const char* string,
status_t writeResult = B_OK; status_t writeResult = B_OK;
uint8* string8bit = (uint8*)string; uint8* string8bit = (uint8*)string;
while (writeResult == B_OK && 0 != length) { while (writeResult == B_OK && length != 0) {
uint8 c = string8bit[offset]; uint8 c = string8bit[offset];
const char* simpleEsc = b_json_simple_esc_sequence(c); const char* simpleEsc = b_json_simple_esc_sequence(c);
@@ -633,11 +646,9 @@ BJsonTextWriter::StreamStringEncoded(const char* string,
offset++; offset++;
length--; length--;
} else { } else {
// if the character is < 128 then it can be rendered // if the character is < 128 then it can be rendered
// verbatim - check how many are like this and then // verbatim - check how many are like this and then
// render those verbatim. // render those verbatim.
const char* stringInitial = &string[offset]; const char* stringInitial = &string[offset];
uint32 unicodeCharacter = BUnicodeChar::FromUTF8( uint32 unicodeCharacter = BUnicodeChar::FromUTF8(
&stringInitial); &stringInitial);
@@ -692,6 +703,4 @@ status_t
BJsonTextWriter::StreamChar(char c) BJsonTextWriter::StreamChar(char c)
{ {
return fDataIO->WriteExactly(&c, 1); return fDataIO->WriteExactly(&c, 1);
} }
+1 -1
View File
@@ -3,6 +3,7 @@
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#include "JsonWriter.h" #include "JsonWriter.h"
#include <stdio.h> #include <stdio.h>
@@ -30,7 +31,6 @@ BJsonWriter::HandleError(status_t status, int32 line,
if(fErrorStatus == B_OK) { if(fErrorStatus == B_OK) {
if (message == NULL) if (message == NULL)
message = "?"; message = "?";
fErrorStatus = status; fErrorStatus = status;
fprintf(stderr, "! json err @line %" B_PRIi32 " - %s : %s\n", line, fprintf(stderr, "! json err @line %" B_PRIi32 " - %s : %s\n", line,
strerror(status), message); strerror(status), message);