[Opensrf-commits] r2000 - in trunk: . include/opensrf src/libopensrf (scottmk)
svn at svn.open-ils.org
svn at svn.open-ils.org
Sat Aug 14 07:09:47 EDT 2010
Author: scottmk
Date: 2010-08-14 07:09:47 -0400 (Sat, 14 Aug 2010)
New Revision: 2000
Removed:
trunk/include/opensrf/osrf_json_utils.h
trunk/src/libopensrf/osrf_json_parser.c
Modified:
trunk/Makefile.am
trunk/include/opensrf/osrf_json.h
trunk/src/libopensrf/Makefile.am
trunk/src/libopensrf/Makefile.json
trunk/src/libopensrf/osrf_json_object.c
trunk/src/libopensrf/osrf_json_tools.c
trunk/src/libopensrf/osrf_parse_json.c
Log:
Eliminate the old JSON parser, implemented in osrf_json_parser.c and
the associated header osrf_json_utils.h.
This parser has been completely replaced by a newer one implemented
in osrf_parse_json.c, plus an incremental JSON parser (so far
unused) in jsonpush.c..
The even older parser of JSON-with-comments is not affected.
D include/opensrf/osrf_json_utils.h
M include/opensrf/osrf_json.h
D src/libopensrf/osrf_json_parser.c
M src/libopensrf/osrf_json_object.c
M src/libopensrf/Makefile.json
M src/libopensrf/osrf_json_tools.c
M src/libopensrf/Makefile.am
M src/libopensrf/osrf_parse_json.c
M Makefile.am
Modified: trunk/Makefile.am
===================================================================
--- trunk/Makefile.am 2010-08-13 17:21:51 UTC (rev 1999)
+++ trunk/Makefile.am 2010-08-14 11:09:47 UTC (rev 2000)
@@ -95,7 +95,6 @@
$(OSRFINC)/osrfConfig.h \
$(OSRFINC)/osrf_hash.h \
$(OSRFINC)/osrf_json.h \
- $(OSRFINC)/osrf_json_utils.h \
$(OSRFINC)/osrf_json_xml.h \
$(OSRFINC)/osrf_legacy_json.h \
$(OSRFINC)/osrf_list.h \
Modified: trunk/include/opensrf/osrf_json.h
===================================================================
--- trunk/include/opensrf/osrf_json.h 2010-08-13 17:21:51 UTC (rev 1999)
+++ trunk/include/opensrf/osrf_json.h 2010-08-14 11:09:47 UTC (rev 2000)
@@ -56,56 +56,7 @@
extern "C" {
#endif
-/* parser states */
/**
- @name Parser states
- @brief Used internally by a JSON parser.
-
- A jsonParserContext stores these values in order to remember where the parser is in the
- parsing.
-*/
-/*@{*/
-#define JSON_STATE_IN_OBJECT 0x1
-#define JSON_STATE_IN_ARRAY 0x2
-#define JSON_STATE_IN_STRING 0x4
-#define JSON_STATE_IN_UTF 0x8
-#define JSON_STATE_IN_ESCAPE 0x10
-#define JSON_STATE_IN_KEY 0x20
-#define JSON_STATE_IN_NULL 0x40
-#define JSON_STATE_IN_TRUE 0x80
-#define JSON_STATE_IN_FALSE 0x100
-#define JSON_STATE_IN_NUMBER 0x200
-#define JSON_STATE_IS_INVALID 0x400
-#define JSON_STATE_IS_DONE 0x800
-#define JSON_STATE_START_COMMEN 0x1000
-#define JSON_STATE_IN_COMMENT 0x2000
-#define JSON_STATE_END_COMMENT 0x4000
-/*@}*/
-
-/**
- @name Parser state operations
- @ Macros to manipulate the parser state in a jsonParserContext.
-*/
-/*@{*/
-/** Set a state. */
-#define JSON_STATE_SET(ctx,s) ctx->state |= s;
-/** Unset a state. */
-#define JSON_STATE_REMOVE(ctx,s) ctx->state &= ~s;
-/** Check if a state is set. */
-#define JSON_STATE_CHECK(ctx,s) (ctx->state & s) ? 1 : 0
-/** Pop a state off the stack. */
-#define JSON_STATE_POP(ctx) osrfListPop( ctx->stateStack );
-/** Push a state on the stack. */
-#define JSON_STATE_PUSH(ctx, state) osrfListPush( ctx->stateStack,(void*) state );
-/** Check which container type we're currently in. */
-#define JSON_STATE_PEEK(ctx) osrfListGetIndex(ctx->stateStack, ctx->stateStack->size -1)
-/** Compare stack values. */
-#define JSON_STATE_CHECK_STACK(ctx, s) (JSON_STATE_PEEK(ctx) == (void*) s ) ? 1 : 0
-/** Check if a parser state is set. */
-#define JSON_PARSE_FLAG_CHECK(ctx, f) (ctx->flags & f) ? 1 : 0
-/*@}*/
-
-/**
@name JSON types
@brief Macros defining types of jsonObject.
@@ -122,12 +73,6 @@
/*@}*/
/**
- This macro is used only by a JSON parser. It probably has no business being published
- in a header.
-*/
-#define JSON_PARSE_LAST_CHUNK 0x1 /* this is the last part of the string we're parsing */
-
-/**
@name JSON extensions
These two macros define tags used for encoding class information. @em JSON_CLASS_KEY
@@ -147,55 +92,6 @@
/*@}*/
/**
- @brief Stores the current state of a JSON parser.
-
- One form of JSON parser operates as a finite state machine. It stores the various
- JSON_STATE_* values in order to keep track of what it's doing. It also maintains a
- stack of previous states in order to keep track of nesting.
-
- The internals of this struct are published in the header in order to provide the client
- with a window into the operations of the parser. By installing its own callback functions,
- and possibly by tinkering with the insides of the jsonParserContext, the client code can
- customize the behavior of the parser.
-
- In practice only the default callbacks are ever installed, at this writing. The potential
- for customized parsing is unused.
-*/
-struct jsonParserContextStruct {
- int state; /**< What are we currently parsing. */
- const char* chunk; /**< The chunk we're currently parsing. */
- int index; /**< Where we are in parsing the current chunk. */
- int chunksize; /**< Size of the current chunk. */
- int flags; /**< Parser flags. */
- osrfList* stateStack; /**< The nest of object/array states. */
- growing_buffer* buffer; /**< Buffer for building strings, numbers, and keywords. */
- growing_buffer* utfbuf; /**< Holds the current unicode characters. */
- void* userData; /**< Opaque user pointer. We ignore this. */
- const struct jsonParserHandlerStruct* handler; /**< The event handler struct. */
-};
-typedef struct jsonParserContextStruct jsonParserContext;
-
-/**
- @brief A collection of function pointers for customizing parser behavior.
-
- The client code can install pointers to its own functions in this struct, in order to
- customize the behavior of the parser at various points in the parsing.
-*/
-struct jsonParserHandlerStruct {
- void (*handleStartObject) (void* userData);
- void (*handleObjectKey) (void* userData, char* key);
- void (*handleEndObject) (void* userData);
- void (*handleStartArray) (void* userData);
- void (*handleEndArray) (void* userData);
- void (*handleNull) (void* userData);
- void (*handleString) (void* userData, char* string);
- void (*handleBool) (void* userData, int boolval);
- void (*handleNumber) (void* userData, const char* numstr);
- void (*handleError) (void* userData, char* err, ...);
-};
-typedef struct jsonParserHandlerStruct jsonParserHandler;
-
-/**
@brief Representation of a JSON string in memory
Different types of jsonObject use different members of the @em value union.
@@ -238,109 +134,11 @@
};
typedef struct _jsonIteratorStruct jsonIterator;
-
-
-/**
- @brief Allocate a new parser context object.
- @param handler Pointer to a collection of function pointers for callback functions.
- @param userData Opaque user pointer which is available to callbacks; ignored by the parser.
- @return An allocated parser context, or NULL on error.
-*/
-jsonParserContext* jsonNewParser( const jsonParserHandler* handler, void* userData);
-
-/**
- @brief Free a jsonParserContext.
- @param ctx Pointer to the jsonParserContext to be freed.
-*/
-void jsonParserFree( jsonParserContext* ctx );
-
-/**
- @brief Parse a chunk of data.
- @param ctx Pointer to the parser context.
- @param data Pointer the data to parse.
- @param datalen The size of the chunk to parse.
- @param flags Reserved.
-*/
-int jsonParseChunk( jsonParserContext* ctx, const char* data, int datalen, int flags );
-
-/**
- @name Parsing functions
-
- There are two sets of parsing functions, which are mostly plug-compatible with each other.
- The older series:
-
- - jsonParseString()
- - jsonParseStringRaw()
- - jsonParseStringFmt()
-
- ...and a newer series:
-
- - jsonParse();
- - jsonParseRaw();
- - jsonParseFmt();
-
- The first series is based on a finite state machine. Its innards are accessible, in
- theory, through the jsonParserContext structure and through callback functions. In
- practice this flexibility is unused at this writing.
-
- The second series is based on recursive descent. It doesn't use the jsonParserContext
- structure, nor does it accept callback functions. However it is faster than the first
- parser. In addition its syntax checking is much stricter -- it catches many kinds of
- syntax errors that slip through the first parser.
-*/
-/*@{*/
-/**
- @brief Parse a JSON string, with decoding of classname hints.
- @param str Pointer to the JSON string to parse.
- @return A pointer to the resulting JSON object, or NULL on error.
-
- If any node in the jsonObject tree is of type JSON_HASH, with a tag of JSON_CLASS_KEY
- and another tag of JSON_DATA_KEY, the parser will collapse a level. The subobject
- tagged with JSON_DATA_KEY will replace the JSON_HASH, and the string tagged as
- JSON_CLASS_KEY will be stored as its classname. If there is no tag of JSON_DATA_KEY,
- the hash will be replaced by a jsonObject of type JSON_NULL.
-
- The calling code is responsible for freeing the resulting jsonObject.
-*/
-jsonObject* jsonParseString( const char* str );
-
-/**
- @brief Parse a JSON string, with no decoding of classname hints.
- @param str Pointer to the JSON string to parse.
- @return A pointer to the resulting JSON object, or NULL on error.
-
- This function is similar to jsonParseString(), except that it does not give any special
- treatment to a JSON_HASH with the JSON_CLASS_KEY tag.
-
- The calling code is responsible for freeing the resulting jsonObject.
-*/
-jsonObject* jsonParseStringRaw( const char* str );
-
-/**
- @brief Parse a JSON string received as a printf-style format string.
- @param str A printf-style format string. Subsequent arguments, if any, are formatted
- and inserted into the JSON string before parsing.
- @return A pointer to the resulting JSON object, or NULL on error.
-
- Unlike jsonParseString(), this function does not give any special treatment to a
- JSON_HASH with tags JSON_CLASS_KEY or JSON_DATA_KEY.
-
- The calling code is responsible for freeing the resulting jsonObject.
-*/
-jsonObject* jsonParseStringFmt( const char* str, ... );
-
jsonObject* jsonParse( const char* str );
+
jsonObject* jsonParseRaw( const char* str );
-jsonObject* jsonParseFmt( const char* s, ... );
-/*@}*/
-/**
- @brief Parses a JSON string, using a customized error handler.
- @param errorHandler A function pointer to an error-handling function.
- @param str The string to parse.
- @return The resulting JSON object, or NULL on error.
-*/
-jsonObject* jsonParseStringHandleError( void (*errorHandler) (const char*), char* str, ... );
+jsonObject* jsonParseFmt( const char* str, ... );
jsonObject* jsonNewObject(const char* data);
@@ -444,9 +242,6 @@
*/
char* jsonFormatString( const char* jsonString );
-/* sets the error handler for all parsers */
-void jsonSetGlobalErrorHandler(void (*errorHandler) (const char*));
-
/* ------------------------------------------------------------------------- */
/*
* The following methods provide a facility for serializing and
Deleted: trunk/include/opensrf/osrf_json_utils.h
===================================================================
--- trunk/include/opensrf/osrf_json_utils.h 2010-08-13 17:21:51 UTC (rev 1999)
+++ trunk/include/opensrf/osrf_json_utils.h 2010-08-14 11:09:47 UTC (rev 2000)
@@ -1,108 +0,0 @@
-/*
-Copyright (C) 2006 Georgia Public Library Service
-Bill Erickson <billserickson at gmail.com>
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-*/
-
-#ifndef OSRF_JSON_UTILS_H
-#define OSRF_JSON_UTILS_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* ----------------------------------------------------------------------- */
-/* Clients need not include this file. These are internal utilities only */
-/* ----------------------------------------------------------------------- */
-
-#define JSON_EAT_WS(ctx) \
- while( ctx->index < ctx->chunksize ) { \
- if(!isspace(ctx->chunk[ctx->index])) break; \
- ctx->index++; \
- } \
- if( ctx->index >= ctx->chunksize ) return 0; \
- c = ctx->chunk[ctx->index];
-
-#define JSON_CACHE_DATA(ctx, buf, size) \
- while( (buf->n_used < size) && (ctx->index < ctx->chunksize) ) \
- buffer_add_char(buf, ctx->chunk[ctx->index++]);
-
-#define JSON_LOG_MARK __FILE__,__LINE__
-
-#define JSON_NUMBER_CHARS "0123456789.+-eE"
-
-/**
- * These are the callbacks through which the top level parser
- * builds objects via the push parser
- */
-void _jsonHandleStartObject(void*);
-void _jsonHandleObjectKey(void*, char* key);
-void _jsonHandleEndObject(void*);
-void _jsonHandleStartArray(void*);
-void _jsonHandleEndArray(void*);
-void _jsonHandleNull(void*);
-void _jsonHandleString(void*, char* string);
-void _jsonHandleBool(void*, int boolval);
-void _jsonHandleNumber(void*, const char* numstr);
-void _jsonHandleError(void*, char* str, ...);
-
-struct jsonInternalParserStruct {
- jsonParserContext* ctx;
- jsonObject* obj;
- jsonObject* current;
- char* lastkey;
- void (*handleError) (const char*);
-};
-typedef struct jsonInternalParserStruct jsonInternalParser;
-
-jsonInternalParser* _jsonNewInternalParser();
-void _jsonInternalParserFree(jsonInternalParser* p);
-
-/**
- * Calls the defined error handler with the given error message.
- * @return -1
- */
-int _jsonParserError( jsonParserContext* ctx, char* err, ... );
-
-
-/**
- *
- * @return 0 on continue, 1 if it goes past the end of the string, -1 on error
- */
-int _jsonParserHandleUnicode( jsonParserContext* ctx );
-
-
-/**
- * @param type 0 for null, 1 for true, 2 for false
- * @return 0 on continue, 1 if it goes past the end of the string, -1 on error
- */
-int _jsonParserHandleMatch( jsonParserContext* ctx, int type );
-
-/**
- * @return 0 on continue, 1 on end of chunk, -1 on error
- */
-int _jsonParserHandleString( jsonParserContext* ctx );
-
-/**
- * @return 0 on continue, 1 on end of chunk, -1 on error
- */
-int _jsonParserHandleNumber( jsonParserContext* ctx );
-
-
-void _jsonInsertParserItem( jsonInternalParser* p, jsonObject* newo );
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
Modified: trunk/src/libopensrf/Makefile.am
===================================================================
--- trunk/src/libopensrf/Makefile.am 2010-08-13 17:21:51 UTC (rev 1999)
+++ trunk/src/libopensrf/Makefile.am 2010-08-14 11:09:47 UTC (rev 2000)
@@ -65,12 +65,10 @@
$(OSRF_INC)/socket_bundle.h \
$(OSRF_INC)/sha.h \
$(OSRF_INC)/string_array.h \
- $(OSRF_INC)/osrf_json_utils.h \
$(OSRF_INC)/osrf_json_xml.h
JSON_TARGS = osrf_json_object.c\
osrf_parse_json.c \
- osrf_json_parser.c \
osrf_json_tools.c \
osrf_legacy_json.c \
osrf_json_xml.c
Modified: trunk/src/libopensrf/Makefile.json
===================================================================
--- trunk/src/libopensrf/Makefile.json 2010-08-13 17:21:51 UTC (rev 1999)
+++ trunk/src/libopensrf/Makefile.json 2010-08-14 11:09:47 UTC (rev 2000)
@@ -7,7 +7,7 @@
# OSRF_INC="../../include/opensrf" LDLIBS="-lxml2" \
# make -f Makefile.json standalone
# ------------------------------------------------------------------
-TARGETS = osrf_json_object.o osrf_json_parser.o osrf_json_tools.o osrf_legacy_json.o osrf_json_xml.o
+TARGETS = osrf_json_object.o osrf_parse_json.o osrf_json_tools.o osrf_legacy_json.o osrf_json_xml.o
# these are only needed when compiling the standalone version
EXT_TARGETS = osrf_list.o osrf_hash.o utils.o log.o md5.o string_array.o
@@ -17,10 +17,10 @@
standalone: $(TARGETS) $(EXT_TARGETS)
$(CC) -shared -W1 $(CFLAGS) $(LDFLAGS) $(LDLIBS) $(TARGETS) $(EXT_TARGETS) -o libosrf_json.so
-osrf_json_object.o: osrf_json_object.c $(OSRF_INC)/osrf_json.h $(OSRF_INC)/osrf_json_utils.h
-osrf_json_parser.o: osrf_json_parser.c $(OSRF_INC)/osrf_json.h $(OSRF_INC)/osrf_json_utils.h
-osrf_json_tools.o: osrf_json_tools.c $(OSRF_INC)/osrf_json.h $(OSRF_INC)/osrf_json_utils.h
-osrf_legacy_json.o: osrf_legacy_json.c $(OSRF_INC)/osrf_json.h $(OSRF_INC)/osrf_json_utils.h
+osrf_json_object.o: osrf_json_object.c $(OSRF_INC)/osrf_json.h
+osrf_parse_json.o: osrf_parse_json.c $(OSRF_INC)/osrf_json.h
+osrf_json_tools.o: osrf_json_tools.c $(OSRF_INC)/osrf_json.h
+osrf_legacy_json.o: osrf_legacy_json.c $(OSRF_INC)/osrf_json.h
osrf_json_xml.o: osrf_json_xml.c $(OSRF_INC)/osrf_json.h $(OSRF_INC)/osrf_json_xml.h
Modified: trunk/src/libopensrf/osrf_json_object.c
===================================================================
--- trunk/src/libopensrf/osrf_json_object.c 2010-08-13 17:21:51 UTC (rev 1999)
+++ trunk/src/libopensrf/osrf_json_object.c 2010-08-14 11:09:47 UTC (rev 2000)
@@ -30,7 +30,6 @@
#include <limits.h>
#include <opensrf/log.h>
#include <opensrf/osrf_json.h>
-#include <opensrf/osrf_json_utils.h>
#include <opensrf/osrf_utf8.h>
/* cleans up an object if it is morphing another object, also
@@ -479,7 +478,7 @@
@brief Recursively traverse a jsonObject, translating it into a JSON string.
@param obj Pointer to the jsonObject to be translated.
@param buf Pointer to a growing_buffer that will receive the JSON string.
- @param do_classname Boolean; if true, expand class names.
+ @param do_classname Boolean; if true, expand (i.e. encode) class names.
@param second_pass Boolean; should always be false except for some recursive calls.
If @a do_classname is true, expand any class names, as described in the discussion of
Deleted: trunk/src/libopensrf/osrf_json_parser.c
===================================================================
--- trunk/src/libopensrf/osrf_json_parser.c 2010-08-13 17:21:51 UTC (rev 1999)
+++ trunk/src/libopensrf/osrf_json_parser.c 2010-08-14 11:09:47 UTC (rev 2000)
@@ -1,692 +0,0 @@
-/*
-Copyright (C) 2006 Georgia Public Library Service
-Bill Erickson <billserickson at gmail.com>
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-*/
-
-#include <opensrf/osrf_json.h>
-#include <opensrf/osrf_json_utils.h>
-#include <ctype.h>
-
-
-/* if the client sets a global error handler, this will point to it */
-static void (*jsonClientErrorCallback) (const char*) = NULL;
-
-/* these are the handlers for our internal parser */
-static const jsonParserHandler jsonInternalParserHandler = {
- _jsonHandleStartObject,
- _jsonHandleObjectKey,
- _jsonHandleEndObject,
- _jsonHandleStartArray,
- _jsonHandleEndArray,
- _jsonHandleNull,
- _jsonHandleString,
- _jsonHandleBool,
- _jsonHandleNumber,
- _jsonHandleError
-};
-
-static jsonParserContext staticContext;
-static int staticContextInUse = 0; // boolean
-
-static jsonInternalParser staticParser;
-static int staticParserInUse = 0; // boolean
-
-jsonParserContext* jsonNewParser( const jsonParserHandler* handler, void* userData) {
- jsonParserContext* ctx;
-
- // Use the static instance of jsonParserContext,
- // if it's available
-
- if( staticContextInUse )
- OSRF_MALLOC(ctx, sizeof(jsonParserContext));
- else {
- ctx = &staticContext;
- staticContextInUse = 1;
- }
-
- ctx->stateStack = osrfNewList();
- ctx->buffer = buffer_init(512);
- ctx->utfbuf = buffer_init(5);
- ctx->handler = handler;
- ctx->state = 0;
- ctx->index = 0;
- ctx->chunksize = 0;
- ctx->flags = 0;
- ctx->chunk = NULL;
- ctx->userData = userData;
- return ctx;
-}
-
-void jsonParserFree( jsonParserContext* ctx ) {
- if(!ctx) return;
- buffer_free(ctx->buffer);
- buffer_free(ctx->utfbuf);
- osrfListFree(ctx->stateStack);
-
- // if the jsonParserContext was allocated
- // dynamically, then free it
-
- if( &staticContext == ctx )
- staticContextInUse = 0;
- else
- free(ctx);
-}
-
-
-void jsonSetGlobalErrorHandler(void (*errorHandler) (const char*)) {
- jsonClientErrorCallback = errorHandler;
-}
-
-
-int _jsonParserError( jsonParserContext* ctx, char* err, ... ) {
- if( ctx->handler->handleError ) {
- VA_LIST_TO_STRING(err);
-
- // Determine the beginning and ending points of a JSON
- // fragment to display, from the vicinity of the error
-
- int pre = ctx->index - 15;
- if( pre < 0 ) pre = 0;
- int post= ctx->index + 15;
- if( post >= ctx->chunksize ) post = ctx->chunksize - 1;
-
- // Copy the fragment into a buffer
-
- int len = post - pre + 1; // length of fragment
- char buf[len + 1];
- memcpy( buf, ctx->chunk + pre, len );
- buf[ len ] = '\0';
-
- // Issue an error message
-
- ctx->handler->handleError( ctx->userData,
- "*JSON Parser Error\n - char = %c\n "
- "- index = %d\n - near => %s\n - %s",
- ctx->chunk[ctx->index], ctx->index, buf, VA_BUF );
- }
- JSON_STATE_SET(ctx, JSON_STATE_IS_INVALID);
- return -1;
-}
-
-
-int _jsonParserHandleUnicode( jsonParserContext* ctx ) {
-
- /* collect as many of the utf characters as we can in this chunk */
- JSON_CACHE_DATA(ctx, ctx->utfbuf, 4);
-
- /* we ran off the end of the chunk */
- if( ctx->utfbuf->n_used < 4 ) {
- JSON_STATE_SET(ctx, JSON_STATE_IN_UTF);
- return 1;
- }
-
- ctx->index--; /* push it back to index of the final utf char */
-
- /* ----------------------------------------------------------------------- */
- /* We have all of the escaped unicode data. Write it to the buffer */
- /* The following chunk is used with permission from
- * json-c http://oss.metaparadigm.com/json-c/
- */
- #define hexdigit(x) ( ((x) <= '9') ? (x) - '0' : ((x) & 7) + 9)
- unsigned char utf_out[4];
- memset(utf_out, 0, sizeof(utf_out));
- char* buf = ctx->utfbuf->buf;
-
- unsigned int ucs_char =
- (hexdigit(buf[0] ) << 12) +
- (hexdigit(buf[1]) << 8) +
- (hexdigit(buf[2]) << 4) +
- hexdigit(buf[3]);
-
- if (ucs_char < 0x80) {
- utf_out[0] = ucs_char;
- OSRF_BUFFER_ADD(ctx->buffer, (char*)utf_out);
-
- } else if (ucs_char < 0x800) {
- utf_out[0] = 0xc0 | (ucs_char >> 6);
- utf_out[1] = 0x80 | (ucs_char & 0x3f);
- OSRF_BUFFER_ADD(ctx->buffer, (char*)utf_out);
-
- } else {
- utf_out[0] = 0xe0 | (ucs_char >> 12);
- utf_out[1] = 0x80 | ((ucs_char >> 6) & 0x3f);
- utf_out[2] = 0x80 | (ucs_char & 0x3f);
- OSRF_BUFFER_ADD(ctx->buffer, (char*)utf_out);
- }
- /* ----------------------------------------------------------------------- */
- /* ----------------------------------------------------------------------- */
-
- JSON_STATE_REMOVE(ctx, JSON_STATE_IN_UTF);
- JSON_STATE_REMOVE(ctx, JSON_STATE_IN_ESCAPE);
- OSRF_BUFFER_RESET(ctx->utfbuf);
- return 0;
-}
-
-
-
-/* type : 0=null, 1=true, 2=false */
-int _jsonParserHandleMatch( jsonParserContext* ctx, int type ) {
-
- switch(type) {
-
- case 0: /* JSON null */
-
- /* first see if we have it all first */
- if( ctx->chunksize > (ctx->index + 3) ) {
- if( strncasecmp(ctx->chunk + ctx->index, "null", 4) )
- return _jsonParserError(ctx, "Invalid JSON 'null' sequence");
- if( ctx->handler->handleNull )
- ctx->handler->handleNull(ctx->userData);
- ctx->index += 4;
- break;
- }
-
- JSON_CACHE_DATA(ctx, ctx->buffer, 4);
- if( ctx->buffer->n_used < 4 ) {
- JSON_STATE_SET(ctx, JSON_STATE_IN_NULL);
- return 1;
- }
-
- if( strncasecmp(ctx->buffer->buf, "null", 4) )
- return _jsonParserError(ctx, "Invalid JSON 'null' sequence");
- if( ctx->handler->handleNull )
- ctx->handler->handleNull(ctx->userData);
- break;
-
- case 1: /* JSON true */
-
- /* see if we have it all first */
- if( ctx->chunksize > (ctx->index + 3) ) {
- if( strncasecmp(ctx->chunk + ctx->index, "true", 4) )
- return _jsonParserError(ctx, "Invalid JSON 'true' sequence");
- if( ctx->handler->handleBool )
- ctx->handler->handleBool(ctx->userData, 1);
- ctx->index += 4;
- break;
- }
-
- JSON_CACHE_DATA(ctx, ctx->buffer, 4);
- if( ctx->buffer->n_used < 4 ) {
- JSON_STATE_SET(ctx, JSON_STATE_IN_TRUE);
- return 1;
- }
- if( strncasecmp( ctx->buffer->buf, "true", 4 ) ) {
- return _jsonParserError(ctx, "Invalid JSON 'true' sequence");
- }
- if( ctx->handler->handleBool )
- ctx->handler->handleBool(ctx->userData, 1);
- break;
-
- case 2: /* JSON false */
-
- /* see if we have it all first */
- if( ctx->chunksize > (ctx->index + 4) ) {
- if( strncasecmp(ctx->chunk + ctx->index, "false", 5) )
- return _jsonParserError(ctx, "Invalid JSON 'false' sequence");
- if( ctx->handler->handleBool )
- ctx->handler->handleBool(ctx->userData, 0);
- ctx->index += 5;
- break;
- }
-
- JSON_CACHE_DATA(ctx, ctx->buffer, 5);
- if( ctx->buffer->n_used < 5 ) {
- JSON_STATE_SET(ctx, JSON_STATE_IN_FALSE);
- return 1;
- }
- if( strncasecmp( ctx->buffer->buf, "false", 5 ) )
- return _jsonParserError(ctx, "Invalid JSON 'false' sequence");
- if( ctx->handler->handleBool )
- ctx->handler->handleBool(ctx->userData, 0);
- break;
-
- default:
- fprintf(stderr, "Invalid type flag\n");
- return -1;
-
- }
-
- ctx->index--; /* set it back to the index of the final sequence character */
- OSRF_BUFFER_RESET(ctx->buffer);
- JSON_STATE_REMOVE(ctx, JSON_STATE_IN_NULL);
- JSON_STATE_REMOVE(ctx, JSON_STATE_IN_TRUE);
- JSON_STATE_REMOVE(ctx, JSON_STATE_IN_FALSE);
-
- return 0;
-}
-
-
-int _jsonParserHandleString( jsonParserContext* ctx ) {
-
- char c = ctx->chunk[ctx->index];
-
- if( JSON_STATE_CHECK(ctx, JSON_STATE_IN_ESCAPE) ) {
-
- if( JSON_STATE_CHECK(ctx, JSON_STATE_IN_UTF) ) {
-
- return _jsonParserHandleUnicode( ctx );
-
- } else {
-
- switch(c) {
-
- /* handle all of the escape chars */
- case '\\': OSRF_BUFFER_ADD_CHAR( ctx->buffer, '\\' ); break;
- case '"' : OSRF_BUFFER_ADD_CHAR( ctx->buffer, '\"' ); break;
- case 't' : OSRF_BUFFER_ADD_CHAR( ctx->buffer, '\t' ); break;
- case 'b' : OSRF_BUFFER_ADD_CHAR( ctx->buffer, '\b' ); break;
- case 'f' : OSRF_BUFFER_ADD_CHAR( ctx->buffer, '\f' ); break;
- case 'r' : OSRF_BUFFER_ADD_CHAR( ctx->buffer, '\r' ); break;
- case 'n' : OSRF_BUFFER_ADD_CHAR( ctx->buffer, '\n' ); break;
- case 'u' :
- ctx->index++; /* progress to the first utf char */
- return _jsonParserHandleUnicode( ctx );
- default : OSRF_BUFFER_ADD_CHAR( ctx->buffer, c );
- }
- }
-
- JSON_STATE_REMOVE(ctx, JSON_STATE_IN_ESCAPE);
- return 0;
-
- } else {
-
- switch(c) {
-
- case '"' : /* this string is ending */
- if( JSON_STATE_CHECK(ctx, JSON_STATE_IN_KEY) ) {
-
- /* object key */
- if(ctx->handler->handleObjectKey) {
- ctx->handler->handleObjectKey(
- ctx->userData, ctx->buffer->buf);
- }
-
- } else { /* regular json string */
-
- if(ctx->handler->handleString) {
- ctx->handler->handleString(
- ctx->userData, ctx->buffer->buf );
- }
-
- }
-
- OSRF_BUFFER_RESET(ctx->buffer); /* flush the buffer and states */
- JSON_STATE_REMOVE(ctx, JSON_STATE_IN_STRING);
- JSON_STATE_REMOVE(ctx, JSON_STATE_IN_KEY);
- break;
-
- case '\\' : JSON_STATE_SET(ctx, JSON_STATE_IN_ESCAPE); break;
- default : OSRF_BUFFER_ADD_CHAR( ctx->buffer, c );
- }
- }
- return 0;
-}
-
-
-int _jsonParserHandleNumber( jsonParserContext* ctx ) {
- char c = ctx->chunk[ctx->index];
-
- do {
- OSRF_BUFFER_ADD_CHAR(ctx->buffer, c);
- c = ctx->chunk[++(ctx->index)];
- } while( strchr(JSON_NUMBER_CHARS, c) && ctx->index < ctx->chunksize );
-
- /* if we're run off the end of the chunk and we're not parsing the last chunk,
- * save the number and the state */
- if( ctx->index >= ctx->chunksize &&
- ! JSON_PARSE_FLAG_CHECK(ctx, JSON_PARSE_LAST_CHUNK) ) {
- JSON_STATE_SET(ctx, JSON_STATE_IN_NUMBER);
- return 1;
- }
-
- if(ctx->handler->handleNumber)
- {
- if( jsonIsNumeric( ctx->buffer->buf ) )
- ctx->handler->handleNumber( ctx->userData, ctx->buffer->buf );
- else {
- // The number string is not numeric according to JSON rules.
- // Scrub it into an acceptable format.
-
- char* scrubbed = jsonScrubNumber( ctx->buffer->buf );
- if( !scrubbed )
- return _jsonParserError(ctx, "Invalid number sequence");
- else {
- ctx->handler->handleNumber( ctx->userData, scrubbed );
- free( scrubbed );
- }
- }
- }
-
- ctx->index--; /* scooch back to the first non-digit number */
- JSON_STATE_REMOVE(ctx, JSON_STATE_IN_NUMBER);
- OSRF_BUFFER_RESET(ctx->buffer);
- return 0;
-}
-
-int jsonParseChunk( jsonParserContext* ctx, const char* data, int datalen, int flags ) {
-
- if( !( ctx && ctx->handler && data && datalen > 0 )) return -1;
- ctx->chunksize = datalen;
- ctx->chunk = data;
- ctx->flags = flags;
- char c;
-
- if( JSON_STATE_CHECK(ctx, JSON_STATE_IS_INVALID) )
- return _jsonParserError( ctx, "JSON Parser cannot continue after an error" );
-
- if( JSON_STATE_CHECK(ctx, JSON_STATE_IS_DONE) )
- return _jsonParserError( ctx, "Extra content at end of JSON data" );
-
- for( ctx->index = 0; (ctx->index < ctx->chunksize) &&
- (c = ctx->chunk[ctx->index]); ctx->index++ ) {
-
- /* middle of parsing a string */
- if( JSON_STATE_CHECK(ctx, JSON_STATE_IN_STRING)) {
- if( _jsonParserHandleString(ctx) == -1 )
- return -1;
- continue;
- }
-
- /* middle of parsing a number */
- if( JSON_STATE_CHECK(ctx, JSON_STATE_IN_NUMBER) ) {
- if( _jsonParserHandleNumber(ctx) == -1 )
- return -1;
- continue;
- }
-
-
-#ifdef OSRF_JSON_ALLOW_COMMENTS
- /* we just saw a bare '/' character */
- if( JSON_STATE_CHECK(ctx, JSON_STATE_START_COMMENT) ) {
- if(c == '*') {
- JSON_STATE_REMOVE(ctx, JSON_STATE_START_COMMENT);
- JSON_STATE_SET(ctx, JSON_STATE_IN_COMMENT);
- continue;
- } else {
- return _jsonParserError( ctx, "Invalid comment initializer" );
- }
- }
-
- /* we're currently in the middle of a comment block */
- if( JSON_STATE_CHECK(ctx, JSON_STATE_IN_COMMENT) ) {
- if(c == '*') {
- JSON_STATE_REMOVE(ctx, JSON_STATE_IN_COMMENT);
- JSON_STATE_SET(ctx, JSON_STATE_END_COMMENT);
- continue;
- } else {
- continue;
- }
- }
-
- /* we're in a comment, and we just saw a '*' character */
- if( JSON_STATE_CHECK(ctx, JSON_STATE_END_COMMENT) ) {
- if( c == '/' ) { /* comment is finished */
- JSON_STATE_REMOVE(ctx, JSON_STATE_END_COMMENT);
- continue;
- } else {
- /* looks like this isn't the end of the comment after all */
- JSON_STATE_SET(ctx, JSON_STATE_IN_COMMENT);
- JSON_STATE_REMOVE(ctx, JSON_STATE_END_COMMENT);
- }
- }
-#endif
-
- /* if we're in the middle of parsing a null/true/false sequence */
- if( JSON_STATE_CHECK(ctx, (JSON_STATE_IN_NULL |
- JSON_STATE_IN_TRUE | JSON_STATE_IN_FALSE)) ) {
-
- int type = (JSON_STATE_CHECK(ctx, JSON_STATE_IN_NULL)) ? 0 :
- (JSON_STATE_CHECK(ctx, JSON_STATE_IN_TRUE)) ? 1 : 2;
-
- if( _jsonParserHandleMatch( ctx, type ) == -1 )
- return -1;
- continue;
- }
-
- JSON_EAT_WS(ctx);
-
- /* handle all of the top level characters */
- switch(c) {
-
- case '{' : /* starting an object */
- if( ctx->handler->handleStartObject)
- ctx->handler->handleStartObject( ctx->userData );
- JSON_STATE_PUSH(ctx, JSON_STATE_IN_OBJECT);
- JSON_STATE_SET(ctx, JSON_STATE_IN_KEY);
- break;
-
- case '}' : /* ending an object */
- if( ctx->handler->handleEndObject)
- ctx->handler->handleEndObject( ctx->userData );
- JSON_STATE_REMOVE(ctx, JSON_STATE_IN_KEY);
- JSON_STATE_POP(ctx);
- if( JSON_STATE_PEEK(ctx) == NULL )
- JSON_STATE_SET(ctx, JSON_STATE_IS_DONE);
- break;
-
- case '[' : /* starting an array */
- if( ctx->handler->handleStartArray )
- ctx->handler->handleStartArray( ctx->userData );
- JSON_STATE_PUSH(ctx, JSON_STATE_IN_ARRAY);
- break;
-
- case ']': /* ending an array */
- if( ctx->handler->handleEndArray )
- ctx->handler->handleEndArray( ctx->userData );
- JSON_STATE_POP(ctx);
- if( JSON_STATE_PEEK(ctx) == NULL )
- JSON_STATE_SET(ctx, JSON_STATE_IS_DONE);
- break;
-
- case ':' : /* done with the object key */
- JSON_STATE_REMOVE(ctx, JSON_STATE_IN_KEY);
- break;
-
- case ',' : /* after object or array item */
- if( JSON_STATE_CHECK_STACK(ctx, JSON_STATE_IN_OBJECT) )
- JSON_STATE_SET(ctx, JSON_STATE_IN_KEY);
- break;
-
- case 'n' :
- case 'N' : /* null */
- if( _jsonParserHandleMatch( ctx, 0 ) == -1)
- return -1;
- break;
-
- case 't' :
- case 'T' :
- if( _jsonParserHandleMatch( ctx, 1 ) == -1 )
- return -1;
- break;
-
- case 'f' :
- case 'F' :
- if( _jsonParserHandleMatch( ctx, 2 ) == -1)
- return -1;
- break;
-
- case '"' :
- JSON_STATE_SET(ctx, JSON_STATE_IN_STRING);
- break;
-
-#ifdef OSRF_JSON_ALLOW_COMMENTS
- case '/' :
- JSON_STATE_SET(ctx, JSON_STATE_START_COMMENT);
- break;
-#endif
-
- default:
- if( strchr(JSON_NUMBER_CHARS, c) ) {
- if( _jsonParserHandleNumber( ctx ) == -1 )
- return -1;
- } else {
- return _jsonParserError( ctx, "Invalid Token" );
- }
- }
- }
-
- return 0;
-}
-
-
-jsonInternalParser* _jsonNewInternalParser() {
- jsonInternalParser* p;
-
- // Use the static instance of jsonInternalParser,
- // if it's available
-
- if( staticParserInUse )
- OSRF_MALLOC(p, sizeof(jsonInternalParser));
- else {
- p = &staticParser;
- staticParserInUse = 1;
- }
-
- p->ctx = jsonNewParser( &jsonInternalParserHandler, p );
- p->obj = NULL;
- p->current = NULL;
- p->lastkey = NULL;
- p->handleError = NULL;
- return p;
-}
-
-void _jsonInternalParserFree(jsonInternalParser* p) {
- if(!p) return;
- jsonParserFree(p->ctx);
- free(p->lastkey);
-
- // if the jsonInternalParser was allocated
- // dynamically, then free it
-
- if( &staticParser == p )
- staticParserInUse = 0;
- else
- free(p);
-}
-
-static jsonObject* _jsonParseStringImpl(const char* str, void (*errorHandler) (const char*) ) {
- jsonInternalParser* parser = _jsonNewInternalParser();
- parser->handleError = errorHandler;
- jsonParseChunk( parser->ctx, str, strlen(str), JSON_PARSE_LAST_CHUNK );
- jsonObject* obj = parser->obj;
- _jsonInternalParserFree(parser);
- return obj;
-}
-
-jsonObject* jsonParseStringHandleError(
- void (*errorHandler) (const char*), char* str, ... ) {
- if(!str) return NULL;
- VA_LIST_TO_STRING(str);
- return _jsonParseStringImpl(VA_BUF, errorHandler);
-}
-
-jsonObject* jsonParseString( const char* str ) {
- if(!str) return NULL;
- jsonObject* obj = _jsonParseStringImpl(str, NULL);
- jsonObject* obj2 = jsonObjectDecodeClass(obj);
- jsonObjectFree(obj);
- return obj2;
-}
-
-jsonObject* jsonParseStringRaw( const char* str ) {
- if(!str) return NULL;
- return _jsonParseStringImpl(str, NULL);
-}
-
-jsonObject* jsonParseStringFmt( const char* str, ... ) {
- if(!str) return NULL;
- VA_LIST_TO_STRING(str);
- return _jsonParseStringImpl(VA_BUF, NULL);
-}
-
-
-#define JSON_SHOVE_ITEM(ctx,type) \
- jsonInternalParser* p = (jsonInternalParser*) ctx;\
- _jsonInsertParserItem(p, jsonNewObjectType(type));
-
-void _jsonHandleStartObject(void* ctx) { JSON_SHOVE_ITEM(ctx, JSON_HASH); }
-void _jsonHandleStartArray(void* ctx) { JSON_SHOVE_ITEM(ctx, JSON_ARRAY); }
-void _jsonHandleNull(void* ctx) { JSON_SHOVE_ITEM(ctx, JSON_NULL); }
-
-void _jsonHandleObjectKey(void* ctx, char* key) {
- jsonInternalParser* p = (jsonInternalParser*) ctx;
- free(p->lastkey);
- p->lastkey = strdup(key);
-}
-
-void _jsonHandleEndObject(void* ctx) {
- jsonInternalParser* p = (jsonInternalParser*) ctx;
- p->current = p->current->parent;
-}
-
-void _jsonHandleEndArray(void* ctx) {
- jsonInternalParser* p = (jsonInternalParser*) ctx;
- p->current = p->current->parent;
-}
-
-void _jsonHandleString(void* ctx, char* string) {
- jsonInternalParser* p = (jsonInternalParser*) ctx;
- _jsonInsertParserItem(p, jsonNewObject(string));
-}
-
-void _jsonHandleBool(void* ctx, int boolval) {
- jsonInternalParser* p = (jsonInternalParser*) ctx;
- jsonObject* obj = jsonNewObjectType(JSON_BOOL);
- obj->value.b = boolval;
- _jsonInsertParserItem(p, obj);
-}
-
-void _jsonHandleNumber(void* ctx, const char* numstr) {
- jsonObject* obj = jsonNewNumberStringObject(numstr);
- jsonInternalParser* p = (jsonInternalParser*) ctx;
- _jsonInsertParserItem(p, obj);
-}
-
-void _jsonHandleError(void* ctx, char* str, ...) {
- jsonInternalParser* p = (jsonInternalParser*) ctx;
- VA_LIST_TO_STRING(str);
-
- if( p->handleError )
- p->handleError(VA_BUF);
- else
- if( jsonClientErrorCallback )
- jsonClientErrorCallback(VA_BUF);
-
- else fprintf(stderr, "%s\n", VA_BUF);
- jsonObjectFree(p->obj);
- p->obj = NULL;
-}
-
-
-void _jsonInsertParserItem( jsonInternalParser* p, jsonObject* newo ) {
-
- if( !p->obj ) {
-
- /* new parser, set the new object to our object */
- p->obj = p->current = newo;
-
- } else {
-
- /* insert the new object into the current container object */
- if(p->current->type == JSON_HASH)
- jsonObjectSetKey(p->current, p->lastkey, newo);
- else // assume it's a JSON_ARRAY; if it isn't, it'll become one
- jsonObjectPush(p->current, newo);
-
- /* if the new object is a container object, make it our current container */
- if( newo->type == JSON_ARRAY || newo->type == JSON_HASH )
- p->current = newo;
- }
-}
-
-
Modified: trunk/src/libopensrf/osrf_json_tools.c
===================================================================
--- trunk/src/libopensrf/osrf_json_tools.c 2010-08-13 17:21:51 UTC (rev 1999)
+++ trunk/src/libopensrf/osrf_json_tools.c 2010-08-14 11:09:47 UTC (rev 2000)
@@ -15,7 +15,6 @@
#include <ctype.h>
#include "opensrf/osrf_json.h"
-#include "opensrf/osrf_json_utils.h"
static jsonObject* findMultiPath( const jsonObject* o,
const char* root, const char* path );
Modified: trunk/src/libopensrf/osrf_parse_json.c
===================================================================
--- trunk/src/libopensrf/osrf_parse_json.c 2010-08-13 17:21:51 UTC (rev 1999)
+++ trunk/src/libopensrf/osrf_parse_json.c 2010-08-14 11:09:47 UTC (rev 2000)
@@ -23,7 +23,6 @@
#include <stdio.h>
#include <ctype.h>
#include <opensrf/osrf_json.h>
-#include <opensrf/osrf_json_utils.h>
/**
@brief A collection of things the parser uses to keep track of what it's doing.
More information about the opensrf-commits
mailing list