mirror of
https://github.com/Telecominfraproject/wlan-cloud-lib-poco.git
synced 2025-11-02 03:27:56 +00:00
replace old pdjson files with new ones
This commit is contained in:
@@ -4,7 +4,7 @@ set(POCO_LIBNAME "Poco${LIBNAME}")
|
||||
# Sources
|
||||
file(GLOB SRCS_G "src/*.cpp")
|
||||
POCO_SOURCES_AUTO( SRCS ${SRCS_G})
|
||||
POCO_SOURCES(SRCS pdjson src/pd_json.c)
|
||||
POCO_SOURCES(SRCS pdjson src/pdjson.c)
|
||||
|
||||
# Headers
|
||||
file(GLOB_RECURSE HDRS_G "include/*.h" )
|
||||
|
||||
@@ -283,7 +283,7 @@
|
||||
<ClCompile Include="src\ParseHandler.cpp" />
|
||||
<ClCompile Include="src\Parser.cpp" />
|
||||
<ClCompile Include="src\ParserImpl.cpp" />
|
||||
<ClCompile Include="src\pd_json.c" />
|
||||
<ClCompile Include="src\pdjson.c" />
|
||||
<ClCompile Include="src\PrintHandler.cpp" />
|
||||
<ClCompile Include="src\Query.cpp" />
|
||||
<ClCompile Include="src\Stringifier.cpp" />
|
||||
@@ -291,8 +291,7 @@
|
||||
<ClCompile Include="src\TemplateCache.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="include\pd_json.h" />
|
||||
<ClInclude Include="include\pd_json_private.h" />
|
||||
<ClInclude Include="src\pdjson.h" />
|
||||
<ClInclude Include="include\Poco\JSON\Array.h" />
|
||||
<ClInclude Include="include\Poco\JSON\Handler.h" />
|
||||
<ClInclude Include="include\Poco\JSON\JSON.h" />
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
<ClCompile Include="src\TemplateCache.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\pd_json.c">
|
||||
<ClCompile Include="src\pdjson.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\ParserImpl.cpp">
|
||||
@@ -86,10 +86,7 @@
|
||||
<ClInclude Include="include\Poco\JSON\TemplateCache.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\pd_json.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\pd_json_private.h">
|
||||
<ClInclude Include="src\pdjson.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\Poco\JSON\ParserImpl.h">
|
||||
|
||||
@@ -283,7 +283,7 @@
|
||||
<ClCompile Include="src\ParseHandler.cpp" />
|
||||
<ClCompile Include="src\Parser.cpp" />
|
||||
<ClCompile Include="src\ParserImpl.cpp" />
|
||||
<ClCompile Include="src\pd_json.c" />
|
||||
<ClCompile Include="src\pdjson.c" />
|
||||
<ClCompile Include="src\PrintHandler.cpp" />
|
||||
<ClCompile Include="src\Query.cpp" />
|
||||
<ClCompile Include="src\Stringifier.cpp" />
|
||||
@@ -291,8 +291,7 @@
|
||||
<ClCompile Include="src\TemplateCache.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="include\pd_json.h" />
|
||||
<ClInclude Include="include\pd_json_private.h" />
|
||||
<ClInclude Include="src\pdjson.h" />
|
||||
<ClInclude Include="include\Poco\JSON\Array.h" />
|
||||
<ClInclude Include="include\Poco\JSON\Handler.h" />
|
||||
<ClInclude Include="include\Poco\JSON\JSON.h" />
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
<ClCompile Include="src\ParserImpl.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\pd_json.c">
|
||||
<ClCompile Include="src\pdjson.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
@@ -86,10 +86,7 @@
|
||||
<ClInclude Include="include\Poco\JSON\TemplateCache.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\pd_json.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\pd_json_private.h">
|
||||
<ClInclude Include="src\pdjson.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\Poco\JSON\ParserImpl.h">
|
||||
|
||||
@@ -282,7 +282,7 @@
|
||||
<ClCompile Include="src\ParseHandler.cpp" />
|
||||
<ClCompile Include="src\Parser.cpp" />
|
||||
<ClCompile Include="src\ParserImpl.cpp" />
|
||||
<ClCompile Include="src\pd_json.c" />
|
||||
<ClCompile Include="src\pdjson.c" />
|
||||
<ClCompile Include="src\PrintHandler.cpp" />
|
||||
<ClCompile Include="src\Query.cpp" />
|
||||
<ClCompile Include="src\Stringifier.cpp" />
|
||||
@@ -303,8 +303,7 @@
|
||||
<ClInclude Include="include\Poco\JSON\Stringifier.h" />
|
||||
<ClInclude Include="include\Poco\JSON\Template.h" />
|
||||
<ClInclude Include="include\Poco\JSON\TemplateCache.h" />
|
||||
<ClInclude Include="src\pd_json.h" />
|
||||
<ClInclude Include="src\pd_json_private.h" />
|
||||
<ClInclude Include="src\pdjson.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets" />
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
<ClCompile Include="src\ParserImpl.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\pd_json.c">
|
||||
<ClCompile Include="src\pdjson.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
@@ -89,10 +89,7 @@
|
||||
<ClInclude Include="include\Poco\JSON\ParserImpl.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\pd_json.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\pd_json_private.h">
|
||||
<ClInclude Include="src\pdjson.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
|
||||
@@ -282,7 +282,7 @@
|
||||
<ClCompile Include="src\ParseHandler.cpp" />
|
||||
<ClCompile Include="src\Parser.cpp" />
|
||||
<ClCompile Include="src\ParserImpl.cpp" />
|
||||
<ClCompile Include="src\pd_json.c" />
|
||||
<ClCompile Include="src\pdjson.c" />
|
||||
<ClCompile Include="src\PrintHandler.cpp" />
|
||||
<ClCompile Include="src\Query.cpp" />
|
||||
<ClCompile Include="src\Stringifier.cpp" />
|
||||
@@ -290,8 +290,7 @@
|
||||
<ClCompile Include="src\TemplateCache.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="include\pd_json.h" />
|
||||
<ClInclude Include="include\pd_json_private.h" />
|
||||
<ClInclude Include="src\pdjson.h" />
|
||||
<ClInclude Include="include\Poco\JSON\Array.h" />
|
||||
<ClInclude Include="include\Poco\JSON\Handler.h" />
|
||||
<ClInclude Include="include\Poco\JSON\JSON.h" />
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
<ClCompile Include="src\ParserImpl.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\pd_json.c">
|
||||
<ClCompile Include="src\pdjson.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
@@ -86,13 +86,7 @@
|
||||
<ClInclude Include="include\Poco\JSON\TemplateCache.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\pd_json.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\pd_json_private.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\Poco\JSON\ParserImpl.h">
|
||||
<ClInclude Include="src\pdjson.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
|
||||
@@ -12,7 +12,7 @@ INCLUDE += -I $(POCO_BASE)/JSON/include/Poco/JSON
|
||||
|
||||
objects = Array Object Parser ParserImpl Handler \
|
||||
Stringifier ParseHandler PrintHandler Query \
|
||||
JSONException Template TemplateCache pd_json
|
||||
JSONException Template TemplateCache pdjson
|
||||
|
||||
target = PocoJSON
|
||||
target_version = $(LIBVERSION)
|
||||
|
||||
@@ -24,9 +24,7 @@
|
||||
#include <limits>
|
||||
#include <clocale>
|
||||
#include <istream>
|
||||
extern "C" {
|
||||
#include "pd_json.h"
|
||||
}
|
||||
#include "pdjson.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
@@ -1,861 +0,0 @@
|
||||
#define _POSIX_C_SOURCE 201112L
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include "pd_json.h"
|
||||
|
||||
#define json_error(json, format, ...) \
|
||||
if (!json->error) { \
|
||||
json->error = 1; \
|
||||
snprintf(json->errmsg, sizeof(json->errmsg), \
|
||||
"error: %lu: " format, \
|
||||
(unsigned long) json->lineno, \
|
||||
__VA_ARGS__); \
|
||||
} \
|
||||
|
||||
#define STACK_INC 4
|
||||
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||
#define strerror_r(err, buf, len) strerror_s(buf, len, err)
|
||||
#endif
|
||||
|
||||
static void json_error_s(json_stream *json, int err)
|
||||
{
|
||||
char errbuf[1024] = { 0 };
|
||||
strerror_r(err, errbuf, sizeof(errbuf));
|
||||
json_error(json, "%s", errbuf);
|
||||
}
|
||||
|
||||
static enum json_type
|
||||
push(json_stream *json, enum json_type type)
|
||||
{
|
||||
json->stack_top++;
|
||||
|
||||
if (json->stack_top >= json->stack_size) {
|
||||
struct json_stack *stack;
|
||||
stack = json->alloc.realloc(json->stack,
|
||||
(json->stack_size + STACK_INC) * sizeof(*json->stack));
|
||||
if (stack == NULL) {
|
||||
json_error_s(json, errno);
|
||||
return JSON_ERROR;
|
||||
}
|
||||
|
||||
json->stack_size += STACK_INC;
|
||||
json->stack = stack;
|
||||
}
|
||||
|
||||
json->stack[json->stack_top].type = type;
|
||||
json->stack[json->stack_top].count = 0;
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
static enum json_type
|
||||
pop(json_stream *json, int c, enum json_type expected)
|
||||
{
|
||||
if (json->stack == NULL || json->stack[json->stack_top].type != expected) {
|
||||
json_error(json, "unexpected byte, '%c'", c);
|
||||
return JSON_ERROR;
|
||||
}
|
||||
json->stack_top--;
|
||||
return expected == JSON_ARRAY ? JSON_ARRAY_END : JSON_OBJECT_END;
|
||||
}
|
||||
|
||||
static int buffer_peek(struct json_source *source)
|
||||
{
|
||||
if (source->position < source->source.buffer.length)
|
||||
return source->source.buffer.buffer[source->position];
|
||||
else
|
||||
return EOF;
|
||||
}
|
||||
|
||||
static int buffer_get(struct json_source *source)
|
||||
{
|
||||
int c = source->peek(source);
|
||||
source->position++;
|
||||
return c;
|
||||
}
|
||||
|
||||
static int stream_get(struct json_source *source)
|
||||
{
|
||||
source->position++;
|
||||
return fgetc(source->source.stream.stream);
|
||||
}
|
||||
|
||||
static int stream_peek(struct json_source *source)
|
||||
{
|
||||
int c = fgetc(source->source.stream.stream);
|
||||
ungetc(c, source->source.stream.stream);
|
||||
return c;
|
||||
}
|
||||
|
||||
static void init(json_stream *json)
|
||||
{
|
||||
json->lineno = 1;
|
||||
json->error = 0;
|
||||
json->errmsg[0] = '\0';
|
||||
json->ntokens = 0;
|
||||
json->next = 0;
|
||||
json->streaming = true;
|
||||
|
||||
json->stack = NULL;
|
||||
json->stack_top = -1;
|
||||
json->stack_size = 0;
|
||||
|
||||
json->data.string = NULL;
|
||||
json->data.string_size = 0;
|
||||
json->data.string_fill = 0;
|
||||
json->source.position = 0;
|
||||
|
||||
json->alloc.malloc = malloc;
|
||||
json->alloc.realloc = realloc;
|
||||
json->alloc.free = free;
|
||||
}
|
||||
|
||||
static enum json_type
|
||||
is_match(json_stream *json, const char *pattern, enum json_type type)
|
||||
{
|
||||
for (const char *p = pattern; *p; p++)
|
||||
if (*p != json->source.get(&json->source))
|
||||
return JSON_ERROR;
|
||||
return type;
|
||||
}
|
||||
|
||||
static int pushchar(json_stream *json, int c)
|
||||
{
|
||||
if (json->data.string_fill == json->data.string_size) {
|
||||
size_t size = json->data.string_size * 2;
|
||||
char *buffer = json->alloc.realloc(json->data.string, size);
|
||||
if (buffer == NULL) {
|
||||
json_error_s(json, errno);
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
json->data.string_size = size;
|
||||
json->data.string = buffer;
|
||||
}
|
||||
}
|
||||
json->data.string[json->data.string_fill++] = c;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int init_string(json_stream *json)
|
||||
{
|
||||
json->data.string_fill = 0;
|
||||
if (json->data.string == NULL) {
|
||||
json->data.string_size = 1024;
|
||||
json->data.string = json->alloc.malloc(json->data.string_size);
|
||||
if (json->data.string == NULL) {
|
||||
json_error_s(json, errno);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
json->data.string[0] = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int encode_utf8(json_stream *json, unsigned long c)
|
||||
{
|
||||
if (c < 0x80UL) {
|
||||
return pushchar(json, c);
|
||||
}
|
||||
else if (c < 0x0800UL) {
|
||||
return !((pushchar(json, (c >> 6 & 0x1F) | 0xC0) == 0) &&
|
||||
(pushchar(json, (c >> 0 & 0x3F) | 0x80) == 0));
|
||||
}
|
||||
else if (c < 0x010000UL) {
|
||||
if (c >= 0xd800 && c <= 0xdfff) {
|
||||
json_error(json, "invalid codepoint %06lx", c);
|
||||
return -1;
|
||||
}
|
||||
return !((pushchar(json, (c >> 12 & 0x0F) | 0xE0) == 0) &&
|
||||
(pushchar(json, (c >> 6 & 0x3F) | 0x80) == 0) &&
|
||||
(pushchar(json, (c >> 0 & 0x3F) | 0x80) == 0));
|
||||
}
|
||||
else if (c < 0x110000UL) {
|
||||
return !((pushchar(json, (c >> 18 & 0x07) | 0xF0) == 0) &&
|
||||
(pushchar(json, (c >> 12 & 0x3F) | 0x80) == 0) &&
|
||||
(pushchar(json, (c >> 6 & 0x3F) | 0x80) == 0) &&
|
||||
(pushchar(json, (c >> 0 & 0x3F) | 0x80) == 0));
|
||||
}
|
||||
else {
|
||||
json_error(json, "can't encode UTF-8 for %06lx", c);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int hexchar(int c)
|
||||
{
|
||||
switch (c) {
|
||||
case '0': return 0;
|
||||
case '1': return 1;
|
||||
case '2': return 2;
|
||||
case '3': return 3;
|
||||
case '4': return 4;
|
||||
case '5': return 5;
|
||||
case '6': return 6;
|
||||
case '7': return 7;
|
||||
case '8': return 8;
|
||||
case '9': return 9;
|
||||
case 'a':
|
||||
case 'A': return 10;
|
||||
case 'b':
|
||||
case 'B': return 11;
|
||||
case 'c':
|
||||
case 'C': return 12;
|
||||
case 'd':
|
||||
case 'D': return 13;
|
||||
case 'e':
|
||||
case 'E': return 14;
|
||||
case 'f':
|
||||
case 'F': return 15;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static long
|
||||
read_unicode_cp(json_stream *json)
|
||||
{
|
||||
long cp = 0;
|
||||
int shift = 12;
|
||||
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
int c = json->source.get(&json->source);
|
||||
int hc;
|
||||
|
||||
if (c == EOF) {
|
||||
json_error(json, "%s", "unterminated string literal in unicode");
|
||||
return -1;
|
||||
}
|
||||
else if ((hc = hexchar(c)) == -1) {
|
||||
json_error(json, "bad escape unicode byte, '%c'", c);
|
||||
return -1;
|
||||
}
|
||||
|
||||
cp += hc * (1 << shift);
|
||||
shift -= 4;
|
||||
}
|
||||
|
||||
|
||||
return cp;
|
||||
}
|
||||
|
||||
static int read_unicode(json_stream *json)
|
||||
{
|
||||
long cp, h, l;
|
||||
|
||||
if ((cp = read_unicode_cp(json)) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cp >= 0xd800 && cp <= 0xdbff) {
|
||||
/* This is the high portion of a surrogate pair; we need to read the
|
||||
* lower portion to get the codepoint
|
||||
*/
|
||||
h = cp;
|
||||
|
||||
int c = json->source.get(&json->source);
|
||||
if (c == EOF) {
|
||||
json_error(json, "%s", "unterminated string literal in unicode");
|
||||
return -1;
|
||||
}
|
||||
else if (c != '\\') {
|
||||
json_error(json, "invalid continuation for surrogate pair: '%c', "
|
||||
"expected '\\'", c);
|
||||
return -1;
|
||||
}
|
||||
|
||||
c = json->source.get(&json->source);
|
||||
if (c == EOF) {
|
||||
json_error(json, "%s", "unterminated string literal in unicode");
|
||||
return -1;
|
||||
}
|
||||
else if (c != 'u') {
|
||||
json_error(json, "invalid continuation for surrogate pair: '%c', "
|
||||
"expected 'u'", c);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((l = read_unicode_cp(json)) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (l < 0xdc00 || l > 0xdfff) {
|
||||
json_error(json, "invalid surrogate pair continuation \\u%04lx out "
|
||||
"of range (dc00-dfff)", l);
|
||||
return -1;
|
||||
}
|
||||
|
||||
cp = ((h - 0xd800) * 0x400) + ((l - 0xdc00) + 0x10000);
|
||||
}
|
||||
else if (cp >= 0xdc00 && cp <= 0xdfff) {
|
||||
json_error(json, "dangling surrogate \\u%04lx", cp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return encode_utf8(json, cp);
|
||||
}
|
||||
|
||||
int read_escaped(json_stream *json)
|
||||
{
|
||||
int c = json->source.get(&json->source);
|
||||
if (c == EOF) {
|
||||
json_error(json, "%s", "unterminated string literal in escape");
|
||||
return -1;
|
||||
}
|
||||
else if (c == 'u') {
|
||||
if (read_unicode(json) != 0)
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
switch (c) {
|
||||
case '\\':
|
||||
case 'b':
|
||||
case 'f':
|
||||
case 'n':
|
||||
case 'r':
|
||||
case 't':
|
||||
case '/':
|
||||
case '"':
|
||||
{
|
||||
const char *codes = "\\bfnrt/\"";
|
||||
char *p = strchr(codes, c);
|
||||
if (pushchar(json, "\\\b\f\n\r\t/\""[p - codes]) != 0)
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
json_error(json, "bad escaped byte, '%c'", c);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
char_needs_escaping(int c)
|
||||
{
|
||||
if ((c >= 0) && (c < 0x20 || c == 0x22 || c == 0x5c)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
utf8_seq_length(char byte)
|
||||
{
|
||||
unsigned char u = (unsigned char)byte;
|
||||
if (u < 0x80) return 1;
|
||||
|
||||
if (0x80 <= u && u <= 0xBF)
|
||||
{
|
||||
// second, third or fourth byte of a multi-byte
|
||||
// sequence, i.e. a "continuation byte"
|
||||
return 0;
|
||||
}
|
||||
else if (u == 0xC0 || u == 0xC1)
|
||||
{
|
||||
// overlong encoding of an ASCII byte
|
||||
return 0;
|
||||
}
|
||||
else if (0xC2 <= u && u <= 0xDF)
|
||||
{
|
||||
// 2-byte sequence
|
||||
return 2;
|
||||
}
|
||||
else if (0xE0 <= u && u <= 0xEF)
|
||||
{
|
||||
// 3-byte sequence
|
||||
return 3;
|
||||
}
|
||||
else if (0xF0 <= u && u <= 0xF4)
|
||||
{
|
||||
// 4-byte sequence
|
||||
return 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
// u >= 0xF5
|
||||
// Restricted (start of 4-, 5- or 6-byte sequence) or invalid UTF-8
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
is_legal_utf8(const unsigned char *bytes, int length)
|
||||
{
|
||||
if (0 == bytes || 0 == length) return 0;
|
||||
|
||||
unsigned char a;
|
||||
const unsigned char* srcptr = bytes + length;
|
||||
switch (length)
|
||||
{
|
||||
default:
|
||||
return 0;
|
||||
// Everything else falls through when true.
|
||||
case 4:
|
||||
if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0;
|
||||
case 3:
|
||||
if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0;
|
||||
case 2:
|
||||
a = (*--srcptr);
|
||||
switch (*bytes)
|
||||
{
|
||||
case 0xE0:
|
||||
if (a < 0xA0 || a > 0xBF) return 0;
|
||||
break;
|
||||
case 0xED:
|
||||
if (a < 0x80 || a > 0x9F) return 0;
|
||||
break;
|
||||
case 0xF0:
|
||||
if (a < 0x90 || a > 0xBF) return 0;
|
||||
break;
|
||||
case 0xF4:
|
||||
if (a < 0x80 || a > 0x8F) return 0;
|
||||
break;
|
||||
default:
|
||||
if (a < 0x80 || a > 0xBF) return 0;
|
||||
}
|
||||
case 1:
|
||||
if (*bytes >= 0x80 && *bytes < 0xC2) return 0;
|
||||
}
|
||||
return *bytes <= 0xF4;
|
||||
}
|
||||
|
||||
static int
|
||||
read_utf8(json_stream* json, int next_char)
|
||||
{
|
||||
int count = utf8_seq_length(next_char);
|
||||
if (!count)
|
||||
{
|
||||
json_error(json, "%s", "Bad character.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
char buffer[4];
|
||||
buffer[0] = next_char;
|
||||
for (int i = 1; i < count; ++i)
|
||||
{
|
||||
buffer[i] = json->source.get(&json->source);;
|
||||
}
|
||||
|
||||
if (!is_legal_utf8((unsigned char*)buffer, count))
|
||||
{
|
||||
json_error(json, "%s", "No legal UTF8 found");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
if (pushchar(json, buffer[i]) != 0)
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static enum json_type
|
||||
read_string(json_stream *json)
|
||||
{
|
||||
if (init_string(json) != 0)
|
||||
return JSON_ERROR;
|
||||
while (1) {
|
||||
int c = json->source.get(&json->source);
|
||||
if (c == EOF) {
|
||||
json_error(json, "%s", "unterminated string literal");
|
||||
return JSON_ERROR;
|
||||
}
|
||||
else if (c == '"') {
|
||||
if (pushchar(json, '\0') == 0)
|
||||
return JSON_STRING;
|
||||
else
|
||||
return JSON_ERROR;
|
||||
}
|
||||
else if (c == '\\') {
|
||||
if (read_escaped(json) != 0)
|
||||
return JSON_ERROR;
|
||||
}
|
||||
else if ((unsigned)c >= 0x80) {
|
||||
if (read_utf8(json, c) != 0)
|
||||
return JSON_ERROR;
|
||||
}
|
||||
else {
|
||||
if (char_needs_escaping(c)) {
|
||||
json_error(json, "%s", "unescaped control character in string");
|
||||
return JSON_ERROR;
|
||||
}
|
||||
|
||||
if (pushchar(json, c) != 0)
|
||||
return JSON_ERROR;
|
||||
}
|
||||
}
|
||||
return JSON_ERROR;
|
||||
}
|
||||
|
||||
static int
|
||||
is_digit(int c)
|
||||
{
|
||||
return c >= 48 /*0*/ && c <= 57 /*9*/;
|
||||
}
|
||||
|
||||
static int
|
||||
read_digits(json_stream *json)
|
||||
{
|
||||
unsigned nread = 0;
|
||||
while (is_digit(json->source.peek(&json->source))) {
|
||||
if (pushchar(json, json->source.get(&json->source)) != 0)
|
||||
return -1;
|
||||
|
||||
nread++;
|
||||
}
|
||||
|
||||
if (nread == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static enum json_type
|
||||
read_number(json_stream *json, int c)
|
||||
{
|
||||
if (pushchar(json, c) != 0)
|
||||
return JSON_ERROR;
|
||||
if (c == '-') {
|
||||
c = json->source.get(&json->source);
|
||||
if (is_digit(c)) {
|
||||
return read_number(json, c);
|
||||
}
|
||||
else {
|
||||
json_error(json, "unexpected byte, '%c'", c);
|
||||
}
|
||||
}
|
||||
else if (strchr("123456789", c) != NULL) {
|
||||
c = json->source.peek(&json->source);
|
||||
if (is_digit(c)) {
|
||||
if (read_digits(json) != 0)
|
||||
return JSON_ERROR;
|
||||
}
|
||||
}
|
||||
/* Up to decimal or exponent has been read. */
|
||||
c = json->source.peek(&json->source);
|
||||
if (strchr(".eE", c) == NULL) {
|
||||
if (pushchar(json, '\0') != 0)
|
||||
return JSON_ERROR;
|
||||
else
|
||||
return JSON_NUMBER;
|
||||
}
|
||||
if (c == '.') {
|
||||
json->source.get(&json->source); // consume .
|
||||
if (pushchar(json, c) != 0)
|
||||
return JSON_ERROR;
|
||||
if (read_digits(json) != 0)
|
||||
return JSON_ERROR;
|
||||
}
|
||||
/* Check for exponent. */
|
||||
c = json->source.peek(&json->source);
|
||||
if (c == 'e' || c == 'E') {
|
||||
json->source.get(&json->source); // consume e/E
|
||||
if (pushchar(json, c) != 0)
|
||||
return JSON_ERROR;
|
||||
c = json->source.peek(&json->source);
|
||||
if (c == '+' || c == '-') {
|
||||
json->source.get(&json->source); // consume
|
||||
if (pushchar(json, c) != 0)
|
||||
return JSON_ERROR;
|
||||
if (read_digits(json) != 0)
|
||||
return JSON_ERROR;
|
||||
}
|
||||
else if (is_digit(c)) {
|
||||
if (read_digits(json) != 0)
|
||||
return JSON_ERROR;
|
||||
}
|
||||
else {
|
||||
json_error(json, "unexpected byte in number, '%c'", c);
|
||||
return JSON_ERROR;
|
||||
}
|
||||
}
|
||||
if (pushchar(json, '\0') != 0)
|
||||
return JSON_ERROR;
|
||||
else
|
||||
return JSON_NUMBER;
|
||||
}
|
||||
|
||||
static int
|
||||
json_isspace(int c)
|
||||
{
|
||||
switch (c) {
|
||||
case 0x09:
|
||||
case 0x0a:
|
||||
case 0x0d:
|
||||
case 0x20:
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Returns the next non-whitespace character in the stream. */
|
||||
static int next(json_stream *json)
|
||||
{
|
||||
int c;
|
||||
while (json_isspace(c = json->source.get(&json->source)))
|
||||
if (c == '\n')
|
||||
json->lineno++;
|
||||
return c;
|
||||
}
|
||||
|
||||
static enum json_type
|
||||
read_value(json_stream *json, int c)
|
||||
{
|
||||
json->ntokens++;
|
||||
switch (c) {
|
||||
case EOF:
|
||||
json_error(json, "%s", "unexpected end of data");
|
||||
return JSON_ERROR;
|
||||
case '{':
|
||||
return push(json, JSON_OBJECT);
|
||||
case '[':
|
||||
return push(json, JSON_ARRAY);
|
||||
case '"':
|
||||
return read_string(json);
|
||||
case 'n':
|
||||
return is_match(json, "ull", JSON_NULL);
|
||||
case 'f':
|
||||
return is_match(json, "alse", JSON_FALSE);
|
||||
case 't':
|
||||
return is_match(json, "rue", JSON_TRUE);
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
case '-':
|
||||
if (init_string(json) != 0)
|
||||
return JSON_ERROR;
|
||||
return read_number(json, c);
|
||||
default:
|
||||
json_error(json, "unexpected byte, '%c'", c);
|
||||
return JSON_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
enum json_type json_peek(json_stream *json)
|
||||
{
|
||||
enum json_type next = json_next(json);
|
||||
json->next = next;
|
||||
return next;
|
||||
}
|
||||
|
||||
enum json_type json_next(json_stream *json)
|
||||
{
|
||||
if (json->error)
|
||||
return JSON_ERROR;
|
||||
if (json->next != 0) {
|
||||
enum json_type next = json->next;
|
||||
json->next = 0;
|
||||
return next;
|
||||
}
|
||||
if (json->ntokens > 0 && json->stack_top == (size_t)-1) {
|
||||
int c;
|
||||
|
||||
do {
|
||||
c = json->source.peek(&json->source);
|
||||
if (json_isspace(c)) {
|
||||
c = json->source.get(&json->source);
|
||||
}
|
||||
} while (json_isspace(c));
|
||||
|
||||
if (!json->streaming && c != EOF) {
|
||||
return JSON_ERROR;
|
||||
}
|
||||
|
||||
return JSON_DONE;
|
||||
}
|
||||
int c = next(json);
|
||||
if (json->stack_top == (size_t)-1)
|
||||
return read_value(json, c);
|
||||
if (json->stack[json->stack_top].type == JSON_ARRAY) {
|
||||
if (json->stack[json->stack_top].count == 0) {
|
||||
if (c == ']') {
|
||||
return pop(json, c, JSON_ARRAY);
|
||||
}
|
||||
json->stack[json->stack_top].count++;
|
||||
return read_value(json, c);
|
||||
}
|
||||
else if (c == ',') {
|
||||
json->stack[json->stack_top].count++;
|
||||
return read_value(json, next(json));
|
||||
}
|
||||
else if (c == ']') {
|
||||
return pop(json, c, JSON_ARRAY);
|
||||
}
|
||||
else {
|
||||
json_error(json, "unexpected byte, '%c'", c);
|
||||
return JSON_ERROR;
|
||||
}
|
||||
}
|
||||
else if (json->stack[json->stack_top].type == JSON_OBJECT) {
|
||||
if (json->stack[json->stack_top].count == 0) {
|
||||
if (c == '}') {
|
||||
return pop(json, c, JSON_OBJECT);
|
||||
}
|
||||
|
||||
/* No property value pairs yet. */
|
||||
enum json_type value = read_value(json, c);
|
||||
if (value != JSON_STRING) {
|
||||
json_error(json, "%s", "expected property name or '}'");
|
||||
return JSON_ERROR;
|
||||
}
|
||||
else {
|
||||
json->stack[json->stack_top].count++;
|
||||
return value;
|
||||
}
|
||||
}
|
||||
else if ((json->stack[json->stack_top].count % 2) == 0) {
|
||||
/* Expecting comma followed by property name. */
|
||||
if (c != ',' && c != '}') {
|
||||
json_error(json, "%s", "expected ',' or '}'");
|
||||
return JSON_ERROR;
|
||||
}
|
||||
else if (c == '}') {
|
||||
return pop(json, c, JSON_OBJECT);
|
||||
}
|
||||
else {
|
||||
enum json_type value = read_value(json, next(json));
|
||||
if (value != JSON_STRING) {
|
||||
json_error(json, "%s", "expected property name");
|
||||
return JSON_ERROR;
|
||||
}
|
||||
else {
|
||||
json->stack[json->stack_top].count++;
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((json->stack[json->stack_top].count % 2) == 1) {
|
||||
/* Expecting colon followed by value. */
|
||||
if (c != ':') {
|
||||
json_error(json, "%s", "expected ':' after property name");
|
||||
return JSON_ERROR;
|
||||
}
|
||||
else {
|
||||
json->stack[json->stack_top].count++;
|
||||
return read_value(json, next(json));
|
||||
}
|
||||
}
|
||||
}
|
||||
json_error(json, "%s", "invalid parser state");
|
||||
return JSON_ERROR;
|
||||
}
|
||||
|
||||
void json_reset(json_stream *json)
|
||||
{
|
||||
json->stack_top = -1;
|
||||
json->ntokens = 0;
|
||||
json->error = 0;
|
||||
json->errmsg[0] = '\0';
|
||||
}
|
||||
|
||||
const char *json_get_string(json_stream *json, size_t *length)
|
||||
{
|
||||
if (length != NULL)
|
||||
*length = json->data.string_fill;
|
||||
if (json->data.string == NULL)
|
||||
return "";
|
||||
else
|
||||
return json->data.string;
|
||||
}
|
||||
|
||||
double json_get_number(json_stream *json)
|
||||
{
|
||||
char *p = json->data.string;
|
||||
return p == NULL ? 0 : strtod(p, NULL);
|
||||
}
|
||||
|
||||
const char *json_get_error(json_stream *json)
|
||||
{
|
||||
return json->error ? json->errmsg : NULL;
|
||||
}
|
||||
|
||||
size_t json_get_lineno(json_stream *json)
|
||||
{
|
||||
return json->lineno;
|
||||
}
|
||||
|
||||
size_t json_get_position(json_stream *json)
|
||||
{
|
||||
return json->source.position;
|
||||
}
|
||||
|
||||
size_t json_get_depth(json_stream *json)
|
||||
{
|
||||
return json->stack_top + 1;
|
||||
}
|
||||
|
||||
void json_open_buffer(json_stream *json, const void *buffer, size_t size)
|
||||
{
|
||||
init(json);
|
||||
json->source.get = buffer_get;
|
||||
json->source.peek = buffer_peek;
|
||||
json->source.source.buffer.buffer = buffer;
|
||||
json->source.source.buffer.length = size;
|
||||
}
|
||||
|
||||
void json_open_string(json_stream *json, const char *string)
|
||||
{
|
||||
json_open_buffer(json, string, strlen(string));
|
||||
}
|
||||
|
||||
void json_open_stream(json_stream *json, FILE * stream)
|
||||
{
|
||||
init(json);
|
||||
json->source.get = stream_get;
|
||||
json->source.peek = stream_peek;
|
||||
json->source.source.stream.stream = stream;
|
||||
}
|
||||
|
||||
static int user_get(struct json_source *json)
|
||||
{
|
||||
return json->source.user.get(json->source.user.ptr);
|
||||
}
|
||||
|
||||
static int user_peek(struct json_source *json)
|
||||
{
|
||||
return json->source.user.peek(json->source.user.ptr);
|
||||
}
|
||||
|
||||
void json_open_user(json_stream *json, json_user_io get, json_user_io peek, void *user)
|
||||
{
|
||||
init(json);
|
||||
json->source.get = user_get;
|
||||
json->source.peek = user_peek;
|
||||
json->source.source.user.ptr = user;
|
||||
json->source.source.user.get = get;
|
||||
json->source.source.user.peek = peek;
|
||||
}
|
||||
|
||||
void json_set_allocator(json_stream *json, json_allocator *a)
|
||||
{
|
||||
json->alloc = *a;
|
||||
}
|
||||
|
||||
void json_set_streaming(json_stream *json, bool streaming)
|
||||
{
|
||||
json->streaming = streaming;
|
||||
}
|
||||
|
||||
void json_close(json_stream *json)
|
||||
{
|
||||
json->alloc.free(json->stack);
|
||||
json->alloc.free(json->data.string);
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
#ifndef PDJSON_H
|
||||
#define PDJSON_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
enum json_type {
|
||||
JSON_ERROR = 1, JSON_DONE,
|
||||
JSON_OBJECT, JSON_OBJECT_END, JSON_ARRAY, JSON_ARRAY_END,
|
||||
JSON_STRING, JSON_NUMBER, JSON_TRUE, JSON_FALSE, JSON_NULL
|
||||
};
|
||||
|
||||
struct json_allocator {
|
||||
void *(*malloc)(size_t);
|
||||
void *(*realloc)(void *, size_t);
|
||||
void(*free)(void *);
|
||||
};
|
||||
|
||||
typedef int(*json_user_io) (void *user);
|
||||
|
||||
#include "pd_json_private.h"
|
||||
|
||||
typedef struct json_stream json_stream;
|
||||
typedef struct json_allocator json_allocator;
|
||||
|
||||
void json_open_buffer(json_stream *json, const void *buffer, size_t size);
|
||||
void json_open_string(json_stream *json, const char *string);
|
||||
void json_open_stream(json_stream *json, FILE *stream);
|
||||
void json_open_user(json_stream *json, json_user_io get, json_user_io peek, void *user);
|
||||
void json_close(json_stream *json);
|
||||
|
||||
void json_set_allocator(json_stream *json, json_allocator *a);
|
||||
void json_set_streaming(json_stream *json, bool strict);
|
||||
|
||||
enum json_type json_next(json_stream *json);
|
||||
enum json_type json_peek(json_stream *json);
|
||||
void json_reset(json_stream *json);
|
||||
const char *json_get_string(json_stream *json, size_t *length);
|
||||
double json_get_number(json_stream *json);
|
||||
|
||||
size_t json_get_lineno(json_stream *json);
|
||||
size_t json_get_position(json_stream *json);
|
||||
size_t json_get_depth(json_stream *json);
|
||||
const char *json_get_error(json_stream *json);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
||||
@@ -1,55 +0,0 @@
|
||||
#ifndef PDJSON_PRIVATE_H
|
||||
#define PDJSON_PRIVATE_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
struct json_source {
|
||||
int(*get) (struct json_source *);
|
||||
int(*peek) (struct json_source *);
|
||||
size_t position;
|
||||
union {
|
||||
struct {
|
||||
FILE *stream;
|
||||
} stream;
|
||||
struct {
|
||||
const char *buffer;
|
||||
size_t length;
|
||||
} buffer;
|
||||
struct {
|
||||
void *ptr;
|
||||
json_user_io get;
|
||||
json_user_io peek;
|
||||
} user;
|
||||
} source;
|
||||
};
|
||||
|
||||
struct json_stack {
|
||||
enum json_type type;
|
||||
long count;
|
||||
};
|
||||
|
||||
struct json_stream {
|
||||
size_t lineno;
|
||||
|
||||
struct json_stack *stack;
|
||||
size_t stack_top;
|
||||
size_t stack_size;
|
||||
enum json_type next;
|
||||
int error : 31;
|
||||
bool streaming : 1;
|
||||
|
||||
struct {
|
||||
char *string;
|
||||
size_t string_fill;
|
||||
size_t string_size;
|
||||
} data;
|
||||
|
||||
size_t ntokens;
|
||||
|
||||
struct json_source source;
|
||||
struct json_allocator alloc;
|
||||
char errmsg[128];
|
||||
};
|
||||
|
||||
#endif
|
||||
2
openssl
2
openssl
Submodule openssl updated: ab73856528...a029ea50e8
Reference in New Issue
Block a user