Merge changes from 3.16 and below into libcom/master
This commit is contained in:
@@ -79,6 +79,7 @@ include $(LIBCOM)/error/RULES
|
||||
include $(LIBCOM)/flex/RULES
|
||||
include $(LIBCOM)/misc/RULES
|
||||
include $(LIBCOM)/osi/RULES
|
||||
include $(LIBCOM)/yajl/RULES
|
||||
|
||||
# Can't use EXPAND as generated headers must appear
|
||||
# in O.Common, but EXPAND emits rules for O.$(T_A)
|
||||
|
||||
@@ -31,6 +31,7 @@ typedef int SOCKET;
|
||||
#define socket_ioctl(A,B,C) ioctl(A,B,C)
|
||||
typedef int osiSockIoctl_t;
|
||||
typedef socklen_t osiSocklen_t;
|
||||
typedef int osiSockOptMcastLoop_t;
|
||||
|
||||
#define FD_IN_FDSET(FD) ((FD)<FD_SETSIZE)
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ typedef int SOCKET;
|
||||
#define socket_ioctl(A,B,C) ioctl(A,B,C)
|
||||
typedef int osiSockIoctl_t;
|
||||
typedef socklen_t osiSocklen_t;
|
||||
typedef int osiSockOptMcastLoop_t;
|
||||
|
||||
#define FD_IN_FDSET(FD) ((FD)<FD_SETSIZE)
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ typedef int SOCKET;
|
||||
#define socket_ioctl(A,B,C) ioctl(A,B,C)
|
||||
typedef int osiSockIoctl_t;
|
||||
typedef socklen_t osiSocklen_t;
|
||||
typedef char osiSockOptMcastLoop_t;
|
||||
|
||||
#define FD_IN_FDSET(FD) ((FD)<FD_SETSIZE)
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#define socket_ioctl(A,B,C) ioctlsocket(A,B,C)
|
||||
typedef u_long FAR osiSockIoctl_t;
|
||||
typedef int osiSocklen_t;
|
||||
typedef BOOL osiSockOptMcastLoop_t;
|
||||
|
||||
#ifndef SHUT_RD
|
||||
# define SHUT_RD SD_RECEIVE
|
||||
|
||||
@@ -34,6 +34,7 @@ typedef int SOCKET;
|
||||
#define socket_ioctl(A,B,C) ioctl(A,B,C)
|
||||
typedef int osiSockIoctl_t;
|
||||
typedef int osiSocklen_t;
|
||||
typedef int osiSockOptMcastLoop_t;
|
||||
#define FD_IN_FDSET(FD) ((FD)<FD_SETSIZE&&(FD)>=0)
|
||||
#ifndef SHUT_RD
|
||||
#define SHUT_RD 0
|
||||
|
||||
@@ -36,6 +36,7 @@ typedef int SOCKET;
|
||||
#define socket_ioctl(A,B,C) ioctl(A,B,C)
|
||||
typedef int osiSockIoctl_t;
|
||||
typedef socklen_t osiSocklen_t;
|
||||
typedef int osiSockOptMcastLoop_t;
|
||||
|
||||
#define FD_IN_FDSET(FD) ((FD)<FD_SETSIZE)
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ typedef int SOCKET;
|
||||
#define socket_ioctl(A,B,C) ioctl(A,B,C)
|
||||
typedef int osiSockIoctl_t;
|
||||
typedef socklen_t osiSocklen_t;
|
||||
typedef int osiSockOptMcastLoop_t;
|
||||
|
||||
#define FD_IN_FDSET(FD) ((FD)<FD_SETSIZE)
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ typedef int osiSockIoctl_t;
|
||||
#else
|
||||
typedef int osiSocklen_t;
|
||||
#endif
|
||||
typedef char osiSockOptMcastLoop_t;
|
||||
|
||||
#define DOES_NOT_ACCEPT_ZERO_LENGTH_UDP
|
||||
|
||||
|
||||
@@ -65,6 +65,7 @@ typedef int SOCKET;
|
||||
#define socket_ioctl(A,B,C) ioctl(A,B,(int)C)
|
||||
typedef int osiSockIoctl_t;
|
||||
typedef int osiSocklen_t;
|
||||
typedef int osiSockOptMcastLoop_t;
|
||||
|
||||
#define FD_IN_FDSET(FD) ((FD)<FD_SETSIZE&&(FD)>=0)
|
||||
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
record(ai, "alarm") {
|
||||
field(HIGH, 1)
|
||||
field(HSV, MINOR)
|
||||
field(HIHI, 2)
|
||||
field(HHSV, MAJOR)
|
||||
field(FLNK, "latch")
|
||||
}
|
||||
|
||||
record(calc, "latch") {
|
||||
field(INPA, "alarm NPP MS")
|
||||
field(INPB, "latch NPP MS")
|
||||
field(CALC, "A")
|
||||
}
|
||||
@@ -1,169 +0,0 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2017 UChicago Argonne LLC, as operator of Argonne
|
||||
* National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "dbAccess.h"
|
||||
#include "dbStaticLib.h"
|
||||
#include "dbTest.h"
|
||||
#include "dbUnitTest.h"
|
||||
#include "errlog.h"
|
||||
#include "registryFunction.h"
|
||||
#include "subRecord.h"
|
||||
#include "testMain.h"
|
||||
|
||||
static
|
||||
void checkDtyp(const char *rec)
|
||||
{
|
||||
char dtyp[16];
|
||||
|
||||
strcpy(dtyp, rec);
|
||||
strcat(dtyp, ".DTYP");
|
||||
|
||||
testdbGetFieldEqual(dtyp, DBF_LONG, 0); /* Soft Channel = 0 */
|
||||
}
|
||||
|
||||
static
|
||||
void checkInput(const char *rec, int value)
|
||||
{
|
||||
char proc[16];
|
||||
|
||||
testDiag("Checking record '%s'", rec);
|
||||
|
||||
strcpy(proc, rec);
|
||||
strcat(proc, ".PROC");
|
||||
|
||||
testdbPutFieldOk(proc, DBF_CHAR, 1);
|
||||
|
||||
testdbGetFieldEqual(rec, DBF_LONG, value);
|
||||
}
|
||||
|
||||
static
|
||||
void testGroup0(void)
|
||||
{
|
||||
const char ** rec;
|
||||
const char * records[] = {
|
||||
"ai0", "bi0", "di0", "ii0", "li0", "lsi0", "mi0", "si0", NULL
|
||||
};
|
||||
|
||||
testDiag("============ Starting %s ============", EPICS_FUNCTION);
|
||||
|
||||
testdbPutFieldOk("source", DBF_LONG, 1);
|
||||
for (rec = records; *rec; rec++) {
|
||||
checkInput(*rec, 1);
|
||||
checkDtyp(*rec);
|
||||
}
|
||||
|
||||
testdbPutFieldOk("source", DBF_LONG, 0);
|
||||
for (rec = records; *rec; rec++) {
|
||||
checkInput(*rec, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void testGroup1(void)
|
||||
{
|
||||
const char ** rec;
|
||||
const char * records[] = {
|
||||
"bi1",
|
||||
"ai1", "di1", "ii1", "li1", "lsi1", "mi1", "si1", NULL
|
||||
};
|
||||
int init = 1; /* bi1 initializes to 1 */
|
||||
|
||||
testDiag("============ Starting %s ============", EPICS_FUNCTION);
|
||||
|
||||
for (rec = records; *rec; rec++) {
|
||||
checkInput(*rec, init);
|
||||
init = 9; /* remainder initialize to 9 */
|
||||
}
|
||||
}
|
||||
|
||||
int dest;
|
||||
|
||||
static
|
||||
long destSubr(subRecord *prec)
|
||||
{
|
||||
dest = prec->val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
void checkOutput(const char *rec, int value)
|
||||
{
|
||||
testDiag("Checking record '%s'", rec);
|
||||
|
||||
testdbPutFieldOk(rec, DBF_LONG, value);
|
||||
|
||||
testOk(dest == value, "value %d output -> %d", value, dest);
|
||||
}
|
||||
|
||||
static
|
||||
void testGroup2(void)
|
||||
{
|
||||
const char ** rec;
|
||||
const char * records[] = {
|
||||
"ao0", "bo0", "io0", "lo0", "lso0", "mo0", "so0", NULL,
|
||||
};
|
||||
|
||||
testDiag("============ Starting %s ============", EPICS_FUNCTION);
|
||||
|
||||
for (rec = records; *rec; rec++) {
|
||||
checkOutput(*rec, 1);
|
||||
checkDtyp(*rec);
|
||||
}
|
||||
checkOutput("do0.B0", 1);
|
||||
checkDtyp("do0");
|
||||
|
||||
for (rec = records; *rec; rec++) {
|
||||
checkOutput(*rec, 0);
|
||||
}
|
||||
checkOutput("do0.B0", 0);
|
||||
}
|
||||
|
||||
static
|
||||
void testGroup3(void)
|
||||
{
|
||||
const char ** rec;
|
||||
const char * records[] = {
|
||||
"ao1", "bo1", "do1.B0", "io1", "lo1", "lso1", "mo1", "so1", NULL,
|
||||
};
|
||||
|
||||
testDiag("============ Starting %s ============", EPICS_FUNCTION);
|
||||
|
||||
for (rec = records; *rec; rec++) {
|
||||
checkOutput(*rec, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void recTestIoc_registerRecordDeviceDriver(struct dbBase *);
|
||||
|
||||
MAIN(softTest)
|
||||
{
|
||||
testPlan(114);
|
||||
|
||||
testdbPrepare();
|
||||
testdbReadDatabase("recTestIoc.dbd", NULL, NULL);
|
||||
|
||||
recTestIoc_registerRecordDeviceDriver(pdbbase);
|
||||
registryFunctionAdd("destSubr", (REGISTRYFUNCTION) destSubr);
|
||||
|
||||
testdbReadDatabase("softTest.db", NULL, NULL);
|
||||
|
||||
eltc(0);
|
||||
testIocInitOk();
|
||||
eltc(1);
|
||||
|
||||
testGroup0();
|
||||
testGroup1();
|
||||
testGroup2();
|
||||
testGroup3();
|
||||
|
||||
testIocShutdownOk();
|
||||
testdbCleanup();
|
||||
|
||||
return testDone();
|
||||
}
|
||||
@@ -1,227 +0,0 @@
|
||||
# Group 0 are input records with INP being a DB link to 'source'.
|
||||
# Processing them reads that value.
|
||||
|
||||
record(longin, "source") {}
|
||||
|
||||
record(ai, "ai0") {
|
||||
field(DTYP, "Soft Channel")
|
||||
field(INP, "source")
|
||||
}
|
||||
record(bi, "bi0") {
|
||||
field(DTYP, "Soft Channel")
|
||||
field(INP, "source")
|
||||
field(ZNAM, "Zero")
|
||||
field(ONAM, "One")
|
||||
}
|
||||
record(int64in, "ii0") {
|
||||
field(DTYP, "Soft Channel")
|
||||
field(INP, "source")
|
||||
}
|
||||
record(longin, "li0") {
|
||||
field(DTYP, "Soft Channel")
|
||||
field(INP, "source")
|
||||
}
|
||||
record(mbbiDirect, "di0") {
|
||||
field(DTYP, "Soft Channel")
|
||||
field(NOBT, 4)
|
||||
field(INP, "source")
|
||||
}
|
||||
record(mbbi, "mi0") {
|
||||
field(DTYP, "Soft Channel")
|
||||
field(NOBT, 4)
|
||||
field(INP, "source")
|
||||
field(ZRST, "Zero")
|
||||
field(ONST, "One")
|
||||
field(TWST, "Two")
|
||||
field(THST, "Three")
|
||||
field(FRST, "Four")
|
||||
field(FVST, "Five")
|
||||
field(SXST, "Six")
|
||||
field(SVST, "Seven")
|
||||
field(EIST, "Eight")
|
||||
field(NIST, "Nine")
|
||||
field(TEST, "Ten")
|
||||
field(ELST, "Eleven")
|
||||
field(TWST, "Twelve")
|
||||
field(TTST, "Thirteen")
|
||||
field(FTST, "Fourteen")
|
||||
field(FFST, "Fifteen")
|
||||
}
|
||||
record(lsi, "lsi0") {
|
||||
field(DTYP, "Soft Channel")
|
||||
field(SIZV, 40)
|
||||
field(INP, "source")
|
||||
}
|
||||
record(stringin, "si0") {
|
||||
field(DTYP, "Soft Channel")
|
||||
field(INP, "source")
|
||||
}
|
||||
|
||||
# Group 1 are input records with INP being a non-zero constant.
|
||||
# Processing them succeeds but does not change VAL.
|
||||
|
||||
record(ai, "ai1") {
|
||||
field(DTYP, "Soft Channel")
|
||||
field(INP, {const:9})
|
||||
}
|
||||
record(bi, "bi1") {
|
||||
field(DTYP, "Soft Channel")
|
||||
field(INP, {const:1})
|
||||
field(ZNAM, "Zero")
|
||||
field(ONAM, "One")
|
||||
}
|
||||
record(int64in, "ii1") {
|
||||
field(DTYP, "Soft Channel")
|
||||
field(INP, {const:9})
|
||||
}
|
||||
record(longin, "li1") {
|
||||
field(DTYP, "Soft Channel")
|
||||
field(INP, {const:9})
|
||||
}
|
||||
record(mbbiDirect, "di1") {
|
||||
field(DTYP, "Soft Channel")
|
||||
field(NOBT, 4)
|
||||
field(INP, {const:9})
|
||||
}
|
||||
record(mbbi, "mi1") {
|
||||
field(DTYP, "Soft Channel")
|
||||
field(NOBT, 4)
|
||||
field(INP, {const:9})
|
||||
field(ZRST, "Zero")
|
||||
field(ONST, "One")
|
||||
field(TWST, "Two")
|
||||
field(THST, "Three")
|
||||
field(FRST, "Four")
|
||||
field(FVST, "Five")
|
||||
field(SXST, "Six")
|
||||
field(SVST, "Seven")
|
||||
field(EIST, "Eight")
|
||||
field(NIST, "Nine")
|
||||
field(TEST, "Ten")
|
||||
field(ELST, "Eleven")
|
||||
field(TWST, "Twelve")
|
||||
field(TTST, "Thirteen")
|
||||
field(FTST, "Fourteen")
|
||||
field(FFST, "Fifteen")
|
||||
}
|
||||
record(lsi, "lsi1") {
|
||||
field(DTYP, "Soft Channel")
|
||||
field(SIZV, 40)
|
||||
field(INP, {const:"9"})
|
||||
}
|
||||
record(stringin, "si1") {
|
||||
field(DTYP, "Soft Channel")
|
||||
field(INP, {const:"9"})
|
||||
}
|
||||
|
||||
|
||||
# Group 2 are output records with OUT being a DB link to 'dest' with PP.
|
||||
# Putting a value to them writes that value to 'dest'.
|
||||
|
||||
record(sub, "dest") {
|
||||
field(SNAM, "destSubr")
|
||||
}
|
||||
|
||||
record(ao, "ao0") {
|
||||
field(DTYP, "Soft Channel")
|
||||
field(OUT, "dest PP")
|
||||
}
|
||||
record(bo, "bo0") {
|
||||
field(DTYP, "Soft Channel")
|
||||
field(OUT, "dest PP")
|
||||
field(ZNAM, "Zero")
|
||||
field(ONAM, "One")
|
||||
}
|
||||
record(int64out, "io0") {
|
||||
field(DTYP, "Soft Channel")
|
||||
field(OUT, "dest PP")
|
||||
}
|
||||
record(longout, "lo0") {
|
||||
field(DTYP, "Soft Channel")
|
||||
field(OUT, "dest PP")
|
||||
}
|
||||
record(mbboDirect, "do0") {
|
||||
field(DTYP, "Soft Channel")
|
||||
field(NOBT, 4)
|
||||
field(OUT, "dest PP")
|
||||
}
|
||||
record(mbbo, "mo0") {
|
||||
field(DTYP, "Soft Channel")
|
||||
field(NOBT, 4)
|
||||
field(OUT, "dest PP")
|
||||
field(ZRST, "Zero")
|
||||
field(ONST, "One")
|
||||
field(TWST, "Two")
|
||||
field(THST, "Three")
|
||||
field(FRST, "Four")
|
||||
field(FVST, "Five")
|
||||
field(SXST, "Six")
|
||||
field(SVST, "Seven")
|
||||
field(EIST, "Eight")
|
||||
field(NIST, "Nine")
|
||||
field(TEST, "Ten")
|
||||
field(ELST, "Eleven")
|
||||
field(TWST, "Twelve")
|
||||
field(TTST, "Thirteen")
|
||||
field(FTST, "Fourteen")
|
||||
field(FFST, "Fifteen")
|
||||
}
|
||||
record(lso, "lso0") {
|
||||
field(DTYP, "Soft Channel")
|
||||
field(OUT, "dest PP")
|
||||
field(SIZV, 40)
|
||||
}
|
||||
record(stringout, "so0") {
|
||||
field(DTYP, "Soft Channel")
|
||||
field(OUT, "dest PP")
|
||||
}
|
||||
|
||||
|
||||
# Group 3 are output records with OUT being empty (a constant link).
|
||||
# Putting a value to them must succeed.
|
||||
|
||||
record(ao, "ao1") {
|
||||
field(DTYP, "Soft Channel")
|
||||
}
|
||||
record(bo, "bo1") {
|
||||
field(DTYP, "Soft Channel")
|
||||
field(ZNAM, "Zero")
|
||||
field(ONAM, "One")
|
||||
}
|
||||
record(int64out, "io1") {
|
||||
field(DTYP, "Soft Channel")
|
||||
}
|
||||
record(longout, "lo1") {
|
||||
field(DTYP, "Soft Channel")
|
||||
}
|
||||
record(mbboDirect, "do1") {
|
||||
field(DTYP, "Soft Channel")
|
||||
field(NOBT, 4)
|
||||
}
|
||||
record(mbbo, "mo1") {
|
||||
field(DTYP, "Soft Channel")
|
||||
field(NOBT, 4)
|
||||
field(ZRST, "Zero")
|
||||
field(ONST, "One")
|
||||
field(TWST, "Two")
|
||||
field(THST, "Three")
|
||||
field(FRST, "Four")
|
||||
field(FVST, "Five")
|
||||
field(SXST, "Six")
|
||||
field(SVST, "Seven")
|
||||
field(EIST, "Eight")
|
||||
field(NIST, "Nine")
|
||||
field(TEST, "Ten")
|
||||
field(ELST, "Eleven")
|
||||
field(TWST, "Twelve")
|
||||
field(TTST, "Thirteen")
|
||||
field(FTST, "Fourteen")
|
||||
field(FFST, "Fifteen")
|
||||
}
|
||||
record(lso, "lso1") {
|
||||
field(DTYP, "Soft Channel")
|
||||
field(SIZV, 40)
|
||||
}
|
||||
record(stringout, "so1") {
|
||||
field(DTYP, "Soft Channel")
|
||||
}
|
||||
17
src/yajl/RULES
Normal file
17
src/yajl/RULES
Normal file
@@ -0,0 +1,17 @@
|
||||
#*************************************************************************
|
||||
# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne
|
||||
# National Laboratory.
|
||||
# EPICS BASE is distributed subject to a Software License Agreement found
|
||||
# in file LICENSE that is included with this distribution.
|
||||
#*************************************************************************
|
||||
|
||||
# This is a Makefile fragment, see src/libCom/Makefile.
|
||||
|
||||
# Ensure epicsVersion.h gets built first
|
||||
yajl$(DEP): $(COMMON_DIR)/epicsVersion.h
|
||||
yajl_alloc$(DEP): $(COMMON_DIR)/epicsVersion.h
|
||||
yajl_buf$(DEP): $(COMMON_DIR)/epicsVersion.h
|
||||
yajl_encode$(DEP): $(COMMON_DIR)/epicsVersion.h
|
||||
yajl_gen$(DEP): $(COMMON_DIR)/epicsVersion.h
|
||||
yajl_lex$(DEP): $(COMMON_DIR)/epicsVersion.h
|
||||
yajl_parser$(DEP): $(COMMON_DIR)/epicsVersion.h
|
||||
138
src/yajl/yajl.c
138
src/yajl/yajl.c
@@ -1,37 +1,22 @@
|
||||
/*
|
||||
* Copyright 2010, Lloyd Hilaiel.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. Neither the name of Lloyd Hilaiel nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
* Copyright (c) 2007-2011, Lloyd Hilaiel <lloyd@hilaiel.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
@@ -51,9 +36,6 @@ yajl_status_to_string(yajl_status stat)
|
||||
case yajl_status_client_canceled:
|
||||
statStr = "client canceled parse";
|
||||
break;
|
||||
case yajl_status_insufficient_data:
|
||||
statStr = "eof was met before the parse could complete";
|
||||
break;
|
||||
case yajl_status_error:
|
||||
statStr = "parse error";
|
||||
break;
|
||||
@@ -63,15 +45,12 @@ yajl_status_to_string(yajl_status stat)
|
||||
|
||||
yajl_handle
|
||||
yajl_alloc(const yajl_callbacks * callbacks,
|
||||
const yajl_parser_config * config,
|
||||
const yajl_alloc_funcs * afs,
|
||||
yajl_alloc_funcs * afs,
|
||||
void * ctx)
|
||||
{
|
||||
unsigned int allowComments = 0;
|
||||
unsigned int validateUTF8 = 0;
|
||||
yajl_handle hand = NULL;
|
||||
yajl_alloc_funcs afsBuffer;
|
||||
|
||||
|
||||
/* first order of business is to set up memory allocation routines */
|
||||
if (afs != NULL) {
|
||||
if (afs->malloc == NULL || afs->realloc == NULL || afs->free == NULL)
|
||||
@@ -84,65 +63,108 @@ yajl_alloc(const yajl_callbacks * callbacks,
|
||||
}
|
||||
|
||||
hand = (yajl_handle) YA_MALLOC(afs, sizeof(struct yajl_handle_t));
|
||||
if (hand == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* copy in pointers to allocation routines */
|
||||
memcpy((void *) &(hand->alloc), (void *) afs, sizeof(yajl_alloc_funcs));
|
||||
|
||||
if (config != NULL) {
|
||||
allowComments = config->allowComments;
|
||||
validateUTF8 = config->checkUTF8;
|
||||
}
|
||||
|
||||
hand->callbacks = callbacks;
|
||||
hand->ctx = ctx;
|
||||
hand->lexer = yajl_lex_alloc(&(hand->alloc), allowComments, validateUTF8);
|
||||
hand->lexer = NULL;
|
||||
hand->bytesConsumed = 0;
|
||||
hand->decodeBuf = yajl_buf_alloc(&(hand->alloc));
|
||||
hand->flags = 0;
|
||||
yajl_bs_init(hand->stateStack, &(hand->alloc));
|
||||
|
||||
yajl_bs_push(hand->stateStack, yajl_state_start);
|
||||
yajl_bs_push(hand->stateStack, yajl_state_start);
|
||||
|
||||
return hand;
|
||||
}
|
||||
|
||||
int
|
||||
yajl_config(yajl_handle h, yajl_option opt, ...)
|
||||
{
|
||||
int rv = 1;
|
||||
va_list ap;
|
||||
va_start(ap, opt);
|
||||
|
||||
switch(opt) {
|
||||
case yajl_allow_comments:
|
||||
case yajl_dont_validate_strings:
|
||||
case yajl_allow_trailing_garbage:
|
||||
case yajl_allow_multiple_values:
|
||||
case yajl_allow_partial_values:
|
||||
if (va_arg(ap, int)) h->flags |= opt;
|
||||
else h->flags &= ~opt;
|
||||
break;
|
||||
default:
|
||||
rv = 0;
|
||||
}
|
||||
va_end(ap);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
yajl_free(yajl_handle handle)
|
||||
{
|
||||
yajl_bs_free(handle->stateStack);
|
||||
yajl_buf_free(handle->decodeBuf);
|
||||
yajl_lex_free(handle->lexer);
|
||||
if (handle->lexer) {
|
||||
yajl_lex_free(handle->lexer);
|
||||
handle->lexer = NULL;
|
||||
}
|
||||
YA_FREE(&(handle->alloc), handle);
|
||||
}
|
||||
|
||||
yajl_status
|
||||
yajl_parse(yajl_handle hand, const unsigned char * jsonText,
|
||||
unsigned int jsonTextLen)
|
||||
size_t jsonTextLen)
|
||||
{
|
||||
yajl_status status;
|
||||
|
||||
/* lazy allocation of the lexer */
|
||||
if (hand->lexer == NULL) {
|
||||
hand->lexer = yajl_lex_alloc(&(hand->alloc),
|
||||
hand->flags & yajl_allow_comments,
|
||||
!(hand->flags & yajl_dont_validate_strings));
|
||||
}
|
||||
if (hand->lexer == NULL) {
|
||||
return yajl_status_error;
|
||||
}
|
||||
|
||||
status = yajl_do_parse(hand, jsonText, jsonTextLen);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
yajl_status
|
||||
yajl_parse_complete(yajl_handle hand)
|
||||
yajl_complete_parse(yajl_handle hand)
|
||||
{
|
||||
/* The particular case we want to handle is a trailing number.
|
||||
* Further input consisting of digits could cause our interpretation
|
||||
* of the number to change (buffered "1" but "2" comes in).
|
||||
* A very simple approach to this is to inject whitespace to terminate
|
||||
* any number in the lex buffer.
|
||||
*/
|
||||
return yajl_parse(hand, (const unsigned char *)" ", 1);
|
||||
/* The lexer is lazy allocated in the first call to parse. if parse is
|
||||
* never called, then no data was provided to parse at all. This is a
|
||||
* "premature EOF" error unless yajl_allow_partial_values is specified.
|
||||
* allocating the lexer now is the simplest possible way to handle this
|
||||
* case while preserving all the other semantics of the parser
|
||||
* (multiple values, partial values, etc). */
|
||||
if (hand->lexer == NULL) {
|
||||
hand->lexer = yajl_lex_alloc(&(hand->alloc),
|
||||
hand->flags & yajl_allow_comments,
|
||||
!(hand->flags & yajl_dont_validate_strings));
|
||||
}
|
||||
|
||||
return yajl_do_finish(hand);
|
||||
}
|
||||
|
||||
unsigned char *
|
||||
yajl_get_error(yajl_handle hand, int verbose,
|
||||
const unsigned char * jsonText, unsigned int jsonTextLen)
|
||||
const unsigned char * jsonText, size_t jsonTextLen)
|
||||
{
|
||||
return yajl_render_error_string(hand, jsonText, jsonTextLen, verbose);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
size_t
|
||||
yajl_get_bytes_consumed(yajl_handle hand)
|
||||
{
|
||||
if (!hand) return 0;
|
||||
|
||||
@@ -1,34 +1,18 @@
|
||||
/*
|
||||
* Copyright 2010, Lloyd Hilaiel.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. Neither the name of Lloyd Hilaiel nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
* Copyright (c) 2007-2011, Lloyd Hilaiel <lloyd@hilaiel.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file yajl_alloc.h
|
||||
@@ -41,13 +25,13 @@
|
||||
#define epicsExportSharedSymbols
|
||||
#include "yajl_alloc.h"
|
||||
|
||||
static void * yajl_internal_malloc(void *ctx, unsigned int sz)
|
||||
static void * yajl_internal_malloc(void *ctx, size_t sz)
|
||||
{
|
||||
return malloc(sz);
|
||||
}
|
||||
|
||||
static void * yajl_internal_realloc(void *ctx, void * previous,
|
||||
unsigned int sz)
|
||||
size_t sz)
|
||||
{
|
||||
return realloc(previous, sz);
|
||||
}
|
||||
|
||||
@@ -1,34 +1,18 @@
|
||||
/*
|
||||
* Copyright 2010, Lloyd Hilaiel.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. Neither the name of Lloyd Hilaiel nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
* Copyright (c) 2007-2011, Lloyd Hilaiel <lloyd@hilaiel.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file yajl_alloc.h
|
||||
|
||||
@@ -1,34 +1,18 @@
|
||||
/*
|
||||
* Copyright 2010, Lloyd Hilaiel.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. Neither the name of Lloyd Hilaiel nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
* Copyright (c) 2007-2011, Lloyd Hilaiel <lloyd@hilaiel.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
@@ -40,16 +24,16 @@
|
||||
#define YAJL_BUF_INIT_SIZE 2048
|
||||
|
||||
struct yajl_buf_t {
|
||||
unsigned int len;
|
||||
unsigned int used;
|
||||
size_t len;
|
||||
size_t used;
|
||||
unsigned char * data;
|
||||
yajl_alloc_funcs * alloc;
|
||||
};
|
||||
|
||||
static
|
||||
void yajl_buf_ensure_available(yajl_buf buf, unsigned int want)
|
||||
void yajl_buf_ensure_available(yajl_buf buf, size_t want)
|
||||
{
|
||||
unsigned int need;
|
||||
size_t need;
|
||||
|
||||
assert(buf != NULL);
|
||||
|
||||
@@ -73,6 +57,10 @@ void yajl_buf_ensure_available(yajl_buf buf, unsigned int want)
|
||||
yajl_buf yajl_buf_alloc(yajl_alloc_funcs * alloc)
|
||||
{
|
||||
yajl_buf b = YA_MALLOC(alloc, sizeof(struct yajl_buf_t));
|
||||
if (b == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset((void *) b, 0, sizeof(struct yajl_buf_t));
|
||||
b->alloc = alloc;
|
||||
return b;
|
||||
@@ -85,7 +73,7 @@ void yajl_buf_free(yajl_buf buf)
|
||||
YA_FREE(buf->alloc, buf);
|
||||
}
|
||||
|
||||
void yajl_buf_append(yajl_buf buf, const void * data, unsigned int len)
|
||||
void yajl_buf_append(yajl_buf buf, const void * data, size_t len)
|
||||
{
|
||||
yajl_buf_ensure_available(buf, len);
|
||||
if (len > 0) {
|
||||
@@ -107,13 +95,13 @@ const unsigned char * yajl_buf_data(yajl_buf buf)
|
||||
return buf->data;
|
||||
}
|
||||
|
||||
unsigned int yajl_buf_len(yajl_buf buf)
|
||||
size_t yajl_buf_len(yajl_buf buf)
|
||||
{
|
||||
return buf->used;
|
||||
}
|
||||
|
||||
void
|
||||
yajl_buf_truncate(yajl_buf buf, unsigned int len)
|
||||
yajl_buf_truncate(yajl_buf buf, size_t len)
|
||||
{
|
||||
assert(len <= buf->used);
|
||||
buf->used = len;
|
||||
|
||||
@@ -1,34 +1,18 @@
|
||||
/*
|
||||
* Copyright 2010, Lloyd Hilaiel.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. Neither the name of Lloyd Hilaiel nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
* Copyright (c) 2007-2011, Lloyd Hilaiel <lloyd@hilaiel.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __YAJL_BUF_H__
|
||||
#define __YAJL_BUF_H__
|
||||
@@ -56,7 +40,7 @@ yajl_buf yajl_buf_alloc(yajl_alloc_funcs * alloc);
|
||||
void yajl_buf_free(yajl_buf buf);
|
||||
|
||||
/* append a number of bytes to the buffer */
|
||||
void yajl_buf_append(yajl_buf buf, const void * data, unsigned int len);
|
||||
void yajl_buf_append(yajl_buf buf, const void * data, size_t len);
|
||||
|
||||
/* empty the buffer */
|
||||
void yajl_buf_clear(yajl_buf buf);
|
||||
@@ -65,9 +49,9 @@ void yajl_buf_clear(yajl_buf buf);
|
||||
const unsigned char * yajl_buf_data(yajl_buf buf);
|
||||
|
||||
/* get the length of the buffer */
|
||||
unsigned int yajl_buf_len(yajl_buf buf);
|
||||
size_t yajl_buf_len(yajl_buf buf);
|
||||
|
||||
/* truncate the buffer */
|
||||
void yajl_buf_truncate(yajl_buf buf, unsigned int len);
|
||||
void yajl_buf_truncate(yajl_buf buf, size_t len);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,34 +1,18 @@
|
||||
/*
|
||||
* Copyright 2010, Lloyd Hilaiel.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. Neither the name of Lloyd Hilaiel nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
* Copyright (c) 2007-2011, Lloyd Hilaiel <lloyd@hilaiel.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* A header only implementation of a simple stack of bytes, used in YAJL
|
||||
@@ -45,8 +29,8 @@
|
||||
typedef struct yajl_bytestack_t
|
||||
{
|
||||
unsigned char * stack;
|
||||
unsigned int size;
|
||||
unsigned int used;
|
||||
size_t size;
|
||||
size_t used;
|
||||
yajl_alloc_funcs * yaf;
|
||||
} yajl_bytestack;
|
||||
|
||||
@@ -61,7 +45,7 @@ typedef struct yajl_bytestack_t
|
||||
|
||||
/* initialize a bytestack */
|
||||
#define yajl_bs_free(obs) \
|
||||
if ((obs).stack) (obs).yaf->free((obs).yaf->ctx, (obs).stack);
|
||||
if ((obs).stack) (obs).yaf->free((obs).yaf->ctx, (obs).stack);
|
||||
|
||||
#define yajl_bs_current(obs) \
|
||||
(assert((obs).used > 0), (obs).stack[(obs).used - 1])
|
||||
@@ -74,12 +58,12 @@ typedef struct yajl_bytestack_t
|
||||
} \
|
||||
(obs).stack[((obs).used)++] = (byte); \
|
||||
}
|
||||
|
||||
|
||||
/* removes the top item of the stack, returns nothing */
|
||||
#define yajl_bs_pop(obs) { ((obs).used)--; }
|
||||
|
||||
#define yajl_bs_set(obs, byte) \
|
||||
(obs).stack[((obs).used) - 1] = (byte);
|
||||
|
||||
(obs).stack[((obs).used) - 1] = (byte);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,58 +1,59 @@
|
||||
/*
|
||||
* Copyright 2010, Lloyd Hilaiel.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. Neither the name of Lloyd Hilaiel nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
* Copyright (c) 2007-2011, Lloyd Hilaiel <lloyd@hilaiel.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __YAJL_COMMON_H__
|
||||
#define __YAJL_COMMON_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <shareLib.h>
|
||||
|
||||
#include <epicsVersion.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** YAJL API history in brief
|
||||
*
|
||||
* Originally macro not defined
|
||||
* YAJL 1.0.12
|
||||
* Bundled with EPICS Base 3.15.0.1
|
||||
*
|
||||
* YAJL 2.1.0
|
||||
* Changes argument type for yajl_integer() from 'int' to 'long long'
|
||||
* Changes argument type for yajl_string() and yajl_map_key() from 'unsigned' to 'size_t'
|
||||
* Replacement of struct yajl_parser_config with yajl_config()
|
||||
* Replacement of yajl_parse_complete() with yajl_complete_parse()
|
||||
*/
|
||||
#define EPICS_YAJL_VERSION VERSION_INT(2,1,0,0)
|
||||
|
||||
#define YAJL_MAX_DEPTH 128
|
||||
|
||||
#define YAJL_API epicsShareFunc
|
||||
|
||||
/** pointer to a malloc function, supporting client overriding memory
|
||||
* allocation routines */
|
||||
typedef void * (*yajl_malloc_func)(void *ctx, unsigned int sz);
|
||||
typedef void * (*yajl_malloc_func)(void *ctx, size_t sz);
|
||||
|
||||
/** pointer to a free function, supporting client overriding memory
|
||||
* allocation routines */
|
||||
typedef void (*yajl_free_func)(void *ctx, void * ptr);
|
||||
|
||||
/** pointer to a realloc function which can resize an allocation. */
|
||||
typedef void * (*yajl_realloc_func)(void *ctx, void * ptr, unsigned int sz);
|
||||
typedef void * (*yajl_realloc_func)(void *ctx, void * ptr, size_t sz);
|
||||
|
||||
/** A structure which can be passed to yajl_*_alloc routines to allow the
|
||||
* client to specify memory allocation functions to be used. */
|
||||
@@ -71,6 +72,6 @@ typedef struct
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,34 +1,18 @@
|
||||
/*
|
||||
* Copyright 2010, Lloyd Hilaiel.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. Neither the name of Lloyd Hilaiel nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
* Copyright (c) 2007-2011, Lloyd Hilaiel <lloyd@hilaiel.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
@@ -46,20 +30,14 @@ static void CharToHex(unsigned char c, char * hexBuf)
|
||||
}
|
||||
|
||||
void
|
||||
yajl_string_encode(yajl_buf buf, const unsigned char * str,
|
||||
unsigned int len)
|
||||
yajl_string_encode(const yajl_print_t print,
|
||||
void * ctx,
|
||||
const unsigned char * str,
|
||||
size_t len,
|
||||
int escape_solidus)
|
||||
{
|
||||
yajl_string_encode2((const yajl_print_t) &yajl_buf_append, buf, str, len);
|
||||
}
|
||||
|
||||
void
|
||||
yajl_string_encode2(const yajl_print_t print,
|
||||
void * ctx,
|
||||
const unsigned char * str,
|
||||
unsigned int len)
|
||||
{
|
||||
unsigned int beg = 0;
|
||||
unsigned int end = 0;
|
||||
size_t beg = 0;
|
||||
size_t end = 0;
|
||||
char hexBuf[7];
|
||||
hexBuf[0] = '\\'; hexBuf[1] = 'u'; hexBuf[2] = '0'; hexBuf[3] = '0';
|
||||
hexBuf[6] = 0;
|
||||
@@ -70,7 +48,12 @@ yajl_string_encode2(const yajl_print_t print,
|
||||
case '\r': escaped = "\\r"; break;
|
||||
case '\n': escaped = "\\n"; break;
|
||||
case '\\': escaped = "\\\\"; break;
|
||||
/* case '/': escaped = "\\/"; break; */
|
||||
/* it is not required to escape a solidus in JSON:
|
||||
* read sec. 2.5: http://www.ietf.org/rfc/rfc4627.txt
|
||||
* specifically, this production from the grammar:
|
||||
* unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
|
||||
*/
|
||||
case '/': if (escape_solidus) escaped = "\\/"; break;
|
||||
case '"': escaped = "\\\""; break;
|
||||
case '\f': escaped = "\\f"; break;
|
||||
case '\b': escaped = "\\b"; break;
|
||||
@@ -132,10 +115,10 @@ static void Utf32toUtf8(unsigned int codepoint, char * utf8Buf)
|
||||
}
|
||||
|
||||
void yajl_string_decode(yajl_buf buf, const unsigned char * str,
|
||||
unsigned int len)
|
||||
size_t len)
|
||||
{
|
||||
unsigned int beg = 0;
|
||||
unsigned int end = 0;
|
||||
size_t beg = 0;
|
||||
size_t end = 0;
|
||||
|
||||
while (end < len) {
|
||||
if (str[end] == '\\') {
|
||||
@@ -194,3 +177,45 @@ void yajl_string_decode(yajl_buf buf, const unsigned char * str,
|
||||
}
|
||||
yajl_buf_append(buf, str + beg, end - beg);
|
||||
}
|
||||
|
||||
#define ADV_PTR s++; if (!(len--)) return 0;
|
||||
|
||||
int yajl_string_validate_utf8(const unsigned char * s, size_t len)
|
||||
{
|
||||
if (!len) return 1;
|
||||
if (!s) return 0;
|
||||
|
||||
while (len--) {
|
||||
/* single byte */
|
||||
if (*s <= 0x7f) {
|
||||
/* noop */
|
||||
}
|
||||
/* two byte */
|
||||
else if ((*s >> 5) == 0x6) {
|
||||
ADV_PTR;
|
||||
if (!((*s >> 6) == 0x2)) return 0;
|
||||
}
|
||||
/* three byte */
|
||||
else if ((*s >> 4) == 0x0e) {
|
||||
ADV_PTR;
|
||||
if (!((*s >> 6) == 0x2)) return 0;
|
||||
ADV_PTR;
|
||||
if (!((*s >> 6) == 0x2)) return 0;
|
||||
}
|
||||
/* four byte */
|
||||
else if ((*s >> 3) == 0x1e) {
|
||||
ADV_PTR;
|
||||
if (!((*s >> 6) == 0x2)) return 0;
|
||||
ADV_PTR;
|
||||
if (!((*s >> 6) == 0x2)) return 0;
|
||||
ADV_PTR;
|
||||
if (!((*s >> 6) == 0x2)) return 0;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
s++;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1,34 +1,18 @@
|
||||
/*
|
||||
* Copyright 2010, Lloyd Hilaiel.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. Neither the name of Lloyd Hilaiel nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
* Copyright (c) 2007-2011, Lloyd Hilaiel <lloyd@hilaiel.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __YAJL_ENCODE_H__
|
||||
#define __YAJL_ENCODE_H__
|
||||
@@ -36,15 +20,15 @@
|
||||
#include "yajl_buf.h"
|
||||
#include "yajl_gen.h"
|
||||
|
||||
void yajl_string_encode2(const yajl_print_t printer,
|
||||
void * ctx,
|
||||
const unsigned char * str,
|
||||
unsigned int length);
|
||||
|
||||
void yajl_string_encode(yajl_buf buf, const unsigned char * str,
|
||||
unsigned int length);
|
||||
void yajl_string_encode(const yajl_print_t printer,
|
||||
void * ctx,
|
||||
const unsigned char * str,
|
||||
size_t length,
|
||||
int escape_solidus);
|
||||
|
||||
void yajl_string_decode(yajl_buf buf, const unsigned char * str,
|
||||
unsigned int length);
|
||||
size_t length);
|
||||
|
||||
int yajl_string_validate_utf8(const unsigned char * s, size_t len);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,38 +1,23 @@
|
||||
/*
|
||||
* Copyright 2010, Lloyd Hilaiel.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. Neither the name of Lloyd Hilaiel nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
* Copyright (c) 2007-2011, Lloyd Hilaiel <lloyd@hilaiel.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include "epicsMath.h"
|
||||
@@ -51,10 +36,10 @@ typedef enum {
|
||||
yajl_gen_error
|
||||
} yajl_gen_state;
|
||||
|
||||
struct yajl_gen_t
|
||||
struct yajl_gen_t
|
||||
{
|
||||
unsigned int flags;
|
||||
unsigned int depth;
|
||||
unsigned int pretty;
|
||||
const char * indentString;
|
||||
yajl_gen_state state[YAJL_MAX_DEPTH];
|
||||
yajl_print_t print;
|
||||
@@ -63,18 +48,54 @@ struct yajl_gen_t
|
||||
yajl_alloc_funcs alloc;
|
||||
};
|
||||
|
||||
yajl_gen
|
||||
yajl_gen_alloc(const yajl_gen_config * config,
|
||||
const yajl_alloc_funcs * afs)
|
||||
int
|
||||
yajl_gen_config(yajl_gen g, yajl_gen_option opt, ...)
|
||||
{
|
||||
return yajl_gen_alloc2(NULL, config, afs, NULL);
|
||||
int rv = 1;
|
||||
va_list ap;
|
||||
va_start(ap, opt);
|
||||
|
||||
switch(opt) {
|
||||
case yajl_gen_beautify:
|
||||
case yajl_gen_validate_utf8:
|
||||
if (va_arg(ap, int)) g->flags |= opt;
|
||||
else g->flags &= ~opt;
|
||||
break;
|
||||
case yajl_gen_indent_string: {
|
||||
const char *indent = va_arg(ap, const char *);
|
||||
g->indentString = indent;
|
||||
for (; *indent; indent++) {
|
||||
if (*indent != '\n'
|
||||
&& *indent != '\v'
|
||||
&& *indent != '\f'
|
||||
&& *indent != '\t'
|
||||
&& *indent != '\r'
|
||||
&& *indent != ' ')
|
||||
{
|
||||
g->indentString = NULL;
|
||||
rv = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case yajl_gen_print_callback:
|
||||
yajl_buf_free(g->ctx);
|
||||
g->print = va_arg(ap, const yajl_print_t);
|
||||
g->ctx = va_arg(ap, void *);
|
||||
break;
|
||||
default:
|
||||
rv = 0;
|
||||
}
|
||||
|
||||
va_end(ap);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
|
||||
yajl_gen
|
||||
yajl_gen_alloc2(const yajl_print_t callback,
|
||||
const yajl_gen_config * config,
|
||||
const yajl_alloc_funcs * afs,
|
||||
void * ctx)
|
||||
yajl_gen_alloc(const yajl_alloc_funcs * afs)
|
||||
{
|
||||
yajl_gen g = NULL;
|
||||
yajl_alloc_funcs afsBuffer;
|
||||
@@ -97,35 +118,9 @@ yajl_gen_alloc2(const yajl_print_t callback,
|
||||
/* copy in pointers to allocation routines */
|
||||
memcpy((void *) &(g->alloc), (void *) afs, sizeof(yajl_alloc_funcs));
|
||||
|
||||
if (config) {
|
||||
const char *indent = config->indentString;
|
||||
g->pretty = config->beautify;
|
||||
g->indentString = config->indentString;
|
||||
if (indent) {
|
||||
for (; *indent; indent++) {
|
||||
if (*indent != '\n'
|
||||
&& *indent != '\v'
|
||||
&& *indent != '\f'
|
||||
&& *indent != '\t'
|
||||
&& *indent != '\r'
|
||||
&& *indent != ' ') {
|
||||
g->indentString = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!g->indentString) {
|
||||
g->indentString = " ";
|
||||
}
|
||||
}
|
||||
|
||||
if (callback) {
|
||||
g->print = callback;
|
||||
g->ctx = ctx;
|
||||
} else {
|
||||
g->print = (yajl_print_t)&yajl_buf_append;
|
||||
g->ctx = yajl_buf_alloc(&(g->alloc));
|
||||
}
|
||||
g->print = (yajl_print_t)&yajl_buf_append;
|
||||
g->ctx = yajl_buf_alloc(&(g->alloc));
|
||||
g->indentString = " ";
|
||||
|
||||
return g;
|
||||
}
|
||||
@@ -141,14 +136,14 @@ yajl_gen_free(yajl_gen g)
|
||||
if (g->state[g->depth] == yajl_gen_map_key || \
|
||||
g->state[g->depth] == yajl_gen_in_array) { \
|
||||
g->print(g->ctx, ",", 1); \
|
||||
if (g->pretty) g->print(g->ctx, "\n", 1); \
|
||||
if ((g->flags & yajl_gen_beautify)) g->print(g->ctx, "\n", 1); \
|
||||
} else if (g->state[g->depth] == yajl_gen_map_val) { \
|
||||
g->print(g->ctx, ":", 1); \
|
||||
if (g->pretty) g->print(g->ctx, " ", 1); \
|
||||
if ((g->flags & yajl_gen_beautify)) g->print(g->ctx, " ", 1); \
|
||||
}
|
||||
|
||||
#define INSERT_WHITESPACE \
|
||||
if (g->pretty) { \
|
||||
if ((g->flags & yajl_gen_beautify)) { \
|
||||
if (g->state[g->depth] != yajl_gen_map_val) { \
|
||||
unsigned int _i; \
|
||||
for (_i=0;_i<g->depth;_i++) \
|
||||
@@ -199,15 +194,15 @@ yajl_gen_free(yajl_gen g)
|
||||
} \
|
||||
|
||||
#define FINAL_NEWLINE \
|
||||
if (g->pretty && g->state[g->depth] == yajl_gen_complete) \
|
||||
g->print(g->ctx, "\n", 1);
|
||||
|
||||
if ((g->flags & yajl_gen_beautify) && g->state[g->depth] == yajl_gen_complete) \
|
||||
g->print(g->ctx, "\n", 1);
|
||||
|
||||
yajl_gen_status
|
||||
yajl_gen_integer(yajl_gen g, long int number)
|
||||
yajl_gen_integer(yajl_gen g, long long int number)
|
||||
{
|
||||
char i[32];
|
||||
ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE;
|
||||
sprintf(i, "%ld", number);
|
||||
sprintf(i, "%lld", number);
|
||||
g->print(g->ctx, i, (unsigned int)strlen(i));
|
||||
APPENDED_ATOM;
|
||||
FINAL_NEWLINE;
|
||||
@@ -229,7 +224,7 @@ yajl_gen_double(yajl_gen g, double number)
|
||||
}
|
||||
|
||||
yajl_gen_status
|
||||
yajl_gen_number(yajl_gen g, const char * s, unsigned int l)
|
||||
yajl_gen_number(yajl_gen g, const char * s, size_t l)
|
||||
{
|
||||
ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE;
|
||||
g->print(g->ctx, s, l);
|
||||
@@ -240,11 +235,19 @@ yajl_gen_number(yajl_gen g, const char * s, unsigned int l)
|
||||
|
||||
yajl_gen_status
|
||||
yajl_gen_string(yajl_gen g, const unsigned char * str,
|
||||
unsigned int len)
|
||||
size_t len)
|
||||
{
|
||||
// if validation is enabled, check that the string is valid utf8
|
||||
// XXX: This checking could be done a little faster, in the same pass as
|
||||
// the string encoding
|
||||
if (g->flags & yajl_gen_validate_utf8) {
|
||||
if (!yajl_string_validate_utf8(str, len)) {
|
||||
return yajl_gen_invalid_string;
|
||||
}
|
||||
}
|
||||
ENSURE_VALID_STATE; INSERT_SEP; INSERT_WHITESPACE;
|
||||
g->print(g->ctx, "\"", 1);
|
||||
yajl_string_encode2(g->print, g->ctx, str, len);
|
||||
yajl_string_encode(g->print, g->ctx, str, len, g->flags & yajl_gen_escape_solidus);
|
||||
g->print(g->ctx, "\"", 1);
|
||||
APPENDED_ATOM;
|
||||
FINAL_NEWLINE;
|
||||
@@ -281,7 +284,7 @@ yajl_gen_map_open(yajl_gen g)
|
||||
|
||||
g->state[g->depth] = yajl_gen_map_start;
|
||||
g->print(g->ctx, "{", 1);
|
||||
if (g->pretty) g->print(g->ctx, "\n", 1);
|
||||
if ((g->flags & yajl_gen_beautify)) g->print(g->ctx, "\n", 1);
|
||||
FINAL_NEWLINE;
|
||||
return yajl_gen_status_ok;
|
||||
}
|
||||
@@ -292,7 +295,7 @@ yajl_gen_map_close(yajl_gen g)
|
||||
ENSURE_VALID_STATE;
|
||||
DECREMENT_DEPTH;
|
||||
|
||||
if (g->pretty) g->print(g->ctx, "\n", 1);
|
||||
if ((g->flags & yajl_gen_beautify)) g->print(g->ctx, "\n", 1);
|
||||
APPENDED_ATOM;
|
||||
INSERT_WHITESPACE;
|
||||
g->print(g->ctx, "}", 1);
|
||||
@@ -307,7 +310,7 @@ yajl_gen_array_open(yajl_gen g)
|
||||
INCREMENT_DEPTH;
|
||||
g->state[g->depth] = yajl_gen_array_start;
|
||||
g->print(g->ctx, "[", 1);
|
||||
if (g->pretty) g->print(g->ctx, "\n", 1);
|
||||
if ((g->flags & yajl_gen_beautify)) g->print(g->ctx, "\n", 1);
|
||||
FINAL_NEWLINE;
|
||||
return yajl_gen_status_ok;
|
||||
}
|
||||
@@ -317,7 +320,7 @@ yajl_gen_array_close(yajl_gen g)
|
||||
{
|
||||
ENSURE_VALID_STATE;
|
||||
DECREMENT_DEPTH;
|
||||
if (g->pretty) g->print(g->ctx, "\n", 1);
|
||||
if ((g->flags & yajl_gen_beautify)) g->print(g->ctx, "\n", 1);
|
||||
APPENDED_ATOM;
|
||||
INSERT_WHITESPACE;
|
||||
g->print(g->ctx, "]", 1);
|
||||
@@ -327,7 +330,7 @@ yajl_gen_array_close(yajl_gen g)
|
||||
|
||||
yajl_gen_status
|
||||
yajl_gen_get_buf(yajl_gen g, const unsigned char ** buf,
|
||||
unsigned int * len)
|
||||
size_t * len)
|
||||
{
|
||||
if (g->print != (yajl_print_t)&yajl_buf_append) return yajl_gen_no_buf;
|
||||
*buf = yajl_buf_data((yajl_buf)g->ctx);
|
||||
|
||||
@@ -1,34 +1,18 @@
|
||||
/*
|
||||
* Copyright 2010, Lloyd Hilaiel.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. Neither the name of Lloyd Hilaiel nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
* Copyright (c) 2007-2011, Lloyd Hilaiel <lloyd@hilaiel.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file yajl_gen.h
|
||||
@@ -38,11 +22,11 @@
|
||||
#ifndef __YAJL_GEN_H__
|
||||
#define __YAJL_GEN_H__
|
||||
|
||||
#include <yajl_common.h>
|
||||
#include "yajl_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif
|
||||
/** generator status codes */
|
||||
typedef enum {
|
||||
/** no error */
|
||||
@@ -63,7 +47,11 @@ extern "C" {
|
||||
yajl_gen_invalid_number,
|
||||
/** A print callback was passed in, so there is no internal
|
||||
* buffer to get from */
|
||||
yajl_gen_no_buf
|
||||
yajl_gen_no_buf,
|
||||
/** returned from yajl_gen_string() when the yajl_gen_validate_utf8
|
||||
* option is enabled and an invalid was passed by client code.
|
||||
*/
|
||||
yajl_gen_invalid_string
|
||||
} yajl_gen_status;
|
||||
|
||||
/** an opaque handle to a generator */
|
||||
@@ -72,21 +60,52 @@ extern "C" {
|
||||
/** a callback used for "printing" the results. */
|
||||
typedef void (*yajl_print_t)(void * ctx,
|
||||
const char * str,
|
||||
unsigned int len);
|
||||
size_t len);
|
||||
|
||||
/** configuration structure for the generator */
|
||||
typedef struct {
|
||||
/** configuration parameters for the parser, these may be passed to
|
||||
* yajl_gen_config() along with option specific argument(s). In general,
|
||||
* all configuration parameters default to *off*. */
|
||||
typedef enum {
|
||||
/** generate indented (beautiful) output */
|
||||
unsigned int beautify;
|
||||
/** an opportunity to define an indent string. such as \\t or
|
||||
* some number of spaces. default is four spaces ' '. This
|
||||
* member is only relevant when beautify is true */
|
||||
const char * indentString;
|
||||
} yajl_gen_config;
|
||||
yajl_gen_beautify = 0x01,
|
||||
/**
|
||||
* Set an indent string which is used when yajl_gen_beautify
|
||||
* is enabled. Maybe something like \\t or some number of
|
||||
* spaces. The default is four spaces ' '.
|
||||
*/
|
||||
yajl_gen_indent_string = 0x02,
|
||||
/**
|
||||
* Set a function and context argument that should be used to
|
||||
* output generated json. the function should conform to the
|
||||
* yajl_print_t prototype while the context argument is a
|
||||
* void * of your choosing.
|
||||
*
|
||||
* example:
|
||||
* yajl_gen_config(g, yajl_gen_print_callback, myFunc, myVoidPtr);
|
||||
*/
|
||||
yajl_gen_print_callback = 0x04,
|
||||
/**
|
||||
* Normally the generator does not validate that strings you
|
||||
* pass to it via yajl_gen_string() are valid UTF8. Enabling
|
||||
* this option will cause it to do so.
|
||||
*/
|
||||
yajl_gen_validate_utf8 = 0x08,
|
||||
/**
|
||||
* the forward solidus (slash or '/' in human) is not required to be
|
||||
* escaped in json text. By default, YAJL will not escape it in the
|
||||
* iterest of saving bytes. Setting this flag will cause YAJL to
|
||||
* always escape '/' in generated JSON strings.
|
||||
*/
|
||||
yajl_gen_escape_solidus = 0x10
|
||||
} yajl_gen_option;
|
||||
|
||||
/** allow the modification of generator options subsequent to handle
|
||||
* allocation (via yajl_alloc)
|
||||
* \returns zero in case of errors, non-zero otherwise
|
||||
*/
|
||||
YAJL_API int yajl_gen_config(yajl_gen g, yajl_gen_option opt, ...);
|
||||
|
||||
/** allocate a generator handle
|
||||
* \param config a pointer to a structure containing parameters which
|
||||
* configure the behavior of the json generator
|
||||
* \param allocFuncs an optional pointer to a structure which allows
|
||||
* the client to overide the memory allocation
|
||||
* used by yajl. May be NULL, in which case
|
||||
@@ -94,47 +113,24 @@ extern "C" {
|
||||
*
|
||||
* \returns an allocated handle on success, NULL on failure (bad params)
|
||||
*/
|
||||
YAJL_API yajl_gen yajl_gen_alloc(const yajl_gen_config * config,
|
||||
const yajl_alloc_funcs * allocFuncs);
|
||||
YAJL_API yajl_gen yajl_gen_alloc(const yajl_alloc_funcs * allocFuncs);
|
||||
|
||||
/** allocate a generator handle that will print to the specified
|
||||
* callback rather than storing the results in an internal buffer.
|
||||
* \param callback a pointer to a printer function. May be NULL
|
||||
* in which case, the results will be store in an
|
||||
* internal buffer.
|
||||
* \param config a pointer to a structure containing parameters
|
||||
* which configure the behavior of the json
|
||||
* generator.
|
||||
* \param allocFuncs an optional pointer to a structure which allows
|
||||
* the client to overide the memory allocation
|
||||
* used by yajl. May be NULL, in which case
|
||||
* malloc/free/realloc will be used.
|
||||
* \param ctx a context pointer that will be passed to the
|
||||
* printer callback.
|
||||
*
|
||||
* \returns an allocated handle on success, NULL on failure (bad params)
|
||||
*/
|
||||
YAJL_API yajl_gen yajl_gen_alloc2(const yajl_print_t callback,
|
||||
const yajl_gen_config * config,
|
||||
const yajl_alloc_funcs * allocFuncs,
|
||||
void * ctx);
|
||||
|
||||
/** free a generator handle */
|
||||
/** free a generator handle */
|
||||
YAJL_API void yajl_gen_free(yajl_gen handle);
|
||||
|
||||
YAJL_API yajl_gen_status yajl_gen_integer(yajl_gen hand, long int number);
|
||||
YAJL_API yajl_gen_status yajl_gen_integer(yajl_gen hand, long long int number);
|
||||
/** generate a floating point number. number may not be infinity or
|
||||
* NaN, as these have no representation in JSON. In these cases the
|
||||
* generator will return 'yajl_gen_invalid_number' */
|
||||
YAJL_API yajl_gen_status yajl_gen_double(yajl_gen hand, double number);
|
||||
YAJL_API yajl_gen_status yajl_gen_number(yajl_gen hand,
|
||||
const char * num,
|
||||
unsigned int len);
|
||||
size_t len);
|
||||
YAJL_API yajl_gen_status yajl_gen_string(yajl_gen hand,
|
||||
const unsigned char * str,
|
||||
unsigned int len);
|
||||
size_t len);
|
||||
YAJL_API yajl_gen_status yajl_gen_null(yajl_gen hand);
|
||||
YAJL_API yajl_gen_status yajl_gen_bool(yajl_gen hand, int boolean);
|
||||
YAJL_API yajl_gen_status yajl_gen_bool(yajl_gen hand, int boolean);
|
||||
YAJL_API yajl_gen_status yajl_gen_map_open(yajl_gen hand);
|
||||
YAJL_API yajl_gen_status yajl_gen_map_close(yajl_gen hand);
|
||||
YAJL_API yajl_gen_status yajl_gen_array_open(yajl_gen hand);
|
||||
@@ -145,7 +141,7 @@ extern "C" {
|
||||
* buffer. This allows stream generation. */
|
||||
YAJL_API yajl_gen_status yajl_gen_get_buf(yajl_gen hand,
|
||||
const unsigned char ** buf,
|
||||
unsigned int * len);
|
||||
size_t * len);
|
||||
|
||||
/** clear yajl's output buffer, but maintain all internal generation
|
||||
* state. This function will not "reset" the generator state, and is
|
||||
|
||||
@@ -1,34 +1,18 @@
|
||||
/*
|
||||
* Copyright 2010, Lloyd Hilaiel.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. Neither the name of Lloyd Hilaiel nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
* Copyright (c) 2007-2011, Lloyd Hilaiel <lloyd@hilaiel.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
@@ -84,8 +68,8 @@ tokToStr(yajl_tok tok)
|
||||
|
||||
struct yajl_lexer_t {
|
||||
/* the overal line and char offset into the data */
|
||||
unsigned int lineOff;
|
||||
unsigned int charOff;
|
||||
size_t lineOff;
|
||||
size_t charOff;
|
||||
|
||||
/* error */
|
||||
yajl_lex_error error;
|
||||
@@ -96,7 +80,7 @@ struct yajl_lexer_t {
|
||||
|
||||
/* in the case where we have data in the lexBuf, bufOff holds
|
||||
* the current offset into the lexBuf. */
|
||||
unsigned int bufOff;
|
||||
size_t bufOff;
|
||||
|
||||
/* are we using the lex buf? */
|
||||
unsigned int bufInUse;
|
||||
@@ -122,6 +106,10 @@ yajl_lex_alloc(yajl_alloc_funcs * alloc,
|
||||
unsigned int allowComments, unsigned int validateUTF8)
|
||||
{
|
||||
yajl_lexer lxr = (yajl_lexer) YA_MALLOC(alloc, sizeof(struct yajl_lexer_t));
|
||||
if (lxr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset((void *) lxr, 0, sizeof(struct yajl_lexer_t));
|
||||
lxr->buf = yajl_buf_alloc(alloc);
|
||||
lxr->allowComments = allowComments;
|
||||
@@ -139,15 +127,19 @@ yajl_lex_free(yajl_lexer lxr)
|
||||
}
|
||||
|
||||
/* a lookup table which lets us quickly determine three things:
|
||||
* VEC - valid escaped conrol char
|
||||
* VEC - valid escaped control char
|
||||
* note. the solidus '/' may be escaped or not.
|
||||
* IJC - invalid json char
|
||||
* VHC - valid hex char
|
||||
* note. the solidus '/' may be escaped or not.
|
||||
* note. the
|
||||
* NFP - needs further processing (from a string scanning perspective)
|
||||
* NUC - needs utf8 checking when enabled (from a string scanning perspective)
|
||||
*/
|
||||
#define VEC 1
|
||||
#define IJC 2
|
||||
#define VHC 4
|
||||
#define VEC 0x01
|
||||
#define IJC 0x02
|
||||
#define VHC 0x04
|
||||
#define NFP 0x08
|
||||
#define NUC 0x10
|
||||
|
||||
static const char charLookupTable[256] =
|
||||
{
|
||||
/*00*/ IJC , IJC , IJC , IJC , IJC , IJC , IJC , IJC ,
|
||||
@@ -155,7 +147,7 @@ static const char charLookupTable[256] =
|
||||
/*10*/ IJC , IJC , IJC , IJC , IJC , IJC , IJC , IJC ,
|
||||
/*18*/ IJC , IJC , IJC , IJC , IJC , IJC , IJC , IJC ,
|
||||
|
||||
/*20*/ 0 , 0 , VEC|IJC, 0 , 0 , 0 , 0 , 0 ,
|
||||
/*20*/ 0 , 0 , NFP|VEC|IJC, 0 , 0 , 0 , 0 , 0 ,
|
||||
/*28*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , VEC ,
|
||||
/*30*/ VHC , VHC , VHC , VHC , VHC , VHC , VHC , VHC ,
|
||||
/*38*/ VHC , VHC , 0 , 0 , 0 , 0 , 0 , 0 ,
|
||||
@@ -163,33 +155,32 @@ static const char charLookupTable[256] =
|
||||
/*40*/ 0 , VHC , VHC , VHC , VHC , VHC , VHC , 0 ,
|
||||
/*48*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
|
||||
/*50*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
|
||||
/*58*/ 0 , 0 , 0 , 0 , VEC|IJC, 0 , 0 , 0 ,
|
||||
/*58*/ 0 , 0 , 0 , 0 , NFP|VEC|IJC, 0 , 0 , 0 ,
|
||||
|
||||
/*60*/ 0 , VHC , VEC|VHC, VHC , VHC , VHC , VEC|VHC, 0 ,
|
||||
/*68*/ 0 , 0 , 0 , 0 , 0 , 0 , VEC , 0 ,
|
||||
/*70*/ 0 , 0 , VEC , 0 , VEC , 0 , 0 , 0 ,
|
||||
/*78*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
|
||||
|
||||
/* include these so we don't have to always check the range of the char */
|
||||
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
|
||||
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
|
||||
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
|
||||
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
|
||||
NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
|
||||
NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
|
||||
NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
|
||||
NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
|
||||
|
||||
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
|
||||
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
|
||||
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
|
||||
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
|
||||
NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
|
||||
NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
|
||||
NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
|
||||
NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
|
||||
|
||||
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
|
||||
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
|
||||
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
|
||||
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
|
||||
NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
|
||||
NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
|
||||
NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
|
||||
NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
|
||||
|
||||
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
|
||||
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
|
||||
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
|
||||
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
|
||||
NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
|
||||
NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
|
||||
NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
|
||||
NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC
|
||||
};
|
||||
|
||||
/** process a variable length utf8 encoded codepoint.
|
||||
@@ -207,7 +198,7 @@ static const char charLookupTable[256] =
|
||||
|
||||
static yajl_tok
|
||||
yajl_lex_utf8_char(yajl_lexer lexer, const unsigned char * jsonText,
|
||||
unsigned int jsonTextLen, unsigned int * offset,
|
||||
size_t jsonTextLen, size_t * offset,
|
||||
unsigned char curChar)
|
||||
{
|
||||
if (curChar <= 0x7f) {
|
||||
@@ -261,17 +252,56 @@ if (*offset >= jsonTextLen) { \
|
||||
goto finish_string_lex; \
|
||||
}
|
||||
|
||||
/** scan a string for interesting characters that might need further
|
||||
* review. return the number of chars that are uninteresting and can
|
||||
* be skipped.
|
||||
* (lth) hi world, any thoughts on how to make this routine faster? */
|
||||
static size_t
|
||||
yajl_string_scan(const unsigned char * buf, size_t len, int utf8check)
|
||||
{
|
||||
unsigned char mask = IJC|NFP|(utf8check ? NUC : 0);
|
||||
size_t skip = 0;
|
||||
while (skip < len && !(charLookupTable[*buf] & mask))
|
||||
{
|
||||
skip++;
|
||||
buf++;
|
||||
}
|
||||
return skip;
|
||||
}
|
||||
|
||||
static yajl_tok
|
||||
yajl_lex_string(yajl_lexer lexer, const unsigned char * jsonText,
|
||||
unsigned int jsonTextLen, unsigned int * offset)
|
||||
size_t jsonTextLen, size_t * offset)
|
||||
{
|
||||
yajl_tok tok = yajl_tok_error;
|
||||
int hasEscapes = 0;
|
||||
|
||||
for (;;) {
|
||||
unsigned char curChar;
|
||||
unsigned char curChar;
|
||||
|
||||
STR_CHECK_EOF;
|
||||
/* now jump into a faster scanning routine to skip as much
|
||||
* of the buffers as possible */
|
||||
{
|
||||
const unsigned char * p;
|
||||
size_t len;
|
||||
|
||||
if ((lexer->bufInUse && yajl_buf_len(lexer->buf) &&
|
||||
lexer->bufOff < yajl_buf_len(lexer->buf)))
|
||||
{
|
||||
p = ((const unsigned char *) yajl_buf_data(lexer->buf) +
|
||||
(lexer->bufOff));
|
||||
len = yajl_buf_len(lexer->buf) - lexer->bufOff;
|
||||
lexer->bufOff += yajl_string_scan(p, len, lexer->validateUTF8);
|
||||
}
|
||||
else if (*offset < jsonTextLen)
|
||||
{
|
||||
p = jsonText + *offset;
|
||||
len = jsonTextLen - *offset;
|
||||
*offset += yajl_string_scan(p, len, lexer->validateUTF8);
|
||||
}
|
||||
}
|
||||
|
||||
STR_CHECK_EOF;
|
||||
|
||||
curChar = readChar(lexer, jsonText, offset);
|
||||
|
||||
@@ -344,7 +374,7 @@ yajl_lex_string(yajl_lexer lexer, const unsigned char * jsonText,
|
||||
|
||||
static yajl_tok
|
||||
yajl_lex_number(yajl_lexer lexer, const unsigned char * jsonText,
|
||||
unsigned int jsonTextLen, unsigned int * offset)
|
||||
size_t jsonTextLen, size_t * offset)
|
||||
{
|
||||
/** XXX: numbers are the only entities in json that we must lex
|
||||
* _beyond_ in order to know that they are complete. There
|
||||
@@ -431,7 +461,7 @@ yajl_lex_number(yajl_lexer lexer, const unsigned char * jsonText,
|
||||
|
||||
static yajl_tok
|
||||
yajl_lex_comment(yajl_lexer lexer, const unsigned char * jsonText,
|
||||
unsigned int jsonTextLen, unsigned int * offset)
|
||||
size_t jsonTextLen, size_t * offset)
|
||||
{
|
||||
unsigned char c;
|
||||
|
||||
@@ -472,12 +502,12 @@ yajl_lex_comment(yajl_lexer lexer, const unsigned char * jsonText,
|
||||
|
||||
yajl_tok
|
||||
yajl_lex_lex(yajl_lexer lexer, const unsigned char * jsonText,
|
||||
unsigned int jsonTextLen, unsigned int * offset,
|
||||
const unsigned char ** outBuf, unsigned int * outLen)
|
||||
size_t jsonTextLen, size_t * offset,
|
||||
const unsigned char ** outBuf, size_t * outLen)
|
||||
{
|
||||
yajl_tok tok = yajl_tok_error;
|
||||
unsigned char c;
|
||||
unsigned int startOffset = *offset;
|
||||
size_t startOffset = *offset;
|
||||
|
||||
*outBuf = NULL;
|
||||
*outLen = 0;
|
||||
@@ -494,17 +524,17 @@ yajl_lex_lex(yajl_lexer lexer, const unsigned char * jsonText,
|
||||
|
||||
switch (c) {
|
||||
case '{':
|
||||
tok = yajl_tok_left_bracket;
|
||||
goto lexed;
|
||||
case '}':
|
||||
tok = yajl_tok_right_bracket;
|
||||
goto lexed;
|
||||
case '[':
|
||||
tok = yajl_tok_left_brace;
|
||||
goto lexed;
|
||||
case ']':
|
||||
case '}':
|
||||
tok = yajl_tok_right_brace;
|
||||
goto lexed;
|
||||
case '[':
|
||||
tok = yajl_tok_left_bracket;
|
||||
goto lexed;
|
||||
case ']':
|
||||
tok = yajl_tok_right_bracket;
|
||||
goto lexed;
|
||||
case ',':
|
||||
tok = yajl_tok_comma;
|
||||
goto lexed;
|
||||
@@ -707,23 +737,23 @@ yajl_lex_get_error(yajl_lexer lexer)
|
||||
return lexer->error;
|
||||
}
|
||||
|
||||
unsigned int yajl_lex_current_line(yajl_lexer lexer)
|
||||
size_t yajl_lex_current_line(yajl_lexer lexer)
|
||||
{
|
||||
return lexer->lineOff;
|
||||
}
|
||||
|
||||
unsigned int yajl_lex_current_char(yajl_lexer lexer)
|
||||
size_t yajl_lex_current_char(yajl_lexer lexer)
|
||||
{
|
||||
return lexer->charOff;
|
||||
}
|
||||
|
||||
yajl_tok yajl_lex_peek(yajl_lexer lexer, const unsigned char * jsonText,
|
||||
unsigned int jsonTextLen, unsigned int offset)
|
||||
size_t jsonTextLen, size_t offset)
|
||||
{
|
||||
const unsigned char * outBuf;
|
||||
unsigned int outLen;
|
||||
unsigned int bufLen = yajl_buf_len(lexer->buf);
|
||||
unsigned int bufOff = lexer->bufOff;
|
||||
size_t outLen;
|
||||
size_t bufLen = yajl_buf_len(lexer->buf);
|
||||
size_t bufOff = lexer->bufOff;
|
||||
unsigned int bufInUse = lexer->bufInUse;
|
||||
yajl_tok tok;
|
||||
|
||||
|
||||
@@ -1,34 +1,18 @@
|
||||
/*
|
||||
* Copyright 2010, Lloyd Hilaiel.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. Neither the name of Lloyd Hilaiel nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
* Copyright (c) 2007-2011, Lloyd Hilaiel <lloyd@hilaiel.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __YAJL_LEX_H__
|
||||
#define __YAJL_LEX_H__
|
||||
@@ -92,12 +76,12 @@ n * error messages.
|
||||
* size to get adequate performance.
|
||||
*/
|
||||
yajl_tok yajl_lex_lex(yajl_lexer lexer, const unsigned char * jsonText,
|
||||
unsigned int jsonTextLen, unsigned int * offset,
|
||||
const unsigned char ** outBuf, unsigned int * outLen);
|
||||
size_t jsonTextLen, size_t * offset,
|
||||
const unsigned char ** outBuf, size_t * outLen);
|
||||
|
||||
/** have a peek at the next token, but don't move the lexer forward */
|
||||
yajl_tok yajl_lex_peek(yajl_lexer lexer, const unsigned char * jsonText,
|
||||
unsigned int jsonTextLen, unsigned int offset);
|
||||
size_t jsonTextLen, size_t offset);
|
||||
|
||||
|
||||
typedef enum {
|
||||
@@ -121,13 +105,13 @@ const char * yajl_lex_error_to_string(yajl_lex_error error);
|
||||
yajl_lex_error yajl_lex_get_error(yajl_lexer lexer);
|
||||
|
||||
/** get the current offset into the most recently lexed json string. */
|
||||
unsigned int yajl_lex_current_offset(yajl_lexer lexer);
|
||||
size_t yajl_lex_current_offset(yajl_lexer lexer);
|
||||
|
||||
/** get the number of lines lexed by this lexer instance */
|
||||
unsigned int yajl_lex_current_line(yajl_lexer lexer);
|
||||
size_t yajl_lex_current_line(yajl_lexer lexer);
|
||||
|
||||
/** get the number of chars lexed by this lexer instance since the last
|
||||
* \n or \r */
|
||||
unsigned int yajl_lex_current_char(yajl_lexer lexer);
|
||||
size_t yajl_lex_current_char(yajl_lexer lexer);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,58 +1,38 @@
|
||||
/*
|
||||
* Copyright 2010, Lloyd Hilaiel.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. Neither the name of Lloyd Hilaiel nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
* Copyright (c) 2007-2011, Lloyd Hilaiel <lloyd@hilaiel.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file yajl_parse.h
|
||||
* Interface to YAJL's JSON parsing facilities.
|
||||
* Interface to YAJL's JSON stream parsing facilities.
|
||||
*/
|
||||
|
||||
#ifndef __YAJL_PARSE_H__
|
||||
#define __YAJL_PARSE_H__
|
||||
|
||||
#include <yajl_common.h>
|
||||
#include "yajl_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif
|
||||
/** error codes returned from this interface */
|
||||
typedef enum {
|
||||
/** no error was encountered */
|
||||
yajl_status_ok,
|
||||
/** a client callback returned zero, stopping the parse */
|
||||
yajl_status_client_canceled,
|
||||
/** The parse cannot yet complete because more json input text
|
||||
* is required, call yajl_parse with the next buffer of input text.
|
||||
* (pertinent only when stream parsing) */
|
||||
yajl_status_insufficient_data,
|
||||
/** An error occured during the parse. Call yajl_get_error for
|
||||
* more information about the encountered error */
|
||||
yajl_status_error
|
||||
@@ -75,64 +55,115 @@ extern "C" {
|
||||
* continue. If zero, the parse will be canceled and
|
||||
* yajl_status_client_canceled will be returned from the parse.
|
||||
*
|
||||
* Note about handling of numbers:
|
||||
* yajl will only convert numbers that can be represented in a double
|
||||
* or a long int. All other numbers will be passed to the client
|
||||
* in string form using the yajl_number callback. Furthermore, if
|
||||
* yajl_number is not NULL, it will always be used to return numbers,
|
||||
* that is yajl_integer and yajl_double will be ignored. If
|
||||
* yajl_number is NULL but one of yajl_integer or yajl_double are
|
||||
* defined, parsing of a number larger than is representable
|
||||
* in a double or long int will result in a parse error.
|
||||
* \attention {
|
||||
* A note about the handling of numbers:
|
||||
*
|
||||
* yajl will only convert numbers that can be represented in a
|
||||
* double or a 64 bit (long long) int. All other numbers will
|
||||
* be passed to the client in string form using the yajl_number
|
||||
* callback. Furthermore, if yajl_number is not NULL, it will
|
||||
* always be used to return numbers, that is yajl_integer and
|
||||
* yajl_double will be ignored. If yajl_number is NULL but one
|
||||
* of yajl_integer or yajl_double are defined, parsing of a
|
||||
* number larger than is representable in a double or 64 bit
|
||||
* integer will result in a parse error.
|
||||
* }
|
||||
*/
|
||||
typedef struct {
|
||||
int (* yajl_null)(void * ctx);
|
||||
int (* yajl_boolean)(void * ctx, int boolVal);
|
||||
int (* yajl_integer)(void * ctx, long integerVal);
|
||||
int (* yajl_integer)(void * ctx, long long integerVal);
|
||||
int (* yajl_double)(void * ctx, double doubleVal);
|
||||
/** A callback which passes the string representation of the number
|
||||
* back to the client. Will be used for all numbers when present */
|
||||
int (* yajl_number)(void * ctx, const char * numberVal,
|
||||
unsigned int numberLen);
|
||||
size_t numberLen);
|
||||
|
||||
/** strings are returned as pointers into the JSON text when,
|
||||
* possible, as a result, they are _not_ null padded */
|
||||
int (* yajl_string)(void * ctx, const unsigned char * stringVal,
|
||||
unsigned int stringLen);
|
||||
size_t stringLen);
|
||||
|
||||
int (* yajl_start_map)(void * ctx);
|
||||
int (* yajl_map_key)(void * ctx, const unsigned char * key,
|
||||
unsigned int stringLen);
|
||||
int (* yajl_end_map)(void * ctx);
|
||||
size_t stringLen);
|
||||
int (* yajl_end_map)(void * ctx);
|
||||
|
||||
int (* yajl_start_array)(void * ctx);
|
||||
int (* yajl_end_array)(void * ctx);
|
||||
int (* yajl_end_array)(void * ctx);
|
||||
} yajl_callbacks;
|
||||
|
||||
/** configuration structure for the generator */
|
||||
typedef struct {
|
||||
/** if nonzero, javascript style comments will be allowed in
|
||||
* the json input, both slash star and slash slash */
|
||||
unsigned int allowComments;
|
||||
/** if nonzero, invalid UTF8 strings will cause a parse
|
||||
* error */
|
||||
unsigned int checkUTF8;
|
||||
} yajl_parser_config;
|
||||
|
||||
/** allocate a parser handle
|
||||
* \param callbacks a yajl callbacks structure specifying the
|
||||
* functions to call when different JSON entities
|
||||
* are encountered in the input text. May be NULL,
|
||||
* which is only useful for validation.
|
||||
* \param config configuration parameters for the parse.
|
||||
* \param afs memory allocation functions, may be NULL for to use
|
||||
* C runtime library routines (malloc and friends)
|
||||
* \param ctx a context pointer that will be passed to callbacks.
|
||||
*/
|
||||
YAJL_API yajl_handle yajl_alloc(const yajl_callbacks * callbacks,
|
||||
const yajl_parser_config * config,
|
||||
const yajl_alloc_funcs * allocFuncs,
|
||||
yajl_alloc_funcs * afs,
|
||||
void * ctx);
|
||||
|
||||
/** free a parser handle */
|
||||
|
||||
/** configuration parameters for the parser, these may be passed to
|
||||
* yajl_config() along with option specific argument(s). In general,
|
||||
* all configuration parameters default to *off*. */
|
||||
typedef enum {
|
||||
/** Ignore javascript style comments present in
|
||||
* JSON input. Non-standard, but rather fun
|
||||
* arguments: toggled off with integer zero, on otherwise.
|
||||
*
|
||||
* example:
|
||||
* yajl_config(h, yajl_allow_comments, 1); // turn comment support on
|
||||
*/
|
||||
yajl_allow_comments = 0x01,
|
||||
/**
|
||||
* When set the parser will verify that all strings in JSON input are
|
||||
* valid UTF8 and will emit a parse error if this is not so. When set,
|
||||
* this option makes parsing slightly more expensive (~7% depending
|
||||
* on processor and compiler in use)
|
||||
*
|
||||
* example:
|
||||
* yajl_config(h, yajl_dont_validate_strings, 1); // disable utf8 checking
|
||||
*/
|
||||
yajl_dont_validate_strings = 0x02,
|
||||
/**
|
||||
* By default, upon calls to yajl_complete_parse(), yajl will
|
||||
* ensure the entire input text was consumed and will raise an error
|
||||
* otherwise. Enabling this flag will cause yajl to disable this
|
||||
* check. This can be useful when parsing json out of a that contains more
|
||||
* than a single JSON document.
|
||||
*/
|
||||
yajl_allow_trailing_garbage = 0x04,
|
||||
/**
|
||||
* Allow multiple values to be parsed by a single handle. The
|
||||
* entire text must be valid JSON, and values can be seperated
|
||||
* by any kind of whitespace. This flag will change the
|
||||
* behavior of the parser, and cause it continue parsing after
|
||||
* a value is parsed, rather than transitioning into a
|
||||
* complete state. This option can be useful when parsing multiple
|
||||
* values from an input stream.
|
||||
*/
|
||||
yajl_allow_multiple_values = 0x08,
|
||||
/**
|
||||
* When yajl_complete_parse() is called the parser will
|
||||
* check that the top level value was completely consumed. I.E.,
|
||||
* if called whilst in the middle of parsing a value
|
||||
* yajl will enter an error state (premature EOF). Setting this
|
||||
* flag suppresses that check and the corresponding error.
|
||||
*/
|
||||
yajl_allow_partial_values = 0x10
|
||||
} yajl_option;
|
||||
|
||||
/** allow the modification of parser options subsequent to handle
|
||||
* allocation (via yajl_alloc)
|
||||
* \returns zero in case of errors, non-zero otherwise
|
||||
*/
|
||||
YAJL_API int yajl_config(yajl_handle h, yajl_option opt, ...);
|
||||
|
||||
/** free a parser handle */
|
||||
YAJL_API void yajl_free(yajl_handle handle);
|
||||
|
||||
/** Parse some json!
|
||||
@@ -142,7 +173,7 @@ extern "C" {
|
||||
*/
|
||||
YAJL_API yajl_status yajl_parse(yajl_handle hand,
|
||||
const unsigned char * jsonText,
|
||||
unsigned int jsonTextLength);
|
||||
size_t jsonTextLength);
|
||||
|
||||
/** Parse any remaining buffered json.
|
||||
* Since yajl is a stream-based parser, without an explicit end of
|
||||
@@ -153,8 +184,8 @@ extern "C" {
|
||||
*
|
||||
* \param hand - a handle to the json parser allocated with yajl_alloc
|
||||
*/
|
||||
YAJL_API yajl_status yajl_parse_complete(yajl_handle hand);
|
||||
|
||||
YAJL_API yajl_status yajl_complete_parse(yajl_handle hand);
|
||||
|
||||
/** get an error string describing the state of the
|
||||
* parse.
|
||||
*
|
||||
@@ -163,31 +194,31 @@ extern "C" {
|
||||
* the specific char.
|
||||
*
|
||||
* \returns A dynamically allocated string will be returned which should
|
||||
* be freed with yajl_free_error
|
||||
* be freed with yajl_free_error
|
||||
*/
|
||||
YAJL_API unsigned char * yajl_get_error(yajl_handle hand, int verbose,
|
||||
const unsigned char * jsonText,
|
||||
unsigned int jsonTextLength);
|
||||
size_t jsonTextLength);
|
||||
|
||||
/**
|
||||
* get the amount of data consumed from the last chunk passed to YAJL.
|
||||
*
|
||||
* In the case of a successful parse this can help you understand if
|
||||
* the entire buffer was consumed (which will allow you to handle
|
||||
* "junk at end of input".
|
||||
*
|
||||
* "junk at end of input").
|
||||
*
|
||||
* In the event an error is encountered during parsing, this function
|
||||
* affords the client a way to get the offset into the most recent
|
||||
* chunk where the error occured. 0 will be returned if no error
|
||||
* was encountered.
|
||||
*/
|
||||
YAJL_API unsigned int yajl_get_bytes_consumed(yajl_handle hand);
|
||||
YAJL_API size_t yajl_get_bytes_consumed(yajl_handle hand);
|
||||
|
||||
/** free an error returned from yajl_get_error */
|
||||
YAJL_API void yajl_free_error(yajl_handle hand, unsigned char * str);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,34 +1,18 @@
|
||||
/*
|
||||
* Copyright 2010, Lloyd Hilaiel.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. Neither the name of Lloyd Hilaiel nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
* Copyright (c) 2007-2011, Lloyd Hilaiel <lloyd@hilaiel.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
@@ -40,21 +24,55 @@
|
||||
#include <math.h>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include "yajl_parse.h"
|
||||
#include "yajl_lex.h"
|
||||
#include "yajl_parser.h"
|
||||
#include "yajl_encode.h"
|
||||
#include "yajl_bytestack.h"
|
||||
|
||||
#ifndef LLONG_MAX
|
||||
#define LLONG_MAX 0x7FFFFFFFFFFFFFFFLL
|
||||
#define LLONG_MIN (-0x7FFFFFFFFFFFFFFFLL - 1)
|
||||
#endif
|
||||
|
||||
#define MAX_VALUE_TO_MULTIPLY ((LLONG_MAX / 10) + (LLONG_MAX % 10))
|
||||
|
||||
/* same semantics as strtol */
|
||||
long long
|
||||
yajl_parse_integer(const unsigned char *number, size_t length)
|
||||
{
|
||||
long long ret = 0;
|
||||
long sign = 1;
|
||||
const unsigned char *pos = number;
|
||||
if (*pos == '-') { pos++; sign = -1; }
|
||||
if (*pos == '+') { pos++; }
|
||||
|
||||
while (pos < number + length) {
|
||||
if ( ret > MAX_VALUE_TO_MULTIPLY ) {
|
||||
errno = ERANGE;
|
||||
return sign == 1 ? LLONG_MAX : LLONG_MIN;
|
||||
}
|
||||
ret *= 10;
|
||||
if (LLONG_MAX - ret < (*pos - '0')) {
|
||||
errno = ERANGE;
|
||||
return sign == 1 ? LLONG_MAX : LLONG_MIN;
|
||||
}
|
||||
ret += (*pos++ - '0');
|
||||
}
|
||||
|
||||
return sign * ret;
|
||||
}
|
||||
|
||||
unsigned char *
|
||||
yajl_render_error_string(yajl_handle hand, const unsigned char * jsonText,
|
||||
unsigned int jsonTextLen, int verbose)
|
||||
size_t jsonTextLen, int verbose)
|
||||
{
|
||||
unsigned int offset = hand->bytesConsumed;
|
||||
size_t offset = hand->bytesConsumed;
|
||||
unsigned char * str;
|
||||
const char * errorType = NULL;
|
||||
const char * errorText = NULL;
|
||||
char text[72];
|
||||
const char * arrow = " (right here) ------^\n";
|
||||
const char * arrow = " (right here) ------^\n";
|
||||
|
||||
if (yajl_bs_current(hand->stateStack) == yajl_state_parse_error) {
|
||||
errorType = "parse";
|
||||
@@ -67,34 +85,35 @@ yajl_render_error_string(yajl_handle hand, const unsigned char * jsonText,
|
||||
}
|
||||
|
||||
{
|
||||
unsigned int memneeded = 0;
|
||||
size_t memneeded = 0;
|
||||
memneeded += strlen(errorType);
|
||||
memneeded += strlen(" error");
|
||||
if (errorText != NULL) {
|
||||
memneeded += strlen(": ");
|
||||
memneeded += strlen(errorText);
|
||||
memneeded += strlen(": ");
|
||||
memneeded += strlen(errorText);
|
||||
}
|
||||
str = (unsigned char *) YA_MALLOC(&(hand->alloc), memneeded + 2);
|
||||
if (!str) return NULL;
|
||||
str[0] = 0;
|
||||
strcat((char *) str, errorType);
|
||||
strcat((char *) str, " error");
|
||||
strcat((char *) str, " error");
|
||||
if (errorText != NULL) {
|
||||
strcat((char *) str, ": ");
|
||||
strcat((char *) str, errorText);
|
||||
strcat((char *) str, ": ");
|
||||
strcat((char *) str, errorText);
|
||||
}
|
||||
strcat((char *) str, "\n");
|
||||
strcat((char *) str, "\n");
|
||||
}
|
||||
|
||||
/* now we append as many spaces as needed to make sure the error
|
||||
* falls at char 41, if verbose was specified */
|
||||
if (verbose) {
|
||||
unsigned int start, end, i;
|
||||
unsigned int spacesNeeded;
|
||||
size_t start, end, i;
|
||||
size_t spacesNeeded;
|
||||
|
||||
spacesNeeded = (offset < 30 ? 40 - offset : 10);
|
||||
start = (offset >= 30 ? offset - 30 : 0);
|
||||
end = (offset + 30 > jsonTextLen ? jsonTextLen : offset + 30);
|
||||
|
||||
|
||||
for (i=0;i<spacesNeeded;i++) text[i] = ' ';
|
||||
|
||||
for (;start < end;start++, i++) {
|
||||
@@ -115,10 +134,12 @@ yajl_render_error_string(yajl_handle hand, const unsigned char * jsonText,
|
||||
YA_MALLOC(&(hand->alloc), (unsigned int)(strlen((char *) str) +
|
||||
strlen((char *) text) +
|
||||
strlen(arrow) + 1));
|
||||
newStr[0] = 0;
|
||||
strcat((char *) newStr, (char *) str);
|
||||
strcat((char *) newStr, text);
|
||||
strcat((char *) newStr, arrow);
|
||||
if (newStr) {
|
||||
newStr[0] = 0;
|
||||
strcat((char *) newStr, (char *) str);
|
||||
strcat((char *) newStr, text);
|
||||
strcat((char *) newStr, arrow);
|
||||
}
|
||||
YA_FREE(&(hand->alloc), str);
|
||||
str = (unsigned char *) newStr;
|
||||
}
|
||||
@@ -136,35 +157,78 @@ yajl_render_error_string(yajl_handle hand, const unsigned char * jsonText,
|
||||
}
|
||||
|
||||
|
||||
yajl_status
|
||||
yajl_do_finish(yajl_handle hand)
|
||||
{
|
||||
yajl_status stat;
|
||||
stat = yajl_do_parse(hand,(const unsigned char *) " ",1);
|
||||
|
||||
if (stat != yajl_status_ok) return stat;
|
||||
|
||||
switch(yajl_bs_current(hand->stateStack))
|
||||
{
|
||||
case yajl_state_parse_error:
|
||||
case yajl_state_lexical_error:
|
||||
return yajl_status_error;
|
||||
case yajl_state_got_value:
|
||||
case yajl_state_parse_complete:
|
||||
return yajl_status_ok;
|
||||
default:
|
||||
if (!(hand->flags & yajl_allow_partial_values))
|
||||
{
|
||||
yajl_bs_set(hand->stateStack, yajl_state_parse_error);
|
||||
hand->parseError = "premature EOF";
|
||||
return yajl_status_error;
|
||||
}
|
||||
return yajl_status_ok;
|
||||
}
|
||||
}
|
||||
|
||||
yajl_status
|
||||
yajl_do_parse(yajl_handle hand, const unsigned char * jsonText,
|
||||
unsigned int jsonTextLen)
|
||||
size_t jsonTextLen)
|
||||
{
|
||||
yajl_tok tok;
|
||||
const unsigned char * buf;
|
||||
unsigned int bufLen;
|
||||
unsigned int * offset = &(hand->bytesConsumed);
|
||||
size_t bufLen;
|
||||
size_t * offset = &(hand->bytesConsumed);
|
||||
|
||||
*offset = 0;
|
||||
|
||||
|
||||
around_again:
|
||||
switch (yajl_bs_current(hand->stateStack)) {
|
||||
case yajl_state_parse_complete:
|
||||
if (hand->flags & yajl_allow_multiple_values) {
|
||||
yajl_bs_set(hand->stateStack, yajl_state_got_value);
|
||||
goto around_again;
|
||||
}
|
||||
if (!(hand->flags & yajl_allow_trailing_garbage)) {
|
||||
if (*offset != jsonTextLen) {
|
||||
tok = yajl_lex_lex(hand->lexer, jsonText, jsonTextLen,
|
||||
offset, &buf, &bufLen);
|
||||
if (tok != yajl_tok_eof) {
|
||||
yajl_bs_set(hand->stateStack, yajl_state_parse_error);
|
||||
hand->parseError = "trailing garbage";
|
||||
}
|
||||
goto around_again;
|
||||
}
|
||||
}
|
||||
return yajl_status_ok;
|
||||
case yajl_state_lexical_error:
|
||||
case yajl_state_parse_error:
|
||||
case yajl_state_parse_error:
|
||||
return yajl_status_error;
|
||||
case yajl_state_start:
|
||||
case yajl_state_got_value:
|
||||
case yajl_state_map_need_val:
|
||||
case yajl_state_array_need_val:
|
||||
case yajl_state_array_start: {
|
||||
case yajl_state_array_start: {
|
||||
/* for arrays and maps, we advance the state for this
|
||||
* depth, then push the state of the next depth.
|
||||
* If an error occurs during the parsing of the nesting
|
||||
* enitity, the state at this level will not matter.
|
||||
* a state that needs pushing will be anything other
|
||||
* than state_start */
|
||||
|
||||
yajl_state stateToPush = yajl_state_start;
|
||||
|
||||
tok = yajl_lex_lex(hand->lexer, jsonText, jsonTextLen,
|
||||
@@ -172,7 +236,7 @@ yajl_do_parse(yajl_handle hand, const unsigned char * jsonText,
|
||||
|
||||
switch (tok) {
|
||||
case yajl_tok_eof:
|
||||
return yajl_status_insufficient_data;
|
||||
return yajl_status_ok;
|
||||
case yajl_tok_error:
|
||||
yajl_bs_set(hand->stateStack, yajl_state_lexical_error);
|
||||
goto around_again;
|
||||
@@ -191,53 +255,38 @@ yajl_do_parse(yajl_handle hand, const unsigned char * jsonText,
|
||||
yajl_buf_len(hand->decodeBuf)));
|
||||
}
|
||||
break;
|
||||
case yajl_tok_bool:
|
||||
case yajl_tok_bool:
|
||||
if (hand->callbacks && hand->callbacks->yajl_boolean) {
|
||||
_CC_CHK(hand->callbacks->yajl_boolean(hand->ctx,
|
||||
*buf == 't'));
|
||||
}
|
||||
break;
|
||||
case yajl_tok_null:
|
||||
case yajl_tok_null:
|
||||
if (hand->callbacks && hand->callbacks->yajl_null) {
|
||||
_CC_CHK(hand->callbacks->yajl_null(hand->ctx));
|
||||
}
|
||||
break;
|
||||
case yajl_tok_left_bracket:
|
||||
case yajl_tok_left_brace:
|
||||
if (hand->callbacks && hand->callbacks->yajl_start_map) {
|
||||
_CC_CHK(hand->callbacks->yajl_start_map(hand->ctx));
|
||||
}
|
||||
stateToPush = yajl_state_map_start;
|
||||
break;
|
||||
case yajl_tok_left_brace:
|
||||
case yajl_tok_left_bracket:
|
||||
if (hand->callbacks && hand->callbacks->yajl_start_array) {
|
||||
_CC_CHK(hand->callbacks->yajl_start_array(hand->ctx));
|
||||
}
|
||||
stateToPush = yajl_state_array_start;
|
||||
break;
|
||||
case yajl_tok_integer:
|
||||
/*
|
||||
* note. strtol does not respect the length of
|
||||
* the lexical token. in a corner case where the
|
||||
* lexed number is a integer with a trailing zero,
|
||||
* immediately followed by the end of buffer,
|
||||
* sscanf could run off into oblivion and cause a
|
||||
* crash. for this reason we copy the integer
|
||||
* (and doubles), into our parse buffer (the same
|
||||
* one used for unescaping strings), before
|
||||
* calling strtol. yajl_buf ensures null padding,
|
||||
* so we're safe.
|
||||
*/
|
||||
if (hand->callbacks) {
|
||||
if (hand->callbacks->yajl_number) {
|
||||
_CC_CHK(hand->callbacks->yajl_number(
|
||||
hand->ctx,(const char *) buf, bufLen));
|
||||
} else if (hand->callbacks->yajl_integer) {
|
||||
long int i = 0;
|
||||
yajl_buf_clear(hand->decodeBuf);
|
||||
yajl_buf_append(hand->decodeBuf, buf, bufLen);
|
||||
buf = yajl_buf_data(hand->decodeBuf);
|
||||
i = strtol((const char *) buf, NULL, 10);
|
||||
if ((i == LONG_MIN || i == LONG_MAX) &&
|
||||
long long int i = 0;
|
||||
i = yajl_parse_integer(buf, bufLen);
|
||||
if ((i == LLONG_MIN || i == LLONG_MAX) &&
|
||||
errno == ERANGE)
|
||||
{
|
||||
yajl_bs_set(hand->stateStack,
|
||||
@@ -281,9 +330,10 @@ yajl_do_parse(yajl_handle hand, const unsigned char * jsonText,
|
||||
}
|
||||
}
|
||||
break;
|
||||
case yajl_tok_right_brace: {
|
||||
if (yajl_bs_current(hand->stateStack) ==
|
||||
yajl_state_array_start)
|
||||
case yajl_tok_right_bracket: {
|
||||
yajl_state s = yajl_bs_current(hand->stateStack);
|
||||
if (s == yajl_state_array_start ||
|
||||
s == yajl_state_array_need_val)
|
||||
{
|
||||
if (hand->callbacks &&
|
||||
hand->callbacks->yajl_end_array)
|
||||
@@ -291,13 +341,13 @@ yajl_do_parse(yajl_handle hand, const unsigned char * jsonText,
|
||||
_CC_CHK(hand->callbacks->yajl_end_array(hand->ctx));
|
||||
}
|
||||
yajl_bs_pop(hand->stateStack);
|
||||
goto around_again;
|
||||
goto around_again;
|
||||
}
|
||||
/* intentional fall-through */
|
||||
}
|
||||
case yajl_tok_colon:
|
||||
case yajl_tok_comma:
|
||||
case yajl_tok_right_bracket:
|
||||
case yajl_tok_colon:
|
||||
case yajl_tok_comma:
|
||||
case yajl_tok_right_brace:
|
||||
yajl_bs_set(hand->stateStack, yajl_state_parse_error);
|
||||
hand->parseError =
|
||||
"unallowed token at this point in JSON text";
|
||||
@@ -310,11 +360,11 @@ yajl_do_parse(yajl_handle hand, const unsigned char * jsonText,
|
||||
/* got a value. transition depends on the state we're in. */
|
||||
{
|
||||
yajl_state s = yajl_bs_current(hand->stateStack);
|
||||
if (s == yajl_state_start) {
|
||||
if (s == yajl_state_start || s == yajl_state_got_value) {
|
||||
yajl_bs_set(hand->stateStack, yajl_state_parse_complete);
|
||||
} else if (s == yajl_state_map_need_val) {
|
||||
yajl_bs_set(hand->stateStack, yajl_state_map_got_val);
|
||||
} else {
|
||||
} else {
|
||||
yajl_bs_set(hand->stateStack, yajl_state_array_got_val);
|
||||
}
|
||||
}
|
||||
@@ -324,7 +374,7 @@ yajl_do_parse(yajl_handle hand, const unsigned char * jsonText,
|
||||
|
||||
goto around_again;
|
||||
}
|
||||
case yajl_state_map_start:
|
||||
case yajl_state_map_start:
|
||||
case yajl_state_map_need_key: {
|
||||
/* only difference between these two states is that in
|
||||
* start '}' is valid, whereas in need_key, we've parsed
|
||||
@@ -333,7 +383,7 @@ yajl_do_parse(yajl_handle hand, const unsigned char * jsonText,
|
||||
offset, &buf, &bufLen);
|
||||
switch (tok) {
|
||||
case yajl_tok_eof:
|
||||
return yajl_status_insufficient_data;
|
||||
return yajl_status_ok;
|
||||
case yajl_tok_error:
|
||||
yajl_bs_set(hand->stateStack, yajl_state_lexical_error);
|
||||
goto around_again;
|
||||
@@ -352,20 +402,21 @@ yajl_do_parse(yajl_handle hand, const unsigned char * jsonText,
|
||||
}
|
||||
yajl_bs_set(hand->stateStack, yajl_state_map_sep);
|
||||
goto around_again;
|
||||
case yajl_tok_right_bracket:
|
||||
if (yajl_bs_current(hand->stateStack) ==
|
||||
yajl_state_map_start)
|
||||
{
|
||||
case yajl_tok_right_brace: {
|
||||
yajl_state s = yajl_bs_current(hand->stateStack);
|
||||
if (s == yajl_state_map_start ||
|
||||
s == yajl_state_map_need_key) {
|
||||
if (hand->callbacks && hand->callbacks->yajl_end_map) {
|
||||
_CC_CHK(hand->callbacks->yajl_end_map(hand->ctx));
|
||||
}
|
||||
yajl_bs_pop(hand->stateStack);
|
||||
goto around_again;
|
||||
goto around_again;
|
||||
}
|
||||
}
|
||||
default:
|
||||
yajl_bs_set(hand->stateStack, yajl_state_parse_error);
|
||||
hand->parseError =
|
||||
"invalid object key (must be a string)";
|
||||
"invalid object key (must be a string)";
|
||||
goto around_again;
|
||||
}
|
||||
}
|
||||
@@ -375,9 +426,9 @@ yajl_do_parse(yajl_handle hand, const unsigned char * jsonText,
|
||||
switch (tok) {
|
||||
case yajl_tok_colon:
|
||||
yajl_bs_set(hand->stateStack, yajl_state_map_need_val);
|
||||
goto around_again;
|
||||
goto around_again;
|
||||
case yajl_tok_eof:
|
||||
return yajl_status_insufficient_data;
|
||||
return yajl_status_ok;
|
||||
case yajl_tok_error:
|
||||
yajl_bs_set(hand->stateStack, yajl_state_lexical_error);
|
||||
goto around_again;
|
||||
@@ -392,24 +443,24 @@ yajl_do_parse(yajl_handle hand, const unsigned char * jsonText,
|
||||
tok = yajl_lex_lex(hand->lexer, jsonText, jsonTextLen,
|
||||
offset, &buf, &bufLen);
|
||||
switch (tok) {
|
||||
case yajl_tok_right_bracket:
|
||||
case yajl_tok_right_brace:
|
||||
if (hand->callbacks && hand->callbacks->yajl_end_map) {
|
||||
_CC_CHK(hand->callbacks->yajl_end_map(hand->ctx));
|
||||
}
|
||||
yajl_bs_pop(hand->stateStack);
|
||||
goto around_again;
|
||||
goto around_again;
|
||||
case yajl_tok_comma:
|
||||
yajl_bs_set(hand->stateStack, yajl_state_map_need_key);
|
||||
goto around_again;
|
||||
goto around_again;
|
||||
case yajl_tok_eof:
|
||||
return yajl_status_insufficient_data;
|
||||
return yajl_status_ok;
|
||||
case yajl_tok_error:
|
||||
yajl_bs_set(hand->stateStack, yajl_state_lexical_error);
|
||||
goto around_again;
|
||||
default:
|
||||
yajl_bs_set(hand->stateStack, yajl_state_parse_error);
|
||||
hand->parseError = "after key and value, inside map, "
|
||||
"I expect ',' or '}'";
|
||||
hand->parseError = "after key and value, inside map, "
|
||||
"I expect ',' or '}'";
|
||||
/* try to restore error offset */
|
||||
if (*offset >= bufLen) *offset -= bufLen;
|
||||
else *offset = 0;
|
||||
@@ -420,17 +471,17 @@ yajl_do_parse(yajl_handle hand, const unsigned char * jsonText,
|
||||
tok = yajl_lex_lex(hand->lexer, jsonText, jsonTextLen,
|
||||
offset, &buf, &bufLen);
|
||||
switch (tok) {
|
||||
case yajl_tok_right_brace:
|
||||
case yajl_tok_right_bracket:
|
||||
if (hand->callbacks && hand->callbacks->yajl_end_array) {
|
||||
_CC_CHK(hand->callbacks->yajl_end_array(hand->ctx));
|
||||
}
|
||||
yajl_bs_pop(hand->stateStack);
|
||||
goto around_again;
|
||||
goto around_again;
|
||||
case yajl_tok_comma:
|
||||
yajl_bs_set(hand->stateStack, yajl_state_array_need_val);
|
||||
goto around_again;
|
||||
goto around_again;
|
||||
case yajl_tok_eof:
|
||||
return yajl_status_insufficient_data;
|
||||
return yajl_status_ok;
|
||||
case yajl_tok_error:
|
||||
yajl_bs_set(hand->stateStack, yajl_state_lexical_error);
|
||||
goto around_again;
|
||||
@@ -442,8 +493,7 @@ yajl_do_parse(yajl_handle hand, const unsigned char * jsonText,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
abort();
|
||||
return yajl_status_error;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,34 +1,18 @@
|
||||
/*
|
||||
* Copyright 2010, Lloyd Hilaiel.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. Neither the name of Lloyd Hilaiel nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
* Copyright (c) 2007-2011, Lloyd Hilaiel <lloyd@hilaiel.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __YAJL_PARSER_H__
|
||||
#define __YAJL_PARSER_H__
|
||||
@@ -36,6 +20,7 @@
|
||||
#include "yajl_parse.h"
|
||||
#include "yajl_bytestack.h"
|
||||
#include "yajl_buf.h"
|
||||
#include "yajl_lex.h"
|
||||
|
||||
|
||||
typedef enum {
|
||||
@@ -44,13 +29,14 @@ typedef enum {
|
||||
yajl_state_parse_error,
|
||||
yajl_state_lexical_error,
|
||||
yajl_state_map_start,
|
||||
yajl_state_map_sep,
|
||||
yajl_state_map_sep,
|
||||
yajl_state_map_need_val,
|
||||
yajl_state_map_got_val,
|
||||
yajl_state_map_need_key,
|
||||
yajl_state_array_start,
|
||||
yajl_state_array_got_val,
|
||||
yajl_state_array_need_val
|
||||
yajl_state_array_need_val,
|
||||
yajl_state_got_value,
|
||||
} yajl_state;
|
||||
|
||||
struct yajl_handle_t {
|
||||
@@ -61,22 +47,32 @@ struct yajl_handle_t {
|
||||
/* the number of bytes consumed from the last client buffer,
|
||||
* in the case of an error this will be an error offset, in the
|
||||
* case of an error this can be used as the error offset */
|
||||
unsigned int bytesConsumed;
|
||||
size_t bytesConsumed;
|
||||
/* temporary storage for decoded strings */
|
||||
yajl_buf decodeBuf;
|
||||
/* a stack of states. access with yajl_state_XXX routines */
|
||||
yajl_bytestack stateStack;
|
||||
/* memory allocation routines */
|
||||
yajl_alloc_funcs alloc;
|
||||
/* bitfield */
|
||||
unsigned int flags;
|
||||
};
|
||||
|
||||
yajl_status
|
||||
yajl_do_parse(yajl_handle handle, const unsigned char * jsonText,
|
||||
unsigned int jsonTextLen);
|
||||
size_t jsonTextLen);
|
||||
|
||||
yajl_status
|
||||
yajl_do_finish(yajl_handle handle);
|
||||
|
||||
unsigned char *
|
||||
yajl_render_error_string(yajl_handle hand, const unsigned char * jsonText,
|
||||
unsigned int jsonTextLen, int verbose);
|
||||
size_t jsonTextLen, int verbose);
|
||||
|
||||
/* A little built in integer parsing routine with the same semantics as strtol
|
||||
* that's unaffected by LOCALE. */
|
||||
long long
|
||||
yajl_parse_integer(const unsigned char *number, size_t length);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user