module FFI_Yajl::FFI::Parser

def setup_callbacks

def setup_callbacks
  @null_callback = ::FFI::Function.new(:int, [:pointer]) do |ctx|
    set_value(nil)
    1
  end
  @boolean_callback = ::FFI::Function.new(:int, [:pointer, :int]) do |ctx, boolval|
    set_value(boolval == 1 ? true : false)
    1
  end
  @integer_callback = ::FFI::Function.new(:int, [:pointer, :long_long]) do |ctx, intval|
    set_value(intval)
    1
  end
  @number_callback = ::FFI::Function.new(:int, [:pointer, :string, :size_t ]) do |ctx, stringval, stringlen|
    s = stringval.slice(0,stringlen)
    s.force_encoding('UTF-8') if defined? Encoding
    # XXX: I can't think of a better way to do this right now.  need to call to_f if and only if its a float.
    v = ( s =~ /[\.eE]/ ) ? s.to_f : s.to_i
    set_value(v)
    1
  end
  @double_callback = ::FFI::Function.new(:int, [:pointer, :double]) do |ctx, doubleval|
    set_value(doubleval)
    1
  end
  @string_callback = ::FFI::Function.new(:int, [:pointer, :string, :size_t]) do |ctx, stringval, stringlen|
    s = stringval.slice(0,stringlen)
    s.force_encoding('UTF-8') if defined? Encoding
    set_value(s)
    1
  end
  @start_map_callback = ::FFI::Function.new(:int, [:pointer]) do |ctx|
    key_push  # for key => { } case, save the key
    stack.push(Hash.new)
    1
  end
  @map_key_callback = ::FFI::Function.new(:int, [:pointer, :string, :size_t]) do |ctx, key, keylen|
    s = key.slice(0,keylen)
    s.force_encoding('UTF-8') if defined? Encoding
    self.key = @opts[:symbolize_keys] ? s.to_sym : s
    1
  end
  @end_map_callback = ::FFI::Function.new(:int, [:pointer]) do |ctx|
    key_pop
    stack_pop
    1
  end
  @start_array_callback = ::FFI::Function.new(:int, [:pointer]) do |ctx|
    key_push  # for key => [ ] case, save the key
    stack.push(Array.new)
    1
  end
  @end_array_callback = ::FFI::Function.new(:int, [:pointer]) do |ctx|
    key_pop
    stack_pop
    1
  end
end