ext/extensions/hash_ext/hash_ext.c in fjson-0.1.0 vs ext/extensions/hash_ext/hash_ext.c in fjson-0.1.1

- old
+ new

@@ -1,98 +1,41 @@ #include "hash_ext.h" +#include "enumerable.c" -static VALUE cHash; static VALUE mJSON; -static VALUE cState; static VALUE cCircularDatastructure; void Init_hash_ext() { mJSON = rb_const_get(rb_cObject, rb_intern("JSON")); - cState = rb_const_get(mJSON, rb_intern("State")); - cHash = rb_const_get(rb_cObject, rb_intern("Hash")); + rb_cJsonState = rb_const_get(mJSON, rb_intern("State")); cCircularDatastructure = rb_const_get(mJSON, rb_intern("CircularDatastructure")); - rb_define_method(cHash, "to_json", (VALUE(*)(ANYARGS)) &to_json, -1); + rb_define_method(rb_cHash, "to_json", (VALUE(*)(ANYARGS)) &to_json, -1); } -/** - * Returns a JSON string containing a JSON hash, that is unparsed from - * this Hash instance. - * _state_ is a JSON::State object, that can also be used to configure the - * produced JSON string output further. - * _depth_ is used to find out nesting depth, to indent accordingly. - */ -static VALUE to_json(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - VALUE state, depth; - rb_scan_args(argc, argv, "02", &state, &depth); - if(depth == Qnil) depth = INT2NUM(0); - - state = rb_funcall(cState, rb_intern("from_state"), 1, state); - return json_check_circular_and_transform(self, state, depth); -} - /** private **/ -static VALUE json_check_circular_and_transform(self, state, depth) - VALUE self, state, depth; -{ - VALUE call_args = rb_ary_new3(3, self, state, depth); - return rb_ensure(json_check_circular_and_transform_call, call_args, json_check_circular_and_transform_ensure, call_args); -} - -static VALUE json_check_circular_and_transform_ensure(args) - VALUE args; -{ - VALUE self = rb_ary_entry(args, 0); - VALUE state = rb_ary_entry(args, 1); - if(state != Qnil) { - rb_funcall(state, rb_intern("forget"), 1, self); - } -} - -static VALUE json_check_circular_and_transform_call(args) - VALUE args; -{ - VALUE self = rb_ary_entry(args, 0); - VALUE state = rb_ary_entry(args, 1); - VALUE depth = rb_ary_entry(args, 2); - if(state != Qnil) { - if(rb_funcall(state, rb_intern("seen?"), 1, self) == Qtrue) { - rb_raise( - cCircularDatastructure, - "circular data structures not supported!" - ); - } - rb_funcall(state, rb_intern("remember"), 1, self); - } - return json_transform(self, state, depth); -} - static VALUE json_transform(self, state, depth) VALUE self, state, depth; { VALUE delim = rb_str_new2(","); VALUE object_nl = Qnil; if(state != Qnil) object_nl = rb_funcall(state, rb_intern("object_nl"), 0); - if(object_nl != Qnil) rb_str_append(delim, object_nl); + new_line(delim, object_nl); VALUE result = rb_str_new2("{"); - if(object_nl != Qnil) rb_str_append(result, object_nl); + new_line(result, object_nl); - process_internal_json(self, result, state, depth, delim); + process_internal_json(self, result, state, depth, delim, object_nl); - if(object_nl != Qnil) rb_str_append(result, object_nl); - json_shift(self, result, state, depth); + new_line(result, object_nl); + if(rb_json_should_shift(state, object_nl) == Qtrue) json_shift(result, state, depth); rb_str_append(result, rb_str_new2("}")); return result; } -static VALUE process_internal_json(self, json, state, depth, delim) - VALUE self, json, state, depth, delim; +static VALUE process_internal_json(self, json, state, depth, delim, object_nl) + VALUE self, json, state, depth, delim, object_nl; { // TODO: Use st_foreach for even better performance VALUE key_value_pairs = rb_funcall(self, rb_intern("to_a"), 0); VALUE new_depth = LONG2NUM(NUM2LONG(depth) + 1); VALUE space = rb_funcall(state, rb_intern("space"), 0); @@ -105,24 +48,13 @@ } key_value = rb_ary_entry(key_value_pairs, i); VALUE key = rb_ary_entry(key_value, 0); VALUE value = rb_ary_entry(key_value, 1); - json_shift(self, json, state, depth); + if(rb_json_should_shift(state, object_nl) == Qtrue) json_shift(json, state, depth); VALUE key_string = rb_funcall(key, rb_intern("to_s"), 0); - rb_str_append(json, rb_funcall(key_string, rb_intern("to_json"), 2, state, new_depth)); + rb_str_append(json, rb_to_json(key_string, state, new_depth)); rb_str_cat2(json, ":"); rb_str_append(json, space); - rb_str_append(json, rb_funcall(value, rb_intern("to_json"), 2, state, new_depth)); + rb_str_append(json, rb_to_json(value, state, new_depth)); } -} - -static VALUE json_shift(self, json, state, depth) - VALUE self, json, state, depth; -{ - if(state == Qnil) return Qnil; - VALUE object_nl = rb_funcall(state, rb_intern("object_nl"), 0); - if(RSTRING(object_nl)->len == 0) return Qnil; - - rb_json_state_indent(state, json, NUM2LONG(depth) + 1); - return Qnil; }