summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorLamont Granquist <lamont@scriptkiddie.org>2013-11-18 20:19:51 -0800
committerLamont Granquist <lamont@scriptkiddie.org>2013-11-18 20:19:51 -0800
commit47905bd4cef721bf5de4e3fc4e9411665414d4ff (patch)
tree8dceb28df551de1d7fe9c8ff1d9c62cf948d0f5e /ext
parentc9673929b4ea808d690d649fe3145c4dd0bb90ee (diff)
downloadffi-yajl-47905bd4cef721bf5de4e3fc4e9411665414d4ff.tar.gz
somewhat working ext code
Diffstat (limited to 'ext')
-rw-r--r--ext/ffi_yajl/ext/encoder/encoder.c75
-rw-r--r--ext/ffi_yajl/ext/encoder/extconf.rb2
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'