Skip to content
Browse files

Switch to libyajl2

  • Loading branch information...
1 parent 2331b0e commit 60748e083cae66d27e371ae6656568072dae0c2b @jedisct1 committed
View
2 src/handle_consumer_ops.c
@@ -6,7 +6,7 @@
static int send_json_gen(yajl_gen json_gen, const OpReply * const op_reply)
{
const unsigned char *json_out_buf;
- unsigned int json_out_len;
+ size_t json_out_len;
struct evbuffer *evb;
yajl_gen_map_close(json_gen);
View
7 src/http_server.c
@@ -51,13 +51,12 @@ int send_op_reply(HttpHandlerContext * const context,
yajl_gen new_json_gen(const OpReply * const op_reply)
{
- yajl_gen json_gen = yajl_gen_alloc(&(yajl_gen_config) {
- .beautify = BEAUTIFY_JSON,
- .indentString = "\t"
- }, NULL);
+ yajl_gen json_gen = yajl_gen_alloc(NULL);
if (json_gen == NULL) {
return NULL;
}
+ yajl_gen_config(json_gen, yajl_gen_beautify, BEAUTIFY_JSON);
+ yajl_gen_config(json_gen, yajl_gen_indent_string, "\t");
yajl_gen_map_open(json_gen);
yajl_gen_string(json_gen, (const unsigned char *) "tid",
sizeof "tid" - (size_t) 1U);
View
5 src/yajl/Makefile.am
@@ -16,9 +16,12 @@ libyajl_a_SOURCES = \
yajl_lex.h \
yajl_parser.c \
yajl_parser.h \
+ yajl_tree.c \
+ yajl_version.c \
api/yajl_common.h \
api/yajl_gen.h \
- api/yajl_parse.h
+ api/yajl_parse.h \
+ api/yajl_tree.h
SUBDIRS = api
View
58 src/yajl/api/yajl_common.h
@@ -1,38 +1,24 @@
/*
- * 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>
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -49,19 +35,23 @@ extern "C" {
# define YAJL_API __declspec(dllimport)
# endif
#else
-# define YAJL_API
+# if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 303
+# define YAJL_API __attribute__ ((visibility("default")))
+# else
+# define YAJL_API
+# endif
#endif
/** 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. */
@@ -80,6 +70,6 @@ typedef struct
#ifdef __cplusplus
}
-#endif
+#endif
#endif
View
144 src/yajl/api/yajl_gen.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.
+ */
/**
* \file yajl_gen.h
@@ -40,9 +24,11 @@
#ifndef __YAJL_GEN_H__
#define __YAJL_GEN_H__
+#include <stddef.h>
+
#ifdef __cplusplus
extern "C" {
-#endif
+#endif
/** generator status codes */
typedef enum {
/** no error */
@@ -63,7 +49,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,69 +62,77 @@ 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;
- /** 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
- * malloc/free/realloc will be used.
- *
- * \returns an allocated handle on success, NULL on failure (bad params)
+ /** allow the modification of generator options subsequent to handle
+ * allocation (via yajl_alloc)
+ * \returns zero in case of errors, non-zero otherwise
*/
- YAJL_API yajl_gen yajl_gen_alloc(const yajl_gen_config * config,
- 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.
+ YAJL_API int yajl_gen_config(yajl_gen g, yajl_gen_option opt, ...);
+
+ /** allocate a generator handle
* \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);
+ YAJL_API yajl_gen yajl_gen_alloc(const yajl_alloc_funcs * allocFuncs);
- /** 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 +143,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
View
181 src/yajl/api/yajl_parse.h
@@ -1,38 +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.
+ */
/**
* \file yajl_parse.h
- * Interface to YAJL's JSON parsing facilities.
+ * Interface to YAJL's JSON stream parsing facilities.
*/
#include "yajl_common.h"
@@ -40,19 +24,17 @@
#ifndef __YAJL_PARSE_H__
#define __YAJL_PARSE_H__
+#include <stddef.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 +57,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 +175,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 +186,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 +196,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
View
185 src/yajl/api/yajl_tree.h
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2010-2011 Florian Forster <ff at octo.it>
+ *
+ * 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_tree.h
+ *
+ * Parses JSON data and returns the data in tree form.
+ *
+ * \author Florian Forster
+ * \date August 2010
+ *
+ * This interface makes quick parsing and extraction of
+ * smallish JSON docs trivial:
+ *
+ * \include example/parse_config.c
+ */
+
+#ifndef YAJL_TREE_H
+#define YAJL_TREE_H 1
+
+#include "yajl_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** possible data types that a yajl_val_s can hold */
+typedef enum {
+ yajl_t_string = 1,
+ yajl_t_number = 2,
+ yajl_t_object = 3,
+ yajl_t_array = 4,
+ yajl_t_true = 5,
+ yajl_t_false = 6,
+ yajl_t_null = 7,
+ /** The any type isn't valid for yajl_val_s.type, but can be
+ * used as an argument to routines like yajl_tree_get().
+ */
+ yajl_t_any = 8
+} yajl_type;
+
+#define YAJL_NUMBER_INT_VALID 0x01
+#define YAJL_NUMBER_DOUBLE_VALID 0x02
+
+/** A pointer to a node in the parse tree */
+typedef struct yajl_val_s * yajl_val;
+
+/**
+ * A JSON value representation capable of holding one of the seven
+ * types above. For "string", "number", "object", and "array"
+ * additional data is available in the union. The "YAJL_IS_*"
+ * and "YAJL_GET_*" macros below allow type checking and convenient
+ * value extraction.
+ */
+struct yajl_val_s
+{
+ /** Type of the value contained. Use the "YAJL_IS_*" macors to check for a
+ * specific type. */
+ yajl_type type;
+ /** Type-specific data. You may use the "YAJL_GET_*" macros to access these
+ * members. */
+ union
+ {
+ char * string;
+ struct {
+ long long i; /*< integer value, if representable. */
+ double d; /*< double value, if representable. */
+ /** Signals whether the \em i and \em d members are
+ * valid. See \c YAJL_NUMBER_INT_VALID and
+ * \c YAJL_NUMBER_DOUBLE_VALID. */
+ char *r; /*< unparsed number in string form. */
+ unsigned int flags;
+ } number;
+ struct {
+ const char **keys; /*< Array of keys */
+ yajl_val *values; /*< Array of values. */
+ size_t len; /*< Number of key-value-pairs. */
+ } object;
+ struct {
+ yajl_val *values; /*< Array of elements. */
+ size_t len; /*< Number of elements. */
+ } array;
+ } u;
+};
+
+/**
+ * Parse a string.
+ *
+ * Parses an null-terminated string containing JSON data and returns a pointer
+ * to the top-level value (root of the parse tree).
+ *
+ * \param input Pointer to a null-terminated utf8 string containing
+ * JSON data.
+ * \param error_buffer Pointer to a buffer in which an error message will
+ * be stored if \em yajl_tree_parse fails, or
+ * \c NULL. The buffer will be initialized before
+ * parsing, so its content will be destroyed even if
+ * \em yajl_tree_parse succeeds.
+ * \param error_buffer_size Size of the memory area pointed to by
+ * \em error_buffer_size. If \em error_buffer_size is
+ * \c NULL, this argument is ignored.
+ *
+ * \returns Pointer to the top-level value or \c NULL on error. The memory
+ * pointed to must be freed using \em yajl_tree_free. In case of an error, a
+ * null terminated message describing the error in more detail is stored in
+ * \em error_buffer if it is not \c NULL.
+ */
+YAJL_API yajl_val yajl_tree_parse (const char *input,
+ char *error_buffer, size_t error_buffer_size);
+
+/**
+ * Free a parse tree returned by "yajl_tree_parse".
+ *
+ * \param v Pointer to a JSON value returned by "yajl_tree_parse". Passing NULL
+ * is valid and results in a no-op.
+ */
+YAJL_API void yajl_tree_free (yajl_val v);
+
+/**
+ * Access a nested value inside a tree.
+ *
+ * \param parent the node under which you'd like to extract values.
+ * \param path A null terminated array of strings, each the name of an object key
+ * \param type the yajl_type of the object you seek, or yajl_t_any if any will do.
+ *
+ * \returns a pointer to the found value, or NULL if we came up empty.
+ *
+ * Future Ideas: it'd be nice to move path to a string and implement support for
+ * a teeny tiny micro language here, so you can extract array elements, do things
+ * like .first and .last, even .length. Inspiration from JSONPath and css selectors?
+ * No it wouldn't be fast, but that's not what this API is about.
+ */
+YAJL_API yajl_val yajl_tree_get(yajl_val parent, const char ** path, yajl_type type);
+
+/* Various convenience macros to check the type of a `yajl_val` */
+#define YAJL_IS_STRING(v) (((v) != NULL) && ((v)->type == yajl_t_string))
+#define YAJL_IS_NUMBER(v) (((v) != NULL) && ((v)->type == yajl_t_number))
+#define YAJL_IS_INTEGER(v) (YAJL_IS_NUMBER(v) && ((v)->u.number.flags & YAJL_NUMBER_INT_VALID))
+#define YAJL_IS_DOUBLE(v) (YAJL_IS_NUMBER(v) && ((v)->u.number.flags & YAJL_NUMBER_DOUBLE_VALID))
+#define YAJL_IS_OBJECT(v) (((v) != NULL) && ((v)->type == yajl_t_object))
+#define YAJL_IS_ARRAY(v) (((v) != NULL) && ((v)->type == yajl_t_array ))
+#define YAJL_IS_TRUE(v) (((v) != NULL) && ((v)->type == yajl_t_true ))
+#define YAJL_IS_FALSE(v) (((v) != NULL) && ((v)->type == yajl_t_false ))
+#define YAJL_IS_NULL(v) (((v) != NULL) && ((v)->type == yajl_t_null ))
+
+/** Given a yajl_val_string return a ptr to the bare string it contains,
+ * or NULL if the value is not a string. */
+#define YAJL_GET_STRING(v) (YAJL_IS_STRING(v) ? (v)->u.string : NULL)
+
+/** Get the string representation of a number. You should check type first,
+ * perhaps using YAJL_IS_NUMBER */
+#define YAJL_GET_NUMBER(v) ((v)->u.number.r)
+
+/** Get the double representation of a number. You should check type first,
+ * perhaps using YAJL_IS_DOUBLE */
+#define YAJL_GET_DOUBLE(v) ((v)->u.number.d)
+
+/** Get the 64bit (long long) integer representation of a number. You should
+ * check type first, perhaps using YAJL_IS_INTEGER */
+#define YAJL_GET_INTEGER(v) ((v)->u.number.i)
+
+/** Get a pointer to a yajl_val_object or NULL if the value is not an object. */
+#define YAJL_GET_OBJECT(v) (YAJL_IS_OBJECT(v) ? &(v)->u.object : NULL)
+
+/** Get a pointer to a yajl_val_array or NULL if the value is not an object. */
+#define YAJL_GET_ARRAY(v) (YAJL_IS_ARRAY(v) ? &(v)->u.array : NULL)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* YAJL_TREE_H */
View
132 src/yajl/yajl.c
@@ -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 "api/yajl_parse.h"
#include "yajl_lex.h"
@@ -37,6 +21,7 @@
#include <stdlib.h>
#include <string.h>
+#include <stdarg.h>
#include <assert.h>
const char *
@@ -50,9 +35,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;
@@ -62,15 +44,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)
@@ -87,61 +66,98 @@ yajl_alloc(const yajl_callbacks * callbacks,
/* 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));
+ }
+
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;
View
51 src/yajl/yajl_alloc.c
@@ -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
@@ -39,22 +23,19 @@
#include "yajl_alloc.h"
#include <stdlib.h>
-static void * yajl_internal_malloc(void *ctx, unsigned int sz)
+static void * yajl_internal_malloc(void *ctx, size_t sz)
{
- (void) ctx;
return malloc(sz);
}
static void * yajl_internal_realloc(void *ctx, void * previous,
- unsigned int sz)
+ size_t sz)
{
- (void) ctx;
return realloc(previous, sz);
}
static void yajl_internal_free(void *ctx, void * ptr)
{
- (void) ctx;
free(ptr);
}
View
44 src/yajl/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.
+ */
/**
* \file yajl_alloc.h
View
58 src/yajl/yajl_buf.c
@@ -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 "yajl_buf.h"
@@ -39,16 +23,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);
@@ -84,7 +68,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) {
@@ -106,13 +90,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;
View
50 src/yajl/yajl_buf.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.
+ */
#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
View
56 src/yajl/yajl_bytestack.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.
+ */
/*
* 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
View
130 src/yajl/yajl_encode.c
@@ -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 "yajl_encode.h"
@@ -45,20 +29,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;
@@ -69,7 +47,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;
@@ -83,7 +66,7 @@ yajl_string_encode2(const yajl_print_t print,
}
if (escaped != NULL) {
print(ctx, (const char *) (str + beg), end - beg);
- print(ctx, escaped, strlen(escaped));
+ print(ctx, escaped, (unsigned int)strlen(escaped));
beg = ++end;
} else {
++end;
@@ -131,10 +114,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] == '\\') {
@@ -173,12 +156,19 @@ void yajl_string_decode(yajl_buf buf, const unsigned char * str,
Utf32toUtf8(codepoint, utf8Buf);
unescaped = utf8Buf;
+
+ if (codepoint == 0) {
+ yajl_buf_append(buf, unescaped, 1);
+ beg = ++end;
+ continue;
+ }
+
break;
}
default:
assert("this should never happen" == NULL);
}
- yajl_buf_append(buf, unescaped, strlen(unescaped));
+ yajl_buf_append(buf, unescaped, (unsigned int)strlen(unescaped));
beg = ++end;
} else {
end++;
@@ -186,3 +176,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;
+}
View
60 src/yajl/yajl_encode.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.
+ */
#ifndef __YAJL_ENCODE_H__
#define __YAJL_ENCODE_H__
@@ -36,15 +20,15 @@
#include "yajl_buf.h"
#include "api/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
View
186 src/yajl/yajl_gen.c
@@ -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 "api/yajl_gen.h"
#include "yajl_buf.h"
@@ -38,6 +22,7 @@
#include <string.h>
#include <stdio.h>
#include <math.h>
+#include <stdarg.h>
typedef enum {
yajl_gen_start,
@@ -50,10 +35,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;
@@ -62,18 +47,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;
@@ -90,22 +111,15 @@ yajl_gen_alloc2(const yajl_print_t callback,
}
g = (yajl_gen) YA_MALLOC(afs, sizeof(struct yajl_gen_t));
+ if (!g) return NULL;
+
memset((void *) g, 0, sizeof(struct yajl_gen_t));
/* copy in pointers to allocation routines */
memcpy((void *) &(g->alloc), (void *) afs, sizeof(yajl_alloc_funcs));
- if (config) {
- g->pretty = config->beautify;
- g->indentString = config->indentString ? config->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;
}
@@ -121,26 +135,28 @@ 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++) \
- g->print(g->ctx, g->indentString, \
- strlen(g->indentString)); \
+ g->print(g->ctx, \
+ g->indentString, \
+ (unsigned int)strlen(g->indentString)); \
} \
}
#define ENSURE_NOT_KEY \
- if (g->state[g->depth] == yajl_gen_map_key) { \
- return yajl_gen_keys_must_be_strings; \
- } \
+ if (g->state[g->depth] == yajl_gen_map_key || \
+ g->state[g->depth] == yajl_gen_map_start) { \
+ return yajl_gen_keys_must_be_strings; \
+ } \
/* check that we're not complete, or in error state. in a valid state
* to be generating */
@@ -154,6 +170,9 @@ yajl_gen_free(yajl_gen g)
#define INCREMENT_DEPTH \
if (++(g->depth) >= YAJL_MAX_DEPTH) return yajl_max_depth_exceeded;
+#define DECREMENT_DEPTH \
+ if (--(g->depth) >= YAJL_MAX_DEPTH) return yajl_gen_error;
+
#define APPENDED_ATOM \
switch (g->state[g->depth]) { \
case yajl_gen_start: \
@@ -174,16 +193,16 @@ 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;
- snprintf(i, sizeof i, "%ld", number);
- g->print(g->ctx, i, strlen(i));
+ sprintf(i, "%lld", number);
+ g->print(g->ctx, i, (unsigned int)strlen(i));
APPENDED_ATOM;
FINAL_NEWLINE;
return yajl_gen_status_ok;
@@ -202,15 +221,15 @@ yajl_gen_double(yajl_gen g, double number)
ENSURE_VALID_STATE; ENSURE_NOT_KEY;
if (isnan(number) || isinf(number)) return yajl_gen_invalid_number;
INSERT_SEP; INSERT_WHITESPACE;
- snprintf(i, sizeof i, "%g", number);
- g->print(g->ctx, i, strlen(i));
+ sprintf(i, "%.20g", number);
+ g->print(g->ctx, i, (unsigned int)strlen(i));
APPENDED_ATOM;
FINAL_NEWLINE;
return yajl_gen_status_ok;
}
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);
@@ -221,11 +240,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;
@@ -248,7 +275,7 @@ yajl_gen_bool(yajl_gen g, int boolean)
const char * val = boolean ? "true" : "false";
ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE;
- g->print(g->ctx, val, strlen(val));
+ g->print(g->ctx, val, (unsigned int)strlen(val));
APPENDED_ATOM;
FINAL_NEWLINE;
return yajl_gen_status_ok;
@@ -262,7 +289,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;
}
@@ -271,8 +298,9 @@ yajl_gen_status
yajl_gen_map_close(yajl_gen g)
{
ENSURE_VALID_STATE;
- (g->depth)--;
- if (g->pretty) g->print(g->ctx, "\n", 1);
+ DECREMENT_DEPTH;
+
+ if ((g->flags & yajl_gen_beautify)) g->print(g->ctx, "\n", 1);
APPENDED_ATOM;
INSERT_WHITESPACE;
g->print(g->ctx, "}", 1);
@@ -287,7 +315,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;
}
@@ -296,8 +324,8 @@ yajl_gen_status
yajl_gen_array_close(yajl_gen g)
{
ENSURE_VALID_STATE;
- if (g->pretty) g->print(g->ctx, "\n", 1);
- (g->depth)--;
+ DECREMENT_DEPTH;
+ if ((g->flags & yajl_gen_beautify)) g->print(g->ctx, "\n", 1);
APPENDED_ATOM;
INSERT_WHITESPACE;
g->print(g->ctx, "]", 1);
@@ -307,7 +335,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);
View
185 src/yajl/yajl_lex.c
@@ -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 "yajl_lex.h"
#include "yajl_buf.h"
@@ -83,8 +67,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;
@@ -95,7 +79,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;
@@ -138,15 +122,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 ,
@@ -154,7 +142,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 ,
@@ -162,33 +150,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 ,
-
- 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 ,
-
- 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 ,
-
- 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 ,
+
+ 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 ,
+
+ 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 ,
+
+ 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.
@@ -206,7 +193,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) {
@@ -260,17 +247,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;
+
+ /* 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)))
+ {