diff options
author | Florian Frank <flori@ping.de> | 2009-11-05 22:54:50 +0100 |
---|---|---|
committer | Florian Frank <flori@ping.de> | 2009-11-07 15:12:51 +0100 |
commit | 1153dfc4c65846e737060fb13d15452bfe408502 (patch) | |
tree | d442e74ef329ec5b1644f9a6287c3a996c8c63f9 /ext | |
parent | cb8e702b2408e1e8a21607e443e6a69e3050939d (diff) | |
download | json-1153dfc4c65846e737060fb13d15452bfe408502.tar.gz |
avoid copying from buffer ptr to rstring ptr
Diffstat (limited to 'ext')
-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) { |