\FF\D8\FF\E0\00JFIF\00\00\00d\00d\00\00\FF\FE\00\border bs:0 bc:#000000 ps:0 pc:#ffffff es:0 ec:#000000 ck:feee6c715d26fd9f38b0ca4278c05026\FF\DB\00C\00P7<F<2PFAFZUP_xxnnx\F5\AF\B9\91\C8\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\DB\00CUZZxix‚\EB\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\C0\00\00b\00d\00\FF\C4\00\00\00\00\00\00\00\00\00\00\00\00\00\00\FF\C4\00\00\00\00\00\00\00\00\00\00\001A!Q\FF\C4\00\00\00\00\00\00\00\00\00\00\00\00\00\FF\C4\00\00\00\00\00\00\00\00\00\00!1AQ\FF\DA\00\00\00?\00\F6\00\00\00\00\00\00\00\00\00\00\A0\00\00\C5\CF\F8\E7Ó\FCjD~\B9^\AD\%\B3]\D8cs-\BBs,-\A0\00"\80\00%\B83rÏ^K~F\A4ea\00E\00\C6\EE=u\B1\9B\D1\00@\00r\BE8\F9:\FE5#.M\00\E7\CB\C9q\CBq\D6\F2\BE\B7\C7>\C9n5×\D6?\BDê\9Ds\EBp\9F[`8m\B7)o\B5\E8\E6I\99\FE3]]A2\BA\8Cw\D6E\93\\DEv\C8\009\F2\F1NI?uc\\F5\EA\96k\xN<~buv\EA\C8\D7	\8B\84\CEcxI\BBg\AE\9E=\D6+n\EC\80\C8A\8C\AE\EB\CF\D5\DA\E9"2\A4\B9j5\EB\F3W\B63\96\B30Yu\DA\FC8\ED\DF\E7Ms\FB\F1\8E\B3\FA\EA\E8\E6(\883zs\F2_\8DFk\8Bh
\00\8C\DCw\D3R\B5+6X\BA\B2\C4j\AB0\B4\FCMw\C2I\8E\9B\E3\A9~9u\FA\D3l\80\C8%p\EE\FDn2€
\00$\FEj\C4e\A9\DB\~\95\A7\A5\80EK\BB\8DDsP\00@@AD'k\CF\E8\DB\D2(\80\9AK\D3\85\D6lb\F2\BA\8C*\80\00)\95
59\A3R:\F3\CE"\B6\80\88\00\00i1u4ê\E9\F2á\A6\A2\FACM\93WMb*\E0*\00\00\00\00\00(\A8\80\00\00\80\00\00\00\00\00\00\00\00\00\FF\D9<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>C///</title>
</head>
module FFISpecs
  #
  # Callback fixtures
  #
  module LibTest
    callback :cbVrS8, [ ], :char
    callback :cbVrU8, [ ], :uchar
    callback :cbVrS16, [ ], :short
    callback :cbVrU16, [ ], :ushort
    callback :cbVrS32, [ ], :int
    callback :cbVrU32, [ ], :uint
    callback :cbVrL, [ ], :long
    callback :cbVrUL, [ ], :ulong
    callback :cbVrS64, [ ], :long_long
    callback :cbVrU64, [ ], :ulong_long
    callback :cbVrP, [], :pointer
    callback :cbCrV, [ :char ], :void
    callback :cbSrV, [ :short ], :void
    callback :cbIrV, [ :int ], :void
    callback :cbLrV, [ :long ], :void
    callback :cbULrV, [ :ulong ], :void
    callback :cbLrV, [ :long_long ], :void

    attach_function :testCallbackVrS8, :testClosureVrB, [ :cbVrS8 ], :char
    attach_function :testCallbackVrU8, :testClosureVrB, [ :cbVrU8 ], :uchar
    attach_function :testCallbackVrS16, :testClosureVrS, [ :cbVrS16 ], :short
    attach_function :testCallbackVrU16, :testClosureVrS, [ :cbVrU16 ], :ushort
    attach_function :testCallbackVrS32, :testClosureVrI, [ :cbVrS32 ], :int
    attach_function :testCallbackVrU32, :testClosureVrI, [ :cbVrU32 ], :uint
    attach_function :testCallbackVrL, :testClosureVrL, [ :cbVrL ], :long
    attach_function :testCallbackVrUL, :testClosureVrL, [ :cbVrUL ], :ulong
    attach_function :testCallbackVrS64, :testClosureVrLL, [ :cbVrS64 ], :long_long
    attach_function :testCallbackVrU64, :testClosureVrLL, [ :cbVrU64 ], :ulong_long
    attach_function :testCallbackVrP, :testClosureVrP, [ :cbVrP ], :pointer
    attach_function :testCallbackCrV, :testClosureBrV, [ :cbCrV, :char ], :void
    attach_variable :cbVrS8, :gvar_pointer, :cbVrS8
    attach_variable :pVrS8, :gvar_pointer, :pointer
    attach_function :testGVarCallbackVrS8, :testClosureVrB, [ :pointer ], :char
    attach_function :testOptionalCallbackCrV, :testOptionalClosureBrV, [ :cbCrV, :char ], :void

    attach_function :testCallbackVrS8, :testClosureVrB, [ callback([ ], :char) ], :char

    callback :cb_return_type, [ :int ], :int
    callback :cb_lookup, [ ], :cb_return_type
    attach_function :testReturnsCallback, :testReturnsClosure, [ :cb_lookup, :int ], :int

    callback :funcptr, [ :int ], :int
    attach_function :testReturnsFunctionPointer, [  ], :funcptr

    callback :cbS8rV, [ :char ], :void
    callback :cbU8rV, [ :uchar ], :void
    callback :cbS16rV, [ :short ], :void
    callback :cbU16rV, [ :ushort ], :void

    callback :cbS32rV, [ :int ], :void
    callback :cbU32rV, [ :uint ], :void

    callback :cbLrV, [ :long ], :void
    callback :cbULrV, [ :ulong ], :void

    callback :cbS64rV, [ :long_long ], :void
    attach_function :testCallbackCrV, :testClosureBrV, [ :cbS8rV, :char ], :void
    attach_function :testCallbackU8rV, :testClosureBrV, [ :cbU8rV, :uchar ], :void
    attach_function :testCallbackSrV, :testClosureSrV, [ :cbS16rV, :short ], :void
    attach_function :testCallbackU16rV, :testClosureSrV, [ :cbU16rV, :ushort ], :void
    attach_function :testCallbackIrV, :testClosureIrV, [ :cbS32rV, :int ], :void
    attach_function :testCallbackU32rV, :testClosureIrV, [ :cbU32rV, :uint ], :void

    attach_function :testCallbackLrV, :testClosureLrV, [ :cbLrV, :long ], :void
    attach_function :testCallbackULrV, :testClosureULrV, [ :cbULrV, :ulong ], :void

    attach_function :testCallbackLLrV, :testClosureLLrV, [ :cbS64rV, :long_long ], :void
  end

  #
  # Enum fixtures
  #
  module TestEnum0
    extend FFI::Library
  end

  module TestEnum1
    extend FFI::Library
    ffi_lib LIBRARY

    enum [:c1, :c2, :c3, :c4]
    enum [:c5, 42, :c6, :c7, :c8]
    enum [:c9, 42, :c10, :c11, 4242, :c12]
    enum [:c13, 42, :c14, 4242, :c15, 424242, :c16, 42424242]

    attach_function :test_untagged_enum, [:int], :int
  end

  module TestEnum3
    extend FFI::Library
    ffi_lib LIBRARY

    enum :enum_type1, [:c1, :c2, :c3, :c4]
    enum :enum_type2, [:c5, 42, :c6, :c7, :c8]
    enum :enum_type3, [:c9, 42, :c10, :c11, 4242, :c12]
    enum :enum_type4, [:c13, 42, :c14, 4242, :c15, 424242, :c16, 42424242]

    attach_function :test_tagged_typedef_enum1, [:enum_type1], :enum_type1
    attach_function :test_tagged_typedef_enum2, [:enum_type2], :enum_type2
    attach_function :test_tagged_typedef_enum3, [:enum_type3], :enum_type3
    attach_function :test_tagged_typedef_enum4, [:enum_type4], :enum_type4
  end

  #
  # Errno fixtures
  #
  module LibTest
    attach_function :setLastError, [ :int ], :void
  end

  #
  # ManagedStruct fixtures
  #
  module LibTest
    attach_function :ptr_from_address, [ FFI::Platform::ADDRESS_SIZE == 32 ? :uint : :ulong_long ], :pointer
  end

  class NoRelease < ManagedStruct
    layout :i, :int
  end

  class WhatClassAmI < ManagedStruct
    layout :i, :int
    def self.release; end
  end

  class PleaseReleaseMe < ManagedStruct
    layout :i, :int
    @@count = 0
    def self.release
      @@count += 1
    end
    def self.wait_gc(count)
      loop = 5
      while loop > 0 && @@count < count
        loop -= 1
        if RUBY_PLATFORM =~ /java/
          require 'java'
          java.lang.System.gc
        else
          GC.start
        end
        sleep 0.05 if @@count < count
      end
    end
  end

  #
  # Number fixtures
  #
  module LibTest
    attach_function :ret_s8, [ :char ], :char
    attach_function :ret_u8, [ :uchar ], :uchar
    attach_function :ret_s16, [ :short ], :short
    attach_function :ret_u16, [ :ushort ], :ushort
    attach_function :ret_s32, [ :int ], :int
    attach_function :ret_u32, [ :uint ], :uint
    attach_function :ret_s64, [ :long_long ], :long_long
    attach_function :ret_u64, [ :ulong_long ], :ulong_long
    attach_function :ret_long, [ :long ], :long
    attach_function :ret_ulong, [ :ulong ], :ulong
    attach_function :set_s8, [ :char ], :void
    attach_function :get_s8, [ ], :char
    attach_function :set_float, [ :float ], :void
    attach_function :get_float, [ ], :float
    attach_function :set_double, [ :double ], :void
    attach_function :get_double, [ ], :double
  end

  PACK_VALUES = {
    's8' => [ 0x12  ],
    'u8' => [ 0x34  ],
    's16' => [ 0x5678 ],
    'u16' => [ 0x9abc ],
    's32' => [ 0x7654321f ],
    'u32' => [ 0xfee1babe ],
    'sL' => [ 0x1f2e3d4c ],
    'uL' => [ 0xf7e8d9ca ],
    's64' => [ 0x1eafdeadbeefa1b2 ],
    #'f32' => [ 1.234567 ], # TODO: Why is this disabled?
    'f64' => [ 9.87654321 ]
  }

  TYPE_MAP = {
    's8' => :char, 'u8' => :uchar, 's16' => :short, 'u16' => :ushort,
    's32' => :int, 'u32' => :uint, 's64' => :long_long, 'u64' => :ulong_long,
    'sL' => :long, 'uL' => :ulong, 'f32' => :float, 'f64' => :double
  }
  TYPES = TYPE_MAP.keys

  module LibTest
    [ 's32', 'u32', 's64', 'u64' ].each do |rt|
      TYPES.each do |t1|
        TYPES.each do |t2|
          TYPES.each do |t3|
            begin
              attach_function "pack_#{t1}#{t2}#{t3}_#{rt}",
                [ TYPE_MAP[t1], TYPE_MAP[t2], TYPE_MAP[t3], :buffer_out ], :void
            rescue FFI::NotFoundError
            end
          end
        end
      end
    end
  end

  #
  # Pointer fixtures
  #
  module LibTest
    attach_function :ptr_ret_int32_t, [ :pointer, :int ], :int
    attach_function :ptr_from_address, [ FFI::Platform::ADDRESS_SIZE == 32 ? :uint : :ulong_long ], :pointer
    attach_function :ptr_set_pointer, [ :pointer, :int, :pointer ], :void
  end

  class ToPtrTest
    def initialize(ptr)
      @ptr = ptr
    end
    def to_ptr
      @ptr
    end
  end

  require 'delegate'
  class PointerDelegate < DelegateClass(FFI::Pointer)
    def initialize(ptr)
      super
      @ptr = ptr
    end
    def to_ptr
      @ptr
    end
  end

  class AutoPointerTestHelper
    @@count = 0
    def self.release
      @@count += 1 if @@count > 0
    end
    def self.reset
      @@count = 0
    end
    def self.gc_everything(count)
      loop = 5
      while @@count < count && loop > 0
        loop -= 1
        if RUBY_PLATFORM =~ /java/
          require "java"
          java.lang.System.gc
        else
          GC.start
        end
        sleep 0.05 unless @@count == count
      end
      @@count = 0
    end
    def self.finalizer
      self.method(:release).to_proc
    end
  end

  #
  # String fixtures
  #
  module LibTest
    attach_function :ptr_ret_pointer, [ :pointer, :int], :string
    attach_function :string_equals, [ :string, :string ], :int
    attach_function :string_dummy, [ :string ], :void
  end

  #
  # Struct initialize fixtures
  #
  class StructWithInitialize < FFI::Struct
    layout :string, :string
    attr_accessor :magic
    def initialize
      super
      self.magic = 42
    end
  end

  #
  # Struct fixtures
  #
  StructTypes = {
    's8' => :char,
    's16' => :short,
    's32' => :int,
    's64' => :long_long,
    'long' => :long,
    'f32' => :float,
    'f64' => :double
  }

  module LibTest
    attach_function :ptr_ret_pointer, [ :pointer, :int], :string
    attach_function :ptr_ret_int32_t, [ :pointer, :int ], :int
    attach_function :ptr_from_address, [ :ulong ], :pointer
    attach_function :string_equals, [ :string, :string ], :int
    [ 's8', 's16', 's32', 's64', 'f32', 'f64', 'long' ].each do |t|
      attach_function "struct_align_#{t}", [ :pointer ], StructTypes[t]
    end
  end

  class PointerMember < FFI::Struct
    layout :pointer, :pointer
  end

  class StringMember < FFI::Struct
    layout :string, :string
  end

  module CallbackMember
    extend FFI::Library
    ffi_lib LIBRARY
    callback :add, [ :int, :int ], :int
    callback :sub, [ :int, :int ], :int

    class TestStruct < FFI::Struct
      layout :add, :add,
        :sub, :sub
    end

    attach_function :struct_call_add_cb, [TestStruct, :int, :int], :int
    attach_function :struct_call_sub_cb, [TestStruct, :int, :int], :int
  end

  module LibTest
    class NestedStruct < FFI::Struct
      layout :i, :int
    end

    class ContainerStruct < FFI::Struct
      layout :first, :char, :ns, NestedStruct
    end

    attach_function :struct_align_nested_struct, [ :pointer ], :int
    attach_function :struct_make_container_struct, [ :int ], :pointer

    class StructWithArray < FFI::Struct
      layout :first, :char, :a, [:int, 5]
    end

    attach_function :struct_make_struct_with_array, [:int, :int, :int, :int, :int], :pointer
    attach_function :struct_field_array, [:pointer], :pointer

    class BuggedStruct < FFI::Struct
      layout :visible, :uchar,
              :x, :uint,
              :y, :uint,
              :rx, :short,
              :ry, :short,
              :order, :uchar,
              :size, :uchar
    end

   