Implementation of JSON Streaming Parser
Addition of missing files from previous commit
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user