summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorFlorian Frank <flori@ping.de>2009-11-20 08:25:28 +0100
committerFlorian Frank <flori@ping.de>2009-11-20 08:25:28 +0100
commit64c9ee30094d02a257eaeb9306e15ed5bdf7f982 (patch)
treea0da7726b257f0114c4b6193ea81d19fa2024479 /ext
parent5a28815043c4ab7aa3c45485f4f0f363b54f95b0 (diff)
downloadjson-64c9ee30094d02a257eaeb9306e15ed5bdf7f982.tar.gz
implemented prototype feature
Diffstat (limited to 'ext')
-rw-r--r--ext/json/ext/generator.c57
-rw-r--r--ext/json/ext/generator.h1
2 files changed, 50 insertions, 8 deletions
diff --git a/ext/json/ext/generator.c b/ext/json/ext/generator.c
index e07a7af..bb187a1 100644
--- a/ext/json/ext/generator.c
+++ b/ext/json/ext/generator.c
@@ -8,7 +8,7 @@ static ID i_encoding, i_encode;
static VALUE mJSON, mExt, mGenerator, cState, mGeneratorMethods, mObject,
mHash, mArray, mInteger, mFloat, mString, mString_Extend,
mTrueClass, mFalseClass, mNilClass, eGeneratorError,
- eNestingError, CRegexp_MULTILINE;
+ eNestingError, CRegexp_MULTILINE, CJSON_SAFE_STATE_PROTOTYPE;
static ID i_to_s, i_to_json, i_new, i_indent, i_space, i_space_before,
i_object_nl, i_array_nl, i_max_nesting, i_allow_nan, i_ascii_only,
@@ -346,7 +346,7 @@ static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned int len)
{
if (len > 0) {
fbuffer_inc_capa(fb, len);
- memcpy(fb->ptr + fb->len, newstr, len);
+ MEMCPY(fb->ptr + fb->len, newstr, char, len);
fb->len += len;
}
}
@@ -358,6 +358,20 @@ static void fbuffer_append_char(FBuffer *fb, char newchr)
fb->len++;
}
+static FBuffer *fbuffer_dup(FBuffer *fb)
+{
+ int len = fb->len;
+ FBuffer *result;
+
+ if (len > 0) {
+ result = fbuffer_alloc_with_length(len);
+ fbuffer_append(result, FBUFFER_PAIR(fb));
+ } else {
+ result = fbuffer_alloc();
+ }
+ return result;
+}
+
/*
* Document-module: JSON::Ext::Generator
*
@@ -659,11 +673,11 @@ static VALUE cState_to_h(VALUE self)
{
VALUE result = rb_hash_new();
GET_STATE(self);
- rb_hash_aset(result, ID2SYM(i_indent), rb_str_new2(state->indent));
- rb_hash_aset(result, ID2SYM(i_space), rb_str_new2(state->space));
- rb_hash_aset(result, ID2SYM(i_space_before), rb_str_new2(state->space_before));
- rb_hash_aset(result, ID2SYM(i_object_nl), rb_str_new2(state->object_nl));
- rb_hash_aset(result, ID2SYM(i_array_nl), rb_str_new2(state->array_nl));
+ rb_hash_aset(result, ID2SYM(i_indent), rb_str_new(state->indent, state->indent_len));
+ rb_hash_aset(result, ID2SYM(i_space), rb_str_new(state->space, state->space_len));
+ rb_hash_aset(result, ID2SYM(i_space_before), rb_str_new(state->space_before, state->space_before_len));
+ rb_hash_aset(result, ID2SYM(i_object_nl), rb_str_new(state->object_nl, state->object_nl_len));
+ rb_hash_aset(result, ID2SYM(i_array_nl), rb_str_new(state->array_nl, state->array_nl_len));
rb_hash_aset(result, ID2SYM(i_allow_nan), state->allow_nan ? Qtrue : Qfalse);
rb_hash_aset(result, ID2SYM(i_ascii_only), state->ascii_only ? Qtrue : Qfalse);
rb_hash_aset(result, ID2SYM(i_max_nesting), LONG2FIX(state->max_nesting));
@@ -951,6 +965,28 @@ static VALUE cState_initialize(int argc, VALUE *argv, VALUE self)
return self;
}
+/* XXX
+*/
+static VALUE cState_init_copy(VALUE obj, VALUE orig)
+{
+ JSON_Generator_State *objState, *origState;
+
+ Data_Get_Struct(obj, JSON_Generator_State, objState);
+ Data_Get_Struct(orig, JSON_Generator_State, origState);
+ if (!objState) rb_raise(rb_eArgError, "unallocated JSON::State");
+
+ MEMCPY(objState, origState, JSON_Generator_State, 1);
+ objState->indent = fstrndup(origState->indent, origState->indent_len);
+ objState->space = fstrndup(origState->space, origState->space_len);
+ objState->space_before = fstrndup(origState->space_before, origState->space_before_len);
+ objState->object_nl = fstrndup(origState->object_nl, origState->object_nl_len);
+ objState->array_nl = fstrndup(origState->array_nl, origState->array_nl_len);
+ if (origState->array_delim) objState->array_delim = fbuffer_dup(origState->array_delim);
+ if (origState->object_delim) objState->object_delim = fbuffer_dup(origState->object_delim);
+ if (origState->object_delim2) objState->object_delim2 = fbuffer_dup(origState->object_delim2);
+ return obj;
+}
+
/*
* call-seq: from_state(opts)
*
@@ -965,7 +1001,10 @@ static VALUE cState_from_state_s(VALUE self, VALUE opts)
} else if (rb_obj_is_kind_of(opts, rb_cHash)) {
return rb_funcall(self, i_new, 1, opts);
} else {
- return rb_funcall(self, i_new, 0);
+ if (NIL_P(CJSON_SAFE_STATE_PROTOTYPE)) {
+ CJSON_SAFE_STATE_PROTOTYPE = rb_const_get(mJSON, rb_intern("SAFE_STATE_PROTOTYPE"));
+ }
+ return CJSON_SAFE_STATE_PROTOTYPE;
}
}
@@ -1200,6 +1239,7 @@ void Init_generator()
rb_define_alloc_func(cState, cState_s_allocate);
rb_define_singleton_method(cState, "from_state", cState_from_state_s, 1);
rb_define_method(cState, "initialize", cState_initialize, -1);
+ rb_define_method(cState, "initialize_copy", cState_init_copy, 1);
rb_define_method(cState, "indent", cState_indent, 0);
rb_define_method(cState, "indent=", cState_indent_set, 1);
rb_define_method(cState, "space", cState_space, 0);
@@ -1265,4 +1305,5 @@ void Init_generator()
i_encoding = rb_intern("encoding");
i_encode = rb_intern("encode");
#endif
+ CJSON_SAFE_STATE_PROTOTYPE = Qnil;
}
diff --git a/ext/json/ext/generator.h b/ext/json/ext/generator.h
index c466402..664d108 100644
--- a/ext/json/ext/generator.h
+++ b/ext/json/ext/generator.h
@@ -81,6 +81,7 @@ static void fbuffer_free_only_buffer(FBuffer *fb);
static void fbuffer_clear(FBuffer *fb);
static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned int len);
static void fbuffer_append_char(FBuffer *fb, char newchr);
+static FBuffer *fbuffer_dup(FBuffer *fb);
/* unicode defintions */