diff options
author | Lamont Granquist <lamont@scriptkiddie.org> | 2013-11-18 20:19:51 -0800 |
---|---|---|
committer | Lamont Granquist <lamont@scriptkiddie.org> | 2013-11-18 20:19:51 -0800 |
commit | 47905bd4cef721bf5de4e3fc4e9411665414d4ff (patch) | |
tree | 8dceb28df551de1d7fe9c8ff1d9c62cf948d0f5e /ext | |
parent | c9673929b4ea808d690d649fe3145c4dd0bb90ee (diff) | |
download | ffi-yajl-47905bd4cef721bf5de4e3fc4e9411665414d4ff.tar.gz |
somewhat working ext code
Diffstat (limited to 'ext')
-rw-r--r-- | ext/ffi_yajl/ext/encoder/encoder.c | 75 | ||||
-rw-r--r-- | ext/ffi_yajl/ext/encoder/extconf.rb | 2 |
2 files changed, 71 insertions, 6 deletions
diff --git a/ext/ffi_yajl/ext/encoder/encoder.c b/ext/ffi_yajl/ext/encoder/encoder.c index 878e3bf..0687f51 100644 --- a/ext/ffi_yajl/ext/encoder/encoder.c +++ b/ext/ffi_yajl/ext/encoder/encoder.c @@ -5,15 +5,79 @@ static VALUE mFFI_Yajl, mExt, mEncoder; /* FIXME: the json gem does a whole bunch of indirection around monkeypatching... not sure if we need to as well... */ +typedef struct { + VALUE json_opts; + int processing_key; +} ffi_state_t; + static VALUE mEncoder_encode(VALUE self, VALUE obj) { - return Qnil; + ID sym_ffi_yajl = rb_intern("ffi_yajl"); + yajl_gen yajl_gen; + const unsigned char *buf; + size_t len; + ffi_state_t state; + VALUE ret; + + yajl_gen = yajl_gen_alloc(NULL); + + yajl_gen_config(yajl_gen, yajl_gen_beautify, 1); + yajl_gen_config(yajl_gen, yajl_gen_validate_utf8, 1); + + state.processing_key = 0; + + rb_funcall(obj, sym_ffi_yajl, 2, yajl_gen, (VALUE) &state); + + yajl_gen_get_buf(yajl_gen, &buf, &len); + + ret = rb_str_new2((char *)buf); + + yajl_gen_free(yajl_gen); + + return ret; +} + +typedef struct { + VALUE yajl_gen; + ffi_state_t *state; +} ffs_extra_t; + +int rb_cHash_ffi_yajl_callback(VALUE key, VALUE val, VALUE extra) { + ffs_extra_t *extra_p = (ffs_extra_t *)extra; + ID sym_ffi_yajl = rb_intern("ffi_yajl"); + + extra_p->state->processing_key = 1; + rb_funcall(key, sym_ffi_yajl, 2, extra_p->yajl_gen, extra_p->state); + extra_p->state->processing_key = 0; + rb_funcall(val, sym_ffi_yajl, 2, extra_p->yajl_gen, extra_p->state); + + return ST_CONTINUE; } static VALUE rb_cHash_ffi_yajl(VALUE self, VALUE yajl_gen, VALUE state) { + ffs_extra_t extra; + + extra.yajl_gen = yajl_gen; + extra.state = (ffi_state_t *)state; + + yajl_gen_map_open((struct yajl_gen_t *) yajl_gen); + rb_hash_foreach(self, rb_cHash_ffi_yajl_callback, (VALUE) &extra); + yajl_gen_map_close((struct yajl_gen_t *) yajl_gen); + return Qnil; } static VALUE rb_cArray_ffi_yajl(VALUE self, VALUE yajl_gen, VALUE state) { + ID sym_ffi_yajl = rb_intern("ffi_yajl"); + long i; + VALUE val; + + yajl_gen_array_open((struct yajl_gen_t *) yajl_gen); + for(i=0; i<RARRAY_LEN(self); i++) { + val = rb_ary_entry(self, i); + rb_funcall(val, sym_ffi_yajl, 2, yajl_gen, state); + } + yajl_gen_array_close((struct yajl_gen_t *) yajl_gen); + return Qnil; } @@ -33,10 +97,9 @@ static VALUE rb_cFalseClass_ffi_yajl(VALUE self, VALUE yajl_gen, VALUE state) { } static VALUE rb_cFixnum_ffi_yajl(VALUE self, VALUE yajl_gen, VALUE state) { - VALUE processing_key, str; + VALUE str; - processing_key = rb_hash_aref(state, ID2SYM(rb_intern("processing_key"))); - if ( RTEST(processing_key) ) { + if ( ((ffi_state_t *)state)->processing_key ) { str = rb_any_to_s(self); yajl_gen_string((struct yajl_gen_t *) yajl_gen, (unsigned char *)RSTRING_PTR(str), RSTRING_LEN(str)); } else { @@ -46,7 +109,7 @@ static VALUE rb_cFixnum_ffi_yajl(VALUE self, VALUE yajl_gen, VALUE state) { } static VALUE rb_cBignum_ffi_yajl(VALUE self, VALUE yajl_gen, VALUE state) { - rb_raise( rb_eNotImpError, "not implemented"); + rb_raise( rb_eNotImpError, "Bignum#ffi_yajl not implemented"); return Qnil; } @@ -61,7 +124,7 @@ static VALUE rb_cString_ffi_yajl(VALUE self, VALUE yajl_gen, VALUE state) { } static VALUE rb_cObject_ffi_yajl(VALUE self, VALUE yajl_gen, VALUE state) { - rb_raise( rb_eNotImpError, "not implemented"); + rb_raise( rb_eNotImpError, "Object#ffi_yajl not implemented"); return Qnil; } diff --git a/ext/ffi_yajl/ext/encoder/extconf.rb b/ext/ffi_yajl/ext/encoder/extconf.rb index bfe042a..563ef5c 100644 --- a/ext/ffi_yajl/ext/encoder/extconf.rb +++ b/ext/ffi_yajl/ext/encoder/extconf.rb @@ -13,6 +13,8 @@ if RbConfig::MAKEFILE_CONFIG['CC'] =~ /gcc|clang/ $CFLAGS << " -Wall" end +$LDFLAGS << " -lyajl" + dir_config 'encoder' create_makefile 'ffi_yajl/ext/encoder' |