* BREAKING API CHANGE: allow client to specify memory allocation routines
* bump yajl version to 1.0.0 * update TODO list, removing completed tasks * update yajl_test to override allocation routines and count allocations/frees, providing an automated standalone way to validate we're not leaky * update all copyright dates * update all .gold files with new test output * update ChangeLog in preparation for 1.0.0 release
This commit is contained in:
parent
af305526e7
commit
b78dd79082
|
@ -1,4 +1,4 @@
|
|||
# Copyright 2007, Lloyd Hilaiel.
|
||||
# Copyright 2007-2009, Lloyd Hilaiel.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
|
@ -32,9 +32,9 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
|
|||
|
||||
PROJECT(YetAnotherJSONParser)
|
||||
|
||||
SET (YAJL_MAJOR 0)
|
||||
SET (YAJL_MINOR 4)
|
||||
SET (YAJL_MICRO 1)
|
||||
SET (YAJL_MAJOR 1)
|
||||
SET (YAJL_MINOR 0)
|
||||
SET (YAJL_MICRO 0)
|
||||
|
||||
SET (YAJL_DIST_NAME "yajl-${YAJL_MAJOR}.${YAJL_MINOR}.${YAJL_MICRO}")
|
||||
|
||||
|
|
2
COPYING
2
COPYING
|
@ -1,4 +1,4 @@
|
|||
Copyright 2007, Lloyd Hilaiel.
|
||||
Copyright 2007-2009, Lloyd Hilaiel.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
|
|
11
ChangeLog
11
ChangeLog
|
@ -1,6 +1,17 @@
|
|||
1.0.0
|
||||
* lth add 'make install' rules, thaks to Andrei Soroker for the
|
||||
contribution.
|
||||
* lth client may override allocation routines at generator or parser
|
||||
allocation time
|
||||
* tjw add yajl_parse_complete routine to allow client to explicitly
|
||||
specify end-of-input, solving the "lonely number" case, where
|
||||
json text consists only of an element with no explicit syntactic
|
||||
end.
|
||||
* tjw many new test cases
|
||||
* tjw cleanup of code for symmetry and ease of reading
|
||||
* lth integration of patches from Robert Varga which cleanup
|
||||
compilation warnings on 64 bit linux
|
||||
|
||||
0.4.0
|
||||
* lth buffer overflow bug in yajl_gen_double s/%lf/%g/ - thanks to
|
||||
Eric Bergstrome
|
||||
|
|
4
TODO
4
TODO
|
@ -1,13 +1,9 @@
|
|||
* add a test for 0x1F bug
|
||||
* numeric overflow in integers and double
|
||||
* line and char offsets in the lexer and in error messages
|
||||
* numbers at eof bug. client must have a way of indicating 'end of input'
|
||||
(other than passing in a ' ' whitespace byte),
|
||||
problem illustrated with lonely number test case.
|
||||
* testing:
|
||||
a. the permuter
|
||||
b. some performance comparison against json_checker.
|
||||
* investigate pull instead of push parsing
|
||||
* Handle memory allocation failures gracefully
|
||||
* allow client to override malloc/calloc/free impl.
|
||||
* cygwin/msys support on win32
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#!/usr/bin/env ruby
|
||||
# Copyright 2007, Lloyd Hilaiel.
|
||||
# Copyright 2007-2009, Lloyd Hilaiel.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright 2007, Lloyd Hilaiel.
|
||||
# Copyright 2007-2009, Lloyd Hilaiel.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2007, Lloyd Hilaiel.
|
||||
* Copyright 2007-2009, Lloyd Hilaiel.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
|
@ -156,10 +156,10 @@ main(int argc, char ** argv)
|
|||
usage(argv[0]);
|
||||
}
|
||||
|
||||
g = yajl_gen_alloc(&conf);
|
||||
g = yajl_gen_alloc(&conf, NULL);
|
||||
|
||||
/* ok. open file. let's read and parse */
|
||||
hand = yajl_alloc(&callbacks, &cfg, (void *) g);
|
||||
hand = yajl_alloc(&callbacks, &cfg, (void *) g, NULL);
|
||||
|
||||
while (!done) {
|
||||
rd = fread((void *) fileData, 1, sizeof(fileData) - 1, stdin);
|
||||
|
@ -185,7 +185,7 @@ main(int argc, char ** argv)
|
|||
{
|
||||
unsigned char * str = yajl_get_error(hand, 1, fileData, rd);
|
||||
fprintf(stderr, (const char *) str);
|
||||
yajl_free_error(str);
|
||||
yajl_free_error(hand, str);
|
||||
} else {
|
||||
const unsigned char * buf;
|
||||
unsigned int len;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright 2007, Lloyd Hilaiel.
|
||||
# Copyright 2007-2009, Lloyd Hilaiel.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
|
@ -28,8 +28,9 @@
|
|||
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
SET (SRCS yajl.c yajl_lex.c yajl_parser.c yajl_buf.c yajl_encode.c yajl_gen.c)
|
||||
SET (HDRS yajl_parser.h yajl_lex.h yajl_buf.h yajl_encode.h)
|
||||
SET (SRCS yajl.c yajl_lex.c yajl_parser.c yajl_buf.c
|
||||
yajl_encode.c yajl_gen.c yajl_alloc.c)
|
||||
SET (HDRS yajl_parser.h yajl_lex.h yajl_buf.h yajl_encode.h yajl_alloc.h)
|
||||
SET (PUB_HDRS api/yajl_parse.h api/yajl_gen.h api/yajl_common.h)
|
||||
|
||||
# useful when fixing lexer bugs.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2007, Lloyd Hilaiel.
|
||||
* Copyright 2007-2009, Lloyd Hilaiel.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
|
@ -33,6 +33,10 @@
|
|||
#ifndef __YAJL_COMMON_H__
|
||||
#define __YAJL_COMMON_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define YAJL_MAX_DEPTH 128
|
||||
|
||||
/* msft dll export gunk. To build a DLL on windows, you
|
||||
|
@ -48,4 +52,34 @@
|
|||
# define YAJL_API
|
||||
#endif
|
||||
|
||||
/** pointer to a malloc function, supporting client overriding memory
|
||||
* allocation routines */
|
||||
typedef void * (*yajl_malloc_func)(void *ctx, unsigned int 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);
|
||||
|
||||
/** A structure which can be passed to yajl_*_alloc routines to allow the
|
||||
* client to specify memory allocation functions to be used. */
|
||||
typedef struct
|
||||
{
|
||||
/** pointer to a function that can allocate uninitialized memory */
|
||||
yajl_malloc_func malloc;
|
||||
/** pointer to a function that can resize memory allocations */
|
||||
yajl_realloc_func realloc;
|
||||
/** pointer to a function that can free memory allocated using
|
||||
* reallocFunction or mallocFunction */
|
||||
yajl_free_func free;
|
||||
/** a context pointer that will be passed to above allocation routines */
|
||||
void * ctx;
|
||||
} yajl_alloc_funcs;
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2007, Lloyd Hilaiel.
|
||||
* Copyright 2007-2009, Lloyd Hilaiel.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
|
@ -73,8 +73,18 @@ extern "C" {
|
|||
const char * indentString;
|
||||
} yajl_gen_config;
|
||||
|
||||
/** allocate a generator handle */
|
||||
yajl_gen YAJL_API yajl_gen_alloc(const yajl_gen_config * config);
|
||||
/** 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)
|
||||
*/
|
||||
yajl_gen YAJL_API yajl_gen_alloc(const yajl_gen_config * config,
|
||||
const yajl_alloc_funcs * allocFuncs);
|
||||
|
||||
/** free a generator handle */
|
||||
void YAJL_API yajl_gen_free(yajl_gen handle);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2007, Lloyd Hilaiel.
|
||||
* Copyright 2007-2009, Lloyd Hilaiel.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
|
@ -129,6 +129,7 @@ extern "C" {
|
|||
*/
|
||||
yajl_handle YAJL_API yajl_alloc(const yajl_callbacks * callbacks,
|
||||
const yajl_parser_config * config,
|
||||
const yajl_alloc_funcs * allocFuncs,
|
||||
void * ctx);
|
||||
|
||||
/** free a parser handle */
|
||||
|
@ -169,7 +170,7 @@ extern "C" {
|
|||
unsigned int jsonTextLength);
|
||||
|
||||
/** free an error returned from yajl_get_error */
|
||||
void YAJL_API yajl_free_error(unsigned char * str);
|
||||
void YAJL_API yajl_free_error(yajl_handle hand, unsigned char * str);
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
|
|
2
src/yajl
2
src/yajl
|
@ -1,7 +1,7 @@
|
|||
/*!
|
||||
\mainpage Yet Another JSON Library (YAJL)
|
||||
\author Lloyd Hilaiel
|
||||
\date 2007-2008
|
||||
\date 2007-2009
|
||||
|
||||
Yet Another JSON Library (YAJL) is a small event-driven (SAX-style)
|
||||
JSON parser written in ANSI C, and a small validating JSON
|
||||
|
|
37
src/yajl.c
37
src/yajl.c
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2007, Lloyd Hilaiel.
|
||||
* Copyright 2007-2009, Lloyd Hilaiel.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
|
@ -33,6 +33,7 @@
|
|||
#include "api/yajl_parse.h"
|
||||
#include "yajl_lex.h"
|
||||
#include "yajl_parser.h"
|
||||
#include "yajl_alloc.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -62,11 +63,29 @@ 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,
|
||||
void * ctx)
|
||||
{
|
||||
unsigned int allowComments = 0;
|
||||
unsigned int validateUTF8 = 0;
|
||||
yajl_handle hand = (yajl_handle) malloc(sizeof(struct yajl_handle_t));
|
||||
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)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
yajl_set_default_alloc_funcs(&afsBuffer);
|
||||
afs = &afsBuffer;
|
||||
}
|
||||
|
||||
hand = (yajl_handle) YA_MALLOC(afs, sizeof(struct yajl_handle_t));
|
||||
|
||||
/* copy in pointers to allocation routines */
|
||||
memcpy((void *) &(hand->alloc), (void *) afs, sizeof(yajl_alloc_funcs));
|
||||
|
||||
if (config != NULL) {
|
||||
allowComments = config->allowComments;
|
||||
|
@ -75,10 +94,10 @@ yajl_alloc(const yajl_callbacks * callbacks,
|
|||
|
||||
hand->callbacks = callbacks;
|
||||
hand->ctx = ctx;
|
||||
hand->lexer = yajl_lex_alloc(allowComments, validateUTF8);
|
||||
hand->lexer = yajl_lex_alloc(&(hand->alloc), allowComments, validateUTF8);
|
||||
hand->errorOffset = 0;
|
||||
hand->decodeBuf = yajl_buf_alloc();
|
||||
hand->stateBuf = yajl_buf_alloc();
|
||||
hand->decodeBuf = yajl_buf_alloc(&(hand->alloc));
|
||||
hand->stateBuf = yajl_buf_alloc(&(hand->alloc));
|
||||
|
||||
yajl_state_push(hand, yajl_state_start);
|
||||
|
||||
|
@ -91,7 +110,7 @@ yajl_free(yajl_handle handle)
|
|||
yajl_buf_free(handle->stateBuf);
|
||||
yajl_buf_free(handle->decodeBuf);
|
||||
yajl_lex_free(handle->lexer);
|
||||
free(handle);
|
||||
YA_FREE(&(handle->alloc), handle);
|
||||
}
|
||||
|
||||
yajl_status
|
||||
|
@ -124,10 +143,10 @@ yajl_get_error(yajl_handle hand, int verbose,
|
|||
}
|
||||
|
||||
void
|
||||
yajl_free_error(unsigned char * str)
|
||||
yajl_free_error(yajl_handle hand, unsigned char * str)
|
||||
{
|
||||
/* XXX: use memory allocation functions if set */
|
||||
free(str);
|
||||
/* use memory allocation functions if set */
|
||||
YA_FREE(&(hand->alloc), str);
|
||||
}
|
||||
|
||||
/* XXX: add utility routines to parse from file */
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright 2007-2009, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file yajl_alloc.h
|
||||
* default memory allocation routines for yajl which use malloc/realloc and
|
||||
* free
|
||||
*/
|
||||
|
||||
#include "yajl_alloc.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
static void * yajl_internal_malloc(void *ctx, unsigned int sz)
|
||||
{
|
||||
return malloc(sz);
|
||||
}
|
||||
|
||||
static void * yajl_internal_realloc(void *ctx, void * previous,
|
||||
unsigned int sz)
|
||||
{
|
||||
return realloc(previous, sz);
|
||||
}
|
||||
|
||||
static void yajl_internal_free(void *ctx, void * ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
void yajl_set_default_alloc_funcs(yajl_alloc_funcs * yaf)
|
||||
{
|
||||
yaf->malloc = yajl_internal_malloc;
|
||||
yaf->free = yajl_internal_free;
|
||||
yaf->realloc = yajl_internal_realloc;
|
||||
yaf->ctx = NULL;
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright 2007-2009, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file yajl_alloc.h
|
||||
* default memory allocation routines for yajl which use malloc/realloc and
|
||||
* free
|
||||
*/
|
||||
|
||||
#ifndef __YAJL_ALLOC_H__
|
||||
#define __YAJL_ALLOC_H__
|
||||
|
||||
#include "api/yajl_common.h"
|
||||
|
||||
#define YA_MALLOC(afs, sz) (afs)->malloc((afs)->ctx, (sz))
|
||||
#define YA_FREE(afs, ptr) (afs)->free((afs)->ctx, (ptr))
|
||||
#define YA_REALLOC(afs, ptr, sz) (afs)->realloc((afs)->ctx, (ptr), (sz))
|
||||
|
||||
void yajl_set_default_alloc_funcs(yajl_alloc_funcs * yaf);
|
||||
|
||||
#endif
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2007, Lloyd Hilaiel.
|
||||
* Copyright 2007-2009, Lloyd Hilaiel.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
|
@ -42,6 +42,7 @@ struct yajl_buf_t {
|
|||
unsigned int len;
|
||||
unsigned int used;
|
||||
unsigned char * data;
|
||||
yajl_alloc_funcs * alloc;
|
||||
};
|
||||
|
||||
static
|
||||
|
@ -54,7 +55,7 @@ void yajl_buf_ensure_available(yajl_buf buf, unsigned int want)
|
|||
/* first call */
|
||||
if (buf->data == NULL) {
|
||||
buf->len = YAJL_BUF_INIT_SIZE;
|
||||
buf->data = (unsigned char *) malloc(buf->len);
|
||||
buf->data = (unsigned char *) YA_MALLOC(buf->alloc, buf->len);
|
||||
buf->data[0] = 0;
|
||||
}
|
||||
|
||||
|
@ -63,21 +64,24 @@ void yajl_buf_ensure_available(yajl_buf buf, unsigned int want)
|
|||
while (want >= (need - buf->used)) need <<= 1;
|
||||
|
||||
if (need != buf->len) {
|
||||
buf->data = (unsigned char *) realloc(buf->data, need);
|
||||
buf->data = (unsigned char *) YA_REALLOC(buf->alloc, buf->data, need);
|
||||
buf->len = need;
|
||||
}
|
||||
}
|
||||
|
||||
yajl_buf yajl_buf_alloc(void)
|
||||
yajl_buf yajl_buf_alloc(yajl_alloc_funcs * alloc)
|
||||
{
|
||||
return (yajl_buf) calloc(1, sizeof(struct yajl_buf_t));
|
||||
yajl_buf b = YA_MALLOC(alloc, sizeof(struct yajl_buf_t));
|
||||
memset((void *) b, 0, sizeof(struct yajl_buf_t));
|
||||
b->alloc = alloc;
|
||||
return b;
|
||||
}
|
||||
|
||||
void yajl_buf_free(yajl_buf buf)
|
||||
{
|
||||
assert(buf != NULL);
|
||||
if (buf->data) free(buf->data);
|
||||
free(buf);
|
||||
if (buf->data) YA_FREE(buf->alloc, buf->data);
|
||||
YA_FREE(buf->alloc, buf);
|
||||
}
|
||||
|
||||
void yajl_buf_append(yajl_buf buf, const void * data, unsigned int len)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2007, Lloyd Hilaiel.
|
||||
* Copyright 2007-2009, Lloyd Hilaiel.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
|
@ -33,6 +33,9 @@
|
|||
#ifndef __YAJL_BUF_H__
|
||||
#define __YAJL_BUF_H__
|
||||
|
||||
#include "api/yajl_common.h"
|
||||
#include "yajl_alloc.h"
|
||||
|
||||
/**
|
||||
* yajl_buf is a buffer with exponential growth. the buffer ensures that
|
||||
* you are always null padded.
|
||||
|
@ -40,7 +43,7 @@
|
|||
typedef struct yajl_buf_t * yajl_buf;
|
||||
|
||||
/* allocate a new buffer */
|
||||
yajl_buf yajl_buf_alloc(void);
|
||||
yajl_buf yajl_buf_alloc(yajl_alloc_funcs * alloc);
|
||||
|
||||
/* free the buffer */
|
||||
void yajl_buf_free(yajl_buf buf);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2007, Lloyd Hilaiel.
|
||||
* Copyright 2007-2009, Lloyd Hilaiel.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2007, Lloyd Hilaiel.
|
||||
* Copyright 2007-2009, Lloyd Hilaiel.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2007, Lloyd Hilaiel.
|
||||
* Copyright 2007-2009, Lloyd Hilaiel.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
|
@ -56,18 +56,39 @@ struct yajl_gen_t
|
|||
const char * indentString;
|
||||
yajl_gen_state state[YAJL_MAX_DEPTH];
|
||||
yajl_buf buf;
|
||||
/* memory allocation routines */
|
||||
yajl_alloc_funcs alloc;
|
||||
};
|
||||
|
||||
yajl_gen
|
||||
yajl_gen_alloc(const yajl_gen_config * config)
|
||||
yajl_gen_alloc(const yajl_gen_config * config,
|
||||
const yajl_alloc_funcs * afs)
|
||||
{
|
||||
yajl_gen g = (yajl_gen) malloc(sizeof(struct yajl_gen_t));
|
||||
yajl_gen g = 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)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
yajl_set_default_alloc_funcs(&afsBuffer);
|
||||
afs = &afsBuffer;
|
||||
}
|
||||
|
||||
g = (yajl_gen) YA_MALLOC(afs, sizeof(struct yajl_gen_t));
|
||||
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 : " ";
|
||||
}
|
||||
g->buf = yajl_buf_alloc();
|
||||
g->buf = yajl_buf_alloc(&(g->alloc));
|
||||
|
||||
return g;
|
||||
}
|
||||
|
||||
|
@ -75,7 +96,7 @@ void
|
|||
yajl_gen_free(yajl_gen g)
|
||||
{
|
||||
yajl_buf_free(g->buf);
|
||||
free(g);
|
||||
YA_FREE(&(g->alloc), g);
|
||||
}
|
||||
|
||||
#define INSERT_SEP \
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2007, Lloyd Hilaiel.
|
||||
* Copyright 2007-2009, Lloyd Hilaiel.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
|
@ -105,6 +105,8 @@ struct yajl_lexer_t {
|
|||
|
||||
/* shall we validate utf8 inside strings? */
|
||||
unsigned int validateUTF8;
|
||||
|
||||
yajl_alloc_funcs * alloc;
|
||||
};
|
||||
|
||||
static unsigned char
|
||||
|
@ -127,12 +129,15 @@ unreadChar(yajl_lexer lxr, unsigned int *off)
|
|||
}
|
||||
|
||||
yajl_lexer
|
||||
yajl_lex_alloc(unsigned int allowComments, unsigned int validateUTF8)
|
||||
yajl_lex_alloc(yajl_alloc_funcs * alloc,
|
||||
unsigned int allowComments, unsigned int validateUTF8)
|
||||
{
|
||||
yajl_lexer lxr = (yajl_lexer) calloc(1, sizeof(struct yajl_lexer_t));
|
||||
lxr->buf = yajl_buf_alloc();
|
||||
yajl_lexer lxr = (yajl_lexer) YA_MALLOC(alloc, sizeof(struct yajl_lexer_t));
|
||||
memset((void *) lxr, 0, sizeof(struct yajl_lexer_t));
|
||||
lxr->buf = yajl_buf_alloc(alloc);
|
||||
lxr->allowComments = allowComments;
|
||||
lxr->validateUTF8 = validateUTF8;
|
||||
lxr->alloc = alloc;
|
||||
return lxr;
|
||||
}
|
||||
|
||||
|
@ -140,7 +145,7 @@ void
|
|||
yajl_lex_free(yajl_lexer lxr)
|
||||
{
|
||||
yajl_buf_free(lxr->buf);
|
||||
free(lxr);
|
||||
YA_FREE(lxr->alloc, lxr);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2007, Lloyd Hilaiel.
|
||||
* Copyright 2007-2009, Lloyd Hilaiel.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
|
@ -33,6 +33,8 @@
|
|||
#ifndef __YAJL_LEX_H__
|
||||
#define __YAJL_LEX_H__
|
||||
|
||||
#include "api/yajl_common.h"
|
||||
|
||||
typedef enum {
|
||||
yajl_tok_bool,
|
||||
yajl_tok_colon,
|
||||
|
@ -61,7 +63,8 @@ typedef enum {
|
|||
|
||||
typedef struct yajl_lexer_t * yajl_lexer;
|
||||
|
||||
yajl_lexer yajl_lex_alloc(unsigned int allowComments,
|
||||
yajl_lexer yajl_lex_alloc(yajl_alloc_funcs * alloc,
|
||||
unsigned int allowComments,
|
||||
unsigned int validateUTF8);
|
||||
|
||||
void yajl_lex_free(yajl_lexer lexer);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2007, Lloyd Hilaiel.
|
||||
* Copyright 2007-2009, Lloyd Hilaiel.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
|
@ -71,7 +71,7 @@ yajl_render_error_string(yajl_handle hand, const unsigned char * jsonText,
|
|||
memneeded += strlen(": ");
|
||||
memneeded += strlen(errorText);
|
||||
}
|
||||
str = (unsigned char *) malloc(memneeded + 2);
|
||||
str = (unsigned char *) YA_MALLOC(&(hand->alloc), memneeded + 2);
|
||||
str[0] = 0;
|
||||
strcat((char *) str, errorType);
|
||||
strcat((char *) str, " error");
|
||||
|
@ -108,14 +108,15 @@ yajl_render_error_string(yajl_handle hand, const unsigned char * jsonText,
|
|||
text[i++] = '\n';
|
||||
text[i] = 0;
|
||||
{
|
||||
char * newStr = (char *) malloc(strlen((char *) str) +
|
||||
strlen((char *) text) +
|
||||
strlen(arrow) + 1);
|
||||
char * newStr = (char *)
|
||||
YA_MALLOC(&(hand->alloc), (strlen((char *) str) +
|
||||
strlen((char *) text) +
|
||||
strlen(arrow) + 1));
|
||||
newStr[0] = 0;
|
||||
strcat((char *) newStr, (char *) str);
|
||||
strcat((char *) newStr, text);
|
||||
strcat((char *) newStr, arrow);
|
||||
free(str);
|
||||
YA_FREE(&(hand->alloc), str);
|
||||
str = (unsigned char *) newStr;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2007, Lloyd Hilaiel.
|
||||
* Copyright 2007-2009, Lloyd Hilaiel.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
|
@ -61,6 +61,8 @@ struct yajl_handle_t {
|
|||
yajl_buf decodeBuf;
|
||||
/* a stack of states. access with yajl_state_XXX routines */
|
||||
yajl_buf stateBuf;
|
||||
/* memory allocation routines */
|
||||
yajl_alloc_funcs alloc;
|
||||
};
|
||||
|
||||
yajl_status
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright 2007, Lloyd Hilaiel.
|
||||
# Copyright 2007-2009, Lloyd Hilaiel.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
|
|
|
@ -19,3 +19,4 @@ array close ']'
|
|||
string: '
|
||||
\'
|
||||
array close ']'
|
||||
memory leaks: 0
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
parse error: unallowed token at this point in JSON text
|
||||
memory leaks: 0
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
array open '['
|
||||
memory leaks: 0
|
||||
|
|
|
@ -7,3 +7,4 @@ string: 'be'
|
|||
string: 'a happy bit of json'
|
||||
string: 'but someone, misspelled "true"'
|
||||
lexical error: invalid string in json text.
|
||||
memory leaks: 0
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
string: 'Mа二𐌂'
|
||||
memory leaks: 0
|
||||
|
|
|
@ -2,3 +2,4 @@ map open '{'
|
|||
key: 'this'
|
||||
string: 'is'
|
||||
lexical error: probable comment found in input text, comments are not enabled.
|
||||
memory leaks: 0
|
||||
|
|
|
@ -2046,3 +2046,4 @@ array close ']'
|
|||
array close ']'
|
||||
array close ']'
|
||||
array close ']'
|
||||
memory leaks: 0
|
||||
|
|
|
@ -33,3 +33,4 @@ array close ']'
|
|||
map close '}'
|
||||
map close '}'
|
||||
map close '}'
|
||||
memory leaks: 0
|
||||
|
|
|
@ -33,3 +33,4 @@ array close ']'
|
|||
map close '}'
|
||||
map close '}'
|
||||
map close '}'
|
||||
memory leaks: 0
|
||||
|
|
|
@ -4,3 +4,4 @@ double: 10
|
|||
double: 3.14157
|
||||
double: 1000
|
||||
array close ']'
|
||||
memory leaks: 0
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
array open '['
|
||||
array close ']'
|
||||
memory leaks: 0
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
string: ''
|
||||
memory leaks: 0
|
||||
|
|
|
@ -4,3 +4,4 @@ string: 'Му'
|
|||
string: 'Еба'
|
||||
string: 'Майката'
|
||||
array close ']'
|
||||
memory leaks: 0
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
string: 'foobar'
|
||||
memory leaks: 0
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
bool: false
|
||||
memory leaks: 0
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
bool: false
|
||||
memory leaks: 0
|
||||
|
|
|
@ -11,3 +11,4 @@ integer: -123456789
|
|||
integer: 2147483647
|
||||
integer: -2147483647
|
||||
parse error: integer overflow
|
||||
memory leaks: 0
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
array open '['
|
||||
lexical error: invalid bytes in UTF8 string.
|
||||
memory leaks: 0
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
string: '?'
|
||||
memory leaks: 0
|
||||
|
|
|
@ -2,3 +2,4 @@ map open '{'
|
|||
key: 'bad thing'
|
||||
integer: 0
|
||||
parse error: after key and value, inside map, I expect ',' or '}'
|
||||
memory leaks: 0
|
||||
|
|
|
@ -6,3 +6,4 @@ string: 'blue'
|
|||
string: 'baby where are you?'
|
||||
string: 'oh boo hoo!'
|
||||
lexical error: malformed number, a digit is required after the minus sign.
|
||||
memory leaks: 0
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
integer: 123456789
|
||||
memory leaks: 0
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
parse error: unallowed token at this point in JSON text
|
||||
memory leaks: 0
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
map open '{'
|
||||
memory leaks: 0
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
lexical error: malformed number, a digit is required after the decimal point.
|
||||
memory leaks: 0
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
lexical error: malformed number, a digit is required after the exponent.
|
||||
memory leaks: 0
|
||||
|
|
|
@ -5,3 +5,4 @@ key: 'CoreletType'
|
|||
string: 'standalone'
|
||||
key: 'documentation'
|
||||
lexical error: invalid bytes in UTF8 string.
|
||||
memory leaks: 0
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
null
|
||||
memory leaks: 0
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
null
|
||||
memory leaks: 0
|
||||
|
|
|
@ -6,3 +6,4 @@ bool: false
|
|||
key: 'null'
|
||||
null
|
||||
map close '}'
|
||||
memory leaks: 0
|
||||
|
|
|
@ -6,3 +6,4 @@ string: 'simple'
|
|||
key: 'json'
|
||||
string: 'right?'
|
||||
map close '}'
|
||||
memory leaks: 0
|
||||
|
|
|
@ -6,3 +6,4 @@ string: 'simple'
|
|||
key: 'json'
|
||||
string: 'right?'
|
||||
map close '}'
|
||||
memory leaks: 0
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
array open '['
|
||||
lexical error: inside a string, '\' occurs before a character which it may not.
|
||||
memory leaks: 0
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
lexical error: invalid (non-hex) character occurs after '\u' inside string.
|
||||
memory leaks: 0
|
||||
|
|
|
@ -4,3 +4,4 @@ string: '
|
|||
string: '"and this string has an escape at the beginning'
|
||||
string: 'and this string has no escapes'
|
||||
array close ']'
|
||||
memory leaks: 0
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
lexical error: invalid character inside string.
|
||||
memory leaks: 0
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
bool: true
|
||||
memory leaks: 0
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
bool: true
|
||||
memory leaks: 0
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
array open '['
|
||||
string: 'Да Му Еба Майката'
|
||||
array close ']'
|
||||
memory leaks: 0
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2007, Lloyd Hilaiel.
|
||||
* Copyright 2007-2009, Lloyd Hilaiel.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
|
@ -37,6 +37,48 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
/* memory debugging routines */
|
||||
typedef struct
|
||||
{
|
||||
unsigned int numFrees;
|
||||
unsigned int numMallocs;
|
||||
/* XXX: we really need a hash table here with per-allocation
|
||||
* information */
|
||||
} yajlTestMemoryContext;
|
||||
|
||||
/* cast void * into context */
|
||||
#define TEST_CTX(vptr) ((yajlTestMemoryContext *) (vptr))
|
||||
|
||||
static void yajlTestFree(void * ctx, void * ptr)
|
||||
{
|
||||
assert(ptr != NULL);
|
||||
TEST_CTX(ctx)->numFrees++;
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
static void * yajlTestMalloc(void * ctx, unsigned int sz)
|
||||
{
|
||||
assert(sz != 0);
|
||||
TEST_CTX(ctx)->numMallocs++;
|
||||
return malloc(sz);
|
||||
}
|
||||
|
||||
static void * yajlTestRealloc(void * ctx, void * ptr, unsigned int sz)
|
||||
{
|
||||
if (ptr == NULL) {
|
||||
assert(sz != 0);
|
||||
TEST_CTX(ctx)->numMallocs++;
|
||||
} else if (sz == 0) {
|
||||
TEST_CTX(ctx)->numFrees++;
|
||||
}
|
||||
|
||||
return realloc(ctx, sz);
|
||||
}
|
||||
|
||||
|
||||
/* begin parsing callback routines */
|
||||
#define BUF_SIZE 2048
|
||||
|
||||
static int test_yajl_null(void *ctx)
|
||||
|
@ -144,6 +186,21 @@ main(int argc, char ** argv)
|
|||
yajl_parser_config cfg = { 0, 1 };
|
||||
int i, j, done;
|
||||
|
||||
/* memory allocation debugging: allocate a structure which collects
|
||||
* statistics */
|
||||
yajlTestMemoryContext memCtx = { 0,0 };
|
||||
|
||||
/* memory allocation debugging: allocate a structure which holds
|
||||
* allocation routines */
|
||||
yajl_alloc_funcs allocFuncs = {
|
||||
yajlTestMalloc,
|
||||
yajlTestRealloc,
|
||||
yajlTestFree,
|
||||
(void *) NULL
|
||||
};
|
||||
|
||||
allocFuncs.ctx = (void *) &memCtx;
|
||||
|
||||
/* check arguments. We expect exactly one! */
|
||||
for (i=1;i<argc;i++) {
|
||||
if (!strcmp("-c", argv[i])) {
|
||||
|
@ -183,7 +240,7 @@ main(int argc, char ** argv)
|
|||
fileName = argv[argc-1];
|
||||
|
||||
/* ok. open file. let's read and parse */
|
||||
hand = yajl_alloc(&callbacks, &cfg, NULL);
|
||||
hand = yajl_alloc(&callbacks, &cfg, &allocFuncs, NULL);
|
||||
|
||||
done = 0;
|
||||
while (!done) {
|
||||
|
@ -210,7 +267,7 @@ main(int argc, char ** argv)
|
|||
unsigned char * str = yajl_get_error(hand, 0, fileData, rd);
|
||||
fflush(stdout);
|
||||
fprintf(stderr, (char *) str);
|
||||
yajl_free_error(str);
|
||||
yajl_free_error(hand, str);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -218,5 +275,15 @@ main(int argc, char ** argv)
|
|||
yajl_free(hand);
|
||||
free(fileData);
|
||||
|
||||
/* finally, print out some memory statistics */
|
||||
|
||||
/* (lth) only print leaks here, as allocations and frees may vary depending
|
||||
* on read buffer size, causing false failures.
|
||||
*
|
||||
* printf("allocations:\t%u\n", memCtx.numMallocs);
|
||||
* printf("frees:\t\t%u\n", memCtx.numFrees);
|
||||
*/
|
||||
printf("memory leaks:\t%u\n", memCtx.numMallocs - memCtx.numFrees);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright 2007, Lloyd Hilaiel.
|
||||
# Copyright 2007-2009, Lloyd Hilaiel.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2007, Lloyd Hilaiel.
|
||||
* Copyright 2007-2009, Lloyd Hilaiel.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
|
@ -80,7 +80,7 @@ main(int argc, char ** argv)
|
|||
}
|
||||
|
||||
/* allocate a parser */
|
||||
hand = yajl_alloc(NULL, &cfg, NULL);
|
||||
hand = yajl_alloc(NULL, &cfg, NULL, NULL);
|
||||
|
||||
while (!done) {
|
||||
rd = fread((void *) fileData, 1, sizeof(fileData) - 1, stdin);
|
||||
|
@ -112,7 +112,7 @@ main(int argc, char ** argv)
|
|||
if (!quiet) {
|
||||
unsigned char * str = yajl_get_error(hand, 1, fileData, rd);
|
||||
fprintf(stderr, (const char *) str);
|
||||
yajl_free_error(str);
|
||||
yajl_free_error(hand, str);
|
||||
}
|
||||
retval = 1;
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue