summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorFlorian Frank <flori@ping.de>2009-11-05 22:54:50 +0100
committerFlorian Frank <flori@ping.de>2009-11-07 15:12:51 +0100
commit1153dfc4c65846e737060fb13d15452bfe408502 (patch)
treed442e74ef329ec5b1644f9a6287c3a996c8c63f9 /ext
parentcb8e702b2408e1e8a21607e443e6a69e3050939d (diff)
downloadjson-1153dfc4c65846e737060fb13d15452bfe408502.tar.gz
avoid copying from buffer ptr to rstring ptr
Diffstat (limited to 'ext')
-rw-r--r--ext/json/ext/generator/extconf.rb3
-rw-r--r--ext/json/ext/generator/generator.c39
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)
{