mirror of
https://github.com/neovim/neovim.git
synced 2025-09-07 20:08:17 +00:00
10
src/cjson/fpconv.h
vendored
10
src/cjson/fpconv.h
vendored
@@ -7,10 +7,20 @@
|
|||||||
# define FPCONV_G_FMT_BUFSIZE 32
|
# define FPCONV_G_FMT_BUFSIZE 32
|
||||||
|
|
||||||
#ifdef USE_INTERNAL_FPCONV
|
#ifdef USE_INTERNAL_FPCONV
|
||||||
|
// #ifdef MULTIPLE_THREADS
|
||||||
|
// #include "dtoa_config.h"
|
||||||
|
// #include <unistd.h>
|
||||||
|
// static inline void fpconv_init()
|
||||||
|
// {
|
||||||
|
// // Add one to try and avoid core id multiplier alignment
|
||||||
|
// set_max_dtoa_threads((sysconf(_SC_NPROCESSORS_CONF) + 1) * 3);
|
||||||
|
// }
|
||||||
|
// #else
|
||||||
static inline void fpconv_init()
|
static inline void fpconv_init()
|
||||||
{
|
{
|
||||||
/* Do nothing - not required */
|
/* Do nothing - not required */
|
||||||
}
|
}
|
||||||
|
// #endif
|
||||||
#else
|
#else
|
||||||
extern void fpconv_init(void);
|
extern void fpconv_init(void);
|
||||||
#endif
|
#endif
|
||||||
|
177
src/cjson/lua_cjson.c
vendored
177
src/cjson/lua_cjson.c
vendored
@@ -1,4 +1,5 @@
|
|||||||
// Upstream: https://github.com/openresty/lua-cjson/blob/master/lua_cjson.c
|
// Upstream: https://github.com/openresty/lua-cjson/blob/master/lua_cjson.c
|
||||||
|
// Synced Commit; 91ca29db9a4a4fd0eedaebcd5d5f3ba2ace5ae63
|
||||||
|
|
||||||
/* Lua CJSON - JSON support for Lua
|
/* Lua CJSON - JSON support for Lua
|
||||||
*
|
*
|
||||||
@@ -42,6 +43,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
// #include <stdint.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <lua.h>
|
#include <lua.h>
|
||||||
#include <lauxlib.h>
|
#include <lauxlib.h>
|
||||||
@@ -57,17 +59,14 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CJSON_VERSION
|
#ifndef CJSON_VERSION
|
||||||
#define CJSON_VERSION "2.1.0.9"
|
#define CJSON_VERSION "2.1.0.11"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#define snprintf sprintf_s
|
// #define CJSON_EXPORT __declspec(dllexport)
|
||||||
|
// #define strncasecmp(x,y,z) _strnicmp(x,y,z)
|
||||||
#ifndef isnan
|
#else
|
||||||
#include <float.h>
|
#define CJSON_EXPORT extern
|
||||||
#define isnan(x) _isnan(x)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Workaround for Solaris platforms missing isinf() */
|
/* Workaround for Solaris platforms missing isinf() */
|
||||||
@@ -87,6 +86,7 @@
|
|||||||
#define DEFAULT_ENCODE_EMPTY_TABLE_AS_OBJECT 0
|
#define DEFAULT_ENCODE_EMPTY_TABLE_AS_OBJECT 0
|
||||||
#define DEFAULT_DECODE_ARRAY_WITH_ARRAY_MT 0
|
#define DEFAULT_DECODE_ARRAY_WITH_ARRAY_MT 0
|
||||||
#define DEFAULT_ENCODE_ESCAPE_FORWARD_SLASH 1
|
#define DEFAULT_ENCODE_ESCAPE_FORWARD_SLASH 1
|
||||||
|
#define DEFAULT_ENCODE_SKIP_UNSUPPORTED_VALUE_TYPES 0
|
||||||
|
|
||||||
#ifdef DISABLE_INVALID_NUMBERS
|
#ifdef DISABLE_INVALID_NUMBERS
|
||||||
#undef DEFAULT_DECODE_INVALID_NUMBERS
|
#undef DEFAULT_DECODE_INVALID_NUMBERS
|
||||||
@@ -107,8 +107,8 @@
|
|||||||
#define json_lightudata_mask(ludata) (ludata)
|
#define json_lightudata_mask(ludata) (ludata)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if LUA_VERSION_NUM > 501
|
#if LUA_VERSION_NUM >= 502
|
||||||
#define lua_objlen(L,i) lua_rawlen(L, (i))
|
#define lua_objlen(L,i) luaL_len(L, (i))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const char * const *json_empty_array;
|
static const char * const *json_empty_array;
|
||||||
@@ -121,6 +121,7 @@ typedef enum {
|
|||||||
T_ARR_END,
|
T_ARR_END,
|
||||||
T_STRING,
|
T_STRING,
|
||||||
T_NUMBER,
|
T_NUMBER,
|
||||||
|
T_INTEGER,
|
||||||
T_BOOLEAN,
|
T_BOOLEAN,
|
||||||
T_NULL,
|
T_NULL,
|
||||||
T_COLON,
|
T_COLON,
|
||||||
@@ -138,6 +139,7 @@ static const char *json_token_type_name[] = {
|
|||||||
"T_ARR_END",
|
"T_ARR_END",
|
||||||
"T_STRING",
|
"T_STRING",
|
||||||
"T_NUMBER",
|
"T_NUMBER",
|
||||||
|
"T_INTEGER",
|
||||||
"T_BOOLEAN",
|
"T_BOOLEAN",
|
||||||
"T_NULL",
|
"T_NULL",
|
||||||
"T_COLON",
|
"T_COLON",
|
||||||
@@ -170,6 +172,7 @@ typedef struct {
|
|||||||
int decode_invalid_numbers;
|
int decode_invalid_numbers;
|
||||||
int decode_max_depth;
|
int decode_max_depth;
|
||||||
int decode_array_with_array_mt;
|
int decode_array_with_array_mt;
|
||||||
|
int encode_skip_unsupported_value_types;
|
||||||
} json_config_t;
|
} json_config_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -200,13 +203,14 @@ typedef struct {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
json_token_type_t type;
|
json_token_type_t type;
|
||||||
int index;
|
size_t index;
|
||||||
union {
|
union {
|
||||||
const char *string;
|
const char *string;
|
||||||
double number;
|
double number;
|
||||||
|
lua_Integer integer;
|
||||||
int boolean;
|
int boolean;
|
||||||
} value;
|
} value;
|
||||||
int string_len;
|
size_t string_len;
|
||||||
} json_token_t;
|
} json_token_t;
|
||||||
|
|
||||||
static const char *char2escape[256] = {
|
static const char *char2escape[256] = {
|
||||||
@@ -254,7 +258,7 @@ static json_config_t *json_fetch_config(lua_State *l)
|
|||||||
{
|
{
|
||||||
json_config_t *cfg;
|
json_config_t *cfg;
|
||||||
|
|
||||||
cfg = lua_touserdata(l, lua_upvalueindex(1));
|
cfg = (json_config_t *)lua_touserdata(l, lua_upvalueindex(1));
|
||||||
if (!cfg)
|
if (!cfg)
|
||||||
luaL_error(l, "BUG: Unable to fetch CJSON configuration");
|
luaL_error(l, "BUG: Unable to fetch CJSON configuration");
|
||||||
|
|
||||||
@@ -397,6 +401,18 @@ static int json_cfg_decode_array_with_array_mt(lua_State *l)
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Configure how to treat invalid types */
|
||||||
|
/*
|
||||||
|
static int json_cfg_encode_skip_unsupported_value_types(lua_State *l)
|
||||||
|
{
|
||||||
|
json_config_t *cfg = json_arg_init(l, 1);
|
||||||
|
|
||||||
|
json_enum_option(l, 1, &cfg->encode_skip_unsupported_value_types, NULL, 1);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/* Configures JSON encoding buffer persistence */
|
/* Configures JSON encoding buffer persistence */
|
||||||
/*
|
/*
|
||||||
static int json_cfg_encode_keep_buffer(lua_State *l)
|
static int json_cfg_encode_keep_buffer(lua_State *l)
|
||||||
@@ -479,7 +495,7 @@ static int json_destroy_config(lua_State *l)
|
|||||||
{
|
{
|
||||||
json_config_t *cfg;
|
json_config_t *cfg;
|
||||||
|
|
||||||
cfg = lua_touserdata(l, 1);
|
cfg = (json_config_t *)lua_touserdata(l, 1);
|
||||||
if (cfg)
|
if (cfg)
|
||||||
strbuf_free(&cfg->encode_buf);
|
strbuf_free(&cfg->encode_buf);
|
||||||
cfg = NULL;
|
cfg = NULL;
|
||||||
@@ -492,7 +508,11 @@ static void json_create_config(lua_State *l)
|
|||||||
json_config_t *cfg;
|
json_config_t *cfg;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
cfg = lua_newuserdata(l, sizeof(*cfg));
|
cfg = (json_config_t *)lua_newuserdata(l, sizeof(*cfg));
|
||||||
|
if (!cfg)
|
||||||
|
abort();
|
||||||
|
|
||||||
|
memset(cfg, 0, sizeof(*cfg));
|
||||||
|
|
||||||
/* Create GC method to clean up strbuf */
|
/* Create GC method to clean up strbuf */
|
||||||
lua_newtable(l);
|
lua_newtable(l);
|
||||||
@@ -512,6 +532,7 @@ static void json_create_config(lua_State *l)
|
|||||||
cfg->encode_empty_table_as_object = DEFAULT_ENCODE_EMPTY_TABLE_AS_OBJECT;
|
cfg->encode_empty_table_as_object = DEFAULT_ENCODE_EMPTY_TABLE_AS_OBJECT;
|
||||||
cfg->decode_array_with_array_mt = DEFAULT_DECODE_ARRAY_WITH_ARRAY_MT;
|
cfg->decode_array_with_array_mt = DEFAULT_DECODE_ARRAY_WITH_ARRAY_MT;
|
||||||
cfg->encode_escape_forward_slash = DEFAULT_ENCODE_ESCAPE_FORWARD_SLASH;
|
cfg->encode_escape_forward_slash = DEFAULT_ENCODE_ESCAPE_FORWARD_SLASH;
|
||||||
|
cfg->encode_skip_unsupported_value_types = DEFAULT_ENCODE_SKIP_UNSUPPORTED_VALUE_TYPES;
|
||||||
|
|
||||||
#if DEFAULT_ENCODE_KEEP_BUFFER > 0
|
#if DEFAULT_ENCODE_KEEP_BUFFER > 0
|
||||||
strbuf_init(&cfg->encode_buf, 0);
|
strbuf_init(&cfg->encode_buf, 0);
|
||||||
@@ -583,9 +604,9 @@ static void json_encode_exception(lua_State *l, json_encode_t *ctx, int lindex,
|
|||||||
static void json_append_string(lua_State *l, json_encode_t *ctx, int lindex)
|
static void json_append_string(lua_State *l, json_encode_t *ctx, int lindex)
|
||||||
{
|
{
|
||||||
const char *escstr;
|
const char *escstr;
|
||||||
unsigned i;
|
|
||||||
const char *str;
|
const char *str;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
size_t i;
|
||||||
strbuf_t *json = ctx->json;
|
strbuf_t *json = ctx->json;
|
||||||
|
|
||||||
str = lua_tolstring(l, lindex, &len);
|
str = lua_tolstring(l, lindex, &len);
|
||||||
@@ -594,6 +615,8 @@ static void json_append_string(lua_State *l, json_encode_t *ctx, int lindex)
|
|||||||
* This buffer is reused constantly for small strings
|
* This buffer is reused constantly for small strings
|
||||||
* If there are any excess pages, they won't be hit anyway.
|
* If there are any excess pages, they won't be hit anyway.
|
||||||
* This gains ~5% speedup. */
|
* This gains ~5% speedup. */
|
||||||
|
if (len > SIZE_MAX / 6 - 3)
|
||||||
|
abort(); /*Overflow check */
|
||||||
strbuf_ensure_empty_length(json, len * 6 + 2);
|
strbuf_ensure_empty_length(json, len * 6 + 2);
|
||||||
|
|
||||||
strbuf_append_char_unsafe(json, '\"');
|
strbuf_append_char_unsafe(json, '\"');
|
||||||
@@ -678,30 +701,44 @@ static void json_check_encode_depth(lua_State *l, json_config_t *cfg,
|
|||||||
current_depth);
|
current_depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void json_append_data(lua_State *l, json_encode_t *cfg,
|
static int json_append_data(lua_State *l, json_encode_t *cfg,
|
||||||
int current_depth);
|
int current_depth);
|
||||||
|
|
||||||
/* json_append_array args:
|
/* json_append_array args:
|
||||||
* - lua_State
|
* - lua_State
|
||||||
* - JSON strbuf
|
* - JSON strbuf
|
||||||
* - Size of passwd Lua array (top of stack) */
|
* - Size of passed Lua array (top of stack) */
|
||||||
static void json_append_array(lua_State *l, json_encode_t *ctx, int current_depth,
|
static void json_append_array(lua_State *l, json_encode_t *ctx, int current_depth,
|
||||||
int array_length)
|
int array_length, int raw)
|
||||||
{
|
{
|
||||||
int comma, i;
|
int comma, i, json_pos, err;
|
||||||
strbuf_t *json = ctx->json;
|
strbuf_t *json = ctx->json;
|
||||||
|
|
||||||
strbuf_append_char(json, '[');
|
strbuf_append_char(json, '[');
|
||||||
|
|
||||||
comma = 0;
|
comma = 0;
|
||||||
for (i = 1; i <= array_length; i++) {
|
for (i = 1; i <= array_length; i++) {
|
||||||
if (comma)
|
json_pos = strbuf_length(json);
|
||||||
|
if (comma++ > 0)
|
||||||
strbuf_append_char(json, ',');
|
strbuf_append_char(json, ',');
|
||||||
else
|
if (raw) {
|
||||||
comma = 1;
|
lua_rawgeti(l, -1, i);
|
||||||
|
} else {
|
||||||
|
#if LUA_VERSION_NUM >= 503
|
||||||
|
lua_geti(l, -1, i);
|
||||||
|
#else
|
||||||
|
lua_pushinteger(l, i);
|
||||||
|
lua_gettable(l, -2);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
lua_rawgeti(l, -1, i);
|
err = json_append_data(l, ctx, current_depth);
|
||||||
json_append_data(l, ctx, current_depth);
|
if (err) {
|
||||||
|
strbuf_set_length(json, json_pos);
|
||||||
|
if (comma == 1) {
|
||||||
|
comma = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
lua_pop(l, 1);
|
lua_pop(l, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -711,8 +748,17 @@ static void json_append_array(lua_State *l, json_encode_t *ctx, int current_dept
|
|||||||
static void json_append_number(lua_State *l, json_encode_t *ctx,
|
static void json_append_number(lua_State *l, json_encode_t *ctx,
|
||||||
int lindex)
|
int lindex)
|
||||||
{
|
{
|
||||||
double num = lua_tonumber(l, lindex);
|
|
||||||
int len;
|
int len;
|
||||||
|
#if LUA_VERSION_NUM >= 503
|
||||||
|
if (lua_isinteger(l, lindex)) {
|
||||||
|
lua_Integer num = lua_tointeger(l, lindex);
|
||||||
|
strbuf_ensure_empty_length(json, FPCONV_G_FMT_BUFSIZE); /* max length of int64 is 19 */
|
||||||
|
len = sprintf(strbuf_empty_ptr(json), LUA_INTEGER_FMT, num);
|
||||||
|
strbuf_extend_length(json, len);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
double num = lua_tonumber(l, lindex);
|
||||||
json_config_t *cfg = ctx->cfg;
|
json_config_t *cfg = ctx->cfg;
|
||||||
strbuf_t *json = ctx->json;
|
strbuf_t *json = ctx->json;
|
||||||
|
|
||||||
@@ -751,7 +797,7 @@ static void json_append_number(lua_State *l, json_encode_t *ctx,
|
|||||||
static void json_append_object(lua_State *l, json_encode_t *ctx,
|
static void json_append_object(lua_State *l, json_encode_t *ctx,
|
||||||
int current_depth)
|
int current_depth)
|
||||||
{
|
{
|
||||||
int comma, keytype;
|
int comma, keytype, json_pos, err;
|
||||||
strbuf_t *json = ctx->json;
|
strbuf_t *json = ctx->json;
|
||||||
|
|
||||||
/* Object */
|
/* Object */
|
||||||
@@ -761,7 +807,8 @@ static void json_append_object(lua_State *l, json_encode_t *ctx,
|
|||||||
/* table, startkey */
|
/* table, startkey */
|
||||||
comma = 0;
|
comma = 0;
|
||||||
while (lua_next(l, -2) != 0) {
|
while (lua_next(l, -2) != 0) {
|
||||||
if (comma)
|
json_pos = strbuf_length(json);
|
||||||
|
if (comma++ > 0)
|
||||||
strbuf_append_char(json, ',');
|
strbuf_append_char(json, ',');
|
||||||
else
|
else
|
||||||
comma = 1;
|
comma = 1;
|
||||||
@@ -782,7 +829,14 @@ static void json_append_object(lua_State *l, json_encode_t *ctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* table, key, value */
|
/* table, key, value */
|
||||||
json_append_data(l, ctx, current_depth);
|
err = json_append_data(l, ctx, current_depth);
|
||||||
|
if (err) {
|
||||||
|
strbuf_set_length(json, json_pos);
|
||||||
|
if (comma == 1) {
|
||||||
|
comma = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
lua_pop(l, 1);
|
lua_pop(l, 1);
|
||||||
/* table, key */
|
/* table, key */
|
||||||
}
|
}
|
||||||
@@ -790,14 +844,15 @@ static void json_append_object(lua_State *l, json_encode_t *ctx,
|
|||||||
strbuf_append_char(json, '}');
|
strbuf_append_char(json, '}');
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Serialise Lua data into JSON string. */
|
/* Serialise Lua data into JSON string. Return 1 if error an error happend, else 0 */
|
||||||
static void json_append_data(lua_State *l, json_encode_t *ctx,
|
static int json_append_data(lua_State *l, json_encode_t *ctx,
|
||||||
int current_depth)
|
int current_depth)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
int as_array = 0;
|
int as_array = 0;
|
||||||
int as_empty_dict = 0;
|
int as_empty_dict = 0;
|
||||||
int has_metatable;
|
int has_metatable;
|
||||||
|
int raw = 1;
|
||||||
json_config_t *cfg = ctx->cfg;
|
json_config_t *cfg = ctx->cfg;
|
||||||
strbuf_t *json = ctx->json;
|
strbuf_t *json = ctx->json;
|
||||||
|
|
||||||
@@ -831,17 +886,31 @@ static void json_append_data(lua_State *l, json_encode_t *ctx,
|
|||||||
lua_rawget(l, LUA_REGISTRYINDEX);
|
lua_rawget(l, LUA_REGISTRYINDEX);
|
||||||
as_array = lua_rawequal(l, -1, -2);
|
as_array = lua_rawequal(l, -1, -2);
|
||||||
}
|
}
|
||||||
lua_pop(l, 2);
|
if (as_array) {
|
||||||
|
raw = 1;
|
||||||
|
lua_pop(l, 2);
|
||||||
|
len = lua_objlen(l, -1);
|
||||||
|
} else {
|
||||||
|
raw = 0;
|
||||||
|
lua_pop(l, 2);
|
||||||
|
if (luaL_getmetafield(l, -1, "__len")) {
|
||||||
|
lua_pushvalue(l, -2);
|
||||||
|
lua_call(l, 1, 1);
|
||||||
|
len = lua_tonumber(l, -1);
|
||||||
|
lua_pop(l, 1);
|
||||||
|
as_array = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (as_array) {
|
if (as_array) {
|
||||||
len = lua_objlen(l, -1);
|
len = lua_objlen(l, -1);
|
||||||
json_append_array(l, ctx, current_depth, len);
|
json_append_array(l, ctx, current_depth, len, raw);
|
||||||
} else {
|
} else {
|
||||||
len = lua_array_length(l, ctx);
|
len = lua_array_length(l, ctx);
|
||||||
|
|
||||||
if (len > 0 || (len == 0 && !cfg->encode_empty_table_as_object && !as_empty_dict)) {
|
if (len > 0 || (len == 0 && !cfg->encode_empty_table_as_object && !as_empty_dict)) {
|
||||||
json_append_array(l, ctx, current_depth, len);
|
json_append_array(l, ctx, current_depth, len, raw);
|
||||||
} else {
|
} else {
|
||||||
if (has_metatable) {
|
if (has_metatable) {
|
||||||
lua_getmetatable(l, -1);
|
lua_getmetatable(l, -1);
|
||||||
@@ -851,7 +920,10 @@ static void json_append_data(lua_State *l, json_encode_t *ctx,
|
|||||||
as_array = lua_rawequal(l, -1, -2);
|
as_array = lua_rawequal(l, -1, -2);
|
||||||
lua_pop(l, 2); /* pop pointer + metatable */
|
lua_pop(l, 2); /* pop pointer + metatable */
|
||||||
if (as_array) {
|
if (as_array) {
|
||||||
json_append_array(l, ctx, current_depth, 0);
|
len = lua_objlen(l, -1);
|
||||||
|
|
||||||
|
raw = 1;
|
||||||
|
json_append_array(l, ctx, current_depth, len, raw);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -864,7 +936,7 @@ static void json_append_data(lua_State *l, json_encode_t *ctx,
|
|||||||
break;
|
break;
|
||||||
case LUA_TLIGHTUSERDATA:
|
case LUA_TLIGHTUSERDATA:
|
||||||
if (lua_touserdata(l, -1) == &json_array) {
|
if (lua_touserdata(l, -1) == &json_array) {
|
||||||
json_append_array(l, ctx, current_depth, 0);
|
json_append_array(l, ctx, current_depth, 0, 1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case LUA_TUSERDATA:
|
case LUA_TUSERDATA:
|
||||||
@@ -880,9 +952,15 @@ static void json_append_data(lua_State *l, json_encode_t *ctx,
|
|||||||
default:
|
default:
|
||||||
/* Remaining types (LUA_TFUNCTION, LUA_TUSERDATA, LUA_TTHREAD,
|
/* Remaining types (LUA_TFUNCTION, LUA_TUSERDATA, LUA_TTHREAD,
|
||||||
* and LUA_TLIGHTUSERDATA) cannot be serialised */
|
* and LUA_TLIGHTUSERDATA) cannot be serialised */
|
||||||
|
if (cfg->encode_skip_unsupported_value_types) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
json_encode_exception(l, ctx, -1, "type not supported");
|
json_encode_exception(l, ctx, -1, "type not supported");
|
||||||
|
}
|
||||||
|
|
||||||
/* never returns */
|
/* never returns */
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int json_encode(lua_State *l)
|
static int json_encode(lua_State *l)
|
||||||
@@ -893,7 +971,7 @@ static int json_encode(lua_State *l)
|
|||||||
strbuf_t local_encode_buf;
|
strbuf_t local_encode_buf;
|
||||||
strbuf_t *encode_buf;
|
strbuf_t *encode_buf;
|
||||||
char *json;
|
char *json;
|
||||||
int len;
|
size_t len;
|
||||||
const char *customChar2escape[256];
|
const char *customChar2escape[256];
|
||||||
|
|
||||||
switch (lua_gettop(l)) {
|
switch (lua_gettop(l)) {
|
||||||
@@ -1215,12 +1293,19 @@ static void json_next_number_token(json_parse_t *json, json_token_t *token)
|
|||||||
{
|
{
|
||||||
char *endptr;
|
char *endptr;
|
||||||
|
|
||||||
token->type = T_NUMBER;
|
token->value.integer = strtoll(json->ptr, &endptr, 10);
|
||||||
token->value.number = fpconv_strtod(json->ptr, &endptr);
|
if (json->ptr == endptr || *endptr == '.' || *endptr == 'e' ||
|
||||||
if (json->ptr == endptr)
|
*endptr == 'E' || *endptr == 'x') {
|
||||||
json_set_token_error(token, json, "invalid number");
|
token->type = T_NUMBER;
|
||||||
else
|
token->value.number = fpconv_strtod(json->ptr, &endptr);
|
||||||
json->ptr = endptr; /* Skip the processed number */
|
if (json->ptr == endptr) {
|
||||||
|
json_set_token_error(token, json, "invalid number");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
token->type = T_INTEGER;
|
||||||
|
}
|
||||||
|
json->ptr = endptr; /* Skip the processed number */
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1458,6 +1543,9 @@ static void json_process_value(lua_State *l, json_parse_t *json,
|
|||||||
case T_NUMBER:
|
case T_NUMBER:
|
||||||
lua_pushnumber(l, token->value.number);
|
lua_pushnumber(l, token->value.number);
|
||||||
break;;
|
break;;
|
||||||
|
case T_INTEGER:
|
||||||
|
lua_pushinteger(l, token->value.integer);
|
||||||
|
break;;
|
||||||
case T_BOOLEAN:
|
case T_BOOLEAN:
|
||||||
lua_pushboolean(l, token->value.boolean);
|
lua_pushboolean(l, token->value.boolean);
|
||||||
break;;
|
break;;
|
||||||
@@ -1621,6 +1709,7 @@ int lua_cjson_new(lua_State *l)
|
|||||||
{ "encode_invalid_numbers", json_cfg_encode_invalid_numbers },
|
{ "encode_invalid_numbers", json_cfg_encode_invalid_numbers },
|
||||||
{ "decode_invalid_numbers", json_cfg_decode_invalid_numbers },
|
{ "decode_invalid_numbers", json_cfg_decode_invalid_numbers },
|
||||||
{ "encode_escape_forward_slash", json_cfg_encode_escape_forward_slash },
|
{ "encode_escape_forward_slash", json_cfg_encode_escape_forward_slash },
|
||||||
|
{ "encode_skip_unsupported_value_types", json_cfg_encode_skip_unsupported_value_types },
|
||||||
*/
|
*/
|
||||||
{ "new", lua_cjson_new },
|
{ "new", lua_cjson_new },
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
@@ -1745,5 +1834,3 @@ int luaopen_cjson_safe(lua_State *l)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* vi:ai et sw=4 ts=4:
|
|
||||||
*/
|
|
||||||
|
113
src/cjson/strbuf.c
vendored
113
src/cjson/strbuf.c
vendored
@@ -26,6 +26,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "strbuf.h"
|
#include "strbuf.h"
|
||||||
|
|
||||||
@@ -41,35 +42,35 @@ static void die(const char *fmt, ...)
|
|||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void strbuf_init(strbuf_t *s, int len)
|
void strbuf_init(strbuf_t *s, size_t len)
|
||||||
{
|
{
|
||||||
int size;
|
size_t size;
|
||||||
|
|
||||||
if (len <= 0)
|
if (!len)
|
||||||
size = STRBUF_DEFAULT_SIZE;
|
size = STRBUF_DEFAULT_SIZE;
|
||||||
else
|
else
|
||||||
size = len + 1; /* \0 terminator */
|
size = len + 1; /* \0 terminator */
|
||||||
|
if (size < len)
|
||||||
|
die("Overflow, len %zu", len);
|
||||||
s->buf = NULL;
|
s->buf = NULL;
|
||||||
s->size = size;
|
s->size = size;
|
||||||
s->length = 0;
|
s->length = 0;
|
||||||
s->increment = STRBUF_DEFAULT_INCREMENT;
|
|
||||||
s->dynamic = 0;
|
s->dynamic = 0;
|
||||||
s->reallocs = 0;
|
s->reallocs = 0;
|
||||||
s->debug = 0;
|
s->debug = 0;
|
||||||
|
|
||||||
s->buf = malloc(size);
|
s->buf = (char *)malloc(size);
|
||||||
if (!s->buf)
|
if (!s->buf)
|
||||||
die("Out of memory");
|
die("Out of memory");
|
||||||
|
|
||||||
strbuf_ensure_null(s);
|
strbuf_ensure_null(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
strbuf_t *strbuf_new(int len)
|
strbuf_t *strbuf_new(size_t len)
|
||||||
{
|
{
|
||||||
strbuf_t *s;
|
strbuf_t *s;
|
||||||
|
|
||||||
s = malloc(sizeof(strbuf_t));
|
s = (strbuf_t*)malloc(sizeof(strbuf_t));
|
||||||
if (!s)
|
if (!s)
|
||||||
die("Out of memory");
|
die("Out of memory");
|
||||||
|
|
||||||
@@ -81,20 +82,10 @@ strbuf_t *strbuf_new(int len)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
void strbuf_set_increment(strbuf_t *s, int increment)
|
|
||||||
{
|
|
||||||
/* Increment > 0: Linear buffer growth rate
|
|
||||||
* Increment < -1: Exponential buffer growth rate */
|
|
||||||
if (increment == 0 || increment == -1)
|
|
||||||
die("BUG: Invalid string increment");
|
|
||||||
|
|
||||||
s->increment = increment;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void debug_stats(strbuf_t *s)
|
static inline void debug_stats(strbuf_t *s)
|
||||||
{
|
{
|
||||||
if (s->debug) {
|
if (s->debug) {
|
||||||
fprintf(stderr, "strbuf(%lx) reallocs: %d, length: %d, size: %d\n",
|
fprintf(stderr, "strbuf(%lx) reallocs: %d, length: %zd, size: %zd\n",
|
||||||
(long)s, s->reallocs, s->length, s->size);
|
(long)s, s->reallocs, s->length, s->size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -113,7 +104,7 @@ void strbuf_free(strbuf_t *s)
|
|||||||
free(s);
|
free(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *strbuf_free_to_string(strbuf_t *s, int *len)
|
char *strbuf_free_to_string(strbuf_t *s, size_t *len)
|
||||||
{
|
{
|
||||||
char *buf;
|
char *buf;
|
||||||
|
|
||||||
@@ -131,57 +122,63 @@ char *strbuf_free_to_string(strbuf_t *s, int *len)
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int calculate_new_size(strbuf_t *s, int len)
|
static size_t calculate_new_size(strbuf_t *s, size_t len)
|
||||||
{
|
{
|
||||||
int reqsize, newsize;
|
size_t reqsize, newsize;
|
||||||
|
|
||||||
if (len <= 0)
|
if (len <= 0)
|
||||||
die("BUG: Invalid strbuf length requested");
|
die("BUG: Invalid strbuf length requested");
|
||||||
|
|
||||||
/* Ensure there is room for optional NULL termination */
|
/* Ensure there is room for optional NULL termination */
|
||||||
reqsize = len + 1;
|
reqsize = len + 1;
|
||||||
|
if (reqsize < len)
|
||||||
|
die("Overflow, len %zu", len);
|
||||||
|
|
||||||
/* If the user has requested to shrink the buffer, do it exactly */
|
/* If the user has requested to shrink the buffer, do it exactly */
|
||||||
if (s->size > reqsize)
|
if (s->size > reqsize)
|
||||||
return reqsize;
|
return reqsize;
|
||||||
|
|
||||||
newsize = s->size;
|
newsize = s->size;
|
||||||
if (s->increment < 0) {
|
if (reqsize >= SIZE_MAX / 2) {
|
||||||
|
newsize = reqsize;
|
||||||
|
} else {
|
||||||
/* Exponential sizing */
|
/* Exponential sizing */
|
||||||
while (newsize < reqsize)
|
while (newsize < reqsize)
|
||||||
newsize *= -s->increment;
|
newsize *= 2;
|
||||||
} else {
|
|
||||||
/* Linear sizing */
|
|
||||||
newsize = ((newsize + s->increment - 1) / s->increment) * s->increment;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (newsize < reqsize)
|
||||||
|
die("BUG: strbuf length would overflow, len: %zu", len);
|
||||||
|
|
||||||
|
|
||||||
return newsize;
|
return newsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Ensure strbuf can handle a string length bytes long (ignoring NULL
|
/* Ensure strbuf can handle a string length bytes long (ignoring NULL
|
||||||
* optional termination). */
|
* optional termination). */
|
||||||
void strbuf_resize(strbuf_t *s, int len)
|
void strbuf_resize(strbuf_t *s, size_t len)
|
||||||
{
|
{
|
||||||
int newsize;
|
size_t newsize;
|
||||||
|
|
||||||
newsize = calculate_new_size(s, len);
|
newsize = calculate_new_size(s, len);
|
||||||
|
|
||||||
if (s->debug > 1) {
|
if (s->debug > 1) {
|
||||||
fprintf(stderr, "strbuf(%lx) resize: %d => %d\n",
|
fprintf(stderr, "strbuf(%lx) resize: %zd => %zd\n",
|
||||||
(long)s, s->size, newsize);
|
(long)s, s->size, newsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
s->size = newsize;
|
s->size = newsize;
|
||||||
s->buf = realloc(s->buf, s->size);
|
s->buf = (char *)realloc(s->buf, s->size);
|
||||||
if (!s->buf)
|
if (!s->buf)
|
||||||
die("Out of memory");
|
die("Out of memory, len: %zu", len);
|
||||||
s->reallocs++;
|
s->reallocs++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void strbuf_append_string(strbuf_t *s, const char *str)
|
void strbuf_append_string(strbuf_t *s, const char *str)
|
||||||
{
|
{
|
||||||
int space, i;
|
int i;
|
||||||
|
size_t space;
|
||||||
|
|
||||||
space = strbuf_empty_length(s);
|
space = strbuf_empty_length(s);
|
||||||
|
|
||||||
@@ -197,55 +194,5 @@ void strbuf_append_string(strbuf_t *s, const char *str)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* strbuf_append_fmt() should only be used when an upper bound
|
|
||||||
* is known for the output string. */
|
|
||||||
void strbuf_append_fmt(strbuf_t *s, int len, const char *fmt, ...)
|
|
||||||
{
|
|
||||||
va_list arg;
|
|
||||||
int fmt_len;
|
|
||||||
|
|
||||||
strbuf_ensure_empty_length(s, len);
|
|
||||||
|
|
||||||
va_start(arg, fmt);
|
|
||||||
fmt_len = vsnprintf(s->buf + s->length, len, fmt, arg);
|
|
||||||
va_end(arg);
|
|
||||||
|
|
||||||
if (fmt_len < 0)
|
|
||||||
die("BUG: Unable to convert number"); /* This should never happen.. */
|
|
||||||
|
|
||||||
s->length += fmt_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* strbuf_append_fmt_retry() can be used when the there is no known
|
|
||||||
* upper bound for the output string. */
|
|
||||||
void strbuf_append_fmt_retry(strbuf_t *s, const char *fmt, ...)
|
|
||||||
{
|
|
||||||
va_list arg;
|
|
||||||
int fmt_len, try;
|
|
||||||
int empty_len;
|
|
||||||
|
|
||||||
/* If the first attempt to append fails, resize the buffer appropriately
|
|
||||||
* and try again */
|
|
||||||
for (try = 0; ; try++) {
|
|
||||||
va_start(arg, fmt);
|
|
||||||
/* Append the new formatted string */
|
|
||||||
/* fmt_len is the length of the string required, excluding the
|
|
||||||
* trailing NULL */
|
|
||||||
empty_len = strbuf_empty_length(s);
|
|
||||||
/* Add 1 since there is also space to store the terminating NULL. */
|
|
||||||
fmt_len = vsnprintf(s->buf + s->length, empty_len + 1, fmt, arg);
|
|
||||||
va_end(arg);
|
|
||||||
|
|
||||||
if (fmt_len <= empty_len)
|
|
||||||
break; /* SUCCESS */
|
|
||||||
if (try > 0)
|
|
||||||
die("BUG: length of formatted string changed");
|
|
||||||
|
|
||||||
strbuf_resize(s, s->length + fmt_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
s->length += fmt_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* vi:ai et sw=4 ts=4:
|
/* vi:ai et sw=4 ts=4:
|
||||||
*/
|
*/
|
||||||
|
52
src/cjson/strbuf.h
vendored
52
src/cjson/strbuf.h
vendored
@@ -32,15 +32,13 @@
|
|||||||
|
|
||||||
/* Size: Total bytes allocated to *buf
|
/* Size: Total bytes allocated to *buf
|
||||||
* Length: String length, excluding optional NULL terminator.
|
* Length: String length, excluding optional NULL terminator.
|
||||||
* Increment: Allocation increments when resizing the string buffer.
|
|
||||||
* Dynamic: True if created via strbuf_new()
|
* Dynamic: True if created via strbuf_new()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char *buf;
|
char *buf;
|
||||||
int size;
|
size_t size;
|
||||||
int length;
|
size_t length;
|
||||||
int increment;
|
|
||||||
int dynamic;
|
int dynamic;
|
||||||
int reallocs;
|
int reallocs;
|
||||||
int debug;
|
int debug;
|
||||||
@@ -49,32 +47,27 @@ typedef struct {
|
|||||||
#ifndef STRBUF_DEFAULT_SIZE
|
#ifndef STRBUF_DEFAULT_SIZE
|
||||||
#define STRBUF_DEFAULT_SIZE 1023
|
#define STRBUF_DEFAULT_SIZE 1023
|
||||||
#endif
|
#endif
|
||||||
#ifndef STRBUF_DEFAULT_INCREMENT
|
|
||||||
#define STRBUF_DEFAULT_INCREMENT -2
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Initialise */
|
/* Initialise */
|
||||||
extern strbuf_t *strbuf_new(int len);
|
extern strbuf_t *strbuf_new(size_t len);
|
||||||
extern void strbuf_init(strbuf_t *s, int len);
|
extern void strbuf_init(strbuf_t *s, size_t len);
|
||||||
extern void strbuf_set_increment(strbuf_t *s, int increment);
|
|
||||||
|
|
||||||
/* Release */
|
/* Release */
|
||||||
extern void strbuf_free(strbuf_t *s);
|
extern void strbuf_free(strbuf_t *s);
|
||||||
extern char *strbuf_free_to_string(strbuf_t *s, int *len);
|
extern char *strbuf_free_to_string(strbuf_t *s, size_t *len);
|
||||||
|
|
||||||
/* Management */
|
/* Management */
|
||||||
extern void strbuf_resize(strbuf_t *s, int len);
|
extern void strbuf_resize(strbuf_t *s, size_t len);
|
||||||
static int strbuf_empty_length(strbuf_t *s);
|
static size_t strbuf_empty_length(strbuf_t *s);
|
||||||
static int strbuf_length(strbuf_t *s);
|
static size_t strbuf_length(strbuf_t *s);
|
||||||
static char *strbuf_string(strbuf_t *s, int *len);
|
static char *strbuf_string(strbuf_t *s, size_t *len);
|
||||||
static void strbuf_ensure_empty_length(strbuf_t *s, int len);
|
static void strbuf_ensure_empty_length(strbuf_t *s, size_t len);
|
||||||
static char *strbuf_empty_ptr(strbuf_t *s);
|
static char *strbuf_empty_ptr(strbuf_t *s);
|
||||||
static void strbuf_extend_length(strbuf_t *s, int len);
|
static void strbuf_extend_length(strbuf_t *s, size_t len);
|
||||||
|
static void strbuf_set_length(strbuf_t *s, int len);
|
||||||
|
|
||||||
/* Update */
|
/* Update */
|
||||||
extern void strbuf_append_fmt(strbuf_t *s, int len, const char *fmt, ...);
|
static void strbuf_append_mem(strbuf_t *s, const char *c, size_t len);
|
||||||
extern void strbuf_append_fmt_retry(strbuf_t *s, const char *format, ...);
|
|
||||||
static void strbuf_append_mem(strbuf_t *s, const char *c, int len);
|
|
||||||
extern void strbuf_append_string(strbuf_t *s, const char *str);
|
extern void strbuf_append_string(strbuf_t *s, const char *str);
|
||||||
static void strbuf_append_char(strbuf_t *s, const char c);
|
static void strbuf_append_char(strbuf_t *s, const char c);
|
||||||
static void strbuf_ensure_null(strbuf_t *s);
|
static void strbuf_ensure_null(strbuf_t *s);
|
||||||
@@ -92,12 +85,12 @@ static inline int strbuf_allocated(strbuf_t *s)
|
|||||||
|
|
||||||
/* Return bytes remaining in the string buffer
|
/* Return bytes remaining in the string buffer
|
||||||
* Ensure there is space for a NULL terminator. */
|
* Ensure there is space for a NULL terminator. */
|
||||||
static inline int strbuf_empty_length(strbuf_t *s)
|
static inline size_t strbuf_empty_length(strbuf_t *s)
|
||||||
{
|
{
|
||||||
return s->size - s->length - 1;
|
return s->size - s->length - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void strbuf_ensure_empty_length(strbuf_t *s, int len)
|
static inline void strbuf_ensure_empty_length(strbuf_t *s, size_t len)
|
||||||
{
|
{
|
||||||
if (len > strbuf_empty_length(s))
|
if (len > strbuf_empty_length(s))
|
||||||
strbuf_resize(s, s->length + len);
|
strbuf_resize(s, s->length + len);
|
||||||
@@ -108,12 +101,17 @@ static inline char *strbuf_empty_ptr(strbuf_t *s)
|
|||||||
return s->buf + s->length;
|
return s->buf + s->length;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void strbuf_extend_length(strbuf_t *s, int len)
|
static inline void strbuf_set_length(strbuf_t *s, int len)
|
||||||
{
|
{
|
||||||
s->length += len;
|
s->length += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int strbuf_length(strbuf_t *s)
|
static inline void strbuf_extend_length(strbuf_t *s, size_t len)
|
||||||
|
{
|
||||||
|
s->length += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline size_t strbuf_length(strbuf_t *s)
|
||||||
{
|
{
|
||||||
return s->length;
|
return s->length;
|
||||||
}
|
}
|
||||||
@@ -129,14 +127,14 @@ static inline void strbuf_append_char_unsafe(strbuf_t *s, const char c)
|
|||||||
s->buf[s->length++] = c;
|
s->buf[s->length++] = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void strbuf_append_mem(strbuf_t *s, const char *c, int len)
|
static inline void strbuf_append_mem(strbuf_t *s, const char *c, size_t len)
|
||||||
{
|
{
|
||||||
strbuf_ensure_empty_length(s, len);
|
strbuf_ensure_empty_length(s, len);
|
||||||
memcpy(s->buf + s->length, c, len);
|
memcpy(s->buf + s->length, c, len);
|
||||||
s->length += len;
|
s->length += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void strbuf_append_mem_unsafe(strbuf_t *s, const char *c, int len)
|
static inline void strbuf_append_mem_unsafe(strbuf_t *s, const char *c, size_t len)
|
||||||
{
|
{
|
||||||
memcpy(s->buf + s->length, c, len);
|
memcpy(s->buf + s->length, c, len);
|
||||||
s->length += len;
|
s->length += len;
|
||||||
@@ -147,7 +145,7 @@ static inline void strbuf_ensure_null(strbuf_t *s)
|
|||||||
s->buf[s->length] = 0;
|
s->buf[s->length] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline char *strbuf_string(strbuf_t *s, int *len)
|
static inline char *strbuf_string(strbuf_t *s, size_t *len)
|
||||||
{
|
{
|
||||||
if (len)
|
if (len)
|
||||||
*len = s->length;
|
*len = s->length;
|
||||||
|
Reference in New Issue
Block a user