Implementation of JSON Streaming Parser

Addition of missing files from previous commit
This commit is contained in:
Andrew Lindesay
2017-05-13 19:35:51 +12:00
parent 1f6b57a5d2
commit e6fa1be5fd
8 changed files with 789 additions and 10 deletions
+42 -10
View File
@@ -1,32 +1,64 @@
/*
* Copyright 2017, Andrew Lindesay <[email protected]>
* Copyright 2014, Augustin Cavalier (waddlesplash)
* Distributed under the terms of the MIT License.
*/
#ifndef _JSON_H
#define _JSON_H
#include "JsonEventListener.h"
#include <Message.h>
#include <String.h>
namespace BPrivate {
class JsonParseContext;
class BJson {
public:
enum JsonObjectType {
JSON_TYPE_MAP = '_JTM',
JSON_TYPE_ARRAY = '_JTA'
};
public:
static status_t Parse(const char* JSON, BMessage& message);
static status_t Parse(const BString& JSON, BMessage& message);
static void Parse(BDataIO* data,
BJsonEventListener* listener);
private:
static void _Parse(const BString& JSON, BMessage& message);
static BString _ParseString(const BString& JSON, int32& pos);
static double _ParseNumber(const BString& JSON, int32& pos);
static bool _ParseConstant(const BString& JSON, int32& pos,
const char* constant);
static bool NextChar(JsonParseContext& jsonParseContext,
char* c);
static bool NextNonWhitespaceChar(
JsonParseContext& jsonParseContext,
char* c);
static bool ParseAny(JsonParseContext& jsonParseContext);
static bool ParseObjectNameValuePair(
JsonParseContext& jsonParseContext);
static bool ParseObject(JsonParseContext& jsonParseContext);
static bool ParseArray(JsonParseContext& jsonParseContext);
static bool ParseEscapeUnicodeSequence(
JsonParseContext& jsonParseContext,
BString& stringResult);
static bool ParseStringEscapeSequence(
JsonParseContext& jsonParseContext,
BString& stringResult);
static bool ParseString(JsonParseContext& jsonParseContext,
json_event_type eventType);
static bool ParseExpectedVerbatimStringAndRaiseEvent(
JsonParseContext& jsonParseContext,
const char* expectedString,
size_t expectedStringLength,
char leadingChar,
json_event_type jsonEventType);
static bool ParseExpectedVerbatimString(
JsonParseContext& jsonParseContext,
const char* expectedString,
size_t expectedStringLength,
char leadingChar);
static bool IsValidNumber(BString& number);
static bool ParseNumber(JsonParseContext& jsonParseContext);
};
} // namespace BPrivate
+59
View File
@@ -0,0 +1,59 @@
/*
* Copyright 2017, Andrew Lindesay <[email protected]>
* Distributed under the terms of the MIT License.
*/
#ifndef _JSON_EVENT_H
#define _JSON_EVENT_H
#include <String.h>
/*! This enumeration defines the types of events that may arise when parsing a
stream of JSON data.
*/
typedef enum json_event_type {
B_JSON_NUMBER = 1,
B_JSON_STRING = 2,
B_JSON_TRUE = 3,
B_JSON_FALSE = 4,
B_JSON_NULL = 5,
B_JSON_OBJECT_START = 6,
B_JSON_OBJECT_END = 7,
B_JSON_OBJECT_NAME = 8, // aka field
B_JSON_ARRAY_START = 9,
B_JSON_ARRAY_END = 10
} json_event_type;
namespace BPrivate {
class BJsonEvent {
public:
BJsonEvent(json_event_type eventType,
const char* content);
BJsonEvent(const char* content);
BJsonEvent(double content);
BJsonEvent(int64 content);
BJsonEvent(json_event_type eventType);
~BJsonEvent();
json_event_type EventType() const;
const char* Content() const;
double ContentDouble() const;
int64 ContentInteger() const;
private:
json_event_type fEventType;
const char* fContent;
char* fOwnedContent;
};
} // namespace BPrivate
using BPrivate::BJsonEvent;
#endif // _JSON_EVENT_H
@@ -0,0 +1,37 @@
/*
* Copyright 2017, Andrew Lindesay <[email protected]>
* Distributed under the terms of the MIT License.
*/
#ifndef _JSON_EVENT_LISTENER_H
#define _JSON_EVENT_LISTENER_H
#include "JsonEvent.h"
#include <String.h>
/*! This constant line number can be used in raising an error where the
client raising the error does not know on which line the error arose.
*/
#define JSON_EVENT_LISTENER_ANY_LINE -1
namespace BPrivate {
class BJsonEventListener {
public:
BJsonEventListener();
virtual ~BJsonEventListener();
virtual bool Handle(const BJsonEvent& event) = 0;
virtual void HandleError(status_t status, int32 line,
const char* message) = 0;
virtual void Complete() = 0;
};
} // namespace BPrivate
using BPrivate::BJsonEventListener;
#endif // _JSON_EVENT_LISTENER_H
@@ -0,0 +1,48 @@
/*
* Copyright 2017, Andrew Lindesay <[email protected]>
* Distributed under the terms of the MIT License.
*/
#ifndef _JSON_MESSAGE_WRITER_H
#define _JSON_MESSAGE_WRITER_H
#include "JsonWriter.h"
#include <Message.h>
#include <String.h>
enum json_message_container_what {
B_JSON_MESSAGE_WHAT_OBJECT = '_JTM',
B_JSON_MESSAGE_WHAT_ARRAY = '_JTA'
};
namespace BPrivate {
class BStackedMessageEventListener;
class BJsonMessageWriter : public BJsonWriter {
friend class BStackedMessageEventListener;
public:
BJsonMessageWriter(BMessage& message);
virtual ~BJsonMessageWriter();
bool Handle(const BJsonEvent& event);
void Complete();
private:
void SetStackedListener(
BStackedMessageEventListener* listener);
BMessage* fTopLevelMessage;
BStackedMessageEventListener*
fStackedListener;
};
} // namespace BPrivate
using BPrivate::BJsonMessageWriter;
#endif // _JSON_MESSAGE_WRITER_H
+61
View File
@@ -0,0 +1,61 @@
/*
* Copyright 2017, Andrew Lindesay <[email protected]>
* Distributed under the terms of the MIT License.
*/
#ifndef _JSON_STRING_STREAM_WRITER_H
#define _JSON_STRING_STREAM_WRITER_H
#include "JsonWriter.h"
#include <DataIO.h>
#include <String.h>
namespace BPrivate {
class BJsonTextWriterStackedEventListener;
class BJsonTextWriter : public BJsonWriter {
friend class BJsonTextWriterStackedEventListener;
public:
BJsonTextWriter(BDataIO* dataIO);
virtual ~BJsonTextWriter();
bool Handle(const BJsonEvent& event);
void Complete();
private:
void SetStackedListener(
BJsonTextWriterStackedEventListener*
stackedListener);
status_t StreamNumberNode(const BJsonEvent& event);
status_t StreamStringVerbatim(const char* string);
status_t StreamStringVerbatim(const char* string,
off_t offset, size_t length);
status_t StreamStringEncoded(const char* string);
status_t StreamStringEncoded(const char* string,
off_t offset, size_t length);
status_t StreamQuotedEncodedString(const char* string);
status_t StreamQuotedEncodedString(const char* string,
off_t offset, size_t length);
status_t StreamChar(char c);
BDataIO* fDataIO;
BJsonTextWriterStackedEventListener*
fStackedListener;
char fUnicodeAssemblyBuffer[7];
};
} // namespace BPrivate
using BPrivate::BJsonTextWriter;
#endif // _JSON_STRING_STREAM_WRITER_H
+52
View File
@@ -0,0 +1,52 @@
/*
* Copyright 2017, Andrew Lindesay <[email protected]>
* Distributed under the terms of the MIT License.
*/
#ifndef _JSON_WRITER_H
#define _JSON_WRITER_H
#include "JsonEventListener.h"
#include <DataIO.h>
#include <String.h>
namespace BPrivate {
class BJsonWriter : public BJsonEventListener {
public:
BJsonWriter();
virtual ~BJsonWriter();
void HandleError(status_t status, int32 line,
const char* message);
status_t ErrorStatus();
status_t WriteBoolean(bool value);
status_t WriteTrue();
status_t WriteFalse();
status_t WriteNull();
status_t WriteInteger(int64 value);
status_t WriteDouble(double value);
status_t WriteString(const char* value);
status_t WriteObjectStart();
status_t WriteObjectName(const char* value);
status_t WriteObjectEnd();
status_t WriteArrayStart();
status_t WriteArrayEnd();
protected:
status_t fErrorStatus;
};
} // namespace BPrivate
using BPrivate::BJsonWriter;
#endif // _JSON_WRITER_H