ffi 1.9.18 → 1.9.23

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.
Files changed (468) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +22 -0
  3. data/.gitmodules +3 -0
  4. data/.travis.yml +52 -0
  5. data/.yardopts +5 -0
  6. data/Gemfile +15 -0
  7. data/{spec/ffi/LICENSE.SPECS → LICENSE.SPECS} +1 -1
  8. data/README.md +3 -4
  9. data/Rakefile +41 -5
  10. data/appveyor.yml +22 -0
  11. data/ext/ffi_c/AbstractMemory.c +6 -1
  12. data/ext/ffi_c/Call.c +1 -22
  13. data/ext/ffi_c/Call.h +0 -9
  14. data/ext/ffi_c/Closure.c +54 -0
  15. data/ext/ffi_c/{ClosurePool.h → Closure.h} +13 -23
  16. data/ext/ffi_c/Function.c +16 -25
  17. data/ext/ffi_c/Function.h +1 -2
  18. data/ext/ffi_c/FunctionInfo.c +0 -4
  19. data/ext/ffi_c/MethodHandle.c +33 -268
  20. data/ext/ffi_c/Platform.c +10 -2
  21. data/ext/ffi_c/extconf.rb +10 -5
  22. data/ext/ffi_c/ffi.c +2 -2
  23. data/ext/ffi_c/libffi/.appveyor.yml +48 -0
  24. data/ext/ffi_c/libffi/.gitignore +36 -0
  25. data/ext/ffi_c/libffi/.travis/install.sh +14 -0
  26. data/ext/ffi_c/libffi/.travis.yml +30 -0
  27. data/ext/ffi_c/libffi/ChangeLog.libffi +2 -2
  28. data/ext/ffi_c/libffi/{ChangeLog → ChangeLog.libffi-3.1} +1402 -2
  29. data/ext/ffi_c/libffi/ChangeLog.v1 +1 -1
  30. data/ext/ffi_c/libffi/LICENSE +1 -1
  31. data/ext/ffi_c/libffi/Makefile.am +169 -158
  32. data/ext/ffi_c/libffi/Makefile.in +927 -938
  33. data/ext/ffi_c/libffi/README +164 -52
  34. data/ext/ffi_c/libffi/acinclude.m4 +387 -0
  35. data/ext/ffi_c/libffi/autogen.sh +2 -0
  36. data/ext/ffi_c/libffi/config.guess +336 -371
  37. data/ext/ffi_c/libffi/config.sub +246 -115
  38. data/ext/ffi_c/libffi/configure +6976 -2189
  39. data/ext/ffi_c/libffi/configure.ac +148 -256
  40. data/ext/ffi_c/libffi/configure.host +277 -4
  41. data/ext/ffi_c/libffi/doc/Makefile.am +3 -0
  42. data/ext/ffi_c/libffi/doc/Makefile.in +811 -0
  43. data/ext/ffi_c/libffi/doc/libffi.texi +430 -45
  44. data/ext/ffi_c/libffi/doc/version.texi +4 -4
  45. data/ext/ffi_c/libffi/fficonfig.h.in +24 -13
  46. data/ext/ffi_c/libffi/generate-darwin-source-and-headers.py +203 -0
  47. data/ext/ffi_c/libffi/include/Makefile.am +3 -3
  48. data/ext/ffi_c/libffi/include/Makefile.in +188 -71
  49. data/ext/ffi_c/libffi/include/ffi.h.in +112 -50
  50. data/ext/ffi_c/libffi/include/ffi_cfi.h +55 -0
  51. data/ext/ffi_c/libffi/include/ffi_common.h +32 -11
  52. data/ext/ffi_c/libffi/install-sh +190 -202
  53. data/ext/ffi_c/libffi/libffi.map.in +80 -0
  54. data/ext/ffi_c/libffi/libffi.pc.in +3 -2
  55. data/ext/ffi_c/libffi/libffi.xcodeproj/project.pbxproj +1043 -0
  56. data/ext/ffi_c/libffi/libtool-ldflags +106 -0
  57. data/ext/ffi_c/libffi/libtool-version +1 -1
  58. data/ext/ffi_c/libffi/ltmain.sh +3553 -2033
  59. data/ext/ffi_c/libffi/m4/asmcfi.m4 +13 -0
  60. data/ext/ffi_c/libffi/m4/ax_append_flag.m4 +69 -0
  61. data/ext/ffi_c/libffi/m4/ax_cc_maxopt.m4 +13 -8
  62. data/ext/ffi_c/libffi/m4/ax_cflags_warn_all.m4 +31 -104
  63. data/ext/ffi_c/libffi/m4/{ax_check_compiler_flags.m4 → ax_check_compile_flag.m4} +30 -34
  64. data/ext/ffi_c/libffi/m4/ax_compiler_vendor.m4 +32 -11
  65. data/ext/ffi_c/libffi/m4/ax_enable_builddir.m4 +6 -5
  66. data/ext/ffi_c/libffi/m4/ax_gcc_archflag.m4 +31 -21
  67. data/ext/ffi_c/libffi/man/Makefile.am +2 -2
  68. data/ext/ffi_c/libffi/man/Makefile.in +141 -49
  69. data/ext/ffi_c/libffi/man/ffi.3 +10 -0
  70. data/ext/ffi_c/libffi/man/ffi_prep_cif.3 +6 -4
  71. data/ext/ffi_c/libffi/man/ffi_prep_cif_var.3 +73 -0
  72. data/ext/ffi_c/libffi/missing +150 -311
  73. data/ext/ffi_c/libffi/msvcc.sh +72 -9
  74. data/ext/ffi_c/libffi/src/aarch64/ffi.c +964 -0
  75. data/ext/ffi_c/libffi/src/aarch64/ffitarget.h +81 -0
  76. data/ext/ffi_c/libffi/src/aarch64/internal.h +67 -0
  77. data/ext/ffi_c/libffi/src/aarch64/sysv.S +438 -0
  78. data/ext/ffi_c/libffi/src/alpha/ffi.c +335 -98
  79. data/ext/ffi_c/libffi/src/alpha/ffitarget.h +10 -1
  80. data/ext/ffi_c/libffi/src/alpha/internal.h +23 -0
  81. data/ext/ffi_c/libffi/src/alpha/osf.S +161 -266
  82. data/ext/ffi_c/libffi/src/arc/arcompact.S +135 -0
  83. data/ext/ffi_c/libffi/src/arc/ffi.c +266 -0
  84. data/ext/ffi_c/libffi/src/arc/ffitarget.h +53 -0
  85. data/ext/ffi_c/libffi/src/arm/ffi.c +608 -517
  86. data/ext/ffi_c/libffi/src/arm/ffitarget.h +24 -7
  87. data/ext/ffi_c/libffi/src/arm/internal.h +7 -0
  88. data/ext/ffi_c/libffi/src/arm/sysv.S +303 -417
  89. data/ext/ffi_c/libffi/src/avr32/ffitarget.h +6 -1
  90. data/ext/ffi_c/libffi/src/bfin/ffi.c +196 -0
  91. data/ext/ffi_c/libffi/src/bfin/ffitarget.h +43 -0
  92. data/ext/ffi_c/libffi/src/bfin/sysv.S +179 -0
  93. data/ext/ffi_c/libffi/src/closures.c +366 -45
  94. data/ext/ffi_c/libffi/src/cris/ffi.c +10 -7
  95. data/ext/ffi_c/libffi/src/cris/ffitarget.h +6 -1
  96. data/ext/ffi_c/libffi/src/debug.c +6 -1
  97. data/ext/ffi_c/libffi/src/dlmalloc.c +16 -11
  98. data/ext/ffi_c/libffi/src/frv/ffi.c +1 -1
  99. data/ext/ffi_c/libffi/src/frv/ffitarget.h +6 -1
  100. data/ext/ffi_c/libffi/src/ia64/ffi.c +11 -7
  101. data/ext/ffi_c/libffi/src/ia64/ffitarget.h +6 -1
  102. data/ext/ffi_c/libffi/src/ia64/unix.S +2 -0
  103. data/ext/ffi_c/libffi/src/java_raw_api.c +23 -5
  104. data/ext/ffi_c/libffi/src/m32r/ffi.c +1 -1
  105. data/ext/ffi_c/libffi/src/m32r/ffitarget.h +6 -1
  106. data/ext/ffi_c/libffi/src/m68k/ffi.c +87 -13
  107. data/ext/ffi_c/libffi/src/m68k/ffitarget.h +6 -1
  108. data/ext/ffi_c/libffi/src/m68k/sysv.S +119 -32
  109. data/ext/ffi_c/libffi/src/m88k/ffi.c +400 -0
  110. data/ext/ffi_c/libffi/src/m88k/ffitarget.h +49 -0
  111. data/ext/ffi_c/libffi/src/m88k/obsd.S +209 -0
  112. data/ext/ffi_c/libffi/src/metag/ffi.c +330 -0
  113. data/ext/ffi_c/libffi/{fficonfig.hw → src/metag/ffitarget.h} +22 -26
  114. data/ext/ffi_c/libffi/src/metag/sysv.S +311 -0
  115. data/ext/ffi_c/libffi/src/microblaze/ffi.c +321 -0
  116. data/ext/ffi_c/libffi/src/microblaze/ffitarget.h +53 -0
  117. data/ext/ffi_c/libffi/src/microblaze/sysv.S +302 -0
  118. data/ext/ffi_c/libffi/src/mips/ffi.c +103 -28
  119. data/ext/ffi_c/libffi/src/mips/ffitarget.h +10 -3
  120. data/ext/ffi_c/libffi/src/mips/n32.S +128 -56
  121. data/ext/ffi_c/libffi/src/mips/o32.S +148 -27
  122. data/ext/ffi_c/libffi/src/moxie/eabi.S +55 -82
  123. data/ext/ffi_c/libffi/src/moxie/ffi.c +40 -44
  124. data/ext/ffi_c/libffi/src/moxie/ffitarget.h +52 -0
  125. data/ext/ffi_c/libffi/src/nios2/ffi.c +304 -0
  126. data/ext/ffi_c/libffi/src/nios2/ffitarget.h +52 -0
  127. data/ext/ffi_c/libffi/src/nios2/sysv.S +136 -0
  128. data/ext/ffi_c/libffi/src/or1k/ffi.c +328 -0
  129. data/ext/ffi_c/libffi/src/or1k/ffitarget.h +58 -0
  130. data/ext/ffi_c/libffi/src/or1k/sysv.S +107 -0
  131. data/ext/ffi_c/libffi/src/pa/ffitarget.h +8 -1
  132. data/ext/ffi_c/libffi/src/powerpc/aix.S +245 -7
  133. data/ext/ffi_c/libffi/src/powerpc/aix_closure.S +253 -4
  134. data/ext/ffi_c/libffi/src/powerpc/asm.h +2 -2
  135. data/ext/ffi_c/libffi/src/powerpc/darwin.S +2 -7
  136. data/ext/ffi_c/libffi/src/powerpc/darwin_closure.S +22 -26
  137. data/ext/ffi_c/libffi/src/powerpc/ffi.c +103 -1378
  138. data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +111 -30
  139. data/ext/ffi_c/libffi/src/powerpc/ffi_linux64.c +945 -0
  140. data/ext/ffi_c/libffi/src/powerpc/ffi_powerpc.h +94 -0
  141. data/ext/ffi_c/libffi/src/powerpc/ffi_sysv.c +923 -0
  142. data/ext/ffi_c/libffi/src/powerpc/ffitarget.h +103 -44
  143. data/ext/ffi_c/libffi/src/powerpc/linux64.S +100 -59
  144. data/ext/ffi_c/libffi/src/powerpc/linux64_closure.S +360 -108
  145. data/ext/ffi_c/libffi/src/powerpc/ppc_closure.S +138 -68
  146. data/ext/ffi_c/libffi/src/powerpc/sysv.S +68 -112
  147. data/ext/ffi_c/libffi/src/prep_cif.c +108 -24
  148. data/ext/ffi_c/libffi/src/raw_api.c +18 -5
  149. data/ext/ffi_c/libffi/src/s390/ffi.c +294 -318
  150. data/ext/ffi_c/libffi/src/s390/ffitarget.h +9 -1
  151. data/ext/ffi_c/libffi/src/s390/internal.h +11 -0
  152. data/ext/ffi_c/libffi/src/s390/sysv.S +257 -366
  153. data/ext/ffi_c/libffi/src/sh/ffi.c +4 -3
  154. data/ext/ffi_c/libffi/src/sh/ffitarget.h +6 -1
  155. data/ext/ffi_c/libffi/src/sh64/ffi.c +3 -2
  156. data/ext/ffi_c/libffi/src/sh64/ffitarget.h +6 -1
  157. data/ext/ffi_c/libffi/src/sparc/ffi.c +326 -527
  158. data/ext/ffi_c/libffi/src/sparc/ffi64.c +608 -0
  159. data/ext/ffi_c/libffi/src/sparc/ffitarget.h +20 -7
  160. data/ext/ffi_c/libffi/src/sparc/internal.h +26 -0
  161. data/ext/ffi_c/libffi/src/sparc/v8.S +364 -234
  162. data/ext/ffi_c/libffi/src/sparc/v9.S +340 -207
  163. data/ext/ffi_c/libffi/src/tile/ffi.c +355 -0
  164. data/ext/ffi_c/libffi/src/tile/ffitarget.h +65 -0
  165. data/ext/ffi_c/libffi/src/tile/tile.S +360 -0
  166. data/ext/ffi_c/libffi/src/types.c +43 -14
  167. data/ext/ffi_c/libffi/src/vax/elfbsd.S +195 -0
  168. data/ext/ffi_c/libffi/src/vax/ffi.c +276 -0
  169. data/ext/ffi_c/libffi/src/vax/ffitarget.h +49 -0
  170. data/ext/ffi_c/libffi/src/x86/asmnames.h +30 -0
  171. data/ext/ffi_c/libffi/src/x86/ffi.c +591 -500
  172. data/ext/ffi_c/libffi/src/x86/ffi64.c +359 -116
  173. data/ext/ffi_c/libffi/src/x86/ffitarget.h +55 -35
  174. data/ext/ffi_c/libffi/src/x86/ffiw64.c +287 -0
  175. data/ext/ffi_c/libffi/src/x86/internal.h +29 -0
  176. data/ext/ffi_c/libffi/src/x86/internal64.h +22 -0
  177. data/ext/ffi_c/libffi/src/x86/sysv.S +975 -400
  178. data/ext/ffi_c/libffi/src/x86/unix64.S +398 -299
  179. data/ext/ffi_c/libffi/src/x86/win64.S +222 -458
  180. data/ext/ffi_c/libffi/src/x86/win64_intel.S +237 -0
  181. data/ext/ffi_c/libffi/src/xtensa/ffi.c +298 -0
  182. data/ext/ffi_c/libffi/src/xtensa/ffitarget.h +53 -0
  183. data/ext/ffi_c/libffi/src/xtensa/sysv.S +253 -0
  184. data/ext/ffi_c/libffi/stamp-h.in +1 -0
  185. data/ext/ffi_c/libffi/testsuite/Makefile.am +79 -73
  186. data/ext/ffi_c/libffi/testsuite/Makefile.in +219 -111
  187. data/ext/ffi_c/libffi/testsuite/lib/libffi.exp +121 -25
  188. data/ext/ffi_c/libffi/testsuite/lib/target-libpath.exp +21 -1
  189. data/ext/ffi_c/libffi/testsuite/libffi.call/align_mixed.c +46 -0
  190. data/ext/ffi_c/libffi/testsuite/libffi.call/call.exp +4 -6
  191. data/ext/ffi_c/libffi/testsuite/libffi.call/{closure_stdcall.c → closure_simple.c} +7 -16
  192. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_12byte.c +4 -4
  193. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_16byte.c +4 -4
  194. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_18byte.c +4 -4
  195. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_19byte.c +4 -4
  196. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_1_1byte.c +4 -4
  197. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_20byte.c +4 -4
  198. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_20byte1.c +4 -4
  199. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_24byte.c +5 -5
  200. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_2byte.c +4 -4
  201. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3_1byte.c +4 -4
  202. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3byte1.c +4 -4
  203. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3byte2.c +4 -4
  204. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3float.c +95 -0
  205. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_4_1byte.c +4 -4
  206. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_4byte.c +4 -4
  207. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_5_1_byte.c +4 -4
  208. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_5byte.c +4 -4
  209. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_64byte.c +5 -5
  210. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_6_1_byte.c +4 -4
  211. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_6byte.c +4 -4
  212. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_7_1_byte.c +4 -4
  213. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_7byte.c +4 -4
  214. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_8byte.c +4 -4
  215. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_9byte1.c +4 -4
  216. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_9byte2.c +4 -4
  217. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_double.c +4 -4
  218. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_float.c +4 -4
  219. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble.c +4 -4
  220. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble_split.c +4 -6
  221. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble_split2.c +4 -6
  222. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_pointer.c +4 -4
  223. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint16.c +4 -4
  224. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint32.c +4 -4
  225. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint64.c +4 -4
  226. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint16.c +4 -4
  227. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint32.c +4 -4
  228. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint64.c +4 -4
  229. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_dbls_struct.c +4 -4
  230. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_double_va.c +10 -9
  231. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_longdouble.c +3 -3
  232. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_longdouble_va.c +10 -9
  233. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_many_mixed_args.c +70 -0
  234. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_many_mixed_float_double.c +55 -0
  235. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_pointer.c +1 -1
  236. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_pointer_stack.c +11 -9
  237. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_struct_va1.c +114 -0
  238. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_uchar_va.c +44 -0
  239. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_uint_va.c +45 -0
  240. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ulong_va.c +45 -0
  241. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ulonglong.c +5 -5
  242. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ushort_va.c +44 -0
  243. data/ext/ffi_c/libffi/testsuite/libffi.call/err_bad_typedef.c +2 -2
  244. data/ext/ffi_c/libffi/testsuite/libffi.call/ffitest.h +23 -40
  245. data/ext/ffi_c/libffi/testsuite/libffi.call/float1.c +3 -1
  246. data/ext/ffi_c/libffi/testsuite/libffi.call/float2.c +6 -4
  247. data/ext/ffi_c/libffi/testsuite/libffi.call/float3.c +4 -2
  248. data/ext/ffi_c/libffi/testsuite/libffi.call/float_va.c +107 -0
  249. data/ext/ffi_c/libffi/testsuite/libffi.call/huge_struct.c +18 -19
  250. data/ext/ffi_c/libffi/testsuite/libffi.call/many.c +6 -16
  251. data/ext/ffi_c/libffi/testsuite/libffi.call/many2.c +57 -0
  252. data/ext/ffi_c/libffi/testsuite/libffi.call/many_double.c +70 -0
  253. data/ext/ffi_c/libffi/testsuite/libffi.call/many_mixed.c +78 -0
  254. data/ext/ffi_c/libffi/testsuite/libffi.call/negint.c +0 -1
  255. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct.c +6 -6
  256. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct1.c +8 -8
  257. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct10.c +6 -6
  258. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct11.c +121 -0
  259. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct2.c +5 -5
  260. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct3.c +5 -5
  261. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct4.c +5 -5
  262. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct5.c +5 -5
  263. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct6.c +6 -6
  264. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct7.c +5 -5
  265. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct8.c +6 -6
  266. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct9.c +6 -6
  267. data/ext/ffi_c/libffi/testsuite/libffi.call/offsets.c +46 -0
  268. data/ext/ffi_c/libffi/testsuite/libffi.call/pr1172638.c +127 -0
  269. data/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl.c +1 -0
  270. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ldl.c +1 -1
  271. data/ext/ffi_c/libffi/testsuite/libffi.call/return_sc.c +1 -1
  272. data/ext/ffi_c/libffi/testsuite/libffi.call/return_uc.c +1 -1
  273. data/ext/ffi_c/libffi/testsuite/libffi.call/stret_large.c +7 -7
  274. data/ext/ffi_c/libffi/testsuite/libffi.call/stret_large2.c +7 -7
  275. data/ext/ffi_c/libffi/testsuite/libffi.call/stret_medium.c +5 -5
  276. data/ext/ffi_c/libffi/testsuite/libffi.call/stret_medium2.c +5 -5
  277. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen.c +2 -2
  278. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen2.c +49 -0
  279. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen3.c +49 -0
  280. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen4.c +55 -0
  281. data/ext/ffi_c/libffi/testsuite/libffi.call/struct1.c +9 -7
  282. data/ext/ffi_c/libffi/testsuite/libffi.call/struct2.c +7 -7
  283. data/ext/ffi_c/libffi/testsuite/libffi.call/struct3.c +7 -6
  284. data/ext/ffi_c/libffi/testsuite/libffi.call/struct4.c +9 -8
  285. data/ext/ffi_c/libffi/testsuite/libffi.call/struct5.c +9 -8
  286. data/ext/ffi_c/libffi/testsuite/libffi.call/struct6.c +9 -9
  287. data/ext/ffi_c/libffi/testsuite/libffi.call/struct7.c +9 -9
  288. data/ext/ffi_c/libffi/testsuite/libffi.call/struct8.c +9 -8
  289. data/ext/ffi_c/libffi/testsuite/libffi.call/struct9.c +9 -8
  290. data/ext/ffi_c/libffi/testsuite/libffi.call/testclosure.c +2 -2
  291. data/ext/ffi_c/libffi/testsuite/libffi.call/uninitialized.c +61 -0
  292. data/ext/ffi_c/libffi/testsuite/{libffi.special → libffi.call}/unwindtest.cc +3 -10
  293. data/ext/ffi_c/libffi/testsuite/{libffi.special → libffi.call}/unwindtest_ffi_call.cc +2 -1
  294. data/ext/ffi_c/libffi/testsuite/libffi.call/va_1.c +196 -0
  295. data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct1.c +121 -0
  296. data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct2.c +123 -0
  297. data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct3.c +125 -0
  298. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex.inc +91 -0
  299. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex_double.c +10 -0
  300. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex_float.c +10 -0
  301. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex_longdouble.c +10 -0
  302. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex.inc +42 -0
  303. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_double.c +10 -0
  304. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_float.c +10 -0
  305. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_longdouble.c +10 -0
  306. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct.inc +71 -0
  307. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct_double.c +10 -0
  308. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct_float.c +10 -0
  309. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct_longdouble.c +10 -0
  310. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va.inc +80 -0
  311. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va_double.c +10 -0
  312. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va_float.c +16 -0
  313. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va_longdouble.c +10 -0
  314. data/ext/ffi_c/libffi/testsuite/{libffi.special/special.exp → libffi.complex/complex.exp} +9 -8
  315. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex.inc +51 -0
  316. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_defs_double.inc +7 -0
  317. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_defs_float.inc +7 -0
  318. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_defs_longdouble.inc +7 -0
  319. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_double.c +10 -0
  320. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_float.c +10 -0
  321. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_int.c +86 -0
  322. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_longdouble.c +10 -0
  323. data/ext/ffi_c/libffi/testsuite/libffi.complex/ffitest.h +1 -0
  324. data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex.inc +78 -0
  325. data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex_double.c +10 -0
  326. data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex_float.c +10 -0
  327. data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex_longdouble.c +10 -0
  328. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex.inc +37 -0
  329. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1.inc +41 -0
  330. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1_double.c +10 -0
  331. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1_float.c +10 -0
  332. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1_longdouble.c +10 -0
  333. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2.inc +44 -0
  334. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2_double.c +10 -0
  335. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2_float.c +10 -0
  336. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2_longdouble.c +10 -0
  337. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex_double.c +10 -0
  338. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex_float.c +10 -0
  339. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex_longdouble.c +10 -0
  340. data/ext/ffi_c/libffi/testsuite/libffi.go/aa-direct.c +34 -0
  341. data/ext/ffi_c/libffi/testsuite/libffi.go/closure1.c +28 -0
  342. data/ext/ffi_c/libffi/testsuite/libffi.go/ffitest.h +1 -0
  343. data/ext/ffi_c/libffi/testsuite/libffi.go/go.exp +36 -0
  344. data/ext/ffi_c/libffi/testsuite/libffi.go/static-chain.h +19 -0
  345. data/ext/ffi_c/libffi.bsd.mk +11 -5
  346. data/ext/ffi_c/libffi.darwin.mk +14 -4
  347. data/ext/ffi_c/libffi.gnu.mk +3 -2
  348. data/ext/ffi_c/libffi.mk +10 -5
  349. data/ext/ffi_c/libffi.vc.mk +1 -1
  350. data/ext/ffi_c/libffi.vc64.mk +1 -1
  351. data/ffi.gemspec +16 -3
  352. data/lib/ffi/enum.rb +124 -0
  353. data/lib/ffi/library.rb +66 -14
  354. data/lib/ffi/platform/sparc64-linux/types.conf +102 -0
  355. data/lib/ffi/platform/x86_64-windows/types.conf +113 -20
  356. data/lib/ffi/platform.rb +7 -2
  357. data/lib/ffi/pointer.rb +1 -0
  358. data/lib/ffi/struct.rb +0 -2
  359. data/lib/ffi/version.rb +1 -2
  360. data/samples/getlogin.rb +8 -0
  361. data/samples/getpid.rb +8 -0
  362. data/samples/gettimeofday.rb +18 -0
  363. data/samples/hello.rb +7 -0
  364. data/samples/inotify.rb +60 -0
  365. data/samples/pty.rb +76 -0
  366. data/samples/qsort.rb +21 -0
  367. data/samples/sample_helper.rb +6 -0
  368. metadata +164 -115
  369. data/ext/ffi_c/ClosurePool.c +0 -283
  370. data/ext/ffi_c/libffi/Makefile.vc +0 -141
  371. data/ext/ffi_c/libffi/Makefile.vc64 +0 -141
  372. data/ext/ffi_c/libffi/aclocal.m4 +0 -1873
  373. data/ext/ffi_c/libffi/build-ios.sh +0 -67
  374. data/ext/ffi_c/libffi/compile +0 -143
  375. data/ext/ffi_c/libffi/depcomp +0 -630
  376. data/ext/ffi_c/libffi/doc/libffi.info +0 -593
  377. data/ext/ffi_c/libffi/doc/stamp-vti +0 -4
  378. data/ext/ffi_c/libffi/include/ffi.h.vc +0 -427
  379. data/ext/ffi_c/libffi/include/ffi.h.vc64 +0 -427
  380. data/ext/ffi_c/libffi/m4/libtool.m4 +0 -7831
  381. data/ext/ffi_c/libffi/m4/ltoptions.m4 +0 -369
  382. data/ext/ffi_c/libffi/m4/ltsugar.m4 +0 -123
  383. data/ext/ffi_c/libffi/m4/ltversion.m4 +0 -23
  384. data/ext/ffi_c/libffi/m4/lt~obsolete.m4 +0 -98
  385. data/ext/ffi_c/libffi/mdate-sh +0 -201
  386. data/ext/ffi_c/libffi/src/arm/gentramp.sh +0 -118
  387. data/ext/ffi_c/libffi/src/arm/trampoline.S +0 -4450
  388. data/ext/ffi_c/libffi/src/x86/darwin.S +0 -444
  389. data/ext/ffi_c/libffi/src/x86/darwin64.S +0 -416
  390. data/ext/ffi_c/libffi/src/x86/freebsd.S +0 -458
  391. data/ext/ffi_c/libffi/src/x86/win32.S +0 -1065
  392. data/ext/ffi_c/libffi/testsuite/lib/libffi-dg.exp +0 -300
  393. data/ext/ffi_c/libffi/testsuite/libffi.call/many_win32.c +0 -63
  394. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen_win32.c +0 -44
  395. data/ext/ffi_c/libffi/testsuite/libffi.special/ffitestcxx.h +0 -96
  396. data/ext/ffi_c/libffi/texinfo.tex +0 -7210
  397. data/gen/Rakefile +0 -30
  398. data/libtest/Benchmark.c +0 -52
  399. data/libtest/BoolTest.c +0 -34
  400. data/libtest/BufferTest.c +0 -31
  401. data/libtest/ClosureTest.c +0 -205
  402. data/libtest/EnumTest.c +0 -51
  403. data/libtest/FunctionTest.c +0 -70
  404. data/libtest/GNUmakefile +0 -149
  405. data/libtest/GlobalVariable.c +0 -62
  406. data/libtest/LastErrorTest.c +0 -21
  407. data/libtest/NumberTest.c +0 -132
  408. data/libtest/PointerTest.c +0 -63
  409. data/libtest/ReferenceTest.c +0 -23
  410. data/libtest/StringTest.c +0 -34
  411. data/libtest/StructTest.c +0 -243
  412. data/libtest/UnionTest.c +0 -43
  413. data/libtest/VariadicTest.c +0 -99
  414. data/spec/ffi/async_callback_spec.rb +0 -35
  415. data/spec/ffi/bool_spec.rb +0 -32
  416. data/spec/ffi/buffer_spec.rb +0 -279
  417. data/spec/ffi/callback_spec.rb +0 -773
  418. data/spec/ffi/custom_param_type.rb +0 -37
  419. data/spec/ffi/custom_type_spec.rb +0 -74
  420. data/spec/ffi/dup_spec.rb +0 -52
  421. data/spec/ffi/enum_spec.rb +0 -423
  422. data/spec/ffi/errno_spec.rb +0 -20
  423. data/spec/ffi/ffi_spec.rb +0 -28
  424. data/spec/ffi/fixtures/Benchmark.c +0 -52
  425. data/spec/ffi/fixtures/BoolTest.c +0 -34
  426. data/spec/ffi/fixtures/BufferTest.c +0 -31
  427. data/spec/ffi/fixtures/ClosureTest.c +0 -205
  428. data/spec/ffi/fixtures/EnumTest.c +0 -51
  429. data/spec/ffi/fixtures/FunctionTest.c +0 -142
  430. data/spec/ffi/fixtures/GNUmakefile +0 -149
  431. data/spec/ffi/fixtures/GlobalVariable.c +0 -62
  432. data/spec/ffi/fixtures/LastErrorTest.c +0 -21
  433. data/spec/ffi/fixtures/NumberTest.c +0 -132
  434. data/spec/ffi/fixtures/PipeHelper.h +0 -21
  435. data/spec/ffi/fixtures/PipeHelperPosix.c +0 -41
  436. data/spec/ffi/fixtures/PipeHelperWindows.c +0 -72
  437. data/spec/ffi/fixtures/PointerTest.c +0 -63
  438. data/spec/ffi/fixtures/ReferenceTest.c +0 -23
  439. data/spec/ffi/fixtures/StringTest.c +0 -34
  440. data/spec/ffi/fixtures/StructTest.c +0 -243
  441. data/spec/ffi/fixtures/UnionTest.c +0 -43
  442. data/spec/ffi/fixtures/VariadicTest.c +0 -99
  443. data/spec/ffi/fixtures/classes.rb +0 -438
  444. data/spec/ffi/function_spec.rb +0 -97
  445. data/spec/ffi/io_spec.rb +0 -16
  446. data/spec/ffi/library_spec.rb +0 -286
  447. data/spec/ffi/long_double.rb +0 -30
  448. data/spec/ffi/managed_struct_spec.rb +0 -68
  449. data/spec/ffi/memorypointer_spec.rb +0 -78
  450. data/spec/ffi/number_spec.rb +0 -247
  451. data/spec/ffi/platform_spec.rb +0 -114
  452. data/spec/ffi/pointer_spec.rb +0 -285
  453. data/spec/ffi/rbx/attach_function_spec.rb +0 -34
  454. data/spec/ffi/rbx/memory_pointer_spec.rb +0 -194
  455. data/spec/ffi/rbx/spec_helper.rb +0 -6
  456. data/spec/ffi/rbx/struct_spec.rb +0 -18
  457. data/spec/ffi/spec_helper.rb +0 -93
  458. data/spec/ffi/string_spec.rb +0 -118
  459. data/spec/ffi/strptr_spec.rb +0 -50
  460. data/spec/ffi/struct_by_ref_spec.rb +0 -43
  461. data/spec/ffi/struct_callback_spec.rb +0 -69
  462. data/spec/ffi/struct_initialize_spec.rb +0 -35
  463. data/spec/ffi/struct_packed_spec.rb +0 -50
  464. data/spec/ffi/struct_spec.rb +0 -886
  465. data/spec/ffi/typedef_spec.rb +0 -91
  466. data/spec/ffi/union_spec.rb +0 -67
  467. data/spec/ffi/variadic_spec.rb +0 -132
  468. data/spec/spec.opts +0 -4
@@ -1,886 +0,0 @@
1
- #
2
- # This file is part of ruby-ffi.
3
- # For licensing, see LICENSE.SPECS
4
- #
5
-
6
- require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
7
-
8
- describe "Struct aligns fields correctly" do
9
- it "char, followed by an int" do
10
- pending("not supported in 1.8") if RUBY_VERSION =~ /^1\.8\..*/
11
- class CIStruct < FFI::Struct
12
- layout :c => :char, :i => :int
13
- end
14
- expect(CIStruct.size).to eq(8)
15
- end
16
-
17
- it "short, followed by an int" do
18
- pending("not supported in 1.8") if RUBY_VERSION =~ /^1\.8\..*/
19
- class SIStruct < FFI::Struct
20
- layout :s => :short, :i => :int
21
- end
22
- expect(SIStruct.size).to eq(8)
23
- end
24
-
25
- it "int, followed by an int" do
26
- pending("not supported in 1.8") if RUBY_VERSION =~ /^1\.8\..*/
27
- class IIStruct < FFI::Struct
28
- layout :i1 => :int, :i => :int
29
- end
30
- expect(IIStruct.size).to eq(8)
31
- end
32
-
33
- it "long long, followed by an int" do
34
- pending("not supported in 1.8") if RUBY_VERSION =~ /^1\.8\..*/
35
- class LLIStruct < FFI::Struct
36
- layout :l => :long_long, :i => :int
37
- end
38
- expect(LLIStruct.size).to eq(FFI::TYPE_UINT64.alignment == 4 ? 12 : 16)
39
- end
40
- end
41
-
42
- describe "Struct tests" do
43
- StructTypes = {
44
- 's8' => :char,
45
- 's16' => :short,
46
- 's32' => :int,
47
- 's64' => :long_long,
48
- 'long' => :long,
49
- 'f32' => :float,
50
- 'f64' => :double
51
- }
52
- module LibTest
53
- extend FFI::Library
54
- ffi_lib TestLibrary::PATH
55
- attach_function :ptr_ret_pointer, [ :pointer, :int], :string
56
- begin
57
- attach_function :ptr_ret_int32_t, [ :pointer, :int ], :int
58
- rescue FFI::NotFoundError
59
- # NetBSD uses #define instead of typedef for these
60
- attach_function :ptr_ret_int32_t, :ptr_ret___int32_t, [ :pointer, :int ], :int
61
- end
62
- attach_function :ptr_from_address, [ :ulong ], :pointer
63
- attach_function :string_equals, [ :string, :string ], :int
64
- [ 's8', 's16', 's32', 's64', 'f32', 'f64', 'long' ].each do |t|
65
- attach_function "struct_align_#{t}", [ :pointer ], StructTypes[t]
66
- end
67
- end
68
- class PointerMember < FFI::Struct
69
- layout :pointer, :pointer
70
- end
71
- class StringMember < FFI::Struct
72
- layout :string, :string
73
- end
74
-
75
- it "Struct#[:pointer]" do
76
- magic = 0x12345678
77
- mp = FFI::MemoryPointer.new :long
78
- mp.put_long(0, magic)
79
- smp = FFI::MemoryPointer.new :pointer
80
- smp.put_pointer(0, mp)
81
- s = PointerMember.new smp
82
- expect(s[:pointer]).to eq(mp)
83
- end
84
-
85
- it "Struct#[:pointer].nil? for NULL value" do
86
- magic = 0x12345678
87
- mp = FFI::MemoryPointer.new :long
88
- mp.put_long(0, magic)
89
- smp = FFI::MemoryPointer.new :pointer
90
- smp.put_pointer(0, nil)
91
- s = PointerMember.new smp
92
- expect(s[:pointer].null?).to be true
93
- end
94
-
95
- it "Struct#[:pointer]=" do
96
- magic = 0x12345678
97
- mp = FFI::MemoryPointer.new :long
98
- mp.put_long(0, magic)
99
- smp = FFI::MemoryPointer.new :pointer
100
- s = PointerMember.new smp
101
- s[:pointer] = mp
102
- expect(smp.get_pointer(0)).to eq(mp)
103
- end
104
-
105
- it "Struct#[:pointer]=struct" do
106
- smp = FFI::MemoryPointer.new :pointer
107
- s = PointerMember.new smp
108
- expect { s[:pointer] = s }.not_to raise_error Exception
109
- expect { s[:pointer].nil? }.not_to raise_error Exception
110
- end
111
-
112
- it "Struct#[:pointer]=nil" do
113
- smp = FFI::MemoryPointer.new :pointer
114
- s = PointerMember.new smp
115
- s[:pointer] = nil
116
- expect(smp.get_pointer(0)).to be_null
117
- end
118
-
119
- it "Struct#[:string]" do
120
- magic = "test"
121
- mp = FFI::MemoryPointer.new 1024
122
- mp.put_string(0, magic)
123
- smp = FFI::MemoryPointer.new :pointer
124
- smp.put_pointer(0, mp)
125
- s = StringMember.new smp
126
- expect(s[:string]).to eq(magic)
127
- end
128
-
129
- it "Struct#[:string].nil? for NULL value" do
130
- smp = FFI::MemoryPointer.new :pointer
131
- smp.put_pointer(0, nil)
132
- s = StringMember.new smp
133
- expect(s[:string]).to be_nil
134
- end
135
-
136
- it "Struct#layout works with :name, :type pairs" do
137
- class PairLayout < FFI::Struct
138
- layout :a, :int, :b, :long_long
139
- end
140
- ll_off = (FFI::TYPE_UINT64.alignment == 4 ? 4 : 8)
141
- expect(PairLayout.size).to eq((ll_off + 8))
142
- mp = FFI::MemoryPointer.new(PairLayout.size)
143
- s = PairLayout.new mp
144
- s[:a] = 0x12345678
145
- expect(mp.get_int(0)).to eq(0x12345678)
146
- s[:b] = 0xfee1deadbeef
147
- expect(mp.get_int64(ll_off)).to eq(0xfee1deadbeef)
148
- end
149
-
150
- it "Struct#layout works with :name, :type, offset tuples" do
151
- class PairLayout < FFI::Struct
152
- layout :a, :int, 0, :b, :long_long, 4
153
- end
154
- expect(PairLayout.size).to eq((FFI::TYPE_UINT64.alignment == 4 ? 12 : 16))
155
- mp = FFI::MemoryPointer.new(PairLayout.size)
156
- s = PairLayout.new mp
157
- s[:a] = 0x12345678
158
- expect(mp.get_int(0)).to eq(0x12345678)
159
- s[:b] = 0xfee1deadbeef
160
- expect(mp.get_int64(4)).to eq(0xfee1deadbeef)
161
- end
162
-
163
- it "Struct#layout works with mixed :name,:type and :name,:type,offset" do
164
- class MixedLayout < FFI::Struct
165
- layout :a, :int, :b, :long_long, 4
166
- end
167
- expect(MixedLayout.size).to eq((FFI::TYPE_UINT64.alignment == 4 ? 12 : 16))
168
- mp = FFI::MemoryPointer.new(MixedLayout.size)
169
- s = MixedLayout.new mp
170
- s[:a] = 0x12345678
171
- expect(mp.get_int(0)).to eq(0x12345678)
172
- s[:b] = 0xfee1deadbeef
173
- expect(mp.get_int64(4)).to eq(0xfee1deadbeef)
174
- end
175
-
176
- rb_maj, rb_min = RUBY_VERSION.split('.')
177
- if rb_maj.to_i >= 1 && rb_min.to_i >= 9 || RUBY_PLATFORM =~ /java/
178
- it "Struct#layout withs with a hash of :name => type" do
179
- class HashLayout < FFI::Struct
180
- layout :a => :int, :b => :long_long
181
- end
182
- ll_off = (FFI::TYPE_UINT64.alignment == 4 ? 4 : 8)
183
- expect(HashLayout.size).to eq(ll_off + 8)
184
- mp = FFI::MemoryPointer.new(HashLayout.size)
185
- s = HashLayout.new mp
186
- s[:a] = 0x12345678
187
- expect(mp.get_int(0)).to eq(0x12345678)
188
- s[:b] = 0xfee1deadbeef
189
- expect(mp.get_int64(ll_off)).to eq(0xfee1deadbeef)
190
- end
191
- end
192
-
193
- it "subclass overrides initialize without calling super" do
194
- class InitializeWithoutSuper < FFI::Struct
195
- layout :a, :int, :b, :long_long, :d, [:double, 2]
196
-
197
- def initialize(a, b)
198
- self[:a] = a
199
- self[:b] = b
200
- self[:d][0] = 1.2
201
- self[:d][1] = 3.4
202
- end
203
-
204
- end
205
- s = InitializeWithoutSuper.new(0x1eefbeef, 0xdeadcafebabe)
206
- expect(s[:a]).to eq(0x1eefbeef)
207
- expect(s[:b]).to eq(0xdeadcafebabe)
208
- end
209
-
210
- it "Can use Struct subclass as parameter type" do
211
- expect(module StructParam
212
- extend FFI::Library
213
- ffi_lib TestLibrary::PATH
214
- class TestStruct < FFI::Struct
215
- layout :c, :char
216
- end
217
- attach_function :struct_field_s8, [ TestStruct.in ], :char
218
- end).to be_an_instance_of FFI::Function
219
- end
220
-
221
- it "Can use Struct subclass as IN parameter type" do
222
- expect(module StructParam2
223
- extend FFI::Library
224
- ffi_lib TestLibrary::PATH
225
- class TestStruct < FFI::Struct
226
- layout :c, :char
227
- end
228
- attach_function :struct_field_s8, [ TestStruct.in ], :char
229
- end).to be_an_instance_of FFI::Function
230
- end
231
-
232
- it "Can use Struct subclass as OUT parameter type" do
233
- expect(module StructParam3
234
- extend FFI::Library
235
- ffi_lib TestLibrary::PATH
236
- class TestStruct < FFI::Struct
237
- layout :c, :char
238
- end
239
- attach_function :struct_field_s8, [ TestStruct.out ], :char
240
- end).to be_an_instance_of FFI::Function
241
- end
242
-
243
- it "can be passed directly as a :pointer parameter" do
244
- class TestStruct < FFI::Struct
245
- layout :i, :int
246
- end
247
- s = TestStruct.new
248
- s[:i] = 0x12
249
- expect(LibTest.ptr_ret_int32_t(s, 0)).to eq(0x12)
250
- end
251
-
252
- it ":char member aligned correctly" do
253
- class AlignChar < FFI::Struct
254
- layout :c, :char, :v, :char
255
- end
256
- s = AlignChar.new
257
- s[:v] = 0x12
258
- expect(LibTest.struct_align_s8(s.pointer)).to eq(0x12)
259
- end
260
-
261
- it ":short member aligned correctly" do
262
- class AlignShort < FFI::Struct
263
- layout :c, :char, :v, :short
264
- end
265
- s = AlignShort.alloc_in
266
- s[:v] = 0x1234
267
- expect(LibTest.struct_align_s16(s.pointer)).to eq(0x1234)
268
- end
269
-
270
- it ":int member aligned correctly" do
271
- class AlignInt < FFI::Struct
272
- layout :c, :char, :v, :int
273
- end
274
- s = AlignInt.alloc_in
275
- s[:v] = 0x12345678
276
- expect(LibTest.struct_align_s32(s.pointer)).to eq(0x12345678)
277
- end
278
-
279
- it ":long_long member aligned correctly" do
280
- class AlignLongLong < FFI::Struct
281
- layout :c, :char, :v, :long_long
282
- end
283
- s = AlignLongLong.alloc_in
284
- s[:v] = 0x123456789abcdef0
285
- expect(LibTest.struct_align_s64(s.pointer)).to eq(0x123456789abcdef0)
286
- end
287
-
288
- it ":long member aligned correctly" do
289
- class AlignLong < FFI::Struct
290
- layout :c, :char, :v, :long
291
- end
292
- s = AlignLong.alloc_in
293
- s[:v] = 0x12345678
294
- expect(LibTest.struct_align_long(s.pointer)).to eq(0x12345678)
295
- end
296
-
297
- it ":float member aligned correctly" do
298
- class AlignFloat < FFI::Struct
299
- layout :c, :char, :v, :float
300
- end
301
- s = AlignFloat.alloc_in
302
- s[:v] = 1.23456
303
- expect((LibTest.struct_align_f32(s.pointer) - 1.23456).abs).to be < 0.00001
304
- end
305
-
306
- it ":double member aligned correctly" do
307
- class AlignDouble < FFI::Struct
308
- layout :c, :char, :v, :double
309
- end
310
- s = AlignDouble.alloc_in
311
- s[:v] = 1.23456789
312
- expect((LibTest.struct_align_f64(s.pointer) - 1.23456789).abs).to be < 0.00000001
313
- end
314
-
315
- it ":ulong, :pointer struct" do
316
- class ULPStruct < FFI::Struct
317
- layout :ul, :ulong, :p, :pointer
318
- end
319
- s = ULPStruct.alloc_in
320
- s[:ul] = 0xdeadbeef
321
- s[:p] = LibTest.ptr_from_address(0x12345678)
322
- expect(s.pointer.get_ulong(0)).to eq(0xdeadbeef)
323
- end
324
- def test_num_field(type, v)
325
- klass = Class.new(FFI::Struct)
326
- klass.layout :v, type, :dummy, :long
327
-
328
- s = klass.new
329
- s[:v] = v
330
- expect(s.pointer.send("get_#{type.to_s}", 0)).to eq(v)
331
- s.pointer.send("put_#{type.to_s}", 0, 0)
332
- expect(s[:v]).to eq(0)
333
- end
334
- def self.int_field_test(type, values)
335
- values.each do |v|
336
- it "#{type} field r/w (#{v.to_s(16)})" do
337
- test_num_field(type, v)
338
- end
339
- end
340
- end
341
- int_field_test(:char, [ 0, 127, -128, -1 ])
342
- int_field_test(:uchar, [ 0, 0x7f, 0x80, 0xff ])
343
- int_field_test(:short, [ 0, 0x7fff, -0x8000, -1 ])
344
- int_field_test(:ushort, [ 0, 0x7fff, 0x8000, 0xffff ])
345
- int_field_test(:int, [ 0, 0x7fffffff, -0x80000000, -1 ])
346
- int_field_test(:uint, [ 0, 0x7fffffff, 0x80000000, 0xffffffff ])
347
- int_field_test(:long_long, [ 0, 0x7fffffffffffffff, -0x8000000000000000, -1 ])
348
- int_field_test(:ulong_long, [ 0, 0x7fffffffffffffff, 0x8000000000000000, 0xffffffffffffffff ])
349
- if FFI::Platform::LONG_SIZE == 32
350
- int_field_test(:long, [ 0, 0x7fffffff, -0x80000000, -1 ])
351
- int_field_test(:ulong, [ 0, 0x7fffffff, 0x80000000, 0xffffffff ])
352
- else
353
- int_field_test(:long, [ 0, 0x7fffffffffffffff, -0x8000000000000000, -1 ])
354
- int_field_test(:ulong, [ 0, 0x7fffffffffffffff, 0x8000000000000000, 0xffffffffffffffff ])
355
- end
356
-
357
- it ":float field r/w" do
358
- klass = Class.new(FFI::Struct)
359
- klass.layout :v, :float, :dummy, :long
360
-
361
- s = klass.new
362
- value = 1.23456
363
- s[:v] = value
364
- expect((s.pointer.get_float(0) - value).abs).to be < 0.0001
365
- end
366
-
367
- it ":double field r/w" do
368
- klass = Class.new(FFI::Struct)
369
- klass.layout :v, :double, :dummy, :long
370
-
371
- s = klass.new
372
- value = 1.23456
373
- s[:v] = value
374
- expect((s.pointer.get_double(0) - value).abs).to be < 0.0001
375
- end
376
- module EnumFields
377
- extend FFI::Library
378
- TestEnum = enum :test_enum, [:c1, 10, :c2, 20, :c3, 30, :c4, 40]
379
- class TestStruct < FFI::Struct
380
- layout :a, :int, :c, :test_enum,
381
- :d, [ TestEnum, TestEnum.symbols.length ]
382
- end
383
- end
384
-
385
- it ":enum field r/w" do
386
- s = EnumFields::TestStruct.new
387
- s[:c] = :c3
388
-
389
- expect(s.pointer.get_uint(FFI::Type::INT32.size)).to eq(30)
390
- expect(s[:c]).to eq(:c3)
391
- end
392
-
393
- it "array of :enum field" do
394
- s = EnumFields::TestStruct.new
395
- EnumFields::TestEnum.symbols.each_with_index do |val, i|
396
- s[:d][i] = val
397
- end
398
-
399
- EnumFields::TestEnum.symbols.each_with_index do |val, i|
400
- expect(s.pointer.get_uint(FFI::Type::INT32.size * (2 + i))).to eq(EnumFields::TestEnum[val])
401
- end
402
-
403
- s[:d].each_with_index do |val, i|
404
- expect(val).to eq(EnumFields::TestEnum.symbols[i])
405
- end
406
- end
407
-
408
- module CallbackMember
409
- extend FFI::Library
410
- ffi_lib TestLibrary::PATH
411
- callback :add, [ :int, :int ], :int
412
- callback :sub, [ :int, :int ], :int
413
- class TestStruct < FFI::Struct
414
- layout :add, :add,
415
- :sub, :sub
416
- end
417
- attach_function :struct_call_add_cb, [TestStruct.in, :int, :int], :int
418
- attach_function :struct_call_sub_cb, [TestStruct.in, :int, :int], :int
419
- end
420
-
421
- it "Can have CallbackInfo struct field" do
422
- s = CallbackMember::TestStruct.new
423
- add_proc = lambda { |a, b| a+b }
424
- sub_proc = lambda { |a, b| a-b }
425
- s[:add] = add_proc
426
- s[:sub] = sub_proc
427
- expect(CallbackMember.struct_call_add_cb(s, 40, 2)).to eq(42)
428
- expect(CallbackMember.struct_call_sub_cb(s, 44, 2)).to eq(42)
429
- end
430
-
431
- it "Can return its members as a list" do
432
- class TestStruct < FFI::Struct
433
- layout :a, :int, :b, :int, :c, :int
434
- end
435
- expect(TestStruct.members).to include(:a, :b, :c)
436
- end
437
-
438
- it "Can return its instance members and values as lists" do
439
- class TestStruct < FFI::Struct
440
- layout :a, :int, :b, :int, :c, :int
441
- end
442
- s = TestStruct.new
443
- expect(s.members).to include(:a, :b, :c)
444
- s[:a] = 1
445
- s[:b] = 2
446
- s[:c] = 3
447
- expect(s.values).to include(1, 2, 3)
448
- end
449
-
450
- it 'should return an ordered field/offset pairs array' do
451
- class TestStruct < FFI::Struct
452
- layout :a, :int, :b, :int, :c, :int
453
- end
454
- s = TestStruct.new
455
- expect(s.offsets).to eq([[:a, 0], [:b, 4], [:c, 8]])
456
- expect(TestStruct.offsets).to eq([[:a, 0], [:b, 4], [:c, 8]])
457
- end
458
-
459
- it "Struct#offset_of returns offset of field within struct" do
460
- class TestStruct < FFI::Struct
461
- layout :a, :int, :b, :int, :c, :int
462
- end
463
- expect(TestStruct.offset_of(:a)).to eq(0)
464
- expect(TestStruct.offset_of(:b)).to eq(4)
465
- expect(TestStruct.offset_of(:c)).to eq(8)
466
- end
467
- end
468
-
469
- describe FFI::Struct, ".layout" do
470
- module FFISpecs
471
- module LibTest
472
- extend FFI::Library
473
- ffi_lib TestLibrary::PATH
474
- begin
475
- attach_function :ptr_ret_int32_t, [ :pointer, :int ], :int
476
- rescue FFI::NotFoundError
477
- # NetBSD uses #define instead of typedef for these
478
- attach_function :ptr_ret_int32_t, :ptr_ret___int32_t, [ :pointer, :int ], :int
479
- end
480
- end
481
- end
482
-
483
- describe "when derived class is not assigned to any constant" do
484
- it "resolves a built-in type" do
485
- klass = Class.new FFI::Struct
486
- klass.layout :number, :int
487
-
488
- instance = klass.new
489
- instance[:number] = 0xA1
490
- expect(FFISpecs::LibTest.ptr_ret_int32_t(instance, 0)).to eq(0xA1)
491
- end
492
- end
493
-
494
- describe "when derived class is assigned to a constant" do
495
- it "resolves a built-in type" do
496
- class FFISpecs::TestStruct < FFI::Struct
497
- layout :number, :int
498
- end
499
-
500
- instance = FFISpecs::TestStruct.new
501
- instance[:number] = 0xA1
502
- expect(FFISpecs::LibTest.ptr_ret_int32_t(instance, 0)).to eq(0xA1)
503
- end
504
-
505
- it "resolves a type from the enclosing module" do
506
- module FFISpecs::LibTest
507
- typedef :uint, :custom_int
508
-
509
- class TestStruct < FFI::Struct
510
- layout :number, :custom_int
511
- end
512
- end
513
-
514
- instance = FFISpecs::LibTest::TestStruct.new
515
- instance[:number] = 0xA1
516
- expect(FFISpecs::LibTest.ptr_ret_int32_t(instance, 0)).to eq(0xA1)
517
- end
518
- end
519
- end
520
-
521
- describe FFI::Struct, ' with a nested struct field' do
522
- module LibTest
523
- extend FFI::Library
524
- ffi_lib TestLibrary::PATH
525
- class NestedStruct < FFI::Struct
526
- layout :i, :int
527
- end
528
- class ContainerStruct < FFI::Struct
529
- layout :first, :char, :ns, NestedStruct
530
- end
531
- attach_function :struct_align_nested_struct, [ :pointer ], :int
532
- attach_function :struct_make_container_struct, [ :int ], :pointer
533
- end
534
- before do
535
- @cs = LibTest::ContainerStruct.new
536
- end
537
-
538
- it 'should align correctly nested struct field' do
539
- @cs[:ns][:i] = 123
540
- expect(LibTest.struct_align_nested_struct(@cs.to_ptr)).to eq(123)
541
- end
542
-
543
- it 'should correctly calculate Container size (in bytes)' do
544
- expect(LibTest::ContainerStruct.size).to eq(8)
545
- end
546
-
547
- it 'should return a Struct object when the field is accessed' do
548
- expect(@cs[:ns].is_a?(FFI::Struct)).to be true
549
- end
550
-
551
- it 'should read a value from memory' do
552
- @cs = LibTest::ContainerStruct.new(LibTest.struct_make_container_struct(123))
553
- expect(@cs[:ns][:i]).to eq(123)
554
- end
555
-
556
- it 'should write a value to memory' do
557
- @cs = LibTest::ContainerStruct.new(LibTest.struct_make_container_struct(123))
558
- @cs[:ns][:i] = 456
559
- expect(LibTest.struct_align_nested_struct(@cs.to_ptr)).to eq(456)
560
- end
561
-
562
- it 'should be able to assign struct instance to nested field' do
563
- cs = LibTest::ContainerStruct.new(LibTest.struct_make_container_struct(123))
564
- ns = LibTest::NestedStruct.new
565
- ns[:i] = 567
566
- cs[:ns] = ns
567
- expect(cs[:ns][:i]).to eq(567)
568
- expect(LibTest.struct_align_nested_struct(cs.to_ptr)).to eq(567)
569
- end
570
- end
571
-
572
- describe FFI::Struct, ' with a nested array of structs' do
573
- module InlineArrayOfStructs
574
- extend FFI::Library
575
- ffi_lib TestLibrary::PATH
576
- class NestedStruct < FFI::Struct
577
- layout :i, :int
578
- end
579
- class ContainerStruct < FFI::Struct
580
- layout :first, :char, :ns, [ NestedStruct, 1 ]
581
- end
582
- attach_function :struct_align_nested_struct, [ :pointer ], :int
583
- attach_function :struct_make_container_struct, [ :int ], :pointer
584
- end
585
-
586
- before do
587
- @cs = InlineArrayOfStructs::ContainerStruct.new
588
- end
589
-
590
- it 'should align correctly nested struct field' do
591
- @cs[:ns][0][:i] = 123
592
- expect(InlineArrayOfStructs.struct_align_nested_struct(@cs.to_ptr)).to eq(123)
593
- end
594
-
595
- it 'should correctly calculate Container size (in bytes)' do
596
- expect(InlineArrayOfStructs::ContainerStruct.size).to eq(8)
597
- end
598
-
599
- it 'should return a Struct object when the field is accessed' do
600
- expect(@cs[:ns][0].is_a?(FFI::Struct)).to be true
601
- end
602
-
603
- it 'should read a value from memory' do
604
- @cs = InlineArrayOfStructs::ContainerStruct.new(InlineArrayOfStructs.struct_make_container_struct(123))
605
- expect(@cs[:ns][0][:i]).to eq(123)
606
- end
607
-
608
- it 'should write a value to memory' do
609
- @cs = InlineArrayOfStructs::ContainerStruct.new(InlineArrayOfStructs.struct_make_container_struct(123))
610
- @cs[:ns][0][:i] = 456
611
- expect(InlineArrayOfStructs.struct_align_nested_struct(@cs.to_ptr)).to eq(456)
612
- end
613
-
614
- it 'should support Enumerable#each' do
615
- @cs = InlineArrayOfStructs::ContainerStruct.new(InlineArrayOfStructs.struct_make_container_struct(123))
616
- ints = []
617
- @cs[:ns].each { |s| ints << s[:i] }
618
- expect(ints[0]).to eq(123)
619
- end
620
- end
621
-
622
- describe FFI::Struct, ' by value' do
623
- module LibTest
624
- extend FFI::Library
625
- ffi_lib TestLibrary::PATH
626
-
627
- class S8S32 < FFI::Struct
628
- layout :s8, :char, :s32, :int
629
- end
630
-
631
- class StructString < FFI::Struct
632
- layout :bytes, :string, :len, :int
633
- end
634
-
635
- attach_function :struct_return_s8s32, [ ], S8S32.by_value
636
- attach_function :struct_s8s32_set, [ :char, :int ], S8S32.by_value
637
- attach_function :struct_s8s32_get_s8, [ S8S32.by_value ], :char
638
- attach_function :struct_s8s32_get_s32, [ S8S32.by_value ], :int
639
- attach_function :struct_s8s32_s32_ret_s32, [ S8S32.by_value, :int ], :int
640
- attach_function :struct_s8s32_s64_ret_s64, [ S8S32.by_value, :long_long ], :long_long
641
- attach_function :struct_s8s32_ret_s8s32, [ S8S32.by_value ], S8S32.by_value
642
- attach_function :struct_s32_ptr_s32_s8s32_ret_s32, [ :int, :pointer, :int, S8S32.by_value ], :int
643
- attach_function :struct_varargs_ret_struct_string, [ :int, :varargs ], StructString.by_value
644
- end
645
-
646
- it 'return using pre-set values' do
647
- s = LibTest.struct_return_s8s32
648
- expect(s[:s8]).to eq(0x7f)
649
- expect(s[:s32]).to eq(0x12345678)
650
- end
651
-
652
- it 'return using passed in values' do
653
- s = LibTest.struct_s8s32_set(123, 456789)
654
- expect(s[:s8]).to eq(123)
655
- expect(s[:s32]).to eq(456789)
656
- end
657
-
658
- it 'parameter' do
659
- s = LibTest::S8S32.new
660
- s[:s8] = 0x12
661
- s[:s32] = 0x34567890
662
- expect(LibTest.struct_s8s32_get_s8(s)).to eq(0x12)
663
- expect(LibTest.struct_s8s32_get_s32(s)).to eq(0x34567890)
664
- end
665
-
666
- it 'parameter with following s32' do
667
- s = LibTest::S8S32.new
668
- s[:s8] = 0x12
669
- s[:s32] = 0x34567890
670
-
671
- expect(LibTest.struct_s8s32_s32_ret_s32(s, 0x1eefdead)).to eq(0x1eefdead)
672
- end
673
-
674
- # it 'parameter with following s64' do
675
- # s = LibTest::S8S64.new
676
- # s[:s8] = 0x12
677
- # s[:s64] = 0x34567890
678
- #
679
- #
680
- # LibTest.struct_s8s64_s64_ret_s64(s, 0x1eefdead1eefdead).should == 0x1eefdead1eefdead
681
- # end
682
-
683
- it 'parameter with preceding s32,ptr,s32' do
684
- s = LibTest::S8S32.new
685
- s[:s8] = 0x12
686
- s[:s32] = 0x34567890
687
- out = LibTest::S8S32.new
688
- expect(LibTest.struct_s32_ptr_s32_s8s32_ret_s32(0x1000000, out, 0x1eafbeef, s)).to eq(0x34567890)
689
- expect(out[:s8]).to eq(s[:s8])
690
- expect(out[:s32]).to eq(s[:s32])
691
- end
692
-
693
- it 'parameter with preceding s32,string,s32' do
694
- s = LibTest::S8S32.new
695
- s[:s8] = 0x12
696
- s[:s32] = 0x34567890
697
- out = 0.chr * 32
698
- expect(LibTest.struct_s32_ptr_s32_s8s32_ret_s32(0x1000000, out, 0x1eafbeef, s)).to eq(0x34567890)
699
- end
700
-
701
- it 'parameter, returning struct by value' do
702
- s = LibTest::S8S32.new
703
- s[:s8] = 0x12
704
- s[:s32] = 0x34567890
705
-
706
- ret = LibTest.struct_s8s32_ret_s8s32(s)
707
- expect(ret[:s8]).to eq(s[:s8])
708
- expect(ret[:s32]).to eq(s[:s32])
709
- end
710
-
711
- it 'varargs returning a struct' do
712
- string = "test"
713
- s = LibTest.struct_varargs_ret_struct_string(4, :string, string)
714
- expect(s[:len]).to eq(string.length)
715
- expect(s[:bytes]).to eq(string)
716
- end
717
- end
718
-
719
- describe FFI::Struct, ' with an array field' do
720
- module LibTest
721
- extend FFI::Library
722
- ffi_lib TestLibrary::PATH
723
- class StructWithArray < FFI::Struct
724
- layout :first, :char, :a, [:int, 5]
725
- end
726
- attach_function :struct_make_struct_with_array, [:int, :int, :int, :int, :int], :pointer
727
- attach_function :struct_field_array, [:pointer], :pointer
728
- end
729
- before do
730
- @s = LibTest::StructWithArray.new
731
- end
732
-
733
- it 'should correctly calculate StructWithArray size (in bytes)' do
734
- expect(LibTest::StructWithArray.size).to eq(24)
735
- end
736
-
737
- it 'should read values from memory' do
738
- @s = LibTest::StructWithArray.new(LibTest.struct_make_struct_with_array(0, 1, 2, 3, 4))
739
- expect(@s[:a].to_a).to eq([0, 1, 2, 3, 4])
740
- end
741
- # it 'should cache array object for successive calls' do
742
- # @s[:a].object_id.should == @s[:a].object_id
743
- # end
744
-
745
- it 'should return the number of elements in the array field' do
746
- @s = LibTest::StructWithArray.new(LibTest.struct_make_struct_with_array(0, 1, 2, 3, 4))
747
- expect(@s[:a].size).to eq(5)
748
- end
749
-
750
- it 'should allow iteration through the array elements' do
751
- @s = LibTest::StructWithArray.new(LibTest.struct_make_struct_with_array(0, 1, 2, 3, 4))
752
- @s[:a].each_with_index { |elem, i| expect(elem).to eq(i) }
753
- end
754
-
755
- it 'should return the pointer to the array' do
756
- @s = LibTest::StructWithArray.new(LibTest.struct_make_struct_with_array(0, 1, 2, 3, 4))
757
- expect(@s[:a].to_ptr).to eq(LibTest::struct_field_array(@s.to_ptr))
758
- end
759
- end
760
-
761
- describe 'BuggedStruct' do
762
- module LibTest
763
- extend FFI::Library
764
- ffi_lib TestLibrary::PATH
765
- class BuggedStruct < FFI::Struct
766
- layout :visible, :uchar,
767
- :x, :uint,
768
- :y, :uint,
769
- :rx, :short,
770
- :ry, :short,
771
- :order, :uchar,
772
- :size, :uchar
773
- end
774
- attach_function :bugged_struct_size, [], :uint
775
- end
776
-
777
- it 'should return its correct size' do
778
- expect(LibTest::BuggedStruct.size).to eq(LibTest.bugged_struct_size)
779
- end
780
-
781
- it "offsets within struct should be correct" do
782
- expect(LibTest::BuggedStruct.offset_of(:visible)).to eq(0)
783
- expect(LibTest::BuggedStruct.offset_of(:x)).to eq(4)
784
- expect(LibTest::BuggedStruct.offset_of(:y)).to eq(8)
785
- expect(LibTest::BuggedStruct.offset_of(:rx)).to eq(12)
786
- expect(LibTest::BuggedStruct.offset_of(:ry)).to eq(14)
787
- expect(LibTest::BuggedStruct.offset_of(:order)).to eq(16)
788
- expect(LibTest::BuggedStruct.offset_of(:size)).to eq(17)
789
- end
790
-
791
- it 'should return correct field/offset pairs' do
792
- expect(LibTest::BuggedStruct.offsets.sort do |a, b|
793
- a[1] <=> b[1]
794
- end).to eq([[:visible, 0], [:x, 4], [:y, 8], [:rx, 12], [:ry, 14], [:order, 16], [:size, 17]])
795
- end
796
- end
797
-
798
- describe "Struct allocation" do
799
- it "MemoryPointer.new(Struct, 2)" do
800
- class S < FFI::Struct
801
- layout :i, :uint
802
- end
803
- p = FFI::MemoryPointer.new(S, 2)
804
- expect(p.total).to eq(8)
805
- expect(p.type_size).to eq(4)
806
- p.put_uint(4, 0xdeadbeef)
807
- expect(S.new(p[1])[:i]).to eq(0xdeadbeef)
808
- expect(p[1].address).to eq((p[0].address + 4))
809
- end
810
-
811
- it "Buffer.new(Struct, 2)" do
812
- class S < FFI::Struct
813
- layout :i, :uint
814
- end
815
- p = FFI::Buffer.new(S, 2)
816
- expect(p.total).to eq(8)
817
- expect(p.type_size).to eq(4)
818
- p.put_uint(4, 0xdeadbeef)
819
- expect(S.new(p[1])[:i]).to eq(0xdeadbeef)
820
- end
821
-
822
- it "null? should be true when initialized with NULL pointer" do
823
- class S < FFI::Struct
824
- layout :i, :uint
825
- end
826
- expect(S.new(FFI::Pointer::NULL)).to be_null
827
- end
828
-
829
- it "null? should be false when initialized with non-NULL pointer" do
830
- class S < FFI::Struct
831
- layout :i, :uint
832
- end
833
- expect(S.new(FFI::MemoryPointer.new(S))).not_to be_null
834
- end
835
-
836
- it "supports :bool as a struct member" do
837
- expect do
838
- c = Class.new(FFI::Struct) do
839
- layout :b, :bool
840
- end
841
- struct = c.new
842
- struct[:b] = ! struct[:b]
843
- end.not_to raise_error Exception
844
- end
845
-
846
- end
847
-
848
- describe "variable-length arrays" do
849
- it "zero length array should be accepted as last field" do
850
- expect {
851
- Class.new(FFI::Struct) do
852
- layout :count, :int, :data, [ :char, 0 ]
853
- end
854
- }.not_to raise_error Exception
855
- end
856
-
857
- it "zero length array before last element should raise error" do
858
- expect {
859
- Class.new(FFI::Struct) do
860
- layout :data, [ :char, 0 ], :count, :int
861
- end
862
- }.to raise_error
863
- end
864
-
865
- it "can access elements of array" do
866
- struct_class = Class.new(FFI::Struct) do
867
- layout :count, :int, :data, [ :long, 0 ]
868
- end
869
- s = struct_class.new(FFI::MemoryPointer.new(1024))
870
- s[:data][0] = 0x1eadbeef
871
- s[:data][1] = 0x12345678
872
- expect(s[:data][0]).to eq(0x1eadbeef)
873
- expect(s[:data][1]).to eq(0x12345678)
874
- end
875
-
876
- it "non-variable length array is bounds checked" do
877
- struct_class = Class.new(FFI::Struct) do
878
- layout :count, :int, :data, [ :long, 1 ]
879
- end
880
- s = struct_class.new(FFI::MemoryPointer.new(1024))
881
- s[:data][0] = 0x1eadbeef
882
- expect { s[:data][1] = 0x12345678 }.to raise_error
883
- expect(s[:data][0]).to eq(0x1eadbeef)
884
- expect { expect(s[:data][1]).to == 0x12345678 }.to raise_error
885
- end
886
- end