Updated jansson to 2.1

This commit is contained in:
Alex Zolotarev 2011-07-28 08:00:25 +03:00 committed by Alex Zolotarev
parent 8d869b98d1
commit 98fd87c4d9
8 changed files with 129 additions and 113 deletions

View file

@ -1,3 +1,36 @@
Version 2.1 (in development)
============================
* New features:
- `json_loadb()`: Decode a string with a given size, useful if the
string is not null terminated.
- Add ``JSON_ENCODE_ANY`` encoding flag to allow encoding any JSON
value. By default, only arrays and objects can be encoded. (#19)
- Add ``JSON_REJECT_DUPLICATES`` decoding flag to issue a decoding
error if any JSON object in the input contins duplicate keys. (#3)
- Add ``JSON_DISABLE_EOF_CHECK`` decoding flag to stop decoding after a
valid JSON input. This allows other data after the JSON data.
* Bug fixes:
- Fix an additional memory leak when memory allocation fails in
`json_object_set()` and friends.
- Clear errno before calling `strtod()` for better portability. (#27)
* Building:
- Avoid set-but-not-used warning/error in a test. (#20)
* Other:
- Minor clarifications to documentation.
Version 2.0.1
=============
@ -10,7 +43,7 @@ Released 2011-03-31
- Fix object key hashing in json_unpack() strict checking mode.
- Fix the parentheses in JANSSON_VERSION_HEX macro.
- Fix the parentheses in ``JANSSON_VERSION_HEX`` macro.
- Fix `json_object_size()` return value.

View file

@ -23,5 +23,4 @@ HEADERS += \
src/hashtable.h \
src/strbuffer.h \
src/utf.h \
src/util.h \
src/jansson_config.h \

View file

@ -1,53 +0,0 @@
/* config.h. Generated from config.h.in by configure. */
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* Define to 1 if you have the <inttypes.h> header file. */
#ifndef _MSC_VER
#define HAVE_INTTYPES_H 1
#endif
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
#ifdef _MSC_VER
#define JSON_INLINE
#else
#define JSON_INLINE inline
#endif
#else
#define JSON_INLINE inline
#endif
/* Define to the type of a signed integer type of width exactly 32 bits if
such a type exists and the standard includes do not define it. */
/* #undef int32_t */

View file

@ -421,8 +421,10 @@ char *json_dumps(const json_t *json, size_t flags)
strbuffer_t strbuff;
char *result;
if(!json_is_array(json) && !json_is_object(json))
return NULL;
if(!(flags & JSON_ENCODE_ANY)) {
if(!json_is_array(json) && !json_is_object(json))
return NULL;
}
if(strbuffer_init(&strbuff))
return NULL;
@ -440,8 +442,10 @@ char *json_dumps(const json_t *json, size_t flags)
int json_dumpf(const json_t *json, FILE *output, size_t flags)
{
if(!json_is_array(json) && !json_is_object(json))
return -1;
if(!(flags & JSON_ENCODE_ANY)) {
if(!json_is_array(json) && !json_is_object(json))
return -1;
}
return do_dump(json, flags, 0, dump_to_file, (void *)output);
}

View file

@ -21,11 +21,11 @@ extern "C" {
/* version */
#define JANSSON_MAJOR_VERSION 2
#define JANSSON_MINOR_VERSION 0
#define JANSSON_MICRO_VERSION 1
#define JANSSON_MINOR_VERSION 1
#define JANSSON_MICRO_VERSION 0
/* Micro version is omitted if it's 0 */
#define JANSSON_VERSION "2.0.1"
#define JANSSON_VERSION "2.1"
/* Version as a 3-byte hex number, e.g. 0x010201 == 1.2.1. Use this
for numeric comparisons, e.g. #if JANSSON_VERSION_HEX >= ... */
@ -214,17 +214,25 @@ json_t *json_copy(json_t *value);
json_t *json_deep_copy(json_t *value);
/* loading, printing */
/* decoding */
#define JSON_REJECT_DUPLICATES 0x1
#define JSON_DISABLE_EOF_CHECK 0x2
json_t *json_loads(const char *input, size_t flags, json_error_t *error);
json_t *json_loadb(const char *buffer, size_t buflen, size_t flags, json_error_t *error);
json_t *json_loadf(FILE *input, size_t flags, json_error_t *error);
json_t *json_load_file(const char *path, size_t flags, json_error_t *error);
/* encoding */
#define JSON_INDENT(n) (n & 0x1F)
#define JSON_COMPACT 0x20
#define JSON_ENSURE_ASCII 0x40
#define JSON_SORT_KEYS 0x80
#define JSON_PRESERVE_ORDER 0x100
#define JSON_ENCODE_ANY 0x200
char *json_dumps(const json_t *json, size_t flags);
int json_dumpf(const json_t *json, FILE *output, size_t flags);

View file

@ -643,9 +643,9 @@ static void lex_close(lex_t *lex)
/*** parser ***/
static json_t *parse_value(lex_t *lex, json_error_t *error);
static json_t *parse_value(lex_t *lex, size_t flags, json_error_t *error);
static json_t *parse_object(lex_t *lex, json_error_t *error)
static json_t *parse_object(lex_t *lex, size_t flags, json_error_t *error)
{
json_t *object = json_object();
if(!object)
@ -668,6 +668,14 @@ static json_t *parse_object(lex_t *lex, json_error_t *error)
if(!key)
return NULL;
if(flags & JSON_REJECT_DUPLICATES) {
if(json_object_get(object, key)) {
jsonp_free(key);
error_set(error, lex, "duplicate object key");
goto error;
}
}
lex_scan(lex, error);
if(lex->token != ':') {
jsonp_free(key);
@ -676,7 +684,7 @@ static json_t *parse_object(lex_t *lex, json_error_t *error)
}
lex_scan(lex, error);
value = parse_value(lex, error);
value = parse_value(lex, flags, error);
if(!value) {
jsonp_free(key);
goto error;
@ -710,7 +718,7 @@ error:
return NULL;
}
static json_t *parse_array(lex_t *lex, json_error_t *error)
static json_t *parse_array(lex_t *lex, size_t flags, json_error_t *error)
{
json_t *array = json_array();
if(!array)
@ -721,7 +729,7 @@ static json_t *parse_array(lex_t *lex, json_error_t *error)
return array;
while(lex->token) {
json_t *elem = parse_value(lex, error);
json_t *elem = parse_value(lex, flags, error);
if(!elem)
goto error;
@ -750,7 +758,7 @@ error:
return NULL;
}
static json_t *parse_value(lex_t *lex, json_error_t *error)
static json_t *parse_value(lex_t *lex, size_t flags, json_error_t *error)
{
json_t *json;
@ -783,11 +791,11 @@ static json_t *parse_value(lex_t *lex, json_error_t *error)
break;
case '{':
json = parse_object(lex, error);
json = parse_object(lex, flags, error);
break;
case '[':
json = parse_array(lex, error);
json = parse_array(lex, flags, error);
break;
case TOKEN_INVALID:
@ -805,15 +813,30 @@ static json_t *parse_value(lex_t *lex, json_error_t *error)
return json;
}
static json_t *parse_json(lex_t *lex, json_error_t *error)
static json_t *parse_json(lex_t *lex, size_t flags, json_error_t *error)
{
json_t *result;
lex_scan(lex, error);
if(lex->token != '[' && lex->token != '{') {
error_set(error, lex, "'[' or '{' expected");
return NULL;
}
return parse_value(lex, error);
result = parse_value(lex, flags, error);
if(!result)
return NULL;
if(!(flags & JSON_DISABLE_EOF_CHECK)) {
lex_scan(lex, error);
if(lex->token != TOKEN_EOF) {
error_set(error, lex, "end of file expected");
json_decref(result);
result = NULL;
}
}
return result;
}
typedef struct
@ -842,8 +865,6 @@ json_t *json_loads(const char *string, size_t flags, json_error_t *error)
json_t *result;
string_data_t stream_data;
(void)flags; /* unused */
stream_data.data = string;
stream_data.pos = 0;
@ -851,19 +872,47 @@ json_t *json_loads(const char *string, size_t flags, json_error_t *error)
return NULL;
jsonp_error_init(error, "<string>");
result = parse_json(&lex, flags, error);
result = parse_json(&lex, error);
if(!result)
goto out;
lex_close(&lex);
return result;
}
lex_scan(&lex, error);
if(lex.token != TOKEN_EOF) {
error_set(error, &lex, "end of file expected");
json_decref(result);
result = NULL;
}
typedef struct
{
const char *data;
size_t len;
size_t pos;
} buffer_data_t;
static int buffer_get(void *data)
{
char c;
buffer_data_t *stream = data;
if(stream->pos >= stream->len)
return EOF;
c = stream->data[stream->pos];
stream->pos++;
return (unsigned char)c;
}
json_t *json_loadb(const char *buffer, size_t buflen, size_t flags, json_error_t *error)
{
lex_t lex;
json_t *result;
buffer_data_t stream_data;
stream_data.data = buffer;
stream_data.pos = 0;
stream_data.len = buflen;
if(lex_init(&lex, buffer_get, (void *)&stream_data))
return NULL;
jsonp_error_init(error, "<buffer>");
result = parse_json(&lex, flags, error);
out:
lex_close(&lex);
return result;
}
@ -873,7 +922,6 @@ json_t *json_loadf(FILE *input, size_t flags, json_error_t *error)
lex_t lex;
const char *source;
json_t *result;
(void)flags; /* unused */
if(lex_init(&lex, (get_func)fgetc, input))
return NULL;
@ -884,19 +932,8 @@ json_t *json_loadf(FILE *input, size_t flags, json_error_t *error)
source = "<stream>";
jsonp_error_init(error, source);
result = parse_json(&lex, flags, error);
result = parse_json(&lex, error);
if(!result)
goto out;
lex_scan(&lex, error);
if(lex.token != TOKEN_EOF) {
error_set(error, &lex, "end of file expected");
json_decref(result);
result = NULL;
}
out:
lex_close(&lex);
return result;
}

View file

@ -1,15 +0,0 @@
/*
* Copyright (c) 2009, 2010 Petri Lehtinen <petri@digip.org>
*
* Jansson is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#ifndef UTIL_H
#define UTIL_H
#ifndef max
#define max(a, b) ((a) > (b) ? (a) : (b))
#endif
#endif

View file

@ -139,7 +139,10 @@ int json_object_set_new_nocheck(json_t *json, const char *key, json_t *value)
allocated. */
k = jsonp_malloc(offsetof(object_key_t, key) + strlen(key) + 1);
if(!k)
{
json_decref(value);
return -1;
}
k->serial = object->serial++;
strcpy(k->key, key);