ffi 0.4.0-x86-mswin32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ffi might be problematic. Click here for more details.
- data/LICENSE +51 -0
- data/README.rdoc +69 -0
- data/Rakefile +142 -0
- data/ext/ffi_c/AbstractMemory.c +412 -0
- data/ext/ffi_c/AbstractMemory.h +68 -0
- data/ext/ffi_c/AutoPointer.c +60 -0
- data/ext/ffi_c/AutoPointer.h +18 -0
- data/ext/ffi_c/Buffer.c +171 -0
- data/ext/ffi_c/Callback.c +374 -0
- data/ext/ffi_c/Callback.h +47 -0
- data/ext/ffi_c/DynamicLibrary.c +213 -0
- data/ext/ffi_c/DynamicLibrary.h +22 -0
- data/ext/ffi_c/Invoker.c +962 -0
- data/ext/ffi_c/LastError.c +135 -0
- data/ext/ffi_c/LastError.h +18 -0
- data/ext/ffi_c/MemoryPointer.c +156 -0
- data/ext/ffi_c/MemoryPointer.h +20 -0
- data/ext/ffi_c/NullPointer.c +143 -0
- data/ext/ffi_c/Platform.c +59 -0
- data/ext/ffi_c/Platform.h +16 -0
- data/ext/ffi_c/Pointer.c +164 -0
- data/ext/ffi_c/Pointer.h +25 -0
- data/ext/ffi_c/Struct.c +477 -0
- data/ext/ffi_c/Struct.h +26 -0
- data/ext/ffi_c/Type.c +230 -0
- data/ext/ffi_c/Type.h +28 -0
- data/ext/ffi_c/Types.c +118 -0
- data/ext/ffi_c/Types.h +54 -0
- data/ext/ffi_c/compat.h +22 -0
- data/ext/ffi_c/endian.h +40 -0
- data/ext/ffi_c/extconf.rb +31 -0
- data/ext/ffi_c/ffi.c +76 -0
- data/ext/ffi_c/libffi.bsd.mk +34 -0
- data/ext/ffi_c/libffi.darwin.mk +75 -0
- data/ext/ffi_c/libffi.gnu.mk +29 -0
- data/ext/ffi_c/libffi.mk +13 -0
- data/ext/ffi_c/libffi/ChangeLog +3243 -0
- data/ext/ffi_c/libffi/ChangeLog.libffi +347 -0
- data/ext/ffi_c/libffi/ChangeLog.libgcj +40 -0
- data/ext/ffi_c/libffi/ChangeLog.v1 +764 -0
- data/ext/ffi_c/libffi/LICENSE +21 -0
- data/ext/ffi_c/libffi/Makefile.am +177 -0
- data/ext/ffi_c/libffi/Makefile.in +1640 -0
- data/ext/ffi_c/libffi/README +328 -0
- data/ext/ffi_c/libffi/TODO +1 -0
- data/ext/ffi_c/libffi/acinclude.m4 +92 -0
- data/ext/ffi_c/libffi/aclocal.m4 +7516 -0
- data/ext/ffi_c/libffi/compile +142 -0
- data/ext/ffi_c/libffi/config.guess +1516 -0
- data/ext/ffi_c/libffi/config.sub +1626 -0
- data/ext/ffi_c/libffi/configure +24414 -0
- data/ext/ffi_c/libffi/configure.ac +365 -0
- data/ext/ffi_c/libffi/configure.host +11 -0
- data/ext/ffi_c/libffi/depcomp +584 -0
- data/ext/ffi_c/libffi/doc/libffi.info +533 -0
- data/ext/ffi_c/libffi/doc/libffi.texi +541 -0
- data/ext/ffi_c/libffi/doc/stamp-vti +4 -0
- data/ext/ffi_c/libffi/doc/version.texi +4 -0
- data/ext/ffi_c/libffi/fficonfig.h.in +160 -0
- data/ext/ffi_c/libffi/include/Makefile.am +9 -0
- data/ext/ffi_c/libffi/include/Makefile.in +422 -0
- data/ext/ffi_c/libffi/include/ffi.h.in +393 -0
- data/ext/ffi_c/libffi/include/ffi_common.h +98 -0
- data/ext/ffi_c/libffi/install-sh +323 -0
- data/ext/ffi_c/libffi/libffi.pc.in +10 -0
- data/ext/ffi_c/libffi/libtool-version +29 -0
- data/ext/ffi_c/libffi/ltcf-c.sh +861 -0
- data/ext/ffi_c/libffi/ltcf-cxx.sh +1069 -0
- data/ext/ffi_c/libffi/ltcf-gcj.sh +700 -0
- data/ext/ffi_c/libffi/ltconfig +2862 -0
- data/ext/ffi_c/libffi/ltmain.sh +6930 -0
- data/ext/ffi_c/libffi/man/Makefile.am +8 -0
- data/ext/ffi_c/libffi/man/Makefile.in +395 -0
- data/ext/ffi_c/libffi/man/ffi.3 +31 -0
- data/ext/ffi_c/libffi/man/ffi_call.3 +103 -0
- data/ext/ffi_c/libffi/man/ffi_prep_cif.3 +66 -0
- data/ext/ffi_c/libffi/mdate-sh +201 -0
- data/ext/ffi_c/libffi/missing +353 -0
- data/ext/ffi_c/libffi/mkinstalldirs +158 -0
- data/ext/ffi_c/libffi/src/alpha/ffi.c +284 -0
- data/ext/ffi_c/libffi/src/alpha/ffitarget.h +48 -0
- data/ext/ffi_c/libffi/src/alpha/osf.S +366 -0
- data/ext/ffi_c/libffi/src/arm/ffi.c +309 -0
- data/ext/ffi_c/libffi/src/arm/ffitarget.h +49 -0
- data/ext/ffi_c/libffi/src/arm/sysv.S +299 -0
- data/ext/ffi_c/libffi/src/closures.c +596 -0
- data/ext/ffi_c/libffi/src/cris/ffi.c +383 -0
- data/ext/ffi_c/libffi/src/cris/ffitarget.h +51 -0
- data/ext/ffi_c/libffi/src/cris/sysv.S +215 -0
- data/ext/ffi_c/libffi/src/debug.c +59 -0
- data/ext/ffi_c/libffi/src/dlmalloc.c +5099 -0
- data/ext/ffi_c/libffi/src/frv/eabi.S +128 -0
- data/ext/ffi_c/libffi/src/frv/ffi.c +292 -0
- data/ext/ffi_c/libffi/src/frv/ffitarget.h +61 -0
- data/ext/ffi_c/libffi/src/ia64/ffi.c +580 -0
- data/ext/ffi_c/libffi/src/ia64/ffitarget.h +50 -0
- data/ext/ffi_c/libffi/src/ia64/ia64_flags.h +40 -0
- data/ext/ffi_c/libffi/src/ia64/unix.S +560 -0
- data/ext/ffi_c/libffi/src/java_raw_api.c +359 -0
- data/ext/ffi_c/libffi/src/m32r/ffi.c +232 -0
- data/ext/ffi_c/libffi/src/m32r/ffitarget.h +48 -0
- data/ext/ffi_c/libffi/src/m32r/sysv.S +121 -0
- data/ext/ffi_c/libffi/src/m68k/ffi.c +278 -0
- data/ext/ffi_c/libffi/src/m68k/ffitarget.h +49 -0
- data/ext/ffi_c/libffi/src/m68k/sysv.S +234 -0
- data/ext/ffi_c/libffi/src/mips/ffi.c +926 -0
- data/ext/ffi_c/libffi/src/mips/ffitarget.h +202 -0
- data/ext/ffi_c/libffi/src/mips/n32.S +534 -0
- data/ext/ffi_c/libffi/src/mips/o32.S +381 -0
- data/ext/ffi_c/libffi/src/pa/ffi.c +709 -0
- data/ext/ffi_c/libffi/src/pa/ffitarget.h +77 -0
- data/ext/ffi_c/libffi/src/pa/hpux32.S +368 -0
- data/ext/ffi_c/libffi/src/pa/linux.S +357 -0
- data/ext/ffi_c/libffi/src/powerpc/aix.S +225 -0
- data/ext/ffi_c/libffi/src/powerpc/aix_closure.S +247 -0
- data/ext/ffi_c/libffi/src/powerpc/asm.h +125 -0
- data/ext/ffi_c/libffi/src/powerpc/darwin.S +245 -0
- data/ext/ffi_c/libffi/src/powerpc/darwin_closure.S +317 -0
- data/ext/ffi_c/libffi/src/powerpc/ffi.c +1429 -0
- data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +800 -0
- data/ext/ffi_c/libffi/src/powerpc/ffitarget.h +118 -0
- data/ext/ffi_c/libffi/src/powerpc/linux64.S +187 -0
- data/ext/ffi_c/libffi/src/powerpc/linux64_closure.S +236 -0
- data/ext/ffi_c/libffi/src/powerpc/ppc_closure.S +327 -0
- data/ext/ffi_c/libffi/src/powerpc/sysv.S +230 -0
- data/ext/ffi_c/libffi/src/prep_cif.c +174 -0
- data/ext/ffi_c/libffi/src/raw_api.c +254 -0
- data/ext/ffi_c/libffi/src/s390/ffi.c +780 -0
- data/ext/ffi_c/libffi/src/s390/ffitarget.h +60 -0
- data/ext/ffi_c/libffi/src/s390/sysv.S +434 -0
- data/ext/ffi_c/libffi/src/sh/ffi.c +716 -0
- data/ext/ffi_c/libffi/src/sh/ffitarget.h +49 -0
- data/ext/ffi_c/libffi/src/sh/sysv.S +850 -0
- data/ext/ffi_c/libffi/src/sh64/ffi.c +453 -0
- data/ext/ffi_c/libffi/src/sh64/ffitarget.h +53 -0
- data/ext/ffi_c/libffi/src/sh64/sysv.S +530 -0
- data/ext/ffi_c/libffi/src/sparc/ffi.c +610 -0
- data/ext/ffi_c/libffi/src/sparc/ffitarget.h +66 -0
- data/ext/ffi_c/libffi/src/sparc/v8.S +272 -0
- data/ext/ffi_c/libffi/src/sparc/v9.S +307 -0
- data/ext/ffi_c/libffi/src/types.c +77 -0
- data/ext/ffi_c/libffi/src/x86/darwin.S +443 -0
- data/ext/ffi_c/libffi/src/x86/darwin64.S +416 -0
- data/ext/ffi_c/libffi/src/x86/ffi.c +475 -0
- data/ext/ffi_c/libffi/src/x86/ffi64.c +572 -0
- data/ext/ffi_c/libffi/src/x86/ffitarget.h +90 -0
- data/ext/ffi_c/libffi/src/x86/freebsd.S +458 -0
- data/ext/ffi_c/libffi/src/x86/sysv.S +437 -0
- data/ext/ffi_c/libffi/src/x86/unix64.S +418 -0
- data/ext/ffi_c/libffi/src/x86/win32.S +391 -0
- data/ext/ffi_c/libffi/testsuite/Makefile.am +71 -0
- data/ext/ffi_c/libffi/testsuite/Makefile.in +447 -0
- data/ext/ffi_c/libffi/testsuite/config/default.exp +1 -0
- data/ext/ffi_c/libffi/testsuite/lib/libffi-dg.exp +289 -0
- data/ext/ffi_c/libffi/testsuite/lib/target-libpath.exp +263 -0
- data/ext/ffi_c/libffi/testsuite/lib/wrapper.exp +45 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/call.exp +36 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn0.c +97 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn1.c +89 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn2.c +89 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn3.c +90 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn4.c +97 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn5.c +99 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn6.c +98 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/closure_stdcall.c +72 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_12byte.c +102 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_16byte.c +103 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_18byte.c +104 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_19byte.c +110 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_1_1byte.c +97 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_20byte.c +99 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_20byte1.c +101 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_24byte.c +121 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_2byte.c +98 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3_1byte.c +103 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3byte1.c +98 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3byte2.c +98 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_4_1byte.c +106 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_4byte.c +98 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_5_1_byte.c +117 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_5byte.c +106 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_64byte.c +132 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_6_1_byte.c +121 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_6byte.c +107 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_7_1_byte.c +125 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_7byte.c +105 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_8byte.c +96 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_9byte1.c +98 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_9byte2.c +99 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_double.c +101 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_float.c +99 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble.c +100 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_pointer.c +101 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint16.c +99 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint32.c +99 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint64.c +99 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint16.c +99 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint32.c +99 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint64.c +100 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_double.c +51 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_float.c +51 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_schar.c +82 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_sshort.c +82 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_sshortchar.c +94 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_uchar.c +99 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_ushort.c +82 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_ushortchar.c +94 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_schar.c +52 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_sint.c +50 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_sshort.c +50 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_uchar.c +50 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_uint.c +51 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ulonglong.c +54 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ushort.c +51 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/ffitest.h +86 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/float.c +59 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/float1.c +58 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/float2.c +57 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/float3.c +72 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/float4.c +62 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/many.c +69 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/many_win32.c +63 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/negint.c +53 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct.c +160 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct1.c +169 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct10.c +141 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct2.c +118 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct3.c +119 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct4.c +119 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct5.c +120 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct6.c +139 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct7.c +119 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct8.c +139 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct9.c +139 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/problem1.c +98 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/promotion.c +59 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/pyobjc-tc.c +114 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl.c +35 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl1.c +43 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl2.c +42 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_fl.c +35 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_fl1.c +36 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_fl2.c +49 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_fl3.c +42 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_ldl.c +34 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_ll.c +41 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_ll1.c +42 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_sc.c +36 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_sl.c +38 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_uc.c +38 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/return_ul.c +38 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/strlen.c +44 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/strlen_win32.c +44 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct1.c +65 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct2.c +67 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct3.c +59 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct4.c +63 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct5.c +65 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct6.c +64 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct7.c +74 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct8.c +80 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct9.c +67 -0
- data/ext/ffi_c/libffi/testsuite/libffi.special/ffitestcxx.h +86 -0
- data/ext/ffi_c/libffi/testsuite/libffi.special/special.exp +38 -0
- data/ext/ffi_c/libffi/testsuite/libffi.special/unwindtest.cc +123 -0
- data/ext/ffi_c/libffi/testsuite/libffi.special/unwindtest_ffi_call.cc +53 -0
- data/ext/ffi_c/libffi/texinfo.tex +7482 -0
- data/ext/ffi_c/rbffi.h +23 -0
- data/gen/Rakefile +12 -0
- data/lib/1.8/ffi_c.so +0 -0
- data/lib/1.9/ffi_c.so +0 -0
- data/lib/ffi.rb +11 -0
- data/lib/ffi/autopointer.rb +61 -0
- data/lib/ffi/buffer.rb +0 -0
- data/lib/ffi/callback.rb +10 -0
- data/lib/ffi/enum.rb +78 -0
- data/lib/ffi/errno.rb +8 -0
- data/lib/ffi/ffi.rb +96 -0
- data/lib/ffi/io.rb +21 -0
- data/lib/ffi/library.rb +243 -0
- data/lib/ffi/managedstruct.rb +55 -0
- data/lib/ffi/memorypointer.rb +73 -0
- data/lib/ffi/platform.rb +78 -0
- data/lib/ffi/pointer.rb +119 -0
- data/lib/ffi/struct.rb +354 -0
- data/lib/ffi/tools/const_generator.rb +177 -0
- data/lib/ffi/tools/generator.rb +58 -0
- data/lib/ffi/tools/generator_task.rb +35 -0
- data/lib/ffi/tools/struct_generator.rb +194 -0
- data/lib/ffi/tools/types_generator.rb +123 -0
- data/lib/ffi/types.rb +153 -0
- data/lib/ffi/union.rb +17 -0
- data/lib/ffi/variadic.rb +30 -0
- data/spec/ffi/bool_spec.rb +24 -0
- data/spec/ffi/buffer_spec.rb +196 -0
- data/spec/ffi/callback_spec.rb +560 -0
- data/spec/ffi/enum_spec.rb +164 -0
- data/spec/ffi/errno_spec.rb +13 -0
- data/spec/ffi/library_spec.rb +144 -0
- data/spec/ffi/managed_struct_spec.rb +56 -0
- data/spec/ffi/number_spec.rb +231 -0
- data/spec/ffi/pointer_spec.rb +195 -0
- data/spec/ffi/rbx/attach_function_spec.rb +27 -0
- data/spec/ffi/rbx/memory_pointer_spec.rb +102 -0
- data/spec/ffi/rbx/spec_helper.rb +1 -0
- data/spec/ffi/rbx/struct_spec.rb +13 -0
- data/spec/ffi/spec_helper.rb +17 -0
- data/spec/ffi/string_spec.rb +103 -0
- data/spec/ffi/struct_callback_spec.rb +41 -0
- data/spec/ffi/struct_initialize_spec.rb +30 -0
- data/spec/ffi/struct_spec.rb +476 -0
- data/spec/ffi/typedef_spec.rb +48 -0
- data/spec/ffi/union_spec.rb +60 -0
- data/spec/ffi/variadic_spec.rb +84 -0
- data/spec/spec.opts +4 -0
- metadata +375 -0
@@ -0,0 +1,59 @@
|
|
1
|
+
#include <sys/param.h>
|
2
|
+
#include <sys/types.h>
|
3
|
+
#include <stdint.h>
|
4
|
+
#include <stdbool.h>
|
5
|
+
#include <ruby.h>
|
6
|
+
#include <ctype.h>
|
7
|
+
#include "endian.h"
|
8
|
+
#include "Platform.h"
|
9
|
+
|
10
|
+
static VALUE PlatformModule = Qnil;
|
11
|
+
|
12
|
+
/*
|
13
|
+
* Determine the cpu type at compile time - useful for MacOSX where the the
|
14
|
+
* system installed ruby incorrectly reports 'host_cpu' as 'powerpc' when running
|
15
|
+
* on intel.
|
16
|
+
*/
|
17
|
+
#ifdef __i386__
|
18
|
+
#define CPU "i386"
|
19
|
+
#elif defined(__ppc__) || defined(__powerpc__)
|
20
|
+
#define CPU "powerpc"
|
21
|
+
#elif defined(__x86_64__)
|
22
|
+
#define CPU "x86_64"
|
23
|
+
#elif defined(__sparc__)
|
24
|
+
#define CPU "sparc"
|
25
|
+
#elif defined(__sparcv9__)
|
26
|
+
#define CPU "sparcv9"
|
27
|
+
#else
|
28
|
+
#error "Unknown cpu type"
|
29
|
+
#endif
|
30
|
+
|
31
|
+
static void
|
32
|
+
export_primitive_types(VALUE module)
|
33
|
+
{
|
34
|
+
#define S(name, T) do { \
|
35
|
+
typedef struct { char c; T v; } s; \
|
36
|
+
rb_define_const(module, #name "_ALIGN", INT2NUM((sizeof(s) - sizeof(T)) * 8)); \
|
37
|
+
rb_define_const(module, #name "_SIZE", INT2NUM(sizeof(T)* 8)); \
|
38
|
+
} while(0)
|
39
|
+
S(INT8, char);
|
40
|
+
S(INT16, short);
|
41
|
+
S(INT32, int);
|
42
|
+
S(INT64, long long);
|
43
|
+
S(LONG, long);
|
44
|
+
S(FLOAT, float);
|
45
|
+
S(DOUBLE, double);
|
46
|
+
S(ADDRESS, void*);
|
47
|
+
#undef S
|
48
|
+
}
|
49
|
+
|
50
|
+
void
|
51
|
+
rbffi_Platform_Init(VALUE moduleFFI)
|
52
|
+
{
|
53
|
+
PlatformModule = rb_define_module_under(moduleFFI, "Platform");
|
54
|
+
rb_define_const(PlatformModule, "BYTE_ORDER", INT2FIX(BYTE_ORDER));
|
55
|
+
rb_define_const(PlatformModule, "LITTLE_ENDIAN", INT2FIX(LITTLE_ENDIAN));
|
56
|
+
rb_define_const(PlatformModule, "BIG_ENDIAN", INT2FIX(BIG_ENDIAN));
|
57
|
+
rb_define_const(PlatformModule, "CPU", rb_str_new2(CPU));
|
58
|
+
export_primitive_types(PlatformModule);
|
59
|
+
}
|
data/ext/ffi_c/Pointer.c
ADDED
@@ -0,0 +1,164 @@
|
|
1
|
+
#include <stdbool.h>
|
2
|
+
#include <stdint.h>
|
3
|
+
#include <limits.h>
|
4
|
+
#include <ruby.h>
|
5
|
+
#include "rbffi.h"
|
6
|
+
#include "AbstractMemory.h"
|
7
|
+
#include "Pointer.h"
|
8
|
+
|
9
|
+
typedef struct Pointer {
|
10
|
+
AbstractMemory memory;
|
11
|
+
VALUE parent;
|
12
|
+
} Pointer;
|
13
|
+
|
14
|
+
#define POINTER(obj) rbffi_AbstractMemory_Cast((obj), rbffi_PointerClass)
|
15
|
+
|
16
|
+
VALUE rbffi_PointerClass;
|
17
|
+
static void ptr_mark(Pointer* ptr);
|
18
|
+
|
19
|
+
VALUE
|
20
|
+
rbffi_Pointer_NewInstance(void* addr)
|
21
|
+
{
|
22
|
+
Pointer* p;
|
23
|
+
VALUE obj;
|
24
|
+
|
25
|
+
if (addr == NULL) {
|
26
|
+
return rbffi_NullPointerSingleton;
|
27
|
+
}
|
28
|
+
|
29
|
+
obj = Data_Make_Struct(rbffi_PointerClass, Pointer, NULL, -1, p);
|
30
|
+
p->memory.address = addr;
|
31
|
+
p->memory.size = LONG_MAX;
|
32
|
+
p->memory.ops = &rbffi_AbstractMemoryOps;
|
33
|
+
p->parent = Qnil;
|
34
|
+
|
35
|
+
return obj;
|
36
|
+
}
|
37
|
+
|
38
|
+
static VALUE
|
39
|
+
ptr_allocate(VALUE klass)
|
40
|
+
{
|
41
|
+
Pointer* p;
|
42
|
+
VALUE obj;
|
43
|
+
|
44
|
+
obj = Data_Make_Struct(rbffi_PointerClass, Pointer, NULL, -1, p);
|
45
|
+
p->parent = Qnil;
|
46
|
+
p->memory.ops = &rbffi_AbstractMemoryOps;
|
47
|
+
|
48
|
+
return obj;
|
49
|
+
}
|
50
|
+
|
51
|
+
static VALUE
|
52
|
+
ptr_initialize(int argc, VALUE* argv, VALUE self)
|
53
|
+
{
|
54
|
+
Pointer* p;
|
55
|
+
VALUE type, address;
|
56
|
+
|
57
|
+
Data_Get_Struct(self, Pointer, p);
|
58
|
+
|
59
|
+
switch (rb_scan_args(argc, argv, "11", &type, &address)) {
|
60
|
+
case 1:
|
61
|
+
p->memory.address = (void*)(uintptr_t) NUM2LL(type);
|
62
|
+
// FIXME set type_size to 1
|
63
|
+
break;
|
64
|
+
case 2:
|
65
|
+
p->memory.address = (void*)(uintptr_t) NUM2LL(address);
|
66
|
+
// FIXME set type_size to rbffi_type_size(type)
|
67
|
+
break;
|
68
|
+
default:
|
69
|
+
rb_raise(rb_eArgError, "Invalid arguments");
|
70
|
+
}
|
71
|
+
if (p->memory.address == NULL) {
|
72
|
+
p->memory.ops = &rbffi_NullPointerOps;
|
73
|
+
}
|
74
|
+
|
75
|
+
p->memory.size = LONG_MAX;
|
76
|
+
|
77
|
+
return self;
|
78
|
+
}
|
79
|
+
|
80
|
+
|
81
|
+
static VALUE
|
82
|
+
ptr_plus(VALUE self, VALUE offset)
|
83
|
+
{
|
84
|
+
AbstractMemory* ptr;
|
85
|
+
Pointer* p;
|
86
|
+
VALUE retval;
|
87
|
+
long off = NUM2LONG(offset);
|
88
|
+
|
89
|
+
Data_Get_Struct(self, AbstractMemory, ptr);
|
90
|
+
checkBounds(ptr, off, 1);
|
91
|
+
|
92
|
+
retval = Data_Make_Struct(rbffi_PointerClass, Pointer, ptr_mark, -1, p);
|
93
|
+
|
94
|
+
p->memory.address = ptr->address + off;
|
95
|
+
p->memory.size = ptr->size == LONG_MAX ? LONG_MAX : ptr->size - off;
|
96
|
+
p->memory.ops = &rbffi_AbstractMemoryOps;
|
97
|
+
p->parent = self;
|
98
|
+
|
99
|
+
return retval;
|
100
|
+
}
|
101
|
+
|
102
|
+
static VALUE
|
103
|
+
ptr_inspect(VALUE self)
|
104
|
+
{
|
105
|
+
Pointer* ptr;
|
106
|
+
char tmp[100];
|
107
|
+
|
108
|
+
Data_Get_Struct(self, Pointer, ptr);
|
109
|
+
snprintf(tmp, sizeof(tmp), "#<Native Pointer address=%p>", ptr->memory.address);
|
110
|
+
|
111
|
+
return rb_str_new2(tmp);
|
112
|
+
}
|
113
|
+
|
114
|
+
static VALUE
|
115
|
+
ptr_null_p(VALUE self)
|
116
|
+
{
|
117
|
+
Pointer* ptr;
|
118
|
+
|
119
|
+
Data_Get_Struct(self, Pointer, ptr);
|
120
|
+
|
121
|
+
return ptr->memory.address == NULL ? Qtrue : Qfalse;
|
122
|
+
}
|
123
|
+
|
124
|
+
static VALUE
|
125
|
+
ptr_equals(VALUE self, VALUE other)
|
126
|
+
{
|
127
|
+
Pointer* ptr;
|
128
|
+
|
129
|
+
Data_Get_Struct(self, Pointer, ptr);
|
130
|
+
|
131
|
+
return ptr->memory.address == POINTER(other)->address ? Qtrue : Qfalse;
|
132
|
+
}
|
133
|
+
|
134
|
+
static VALUE
|
135
|
+
ptr_address(VALUE self)
|
136
|
+
{
|
137
|
+
Pointer* ptr;
|
138
|
+
|
139
|
+
Data_Get_Struct(self, Pointer, ptr);
|
140
|
+
|
141
|
+
return ULL2NUM((uintptr_t) ptr->memory.address);
|
142
|
+
}
|
143
|
+
|
144
|
+
static void
|
145
|
+
ptr_mark(Pointer* ptr)
|
146
|
+
{
|
147
|
+
rb_gc_mark(ptr->parent);
|
148
|
+
}
|
149
|
+
|
150
|
+
void
|
151
|
+
rbffi_Pointer_Init(VALUE moduleFFI)
|
152
|
+
{
|
153
|
+
rbffi_PointerClass = rb_define_class_under(moduleFFI, "Pointer", rbffi_AbstractMemoryClass);
|
154
|
+
rb_global_variable(&rbffi_PointerClass);
|
155
|
+
|
156
|
+
rb_define_alloc_func(rbffi_PointerClass, ptr_allocate);
|
157
|
+
rb_define_method(rbffi_PointerClass, "initialize", ptr_initialize, -1);
|
158
|
+
rb_define_method(rbffi_PointerClass, "inspect", ptr_inspect, 0);
|
159
|
+
rb_define_method(rbffi_PointerClass, "+", ptr_plus, 1);
|
160
|
+
rb_define_method(rbffi_PointerClass, "null?", ptr_null_p, 0);
|
161
|
+
rb_define_method(rbffi_PointerClass, "address", ptr_address, 0);
|
162
|
+
rb_define_alias(rbffi_PointerClass, "to_i", "address");
|
163
|
+
rb_define_method(rbffi_PointerClass, "==", ptr_equals, 1);
|
164
|
+
}
|
data/ext/ffi_c/Pointer.h
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
|
2
|
+
#ifndef _POINTER_H
|
3
|
+
#define _POINTER_H
|
4
|
+
|
5
|
+
#ifdef __cplusplus
|
6
|
+
extern "C" {
|
7
|
+
#endif
|
8
|
+
|
9
|
+
#include "AbstractMemory.h"
|
10
|
+
|
11
|
+
extern void rbffi_Pointer_Init(VALUE moduleFFI);
|
12
|
+
extern void rbffi_NullPointer_Init(VALUE moduleFFI);
|
13
|
+
extern VALUE rbffi_Pointer_NewInstance(void* addr);
|
14
|
+
extern VALUE rbffi_PointerClass;
|
15
|
+
extern VALUE rbffi_NullPointerClass;
|
16
|
+
extern VALUE rbffi_NullPointerSingleton;
|
17
|
+
extern MemoryOps rbffi_NullPointerOps;
|
18
|
+
|
19
|
+
|
20
|
+
#ifdef __cplusplus
|
21
|
+
}
|
22
|
+
#endif
|
23
|
+
|
24
|
+
#endif /* _POINTER_H */
|
25
|
+
|
data/ext/ffi_c/Struct.c
ADDED
@@ -0,0 +1,477 @@
|
|
1
|
+
#include <sys/types.h>
|
2
|
+
#include <sys/param.h>
|
3
|
+
#include <stdint.h>
|
4
|
+
#include <stdbool.h>
|
5
|
+
#include <ruby.h>
|
6
|
+
#include "rbffi.h"
|
7
|
+
#include "compat.h"
|
8
|
+
#include "AbstractMemory.h"
|
9
|
+
#include "Pointer.h"
|
10
|
+
#include "MemoryPointer.h"
|
11
|
+
#include "Types.h"
|
12
|
+
#include "Struct.h"
|
13
|
+
|
14
|
+
typedef struct StructField {
|
15
|
+
unsigned int type;
|
16
|
+
unsigned int offset;
|
17
|
+
unsigned int size;
|
18
|
+
unsigned int align;
|
19
|
+
} StructField;
|
20
|
+
|
21
|
+
typedef struct StructLayout {
|
22
|
+
VALUE rbFields;
|
23
|
+
unsigned int fieldCount;
|
24
|
+
int size;
|
25
|
+
int align;
|
26
|
+
} StructLayout;
|
27
|
+
|
28
|
+
typedef struct StructLayoutBuilder {
|
29
|
+
unsigned int offset;
|
30
|
+
} StructLayoutBuilder;
|
31
|
+
|
32
|
+
static void struct_mark(Struct *);
|
33
|
+
static void struct_layout_mark(StructLayout *);
|
34
|
+
static inline MemoryOp* ptr_get_op(AbstractMemory* ptr, int type);
|
35
|
+
|
36
|
+
VALUE rbffi_StructClass = Qnil;
|
37
|
+
static VALUE StructLayoutClass = Qnil;
|
38
|
+
static VALUE StructFieldClass = Qnil, StructLayoutBuilderClass = Qnil;
|
39
|
+
static ID pointer_var_id = 0, layout_var_id = 0, SIZE_ID, ALIGN_ID, TYPE_ID;
|
40
|
+
static ID get_id = 0, put_id = 0, to_ptr = 0, to_s = 0, layout_id = 0;
|
41
|
+
|
42
|
+
static VALUE
|
43
|
+
struct_field_allocate(VALUE klass)
|
44
|
+
{
|
45
|
+
StructField* field;
|
46
|
+
return Data_Make_Struct(klass, StructField, NULL, -1, field);
|
47
|
+
}
|
48
|
+
|
49
|
+
static VALUE
|
50
|
+
struct_field_initialize(int argc, VALUE* argv, VALUE self)
|
51
|
+
{
|
52
|
+
VALUE offset = Qnil, info = Qnil;
|
53
|
+
StructField* field;
|
54
|
+
int nargs;
|
55
|
+
|
56
|
+
Data_Get_Struct(self, StructField, field);
|
57
|
+
|
58
|
+
nargs = rb_scan_args(argc, argv, "11", &offset, &info);
|
59
|
+
|
60
|
+
field->offset = NUM2UINT(offset);
|
61
|
+
if (rb_const_defined(CLASS_OF(self), TYPE_ID)) {
|
62
|
+
field->type = NUM2UINT(rb_const_get(CLASS_OF(self), TYPE_ID));
|
63
|
+
} else {
|
64
|
+
field->type = ~0;
|
65
|
+
}
|
66
|
+
|
67
|
+
#ifdef notyet
|
68
|
+
field->size = NUM2UINT(rb_const_get(klass, SIZE_ID));
|
69
|
+
field->align = NUM2UINT(rb_const_get(klass, ALIGN_ID));
|
70
|
+
#endif
|
71
|
+
rb_iv_set(self, "@off", offset);
|
72
|
+
rb_iv_set(self, "@info", info);
|
73
|
+
|
74
|
+
return self;
|
75
|
+
}
|
76
|
+
|
77
|
+
static VALUE
|
78
|
+
struct_field_offset(VALUE self)
|
79
|
+
{
|
80
|
+
StructField* field;
|
81
|
+
Data_Get_Struct(self, StructField, field);
|
82
|
+
return UINT2NUM(field->offset);
|
83
|
+
}
|
84
|
+
|
85
|
+
static VALUE
|
86
|
+
struct_field_get(VALUE self, VALUE pointer)
|
87
|
+
{
|
88
|
+
StructField* f;
|
89
|
+
MemoryOp* op;
|
90
|
+
AbstractMemory* memory = MEMORY(pointer);
|
91
|
+
|
92
|
+
Data_Get_Struct(self, StructField, f);
|
93
|
+
op = ptr_get_op(memory, f->type);
|
94
|
+
if (op == NULL) {
|
95
|
+
VALUE name = rb_class_name(CLASS_OF(self));
|
96
|
+
rb_raise(rb_eArgError, "get not supported for %s", StringValueCStr(name));
|
97
|
+
return Qnil;
|
98
|
+
}
|
99
|
+
|
100
|
+
return (*op->get)(memory, f->offset);
|
101
|
+
}
|
102
|
+
|
103
|
+
static VALUE
|
104
|
+
struct_field_put(VALUE self, VALUE pointer, VALUE value)
|
105
|
+
{
|
106
|
+
StructField* f;
|
107
|
+
MemoryOp* op;
|
108
|
+
AbstractMemory* memory = MEMORY(pointer);
|
109
|
+
|
110
|
+
Data_Get_Struct(self, StructField, f);
|
111
|
+
op = ptr_get_op(memory, f->type);
|
112
|
+
if (op == NULL) {
|
113
|
+
VALUE name = rb_class_name(CLASS_OF(self));
|
114
|
+
rb_raise(rb_eArgError, "put not supported for %s", StringValueCStr(name));
|
115
|
+
return self;
|
116
|
+
}
|
117
|
+
|
118
|
+
(*op->put)(memory, f->offset, value);
|
119
|
+
|
120
|
+
return self;
|
121
|
+
}
|
122
|
+
|
123
|
+
static inline char*
|
124
|
+
memory_address(VALUE self)
|
125
|
+
{
|
126
|
+
return ((AbstractMemory *)DATA_PTR((self)))->address;
|
127
|
+
}
|
128
|
+
|
129
|
+
static VALUE
|
130
|
+
struct_allocate(VALUE klass)
|
131
|
+
{
|
132
|
+
Struct* s;
|
133
|
+
VALUE obj = Data_Make_Struct(klass, Struct, struct_mark, -1, s);
|
134
|
+
|
135
|
+
s->rbPointer = Qnil;
|
136
|
+
s->rbLayout = Qnil;
|
137
|
+
|
138
|
+
return obj;
|
139
|
+
}
|
140
|
+
|
141
|
+
static VALUE
|
142
|
+
struct_initialize(int argc, VALUE* argv, VALUE self)
|
143
|
+
{
|
144
|
+
Struct* s;
|
145
|
+
VALUE rbPointer = Qnil, rest = Qnil, klass = CLASS_OF(self);
|
146
|
+
int nargs;
|
147
|
+
|
148
|
+
Data_Get_Struct(self, Struct, s);
|
149
|
+
|
150
|
+
nargs = rb_scan_args(argc, argv, "01*", &rbPointer, &rest);
|
151
|
+
|
152
|
+
/* Call up into ruby code to adjust the layout */
|
153
|
+
if (nargs > 1) {
|
154
|
+
s->rbLayout = rb_funcall2(CLASS_OF(self), layout_id, RARRAY_LEN(rest), RARRAY_PTR(rest));
|
155
|
+
} else if (rb_cvar_defined(klass, layout_var_id)) {
|
156
|
+
s->rbLayout = rb_cvar_get(klass, layout_var_id);
|
157
|
+
} else {
|
158
|
+
rb_raise(rb_eRuntimeError, "No Struct layout configured");
|
159
|
+
}
|
160
|
+
|
161
|
+
if (!rb_obj_is_kind_of(s->rbLayout, StructLayoutClass)) {
|
162
|
+
rb_raise(rb_eRuntimeError, "Invalid Struct layout");
|
163
|
+
}
|
164
|
+
|
165
|
+
Data_Get_Struct(s->rbLayout, StructLayout, s->layout);
|
166
|
+
|
167
|
+
if (rbPointer != Qnil) {
|
168
|
+
s->pointer = MEMORY(rbPointer);
|
169
|
+
s->rbPointer = rbPointer;
|
170
|
+
} else {
|
171
|
+
s->rbPointer = rbffi_MemoryPointer_NewInstance(s->layout->size, 1, true);
|
172
|
+
s->pointer = (AbstractMemory *) DATA_PTR(s->rbPointer);
|
173
|
+
}
|
174
|
+
|
175
|
+
if (s->pointer->ops == NULL) {
|
176
|
+
VALUE name = rb_class_name(CLASS_OF(s->rbPointer));
|
177
|
+
rb_raise(rb_eRuntimeError, "No memory ops set for %s", StringValueCStr(name));
|
178
|
+
}
|
179
|
+
|
180
|
+
return self;
|
181
|
+
}
|
182
|
+
|
183
|
+
static void
|
184
|
+
struct_mark(Struct *s)
|
185
|
+
{
|
186
|
+
rb_gc_mark(s->rbPointer);
|
187
|
+
rb_gc_mark(s->rbLayout);
|
188
|
+
}
|
189
|
+
|
190
|
+
static VALUE
|
191
|
+
struct_field(Struct* s, VALUE fieldName)
|
192
|
+
{
|
193
|
+
StructLayout* layout = s->layout;
|
194
|
+
VALUE rbField;
|
195
|
+
if (layout == NULL) {
|
196
|
+
rb_raise(rb_eRuntimeError, "layout not set for Struct");
|
197
|
+
}
|
198
|
+
|
199
|
+
rbField = rb_hash_aref(layout->rbFields, fieldName);
|
200
|
+
if (rbField == Qnil) {
|
201
|
+
VALUE str = rb_funcall2(fieldName, to_s, 0, NULL);
|
202
|
+
rb_raise(rb_eArgError, "No such field '%s'", StringValuePtr(str));
|
203
|
+
}
|
204
|
+
|
205
|
+
return rbField;
|
206
|
+
}
|
207
|
+
|
208
|
+
static inline MemoryOp*
|
209
|
+
ptr_get_op(AbstractMemory* ptr, int type)
|
210
|
+
{
|
211
|
+
if (ptr == NULL || ptr->ops == NULL) {
|
212
|
+
return NULL;
|
213
|
+
}
|
214
|
+
switch (type) {
|
215
|
+
case NATIVE_INT8:
|
216
|
+
return ptr->ops->int8;
|
217
|
+
case NATIVE_UINT8:
|
218
|
+
return ptr->ops->uint8;
|
219
|
+
case NATIVE_INT16:
|
220
|
+
return ptr->ops->int16;
|
221
|
+
case NATIVE_UINT16:
|
222
|
+
return ptr->ops->uint16;
|
223
|
+
case NATIVE_INT32:
|
224
|
+
return ptr->ops->int32;
|
225
|
+
case NATIVE_UINT32:
|
226
|
+
return ptr->ops->uint32;
|
227
|
+
case NATIVE_INT64:
|
228
|
+
return ptr->ops->int64;
|
229
|
+
case NATIVE_UINT64:
|
230
|
+
return ptr->ops->uint64;
|
231
|
+
case NATIVE_FLOAT32:
|
232
|
+
return ptr->ops->float32;
|
233
|
+
case NATIVE_FLOAT64:
|
234
|
+
return ptr->ops->float64;
|
235
|
+
case NATIVE_POINTER:
|
236
|
+
return ptr->ops->pointer;
|
237
|
+
case NATIVE_STRING:
|
238
|
+
return ptr->ops->strptr;
|
239
|
+
default:
|
240
|
+
return NULL;
|
241
|
+
}
|
242
|
+
}
|
243
|
+
|
244
|
+
static VALUE
|
245
|
+
struct_get_field(VALUE self, VALUE fieldName)
|
246
|
+
{
|
247
|
+
Struct* s;
|
248
|
+
VALUE rbField;
|
249
|
+
StructField* f;
|
250
|
+
MemoryOp* op;
|
251
|
+
|
252
|
+
Data_Get_Struct(self, Struct, s);
|
253
|
+
rbField = struct_field(s, fieldName);
|
254
|
+
f = (StructField *) DATA_PTR(rbField);
|
255
|
+
|
256
|
+
op = ptr_get_op(s->pointer, f->type);
|
257
|
+
if (op != NULL) {
|
258
|
+
return (*op->get)(s->pointer, f->offset);
|
259
|
+
}
|
260
|
+
|
261
|
+
/* call up to the ruby code to fetch the value */
|
262
|
+
return rb_funcall2(rbField, get_id, 1, &s->rbPointer);
|
263
|
+
}
|
264
|
+
|
265
|
+
static VALUE
|
266
|
+
struct_put_field(VALUE self, VALUE fieldName, VALUE value)
|
267
|
+
{
|
268
|
+
Struct* s;
|
269
|
+
VALUE rbField;
|
270
|
+
StructField* f;
|
271
|
+
MemoryOp* op;
|
272
|
+
VALUE argv[2];
|
273
|
+
|
274
|
+
Data_Get_Struct(self, Struct, s);
|
275
|
+
rbField = struct_field(s, fieldName);
|
276
|
+
f = (StructField *) DATA_PTR(rbField);
|
277
|
+
|
278
|
+
op = ptr_get_op(s->pointer, f->type);
|
279
|
+
if (op != NULL) {
|
280
|
+
(*op->put)(s->pointer, f->offset, value);
|
281
|
+
return self;
|
282
|
+
}
|
283
|
+
|
284
|
+
/* call up to the ruby code to set the value */
|
285
|
+
argv[0] = s->rbPointer;
|
286
|
+
argv[1] = value;
|
287
|
+
rb_funcall2(rbField, put_id, 2, argv);
|
288
|
+
|
289
|
+
return self;
|
290
|
+
}
|
291
|
+
|
292
|
+
static VALUE
|
293
|
+
struct_set_pointer(VALUE self, VALUE pointer)
|
294
|
+
{
|
295
|
+
Struct* s;
|
296
|
+
|
297
|
+
if (!rb_obj_is_kind_of(pointer, rbffi_AbstractMemoryClass)) {
|
298
|
+
rb_raise(rb_eArgError, "Invalid pointer");
|
299
|
+
}
|
300
|
+
|
301
|
+
Data_Get_Struct(self, Struct, s);
|
302
|
+
s->pointer = MEMORY(pointer);
|
303
|
+
s->rbPointer = pointer;
|
304
|
+
rb_ivar_set(self, pointer_var_id, pointer);
|
305
|
+
|
306
|
+
return self;
|
307
|
+
}
|
308
|
+
|
309
|
+
static VALUE
|
310
|
+
struct_get_pointer(VALUE self)
|
311
|
+
{
|
312
|
+
Struct* s;
|
313
|
+
|
314
|
+
Data_Get_Struct(self, Struct, s);
|
315
|
+
|
316
|
+
return s->rbPointer;
|
317
|
+
}
|
318
|
+
|
319
|
+
static VALUE
|
320
|
+
struct_set_layout(VALUE self, VALUE layout)
|
321
|
+
{
|
322
|
+
Struct* s;
|
323
|
+
Data_Get_Struct(self, Struct, s);
|
324
|
+
|
325
|
+
if (!rb_obj_is_kind_of(layout, StructLayoutClass)) {
|
326
|
+
rb_raise(rb_eArgError, "Invalid Struct layout");
|
327
|
+
}
|
328
|
+
|
329
|
+
Data_Get_Struct(layout, StructLayout, s->layout);
|
330
|
+
rb_ivar_set(self, layout_var_id, layout);
|
331
|
+
|
332
|
+
return self;
|
333
|
+
}
|
334
|
+
|
335
|
+
static VALUE
|
336
|
+
struct_get_layout(VALUE self)
|
337
|
+
{
|
338
|
+
Struct* s;
|
339
|
+
|
340
|
+
Data_Get_Struct(self, Struct, s);
|
341
|
+
|
342
|
+
return s->rbLayout;
|
343
|
+
}
|
344
|
+
|
345
|
+
static VALUE
|
346
|
+
struct_layout_allocate(VALUE klass)
|
347
|
+
{
|
348
|
+
StructLayout* layout;
|
349
|
+
VALUE obj;
|
350
|
+
|
351
|
+
obj = Data_Make_Struct(klass, StructLayout, struct_layout_mark, -1, layout);
|
352
|
+
layout->rbFields = Qnil;
|
353
|
+
|
354
|
+
return obj;
|
355
|
+
}
|
356
|
+
|
357
|
+
static VALUE
|
358
|
+
struct_layout_initialize(VALUE self, VALUE field_names, VALUE fields, VALUE size, VALUE align)
|
359
|
+
{
|
360
|
+
StructLayout* layout;
|
361
|
+
int i;
|
362
|
+
|
363
|
+
Data_Get_Struct(self, StructLayout, layout);
|
364
|
+
layout->rbFields = rb_hash_new();
|
365
|
+
layout->size = NUM2INT(size);
|
366
|
+
layout->align = NUM2INT(align);
|
367
|
+
|
368
|
+
rb_iv_set(self, "@field_names", field_names);
|
369
|
+
rb_iv_set(self, "@fields", fields);
|
370
|
+
rb_iv_set(self, "@size", size);
|
371
|
+
rb_iv_set(self, "@align", align);
|
372
|
+
|
373
|
+
for (i = 0; i < RARRAY_LEN(field_names); ++i) {
|
374
|
+
VALUE name = RARRAY_PTR(field_names)[i];
|
375
|
+
VALUE field = rb_hash_aref(fields, name);
|
376
|
+
if (TYPE(field) != T_DATA || !rb_obj_is_kind_of(field, StructFieldClass)) {
|
377
|
+
rb_raise(rb_eArgError, "Invalid field");
|
378
|
+
}
|
379
|
+
rb_hash_aset(layout->rbFields, name, field);
|
380
|
+
}
|
381
|
+
return self;
|
382
|
+
}
|
383
|
+
|
384
|
+
static VALUE
|
385
|
+
struct_layout_aref(VALUE self, VALUE field)
|
386
|
+
{
|
387
|
+
StructLayout* layout;
|
388
|
+
|
389
|
+
Data_Get_Struct(self, StructLayout, layout);
|
390
|
+
|
391
|
+
return rb_hash_aref(layout->rbFields, field);
|
392
|
+
}
|
393
|
+
|
394
|
+
|
395
|
+
static void
|
396
|
+
struct_layout_mark(StructLayout *layout)
|
397
|
+
{
|
398
|
+
rb_gc_mark(layout->rbFields);
|
399
|
+
}
|
400
|
+
|
401
|
+
void
|
402
|
+
rbffi_Struct_Init(VALUE moduleFFI)
|
403
|
+
{
|
404
|
+
VALUE klass, StructClass;
|
405
|
+
rbffi_StructClass = StructClass = rb_define_class_under(moduleFFI, "Struct", rb_cObject);
|
406
|
+
rb_global_variable(&rbffi_StructClass);
|
407
|
+
|
408
|
+
StructLayoutClass = rb_define_class_under(moduleFFI, "StructLayout", rb_cObject);
|
409
|
+
rb_global_variable(&StructLayoutClass);
|
410
|
+
|
411
|
+
StructLayoutBuilderClass = rb_define_class_under(moduleFFI, "StructLayoutBuilder", rb_cObject);
|
412
|
+
rb_global_variable(&StructLayoutBuilderClass);
|
413
|
+
|
414
|
+
StructFieldClass = rb_define_class_under(StructLayoutBuilderClass, "Field", rb_cObject);
|
415
|
+
rb_global_variable(&StructFieldClass);
|
416
|
+
|
417
|
+
rb_define_alloc_func(StructClass, struct_allocate);
|
418
|
+
rb_define_method(StructClass, "initialize", struct_initialize, -1);
|
419
|
+
|
420
|
+
rb_define_alias(rb_singleton_class(StructClass), "alloc_in", "new");
|
421
|
+
rb_define_alias(rb_singleton_class(StructClass), "alloc_out", "new");
|
422
|
+
rb_define_alias(rb_singleton_class(StructClass), "alloc_inout", "new");
|
423
|
+
rb_define_alias(rb_singleton_class(StructClass), "new_in", "new");
|
424
|
+
rb_define_alias(rb_singleton_class(StructClass), "new_out", "new");
|
425
|
+
rb_define_alias(rb_singleton_class(StructClass), "new_inout", "new");
|
426
|
+
|
427
|
+
rb_define_method(StructClass, "pointer", struct_get_pointer, 0);
|
428
|
+
rb_define_private_method(StructClass, "pointer=", struct_set_pointer, 1);
|
429
|
+
|
430
|
+
rb_define_method(StructClass, "layout", struct_get_layout, 0);
|
431
|
+
rb_define_private_method(StructClass, "layout=", struct_set_layout, 1);
|
432
|
+
|
433
|
+
rb_define_method(StructClass, "[]", struct_get_field, 1);
|
434
|
+
rb_define_method(StructClass, "[]=", struct_put_field, 2);
|
435
|
+
|
436
|
+
rb_define_alloc_func(StructFieldClass, struct_field_allocate);
|
437
|
+
rb_define_method(StructFieldClass, "initialize", struct_field_initialize, -1);
|
438
|
+
rb_define_method(StructFieldClass, "offset", struct_field_offset, 0);
|
439
|
+
rb_define_method(StructFieldClass, "put", struct_field_put, 2);
|
440
|
+
rb_define_method(StructFieldClass, "get", struct_field_get, 1);
|
441
|
+
|
442
|
+
rb_define_alloc_func(StructLayoutClass, struct_layout_allocate);
|
443
|
+
rb_define_method(StructLayoutClass, "initialize", struct_layout_initialize, 4);
|
444
|
+
rb_define_method(StructLayoutClass, "[]", struct_layout_aref, 1);
|
445
|
+
|
446
|
+
pointer_var_id = rb_intern("@pointer");
|
447
|
+
layout_var_id = rb_intern("@layout");
|
448
|
+
layout_id = rb_intern("layout");
|
449
|
+
get_id = rb_intern("get");
|
450
|
+
put_id = rb_intern("put");
|
451
|
+
to_ptr = rb_intern("to_ptr");
|
452
|
+
to_s = rb_intern("to_s");
|
453
|
+
SIZE_ID = rb_intern("SIZE");
|
454
|
+
ALIGN_ID = rb_intern("ALIGN");
|
455
|
+
TYPE_ID = rb_intern("TYPE");
|
456
|
+
#undef FIELD
|
457
|
+
#define FIELD(name, typeName, nativeType, T) do { \
|
458
|
+
typedef struct { char c; T v; } s; \
|
459
|
+
klass = rb_define_class_under(StructLayoutBuilderClass, #name, StructFieldClass); \
|
460
|
+
rb_define_const(klass, "ALIGN", INT2NUM((sizeof(s) - sizeof(T)))); \
|
461
|
+
rb_define_const(klass, "SIZE", INT2NUM(sizeof(T))); \
|
462
|
+
rb_define_const(klass, "TYPE", INT2NUM(nativeType)); \
|
463
|
+
} while(0)
|
464
|
+
|
465
|
+
FIELD(Signed8, int8, NATIVE_INT8, char);
|
466
|
+
FIELD(Unsigned8, uint8, NATIVE_UINT8, unsigned char);
|
467
|
+
FIELD(Signed16, int16, NATIVE_INT16, short);
|
468
|
+
FIELD(Unsigned16, uint16, NATIVE_UINT16, unsigned short);
|
469
|
+
FIELD(Signed32, int32, NATIVE_INT32, int);
|
470
|
+
FIELD(Unsigned32, uint32, NATIVE_UINT32, unsigned int);
|
471
|
+
FIELD(Signed64, int64, NATIVE_INT64, long long);
|
472
|
+
FIELD(Unsigned64, uint64, NATIVE_UINT64, unsigned long long);
|
473
|
+
FIELD(FloatField, float32, NATIVE_FLOAT32, float);
|
474
|
+
FIELD(DoubleField, float64, NATIVE_FLOAT64, double);
|
475
|
+
FIELD(PointerField, pointer, NATIVE_POINTER, char *);
|
476
|
+
FIELD(StringField, string, NATIVE_STRING, char *);
|
477
|
+
}
|