summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorFlorian Frank <flori@ping.de>2009-10-26 01:28:16 +0100
committerFlorian Frank <flori@ping.de>2009-10-26 22:58:08 +0100
commit4852738aad89a27fbb48673eb2604f381bc8b811 (patch)
treef2f4b0b499e252bde663f008f64af62e53d4e04e /ext
parent07d786882cd0a9d9131096bfcbc613f8262e1fc0 (diff)
downloadjson-4852738aad89a27fbb48673eb2604f381bc8b811.tar.gz
use fbuffer more
Diffstat (limited to 'ext')
-rw-r--r--ext/json/ext/generator/fbuffer.c5
-rw-r--r--ext/json/ext/generator/fbuffer.h3
-rw-r--r--ext/json/ext/generator/generator.c58
-rw-r--r--ext/json/ext/generator/unicode.c2
-rw-r--r--ext/json/ext/generator/unicode.h2
5 files changed, 52 insertions, 18 deletions
diff --git a/ext/json/ext/generator/fbuffer.c b/ext/json/ext/generator/fbuffer.c
index ed92936..66d4b61 100644
--- a/ext/json/ext/generator/fbuffer.c
+++ b/ext/json/ext/generator/fbuffer.c
@@ -14,6 +14,11 @@ inline void fbuffer_free(FBuffer *fb)
ruby_xfree(fb);
}
+inline void fbuffer_clear(FBuffer *fb)
+{
+ fb->len = 0;
+}
+
inline void fbuffer_inc_capa(FBuffer *fb, unsigned int requested)
{
unsigned int required;
diff --git a/ext/json/ext/generator/fbuffer.h b/ext/json/ext/generator/fbuffer.h
index 06adb25..3b42721 100644
--- a/ext/json/ext/generator/fbuffer.h
+++ b/ext/json/ext/generator/fbuffer.h
@@ -10,11 +10,12 @@ typedef struct FBufferStruct {
#define FBUFFER_INITIAL_LENGTH 4096
#define FBUFFER_PTR(fb) (fb->ptr)
-
#define FBUFFER_LEN(fb) (fb->len)
+#define FBUFFER_PAIR(fb) FBUFFER_PTR(fb), FBUFFER_LEN(fb)
inline FBuffer *fbuffer_alloc();
inline void fbuffer_free(FBuffer *fb);
+inline void fbuffer_clear(FBuffer *fb);
inline void fbuffer_inc_capa(FBuffer *fb, unsigned int requested);
inline void fbuffer_append(FBuffer *fb, const char *newstr, unsigned int len);
inline void fbuffer_append_char(FBuffer *fb, const char newchr);
diff --git a/ext/json/ext/generator/generator.c b/ext/json/ext/generator/generator.c
index de43db4..36580ad 100644
--- a/ext/json/ext/generator/generator.c
+++ b/ext/json/ext/generator/generator.c
@@ -53,6 +53,8 @@ typedef struct JSON_Generator_StateStruct {
VALUE space_before;
VALUE object_nl;
VALUE array_nl;
+ FBuffer *delim;
+ FBuffer *delim2;
long max_nesting;
int flag;
int allow_nan;
@@ -274,6 +276,12 @@ static void State_mark(JSON_Generator_State *state)
rb_gc_mark_maybe(state->array_nl);
}
+static void State_free(JSON_Generator_State *state) {
+ if (state->delim) fbuffer_free(state->delim);
+ if (state->delim2) fbuffer_free(state->delim2);
+ ruby_xfree(state);
+}
+
static JSON_Generator_State *State_allocate()
{
JSON_Generator_State *state = ALLOC(JSON_Generator_State);
@@ -283,7 +291,7 @@ static JSON_Generator_State *State_allocate()
static VALUE cState_s_allocate(VALUE klass)
{
JSON_Generator_State *state = State_allocate();
- return Data_Wrap_Struct(klass, State_mark, -1, state);
+ return Data_Wrap_Struct(klass, State_mark, State_free, state);
}
/*
@@ -370,21 +378,34 @@ void generate_json(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, V
case T_HASH:
{
int i, j;
- VALUE delim = rb_str_new2(","), delim2 = rb_str_new2("");
+ FBuffer *delim, *delim2;
+ if (state->delim) {
+ fbuffer_clear(state->delim);
+ delim = state->delim;
+ } else {
+ delim = state->delim = fbuffer_alloc();
+ }
+ if (state->delim2) {
+ fbuffer_clear(state->delim2);
+ delim2 = state->delim2;
+ } else {
+ delim2 = state->delim2 = fbuffer_alloc();
+ }
+ fbuffer_append_char(delim, ',');
depth++;
if (state->max_nesting != 0 && depth > state->max_nesting) {
fbuffer_free(buffer);
rb_raise(eNestingError, "nesting of %ld is too deep", depth);
}
- if (state->object_nl) rb_str_append(delim, state->object_nl);
- if (state->space_before) rb_str_buf_append(delim2, state->space_before);
- rb_str_buf_cat2(delim2, ":");
- if (state->space) rb_str_buf_append(delim2, state->space);
+ if (state->object_nl) fbuffer_append(delim, RSTRING_PAIR(state->object_nl));
+ if (state->space_before) fbuffer_append(delim2, RSTRING_PAIR(state->space_before));
+ fbuffer_append_char(delim2, ':');
+ if (state->space) fbuffer_append(delim2, RSTRING_PAIR(state->space));
fbuffer_append_char(buffer, '{');
VALUE keys = rb_funcall(obj, rb_intern("keys"), 0);
VALUE key, key_to_s;
for(i = 0; i < RARRAY_LEN(keys); i++) {
- if (i > 0) fbuffer_append(buffer, RSTRING_PAIR(delim));
+ if (i > 0) fbuffer_append(buffer, FBUFFER_PAIR(delim));
if (state->object_nl) {
fbuffer_append(buffer, RSTRING_PAIR(state->object_nl));
}
@@ -397,7 +418,7 @@ void generate_json(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, V
key_to_s = rb_funcall(key, i_to_s, 0);
Check_Type(key_to_s, T_STRING);
generate_json(buffer, Vstate, state, key_to_s, depth);
- fbuffer_append(buffer, RSTRING_PAIR(delim2));
+ fbuffer_append(buffer, FBUFFER_PAIR(delim2));
generate_json(buffer, Vstate, state, rb_hash_aref(obj, key), depth);
}
depth--;
@@ -415,17 +436,24 @@ void generate_json(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, V
case T_ARRAY:
{
int i, j;
- VALUE delim = rb_str_new2(",");
+ FBuffer *delim;
+ if (state->delim) {
+ fbuffer_clear(state->delim);
+ delim = state->delim;
+ } else {
+ delim = state->delim = fbuffer_alloc();
+ }
+ fbuffer_append_char(delim, ',');
depth++;
if (state->max_nesting != 0 && depth > state->max_nesting) {
fbuffer_free(buffer);
rb_raise(eNestingError, "nesting of %ld is too deep", depth);
}
- if (state->array_nl) rb_str_append(delim, state->array_nl);
+ if (state->array_nl) fbuffer_append(delim, RSTRING_PAIR(state->array_nl));
fbuffer_append_char(buffer, '[');
if (state->array_nl) fbuffer_append(buffer, RSTRING_PAIR(state->array_nl));
for(i = 0; i < RARRAY_LEN(obj); i++) {
- if (i > 0) fbuffer_append(buffer, RSTRING_PAIR(delim));
+ if (i > 0) fbuffer_append(buffer, FBUFFER_PAIR(delim));
if (state->indent) {
for (j = 0; j < depth; j++) {
fbuffer_append(buffer, RSTRING_PAIR(state->indent));
@@ -449,13 +477,13 @@ void generate_json(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, V
fbuffer_append_char(buffer, '"');
#ifdef HAVE_RUBY_ENCODING_H
if (rb_funcall(obj, i_encoding, 0) == CEncoding_UTF_8) {
- JSON_convert_UTF8_to_JSON(buffer, obj);
+ JSON_convert_UTF8_to_JSON_ASCII(buffer, obj);
} else {
VALUE string = rb_funcall(obj, i_encode, 1, CEncoding_UTF_8);
- JSON_convert_UTF8_to_JSON(buffer, string);
+ JSON_convert_UTF8_to_JSON_ASCII(buffer, string);
}
#else
- JSON_convert_UTF8_to_JSON(buffer, obj);
+ JSON_convert_UTF8_to_JSON_ASCII(buffer, obj);
#endif
fbuffer_append_char(buffer, '"');
break;
@@ -512,7 +540,7 @@ inline static VALUE cState_partial_generate(VALUE self, VALUE obj, VALUE depth)
FBuffer *buffer = fbuffer_alloc();
GET_STATE(self);
generate_json(buffer, self, state, obj, NIL_P(depth) ? 0 : FIX2INT(depth));
- result = rb_str_new(buffer->ptr, buffer->len);
+ result = rb_str_new(FBUFFER_PAIR(buffer));
fbuffer_free(buffer);
FORCE_UTF8(result);
return result;
diff --git a/ext/json/ext/generator/unicode.c b/ext/json/ext/generator/unicode.c
index 7bac615..2084c60 100644
--- a/ext/json/ext/generator/unicode.c
+++ b/ext/json/ext/generator/unicode.c
@@ -99,7 +99,7 @@ inline static void unicode_escape(FBuffer *buffer, UTF16 character)
fbuffer_append(buffer, buf, 6);
}
-inline void JSON_convert_UTF8_to_JSON(FBuffer *buffer, VALUE string)
+inline void JSON_convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string)
{
const UTF8* source = (UTF8 *) RSTRING_PTR(string);
const UTF8* sourceEnd = source + RSTRING_LEN(string);
diff --git a/ext/json/ext/generator/unicode.h b/ext/json/ext/generator/unicode.h
index 0652a19..a9abf5b 100644
--- a/ext/json/ext/generator/unicode.h
+++ b/ext/json/ext/generator/unicode.h
@@ -26,7 +26,7 @@ static const int halfShift = 10; /* used for shifting by 10 bits */
static const UTF32 halfBase = 0x0010000UL;
static const UTF32 halfMask = 0x3FFUL;
-inline void JSON_convert_UTF8_to_JSON(FBuffer *buffer, VALUE string);
+inline void JSON_convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string);
#ifndef RARRAY_PTR
#define RARRAY_PTR(ARRAY) RARRAY(ARRAY)->ptr