diff options
-rw-r--r-- | ext/json/ext/generator/extconf.rb | 3 | ||||
-rw-r--r-- | ext/json/ext/generator/generator.c | 39 |
2 files changed, 42 insertions, 0 deletions
diff --git a/ext/json/ext/generator/extconf.rb b/ext/json/ext/generator/extconf.rb index 3d2b6f7..33a5625 100644 --- a/ext/json/ext/generator/extconf.rb +++ b/ext/json/ext/generator/extconf.rb @@ -8,6 +8,9 @@ if CONFIG['CC'] =~ /gcc/ $CFLAGS << ' -Wall' #$CFLAGS.gsub!(/ -O[\dsz]?/, ' -O0 -ggdb') end +if RUBY_VERSION >= '1.9' + $CFLAGS << ' -DRUBY_19' +end have_header("ruby/st.h") || have_header("st.h") have_header("ruby/re.h") || have_header("re.h") diff --git a/ext/json/ext/generator/generator.c b/ext/json/ext/generator/generator.c index 792c4a4..7d2abd1 100644 --- a/ext/json/ext/generator/generator.c +++ b/ext/json/ext/generator/generator.c @@ -1,16 +1,21 @@ #include <string.h> #include "ruby.h" + #if HAVE_RUBY_ST_H #include "ruby/st.h" #endif + #if HAVE_ST_H #include "st.h" #endif + #include "unicode.h" #include <math.h> + #if HAVE_RUBY_RE_H #include "ruby/re.h" #endif + #if HAVE_RE_H #include "re.h" #endif @@ -376,6 +381,39 @@ static VALUE cState_to_h(VALUE self) return result; } +/* + * The fbuffer2rstring breaks encapsulation of Ruby's String datatype to avoid + * calling memcpy while creating a RString from a c string. This is rather + * hackish code, I am not sure if it's a good idea to keep it. + */ +#ifdef RUBY_19 +#define STR_NOEMBED FL_USER1 + +#define STR_SET_EMBED_LEN(str, n) do { \ + long tmp_n = (n);\ + RBASIC(str)->flags &= ~RSTRING_EMBED_LEN_MASK;\ + RBASIC(str)->flags |= (tmp_n) << RSTRING_EMBED_LEN_SHIFT;\ +} while (0) + +#define STR_SET_NOEMBED(str) do {\ + FL_SET(str, STR_NOEMBED);\ + STR_SET_EMBED_LEN(str, 0);\ +} while (0) + +inline static VALUE fbuffer2rstring(FBuffer *buffer) +{ + NEWOBJ(str, struct RString); + OBJSETUP(str, rb_cString, T_STRING); + + str->as.heap.ptr = FBUFFER_PTR(buffer); + str->as.heap.len = FBUFFER_LEN(buffer); + str->as.heap.aux.capa = FBUFFER_CAPA(buffer); + STR_SET_NOEMBED(str); + + return (VALUE) str; +} +#else + inline static VALUE fbuffer2rstring(FBuffer *buffer) { NEWOBJ(str, struct RString); @@ -387,6 +425,7 @@ inline static VALUE fbuffer2rstring(FBuffer *buffer) return (VALUE) str; } +#endif void generate_json(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth) { |