summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLamont Granquist <lamont@scriptkiddie.org>2013-11-18 15:18:19 -0800
committerLamont Granquist <lamont@scriptkiddie.org>2013-11-18 15:18:19 -0800
commit5ebcb3c42654f50db90127cfbfc4a4ea0a5ec039 (patch)
treebedc0164dd2a05d8b41d5058b188755c7c90d65b
parent1a872d2dbd17b3ce7c95f5d010ac31b0c026abac (diff)
downloadffi-yajl-5ebcb3c42654f50db90127cfbfc4a4ea0a5ec039.tar.gz
moving things around to support ext encoding
-rw-r--r--ext/encoder/encoder.c6
-rw-r--r--ext/encoder/extconf.rb16
-rw-r--r--ext/libyajl2/extconf.rb3
-rw-r--r--ffi-yajl.gemspec2
-rw-r--r--lib/ffi_yajl.rb48
-rw-r--r--lib/ffi_yajl/encoder.rb7
-rw-r--r--lib/ffi_yajl/ext.rb1
-rw-r--r--lib/ffi_yajl/ffi.rb1
-rw-r--r--lib/ffi_yajl/ffi/encoder.rb (renamed from lib/ffi_yajl/encoder/ffi.rb)101
9 files changed, 114 insertions, 71 deletions
diff --git a/ext/encoder/encoder.c b/ext/encoder/encoder.c
new file mode 100644
index 0000000..d664647
--- /dev/null
+++ b/ext/encoder/encoder.c
@@ -0,0 +1,6 @@
+
+void Init_encoder() {
+ mJSON_Yajl = rb_define_module("JSON_Yajl");
+ mEncoder
+}
+
diff --git a/ext/encoder/extconf.rb b/ext/encoder/extconf.rb
new file mode 100644
index 0000000..bc3013b
--- /dev/null
+++ b/ext/encoder/extconf.rb
@@ -0,0 +1,16 @@
+require 'mkmf'
+
+# the customer is always right, ruby is always compiled to be stupid
+$CFLAGS = ENV['CFLAGS'] if ENV['CFLAGS']
+$LDFLAGS = ENV['LDFLAGS'] if ENV['LDFLAGS']
+RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC'] if ENV['CC']
+
+# except if you're doing an unoptimized gcc install we're going to help you out a bit
+if RbConfig::MAKEFILE_CONFIG['CC'] =~ /gcc|clang/
+ $CFLAGS << " -O3" unless $CFLAGS[/-O\d/]
+ # how many people realize that -Wall is a compiler-specific flag???
+ # apparently not many based on reading lots of shitty extconf.rb's out there
+ $CFLAGS << " -Wall"
+end
+
+create_makefile 'encoder'
diff --git a/ext/libyajl2/extconf.rb b/ext/libyajl2/extconf.rb
index 48c3207..e8fa60f 100644
--- a/ext/libyajl2/extconf.rb
+++ b/ext/libyajl2/extconf.rb
@@ -13,6 +13,9 @@ if !defined?(RUBY_ENGINE) || RUBY_ENGINE == 'ruby' || RUBY_ENGINE == 'rbx'
# except if you're doing an unoptimized gcc install we're going to help you out a bit
if RbConfig::MAKEFILE_CONFIG['CC'] =~ /gcc|clang/
$CFLAGS << " -O3" unless $CFLAGS[/-O\d/]
+ # how many people realize that -Wall is a compiler-specific flag???
+ # apparently not many based on reading lots of shitty extconf.rb's out there
+ $CFLAGS << " -Wall"
end
# yajl_complete_parse is only in >= 2.0
diff --git a/ffi-yajl.gemspec b/ffi-yajl.gemspec
index cc5240c..652505e 100644
--- a/ffi-yajl.gemspec
+++ b/ffi-yajl.gemspec
@@ -12,7 +12,7 @@ Gem::Specification.new do |s|
s.email = "lamont@scriptkiddie.org"
s.homepage = "http://github.com/lamont-granquist/ffi-yajl"
- s.extensions = %w(ext/libyajl2/extconf.rb)
+ s.extensions = %w(ext/libyajl2/extconf.rb ext/encoder/extconf.rb)
s.add_development_dependency "rake"
s.add_development_dependency "rspec", "~> 2.14"
diff --git a/lib/ffi_yajl.rb b/lib/ffi_yajl.rb
index d6fadc0..a6f5aa4 100644
--- a/lib/ffi_yajl.rb
+++ b/lib/ffi_yajl.rb
@@ -1,12 +1,26 @@
require 'rubygems'
require 'ffi'
-require 'ffi_yajl/encoder'
+begin
+ require 'ffi_yajl/ext'
+ module FFI_Yajl
+ class Encoder
+ include FFI_Yajl::Ext::Encoder
+ end
+ end
+rescue LoadError
+ require 'ffi_yajl/ffi'
+ module FFI_Yajl
+ class Encoder
+ include FFI_Yajl::FFI::Encoder
+ end
+ end
+end
module FFI_Yajl
- extend FFI::Library
+ extend ::FFI::Library
- libname = FFI.map_library_name("yajl")
+ libname = ::FFI.map_library_name("yajl")
libpath = File.join(File.dirname(__FILE__), libname)
if File.file?(libpath)
@@ -16,7 +30,7 @@ module FFI_Yajl
ffi_lib 'yajl'
end
- class YajlCallbacks < FFI::Struct
+ class YajlCallbacks < ::FFI::Struct
layout :yajl_null, :pointer,
:yajl_boolean, :pointer,
:yajl_integer, :pointer,
@@ -144,53 +158,53 @@ module FFI_Yajl
end
end
- NullCallback = FFI::Function.new(:int, [:pointer]) do |ctx|
+ NullCallback = ::FFI::Function.new(:int, [:pointer]) do |ctx|
@@CTX_MAPPING[ctx.get_ulong(0)].set_value(nil)
1
end
- BooleanCallback = FFI::Function.new(:int, [:pointer, :int]) do |ctx, boolval|
+ BooleanCallback = ::FFI::Function.new(:int, [:pointer, :int]) do |ctx, boolval|
@@CTX_MAPPING[ctx.get_ulong(0)].set_value(boolval == 1 ? true : false)
1
end
- IntegerCallback = FFI::Function.new(:int, [:pointer, :long_long]) do |ctx, intval|
+ IntegerCallback = ::FFI::Function.new(:int, [:pointer, :long_long]) do |ctx, intval|
@@CTX_MAPPING[ctx.get_ulong(0)].set_value(intval)
1
end
- DoubleCallback = FFI::Function.new(:int, [:pointer, :double]) do |ctx, doubleval|
+ DoubleCallback = ::FFI::Function.new(:int, [:pointer, :double]) do |ctx, doubleval|
@@CTX_MAPPING[ctx.get_ulong(0)].set_value(doubleval)
1
end
- NumberCallback = FFI::Function.new(:int, [:pointer, :pointer, :size_t]) do |ctx, numberval, numberlen|
+ NumberCallback = ::FFI::Function.new(:int, [:pointer, :pointer, :size_t]) do |ctx, numberval, numberlen|
raise "NumberCallback: not implemented"
1
end
- StringCallback = FFI::Function.new(:int, [:pointer, :string, :size_t]) do |ctx, stringval, stringlen|
+ StringCallback = ::FFI::Function.new(:int, [:pointer, :string, :size_t]) do |ctx, stringval, stringlen|
@@CTX_MAPPING[ctx.get_ulong(0)].set_value(stringval.slice(0,stringlen))
1
end
- StartMapCallback = FFI::Function.new(:int, [:pointer]) do |ctx|
+ StartMapCallback = ::FFI::Function.new(:int, [:pointer]) do |ctx|
state = @@CTX_MAPPING[ctx.get_ulong(0)]
state.save_key
state.stack.push(Hash.new)
1
end
- MapKeyCallback = FFI::Function.new(:int, [:pointer, :string, :size_t]) do |ctx, key, keylen|
+ MapKeyCallback = ::FFI::Function.new(:int, [:pointer, :string, :size_t]) do |ctx, key, keylen|
@@CTX_MAPPING[ctx.get_ulong(0)].key = key.slice(0,keylen)
1
end
- EndMapCallback = FFI::Function.new(:int, [:pointer]) do |ctx|
+ EndMapCallback = ::FFI::Function.new(:int, [:pointer]) do |ctx|
state = @@CTX_MAPPING[ctx.get_ulong(0)]
state.restore_key
state.set_value( state.stack.pop ) if state.stack.length > 1
1
end
- StartArrayCallback = FFI::Function.new(:int, [:pointer]) do |ctx|
+ StartArrayCallback = ::FFI::Function.new(:int, [:pointer]) do |ctx|
state = @@CTX_MAPPING[ctx.get_ulong(0)]
state.save_key
state.stack.push(Array.new)
1
end
- EndArrayCallback = FFI::Function.new(:int, [:pointer]) do |ctx|
+ EndArrayCallback = ::FFI::Function.new(:int, [:pointer]) do |ctx|
state = @@CTX_MAPPING[ctx.get_ulong(0)]
state.restore_key
@@CTX_MAPPING[ctx.get_ulong(0)].set_value( @@CTX_MAPPING[ctx.get_ulong(0)].stack.pop ) if @@CTX_MAPPING[ctx.get_ulong(0)].stack.length > 1
@@ -201,9 +215,9 @@ module FFI_Yajl
@@CTX_MAPPING ||= Hash.new
rb_ctx = FFI_Yajl::Parser::State.new()
@@CTX_MAPPING[rb_ctx.object_id] = rb_ctx
- ctx = FFI::MemoryPointer.new(:long)
+ ctx = ::FFI::MemoryPointer.new(:long)
ctx.write_long( rb_ctx.object_id )
- callback_ptr = FFI::MemoryPointer.new(FFI_Yajl::YajlCallbacks)
+ callback_ptr = ::FFI::MemoryPointer.new(FFI_Yajl::YajlCallbacks)
callbacks = FFI_Yajl::YajlCallbacks.new(callback_ptr)
callbacks[:yajl_null] = NullCallback
callbacks[:yajl_boolean] = BooleanCallback
diff --git a/lib/ffi_yajl/encoder.rb b/lib/ffi_yajl/encoder.rb
deleted file mode 100644
index 897a045..0000000
--- a/lib/ffi_yajl/encoder.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-
-begin
- require 'ffi_yajl/encoder/ext'
-rescue LoadError
- require 'ffi_yajl/encoder/ffi'
-end
-
diff --git a/lib/ffi_yajl/ext.rb b/lib/ffi_yajl/ext.rb
new file mode 100644
index 0000000..ee78b46
--- /dev/null
+++ b/lib/ffi_yajl/ext.rb
@@ -0,0 +1 @@
+require 'ffi_yajl/ext/encoder'
diff --git a/lib/ffi_yajl/ffi.rb b/lib/ffi_yajl/ffi.rb
new file mode 100644
index 0000000..0581d4a
--- /dev/null
+++ b/lib/ffi_yajl/ffi.rb
@@ -0,0 +1 @@
+require 'ffi_yajl/ffi/encoder'
diff --git a/lib/ffi_yajl/encoder/ffi.rb b/lib/ffi_yajl/ffi/encoder.rb
index 2e79577..178d4db 100644
--- a/lib/ffi_yajl/encoder/ffi.rb
+++ b/lib/ffi_yajl/ffi/encoder.rb
@@ -1,55 +1,64 @@
-module FFI_Yajl
- class Encoder
- attr_accessor :opts
-
- def self.encode(obj, *args)
- new(*args).encode(obj)
- end
-
- def initialize(opts = {})
- @opts = opts
- end
+require 'ffi'
+# FIXME: should require the lower level ffi stuff here instead of having this included higher up
- def encode(obj)
- yajl_gen = FFI_Yajl.yajl_gen_alloc(nil, nil)
-
- # configure the yajl encoder
- FFI_Yajl.yajl_gen_config(yajl_gen, :yajl_gen_beautify, :int, 1) if opts[:pretty]
- FFI_Yajl.yajl_gen_config(yajl_gen, :yajl_gen_validate_utf8, :int, 1)
- indent = if opts[:pretty]
- opts[:indent] ? opts[:indent] : " "
- else
- " "
- end
- FFI_Yajl.yajl_gen_config(yajl_gen, :yajl_gen_indent_string, :string, indent)
-
- # setup our own state
- state = {
- :json_opts => opts,
- :processing_key => false,
- }
-
- # do the encoding
- obj.ffi_yajl(yajl_gen, state)
-
- # get back our encoded JSON
- string_ptr = FFI::MemoryPointer.new(:string)
- length_ptr = FFI::MemoryPointer.new(:int)
- FFI_Yajl.yajl_gen_get_buf(yajl_gen, string_ptr, length_ptr)
- length = length_ptr.read_int
- string = string_ptr.get_pointer(0).read_string
-
- return string
- ensure
- # free up the yajl encoder
- FFI_Yajl.yajl_gen_free(yajl_gen)
+module FFI_Yajl
+ module FFI
+ module Encoder
+ module ClassMethods
+ def encode(obj, *args)
+ new(*args).encode(obj)
+ end
+ end
+
+ def self.included(base)
+ base.extend ClassMethods
+ end
+
+ attr_accessor :opts
+
+ def initialize(opts = {})
+ @opts = opts
+ end
+
+ def encode(obj)
+ yajl_gen = FFI_Yajl.yajl_gen_alloc(nil, nil)
+
+ # configure the yajl encoder
+ FFI_Yajl.yajl_gen_config(yajl_gen, :yajl_gen_beautify, :int, 1) if opts[:pretty]
+ FFI_Yajl.yajl_gen_config(yajl_gen, :yajl_gen_validate_utf8, :int, 1)
+ indent = if opts[:pretty]
+ opts[:indent] ? opts[:indent] : " "
+ else
+ " "
+ end
+ FFI_Yajl.yajl_gen_config(yajl_gen, :yajl_gen_indent_string, :string, indent)
+
+ # setup our own state
+ state = {
+ :json_opts => opts,
+ :processing_key => false,
+ }
+
+ # do the encoding
+ obj.ffi_yajl(yajl_gen, state)
+
+ # get back our encoded JSON
+ string_ptr = ::FFI::MemoryPointer.new(:string)
+ length_ptr = ::FFI::MemoryPointer.new(:int)
+ FFI_Yajl.yajl_gen_get_buf(yajl_gen, string_ptr, length_ptr)
+ length = length_ptr.read_int
+ string = string_ptr.get_pointer(0).read_string
+
+ return string
+ ensure
+ # free up the yajl encoder
+ FFI_Yajl.yajl_gen_free(yajl_gen)
+ end
end
end
-
end
-
class Hash
def ffi_yajl(yajl_gen, state)
FFI_Yajl.yajl_gen_map_open(yajl_gen)