summaryrefslogtreecommitdiff
path: root/lib/ffi_yajl/encoder.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ffi_yajl/encoder.rb')
-rw-r--r--lib/ffi_yajl/encoder.rb138
1 files changed, 4 insertions, 134 deletions
diff --git a/lib/ffi_yajl/encoder.rb b/lib/ffi_yajl/encoder.rb
index 2e79577..897a045 100644
--- a/lib/ffi_yajl/encoder.rb
+++ b/lib/ffi_yajl/encoder.rb
@@ -1,137 +1,7 @@
-module FFI_Yajl
- class Encoder
- attr_accessor :opts
-
- def self.encode(obj, *args)
- new(*args).encode(obj)
- end
-
- 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
-
-
-class Hash
- def ffi_yajl(yajl_gen, state)
- FFI_Yajl.yajl_gen_map_open(yajl_gen)
- self.each do |key, value|
- # Perf Fix: mutate state hash rather than creating new copy
- state[:processing_key] = true
- key.ffi_yajl(yajl_gen, state)
- state[:processing_key] = false
- value.ffi_yajl(yajl_gen, state)
- end
- FFI_Yajl.yajl_gen_map_close(yajl_gen)
- end
-end
-
-class Array
- def ffi_yajl(yajl_gen, state)
- FFI_Yajl.yajl_gen_array_open(yajl_gen)
- self.each do |value|
- value.ffi_yajl(yajl_gen, state)
- end
- FFI_Yajl.yajl_gen_array_close(yajl_gen)
- end
-end
-
-class NilClass
- def ffi_yajl(yajl_gen, state)
- FFI_Yajl.yajl_gen_null(yajl_gen)
- end
-end
-
-class TrueClass
- def ffi_yajl(yajl_gen, state)
- FFI_Yajl.yajl_gen_bool(yajl_gen, 0)
- end
-end
-
-class FalseClass
- def ffi_yajl(yajl_gen, state)
- FFI_Yajl.yajl_gen_bool(yajl_gen, 1)
- end
-end
-
-class Fixnum
- def ffi_yajl(yajl_gen, state)
- if state[:processing_key]
- str = self.to_s
- FFI_Yajl.yajl_gen_string(yajl_gen, str, str.length)
- else
- FFI_Yajl.yajl_gen_integer(yajl_gen, self)
- end
- end
-end
-
-class Bignum
- def ffi_yajl(yajl_gen, state)
- raise NotImpelementedError
- end
-end
-
-class Float
- def ffi_yajl(yajl_gen, state)
- FFI_Yajl.yajl_gen_double(yajl_gen, self)
- end
-end
-
-class String
- def ffi_yajl(yajl_gen, state)
- FFI_Yajl.yajl_gen_string(yajl_gen, self, self.length)
- end
-end
-
-# I feel dirty
-class Object
- unless defined?(ActiveSupport)
- def to_json(*args, &block)
- "\"#{to_s}\""
- end
- end
-
- def ffi_yajl(yajl_gen, state)
- json = self.to_json(state[:json_opts])
- FFI_Yajl.yajl_gen_number(yajl_gen, json, json.length)
- end
+begin
+ require 'ffi_yajl/encoder/ext'
+rescue LoadError
+ require 'ffi_yajl/encoder/ffi'
end