ffi 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of ffi might be problematic. Click here for more details.

Files changed (305) hide show
  1. data/README.rdoc +19 -0
  2. data/Rakefile +65 -55
  3. data/ext/{AbstractMemory.c → ffi_c/AbstractMemory.c} +67 -40
  4. data/ext/{AbstractMemory.h → ffi_c/AbstractMemory.h} +10 -8
  5. data/ext/{AutoPointer.c → ffi_c/AutoPointer.c} +17 -8
  6. data/ext/{AutoPointer.h → ffi_c/AutoPointer.h} +0 -0
  7. data/ext/ffi_c/Buffer.c +136 -0
  8. data/ext/{Callback.c → ffi_c/Callback.c} +60 -35
  9. data/ext/{Callback.h → ffi_c/Callback.h} +1 -7
  10. data/ext/{Invoker.c → ffi_c/Invoker.c} +472 -102
  11. data/ext/ffi_c/MemoryPointer.c +146 -0
  12. data/ext/{MemoryPointer.h → ffi_c/MemoryPointer.h} +2 -7
  13. data/ext/ffi_c/NativeLibrary.c +149 -0
  14. data/ext/{NativeLibrary.h → ffi_c/NativeLibrary.h} +0 -0
  15. data/ext/ffi_c/NullPointer.c +104 -0
  16. data/ext/{Platform.c → ffi_c/Platform.c} +0 -0
  17. data/ext/{Platform.h → ffi_c/Platform.h} +0 -7
  18. data/ext/{Pointer.c → ffi_c/Pointer.c} +35 -15
  19. data/ext/{Pointer.h → ffi_c/Pointer.h} +4 -2
  20. data/ext/ffi_c/Struct.c +542 -0
  21. data/ext/ffi_c/Struct.h +26 -0
  22. data/ext/ffi_c/Types.c +76 -0
  23. data/ext/{Types.h → ffi_c/Types.h} +23 -28
  24. data/ext/{compat.h → ffi_c/compat.h} +2 -2
  25. data/ext/{extconf.rb → ffi_c/extconf.rb} +12 -7
  26. data/ext/ffi_c/ffi.c +99 -0
  27. data/ext/ffi_c/ffi.mk +23 -0
  28. data/ext/{libffi.darwin.mk → ffi_c/libffi.darwin.mk} +0 -0
  29. data/ext/ffi_c/libffi.mk +11 -0
  30. data/ext/{libffi → ffi_c/libffi}/ChangeLog +0 -0
  31. data/ext/{libffi → ffi_c/libffi}/ChangeLog.libffi +0 -0
  32. data/ext/{libffi → ffi_c/libffi}/ChangeLog.libgcj +0 -0
  33. data/ext/{libffi → ffi_c/libffi}/ChangeLog.v1 +0 -0
  34. data/ext/{libffi → ffi_c/libffi}/LICENSE +0 -0
  35. data/ext/{libffi → ffi_c/libffi}/Makefile.am +0 -0
  36. data/ext/{libffi → ffi_c/libffi}/Makefile.in +0 -0
  37. data/ext/{libffi → ffi_c/libffi}/README +0 -0
  38. data/ext/{libffi → ffi_c/libffi}/TODO +0 -0
  39. data/ext/{libffi → ffi_c/libffi}/acinclude.m4 +0 -0
  40. data/ext/{libffi → ffi_c/libffi}/aclocal.m4 +0 -0
  41. data/ext/{libffi → ffi_c/libffi}/compile +0 -0
  42. data/ext/{libffi → ffi_c/libffi}/config.guess +0 -0
  43. data/ext/{libffi → ffi_c/libffi}/config.sub +0 -0
  44. data/ext/{libffi → ffi_c/libffi}/configure +0 -0
  45. data/ext/{libffi → ffi_c/libffi}/configure.ac +0 -0
  46. data/ext/{libffi → ffi_c/libffi}/configure.host +0 -0
  47. data/ext/{libffi → ffi_c/libffi}/depcomp +0 -0
  48. data/ext/{libffi → ffi_c/libffi}/doc/libffi.info +0 -0
  49. data/ext/{libffi → ffi_c/libffi}/doc/libffi.texi +0 -0
  50. data/ext/{libffi → ffi_c/libffi}/doc/stamp-vti +0 -0
  51. data/ext/{libffi → ffi_c/libffi}/doc/version.texi +0 -0
  52. data/ext/{libffi → ffi_c/libffi}/fficonfig.h.in +0 -0
  53. data/ext/{libffi → ffi_c/libffi}/include/Makefile.am +0 -0
  54. data/ext/{libffi → ffi_c/libffi}/include/Makefile.in +0 -0
  55. data/ext/{libffi → ffi_c/libffi}/include/ffi.h.in +0 -0
  56. data/ext/{libffi → ffi_c/libffi}/include/ffi_common.h +0 -0
  57. data/ext/{libffi → ffi_c/libffi}/install-sh +0 -0
  58. data/ext/{libffi → ffi_c/libffi}/libffi.pc.in +0 -0
  59. data/ext/{libffi → ffi_c/libffi}/libtool-version +0 -0
  60. data/ext/{libffi → ffi_c/libffi}/ltcf-c.sh +0 -0
  61. data/ext/{libffi → ffi_c/libffi}/ltcf-cxx.sh +0 -0
  62. data/ext/{libffi → ffi_c/libffi}/ltcf-gcj.sh +0 -0
  63. data/ext/{libffi → ffi_c/libffi}/ltconfig +0 -0
  64. data/ext/{libffi → ffi_c/libffi}/ltmain.sh +0 -0
  65. data/ext/{libffi → ffi_c/libffi}/man/Makefile.am +0 -0
  66. data/ext/{libffi → ffi_c/libffi}/man/Makefile.in +0 -0
  67. data/ext/{libffi → ffi_c/libffi}/man/ffi.3 +0 -0
  68. data/ext/{libffi → ffi_c/libffi}/man/ffi_call.3 +0 -0
  69. data/ext/{libffi → ffi_c/libffi}/man/ffi_prep_cif.3 +0 -0
  70. data/ext/{libffi → ffi_c/libffi}/mdate-sh +0 -0
  71. data/ext/{libffi → ffi_c/libffi}/missing +0 -0
  72. data/ext/{libffi → ffi_c/libffi}/mkinstalldirs +0 -0
  73. data/ext/{libffi → ffi_c/libffi}/src/alpha/ffi.c +0 -0
  74. data/ext/{libffi → ffi_c/libffi}/src/alpha/ffitarget.h +0 -0
  75. data/ext/{libffi → ffi_c/libffi}/src/alpha/osf.S +0 -0
  76. data/ext/{libffi → ffi_c/libffi}/src/arm/ffi.c +0 -0
  77. data/ext/{libffi → ffi_c/libffi}/src/arm/ffitarget.h +0 -0
  78. data/ext/{libffi → ffi_c/libffi}/src/arm/sysv.S +0 -0
  79. data/ext/{libffi → ffi_c/libffi}/src/closures.c +0 -0
  80. data/ext/{libffi → ffi_c/libffi}/src/cris/ffi.c +0 -0
  81. data/ext/{libffi → ffi_c/libffi}/src/cris/ffitarget.h +0 -0
  82. data/ext/{libffi → ffi_c/libffi}/src/cris/sysv.S +0 -0
  83. data/ext/{libffi → ffi_c/libffi}/src/debug.c +0 -0
  84. data/ext/{libffi → ffi_c/libffi}/src/dlmalloc.c +0 -0
  85. data/ext/{libffi → ffi_c/libffi}/src/frv/eabi.S +0 -0
  86. data/ext/{libffi → ffi_c/libffi}/src/frv/ffi.c +0 -0
  87. data/ext/{libffi → ffi_c/libffi}/src/frv/ffitarget.h +0 -0
  88. data/ext/{libffi → ffi_c/libffi}/src/ia64/ffi.c +0 -0
  89. data/ext/{libffi → ffi_c/libffi}/src/ia64/ffitarget.h +0 -0
  90. data/ext/{libffi → ffi_c/libffi}/src/ia64/ia64_flags.h +0 -0
  91. data/ext/{libffi → ffi_c/libffi}/src/ia64/unix.S +0 -0
  92. data/ext/{libffi → ffi_c/libffi}/src/java_raw_api.c +0 -0
  93. data/ext/{libffi → ffi_c/libffi}/src/m32r/ffi.c +0 -0
  94. data/ext/{libffi → ffi_c/libffi}/src/m32r/ffitarget.h +0 -0
  95. data/ext/{libffi → ffi_c/libffi}/src/m32r/sysv.S +0 -0
  96. data/ext/{libffi → ffi_c/libffi}/src/m68k/ffi.c +0 -0
  97. data/ext/{libffi → ffi_c/libffi}/src/m68k/ffitarget.h +0 -0
  98. data/ext/{libffi → ffi_c/libffi}/src/m68k/sysv.S +0 -0
  99. data/ext/{libffi → ffi_c/libffi}/src/mips/ffi.c +0 -0
  100. data/ext/{libffi → ffi_c/libffi}/src/mips/ffitarget.h +0 -0
  101. data/ext/{libffi → ffi_c/libffi}/src/mips/n32.S +0 -0
  102. data/ext/{libffi → ffi_c/libffi}/src/mips/o32.S +0 -0
  103. data/ext/{libffi → ffi_c/libffi}/src/pa/ffi.c +0 -0
  104. data/ext/{libffi → ffi_c/libffi}/src/pa/ffitarget.h +0 -0
  105. data/ext/{libffi → ffi_c/libffi}/src/pa/hpux32.S +0 -0
  106. data/ext/{libffi → ffi_c/libffi}/src/pa/linux.S +0 -0
  107. data/ext/{libffi → ffi_c/libffi}/src/powerpc/aix.S +0 -0
  108. data/ext/{libffi → ffi_c/libffi}/src/powerpc/aix_closure.S +0 -0
  109. data/ext/{libffi → ffi_c/libffi}/src/powerpc/asm.h +0 -0
  110. data/ext/{libffi → ffi_c/libffi}/src/powerpc/darwin.S +0 -0
  111. data/ext/{libffi → ffi_c/libffi}/src/powerpc/darwin_closure.S +0 -0
  112. data/ext/{libffi → ffi_c/libffi}/src/powerpc/ffi.c +0 -0
  113. data/ext/{libffi → ffi_c/libffi}/src/powerpc/ffi_darwin.c +0 -0
  114. data/ext/{libffi → ffi_c/libffi}/src/powerpc/ffitarget.h +0 -0
  115. data/ext/{libffi → ffi_c/libffi}/src/powerpc/linux64.S +0 -0
  116. data/ext/{libffi → ffi_c/libffi}/src/powerpc/linux64_closure.S +0 -0
  117. data/ext/{libffi → ffi_c/libffi}/src/powerpc/ppc_closure.S +0 -0
  118. data/ext/{libffi → ffi_c/libffi}/src/powerpc/sysv.S +0 -0
  119. data/ext/{libffi → ffi_c/libffi}/src/prep_cif.c +0 -0
  120. data/ext/{libffi → ffi_c/libffi}/src/raw_api.c +0 -0
  121. data/ext/{libffi → ffi_c/libffi}/src/s390/ffi.c +0 -0
  122. data/ext/{libffi → ffi_c/libffi}/src/s390/ffitarget.h +0 -0
  123. data/ext/{libffi → ffi_c/libffi}/src/s390/sysv.S +0 -0
  124. data/ext/{libffi → ffi_c/libffi}/src/sh/ffi.c +0 -0
  125. data/ext/{libffi → ffi_c/libffi}/src/sh/ffitarget.h +0 -0
  126. data/ext/{libffi → ffi_c/libffi}/src/sh/sysv.S +0 -0
  127. data/ext/{libffi → ffi_c/libffi}/src/sh64/ffi.c +0 -0
  128. data/ext/{libffi → ffi_c/libffi}/src/sh64/ffitarget.h +0 -0
  129. data/ext/{libffi → ffi_c/libffi}/src/sh64/sysv.S +0 -0
  130. data/ext/{libffi → ffi_c/libffi}/src/sparc/ffi.c +0 -0
  131. data/ext/{libffi → ffi_c/libffi}/src/sparc/ffitarget.h +0 -0
  132. data/ext/{libffi → ffi_c/libffi}/src/sparc/v8.S +0 -0
  133. data/ext/{libffi → ffi_c/libffi}/src/sparc/v9.S +0 -0
  134. data/ext/{libffi → ffi_c/libffi}/src/types.c +0 -0
  135. data/ext/{libffi → ffi_c/libffi}/src/x86/darwin.S +0 -0
  136. data/ext/{libffi → ffi_c/libffi}/src/x86/darwin64.S +0 -0
  137. data/ext/{libffi → ffi_c/libffi}/src/x86/ffi.c +0 -0
  138. data/ext/{libffi → ffi_c/libffi}/src/x86/ffi64.c +0 -0
  139. data/ext/{libffi → ffi_c/libffi}/src/x86/ffitarget.h +0 -0
  140. data/ext/{libffi → ffi_c/libffi}/src/x86/freebsd.S +0 -0
  141. data/ext/{libffi → ffi_c/libffi}/src/x86/sysv.S +0 -0
  142. data/ext/{libffi → ffi_c/libffi}/src/x86/unix64.S +0 -0
  143. data/ext/{libffi → ffi_c/libffi}/src/x86/win32.S +0 -0
  144. data/ext/{libffi → ffi_c/libffi}/testsuite/Makefile.am +0 -0
  145. data/ext/{libffi → ffi_c/libffi}/testsuite/Makefile.in +0 -0
  146. data/ext/{libffi → ffi_c/libffi}/testsuite/config/default.exp +0 -0
  147. data/ext/{libffi → ffi_c/libffi}/testsuite/lib/libffi-dg.exp +0 -0
  148. data/ext/{libffi → ffi_c/libffi}/testsuite/lib/target-libpath.exp +0 -0
  149. data/ext/{libffi → ffi_c/libffi}/testsuite/lib/wrapper.exp +0 -0
  150. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/call.exp +0 -0
  151. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/closure_fn0.c +0 -0
  152. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/closure_fn1.c +0 -0
  153. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/closure_fn2.c +0 -0
  154. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/closure_fn3.c +0 -0
  155. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/closure_fn4.c +0 -0
  156. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/closure_fn5.c +0 -0
  157. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/closure_fn6.c +0 -0
  158. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/closure_stdcall.c +0 -0
  159. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_12byte.c +0 -0
  160. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_16byte.c +0 -0
  161. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_18byte.c +0 -0
  162. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_19byte.c +0 -0
  163. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_1_1byte.c +0 -0
  164. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_20byte.c +0 -0
  165. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_20byte1.c +0 -0
  166. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_24byte.c +0 -0
  167. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_2byte.c +0 -0
  168. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_3_1byte.c +0 -0
  169. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_3byte1.c +0 -0
  170. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_3byte2.c +0 -0
  171. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_4_1byte.c +0 -0
  172. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_4byte.c +0 -0
  173. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_5_1_byte.c +0 -0
  174. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_5byte.c +0 -0
  175. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_64byte.c +0 -0
  176. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_6_1_byte.c +0 -0
  177. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_6byte.c +0 -0
  178. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_7_1_byte.c +0 -0
  179. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_7byte.c +0 -0
  180. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_8byte.c +0 -0
  181. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_9byte1.c +0 -0
  182. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_9byte2.c +0 -0
  183. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_align_double.c +0 -0
  184. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_align_float.c +0 -0
  185. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_align_longdouble.c +0 -0
  186. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_align_pointer.c +0 -0
  187. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_align_sint16.c +0 -0
  188. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_align_sint32.c +0 -0
  189. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_align_sint64.c +0 -0
  190. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_align_uint16.c +0 -0
  191. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_align_uint32.c +0 -0
  192. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_align_uint64.c +0 -0
  193. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_double.c +0 -0
  194. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_float.c +0 -0
  195. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_multi_schar.c +0 -0
  196. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_multi_sshort.c +0 -0
  197. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_multi_sshortchar.c +0 -0
  198. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_multi_uchar.c +0 -0
  199. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_multi_ushort.c +0 -0
  200. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_multi_ushortchar.c +0 -0
  201. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_schar.c +0 -0
  202. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_sint.c +0 -0
  203. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_sshort.c +0 -0
  204. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_uchar.c +0 -0
  205. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_uint.c +0 -0
  206. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_ulonglong.c +0 -0
  207. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/cls_ushort.c +0 -0
  208. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/ffitest.h +0 -0
  209. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/float.c +0 -0
  210. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/float1.c +0 -0
  211. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/float2.c +0 -0
  212. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/float3.c +0 -0
  213. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/float4.c +0 -0
  214. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/many.c +0 -0
  215. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/many_win32.c +0 -0
  216. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/negint.c +0 -0
  217. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/nested_struct.c +0 -0
  218. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/nested_struct1.c +0 -0
  219. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/nested_struct10.c +0 -0
  220. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/nested_struct2.c +0 -0
  221. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/nested_struct3.c +0 -0
  222. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/nested_struct4.c +0 -0
  223. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/nested_struct5.c +0 -0
  224. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/nested_struct6.c +0 -0
  225. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/nested_struct7.c +0 -0
  226. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/nested_struct8.c +0 -0
  227. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/nested_struct9.c +0 -0
  228. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/problem1.c +0 -0
  229. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/promotion.c +0 -0
  230. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/pyobjc-tc.c +0 -0
  231. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/return_dbl.c +0 -0
  232. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/return_dbl1.c +0 -0
  233. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/return_dbl2.c +0 -0
  234. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/return_fl.c +0 -0
  235. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/return_fl1.c +0 -0
  236. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/return_fl2.c +0 -0
  237. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/return_fl3.c +0 -0
  238. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/return_ldl.c +0 -0
  239. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/return_ll.c +0 -0
  240. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/return_ll1.c +0 -0
  241. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/return_sc.c +0 -0
  242. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/return_sl.c +0 -0
  243. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/return_uc.c +0 -0
  244. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/return_ul.c +0 -0
  245. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/strlen.c +0 -0
  246. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/strlen_win32.c +0 -0
  247. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/struct1.c +0 -0
  248. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/struct2.c +0 -0
  249. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/struct3.c +0 -0
  250. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/struct4.c +0 -0
  251. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/struct5.c +0 -0
  252. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/struct6.c +0 -0
  253. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/struct7.c +0 -0
  254. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/struct8.c +0 -0
  255. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.call/struct9.c +0 -0
  256. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.special/ffitestcxx.h +0 -0
  257. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.special/special.exp +0 -0
  258. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.special/unwindtest.cc +0 -0
  259. data/ext/{libffi → ffi_c/libffi}/testsuite/libffi.special/unwindtest_ffi_call.cc +0 -0
  260. data/ext/{libffi → ffi_c/libffi}/texinfo.tex +0 -0
  261. data/ext/{rbffi.h → ffi_c/rbffi.h} +1 -8
  262. data/lib/ffi/autopointer.rb +7 -7
  263. data/lib/ffi/buffer.rb +0 -25
  264. data/lib/ffi/ffi.rb +1 -0
  265. data/lib/ffi/library.rb +103 -37
  266. data/lib/ffi/memorypointer.rb +25 -28
  267. data/lib/ffi/platform.rb +2 -2
  268. data/lib/ffi/pointer.rb +21 -7
  269. data/lib/ffi/struct.rb +161 -179
  270. data/lib/ffi/types.rb +3 -3
  271. data/lib/ffi/union.rb +17 -0
  272. data/nbproject/configurations.xml +98 -88
  273. data/samples/hello.rb +1 -2
  274. data/samples/sample_helper.rb +6 -0
  275. data/{specs → spec/ffi}/buffer_spec.rb +0 -0
  276. data/{specs → spec/ffi}/callback_spec.rb +114 -89
  277. data/{specs → spec/ffi}/errno_spec.rb +0 -0
  278. data/spec/ffi/library_spec.rb +144 -0
  279. data/{specs → spec/ffi}/managed_struct_spec.rb +12 -1
  280. data/{specs → spec/ffi}/number_spec.rb +34 -16
  281. data/{specs → spec/ffi}/pointer_spec.rb +46 -2
  282. data/{specs → spec/ffi}/rbx/attach_function_spec.rb +2 -1
  283. data/{specs → spec/ffi}/rbx/memory_pointer_spec.rb +19 -19
  284. data/{specs → spec/ffi}/rbx/spec_helper.rb +0 -0
  285. data/{specs → spec/ffi}/rbx/struct_spec.rb +0 -0
  286. data/spec/ffi/spec_helper.rb +13 -0
  287. data/{specs → spec/ffi}/string_spec.rb +8 -0
  288. data/spec/ffi/struct_spec.rb +453 -0
  289. data/{specs → spec/ffi}/typedef_spec.rb +3 -3
  290. data/spec/ffi/union_spec.rb +60 -0
  291. data/{specs → spec/ffi}/variadic_spec.rb +0 -0
  292. data/spec/spec.opts +4 -0
  293. metadata +356 -334
  294. data/README +0 -0
  295. data/ext/Buffer.c +0 -98
  296. data/ext/MemoryPointer.c +0 -99
  297. data/ext/NativeLibrary.c +0 -90
  298. data/ext/Types.c +0 -76
  299. data/ext/ffi.c +0 -64
  300. data/ext/ffi.mk +0 -24
  301. data/ext/libffi.mk +0 -10
  302. data/gen/Rakefile +0 -12
  303. data/specs/library_spec.rb +0 -55
  304. data/specs/spec_helper.rb +0 -9
  305. data/specs/struct_spec.rb +0 -223
File without changes
File without changes
@@ -0,0 +1,13 @@
1
+ require 'rubygems'
2
+ require 'spec'
3
+
4
+ $:.unshift File.join(File.dirname(__FILE__), "..", "..", "lib"), File.join(File.dirname(__FILE__), "..", "..", "build", RUBY_VERSION) if ENV["MRI_FFI"]
5
+ require "ffi"
6
+
7
+ module TestLibrary
8
+ PATH = "build/libtest.#{FFI::Platform::LIBSUFFIX}"
9
+ end
10
+ module LibTest
11
+ extend FFI::Library
12
+ ffi_lib TestLibrary::PATH
13
+ end
@@ -6,6 +6,7 @@ describe "String tests" do
6
6
  ffi_lib TestLibrary::PATH
7
7
  attach_function :ptr_ret_pointer, [ :pointer, :int], :string
8
8
  attach_function :string_equals, [ :string, :string ], :int
9
+ attach_function :string_dummy, [ :string ], :void
9
10
  end
10
11
  it "MemoryPointer#get_string returns a tainted string" do
11
12
  mp = MemoryPointer.new 1024
@@ -22,6 +23,10 @@ describe "String tests" do
22
23
  str.should == "test"
23
24
  str.tainted?.should == true
24
25
  end
26
+ it "Poison null byte raises error" do
27
+ s = "123\0abc"
28
+ lambda { LibTest.string_equals(s, s) }.should raise_error
29
+ end
25
30
  it "Tainted String parameter should throw a SecurityError" do
26
31
  $SAFE = 1
27
32
  str = "test"
@@ -31,4 +36,7 @@ describe "String tests" do
31
36
  rescue SecurityError => e
32
37
  end
33
38
  end if false
39
+ it "casts nil as NULL pointer" do
40
+ LibTest.string_dummy(nil)
41
+ end
34
42
  end
@@ -0,0 +1,453 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
2
+ describe "Struct tests" do
3
+ include FFI
4
+ StructTypes = {
5
+ 's8' => :char,
6
+ 's16' => :short,
7
+ 's32' => :int,
8
+ 's64' => :long_long,
9
+ 'long' => :long,
10
+ 'f32' => :float,
11
+ 'f64' => :double
12
+ }
13
+ module LibTest
14
+ extend FFI::Library
15
+ ffi_lib TestLibrary::PATH
16
+ attach_function :ptr_ret_pointer, [ :pointer, :int], :string
17
+ attach_function :ptr_ret_int32_t, [ :pointer, :int ], :int
18
+ attach_function :ptr_from_address, [ :ulong ], :pointer
19
+ attach_function :string_equals, [ :string, :string ], :int
20
+ [ 's8', 's16', 's32', 's64', 'f32', 'f64', 'long' ].each do |t|
21
+ attach_function "struct_align_#{t}", [ :pointer ], StructTypes[t]
22
+ end
23
+ end
24
+ class PointerMember < FFI::Struct
25
+ layout :pointer, :pointer
26
+ end
27
+ class StringMember < FFI::Struct
28
+ layout :string, :string
29
+ end
30
+ it "Struct#[:pointer]" do
31
+ magic = 0x12345678
32
+ mp = MemoryPointer.new :long
33
+ mp.put_long(0, magic)
34
+ smp = MemoryPointer.new :pointer
35
+ smp.put_pointer(0, mp)
36
+ s = PointerMember.new smp
37
+ s[:pointer].should == mp
38
+ end
39
+ it "Struct#[:pointer].nil? for NULL value" do
40
+ magic = 0x12345678
41
+ mp = MemoryPointer.new :long
42
+ mp.put_long(0, magic)
43
+ smp = MemoryPointer.new :pointer
44
+ smp.put_pointer(0, nil)
45
+ s = PointerMember.new smp
46
+ s[:pointer].null?.should == true
47
+ end
48
+ it "Struct#[:pointer]=" do
49
+ magic = 0x12345678
50
+ mp = MemoryPointer.new :long
51
+ mp.put_long(0, magic)
52
+ smp = MemoryPointer.new :pointer
53
+ s = PointerMember.new smp
54
+ s[:pointer] = mp
55
+ smp.get_pointer(0).should == mp
56
+ end
57
+ it "Struct#[:pointer]=struct" do
58
+ magic = 0x12345678
59
+ smp = MemoryPointer.new :pointer
60
+ s = PointerMember.new smp
61
+ lambda { s[:pointer] = s }.should_not raise_error
62
+ end
63
+ it "Struct#[:pointer]=nil" do
64
+ smp = MemoryPointer.new :pointer
65
+ s = PointerMember.new smp
66
+ s[:pointer] = nil
67
+ smp.get_pointer(0).null?.should == true
68
+ end
69
+ it "Struct#[:string]" do
70
+ magic = "test"
71
+ mp = MemoryPointer.new 1024
72
+ mp.put_string(0, magic)
73
+ smp = MemoryPointer.new :pointer
74
+ smp.put_pointer(0, mp)
75
+ s = StringMember.new smp
76
+ s[:string].should == magic
77
+ end
78
+ it "Struct#[:string].nil? for NULL value" do
79
+ smp = MemoryPointer.new :pointer
80
+ smp.put_pointer(0, nil)
81
+ s = StringMember.new smp
82
+ s[:string].nil?.should == true
83
+ end
84
+ it "Struct#layout works with :name, :type pairs" do
85
+ class PairLayout < FFI::Struct
86
+ layout :a, :int, :b, :long_long
87
+ end
88
+ ll_off = (FFI::Platform::ADDRESS_SIZE == 32 ? 4 : 8)
89
+ PairLayout.size.should == (ll_off + 8)
90
+ mp = MemoryPointer.new(PairLayout.size)
91
+ s = PairLayout.new mp
92
+ s[:a] = 0x12345678
93
+ mp.get_int(0).should == 0x12345678
94
+ s[:b] = 0xfee1deadbeef
95
+ mp.get_int64(ll_off).should == 0xfee1deadbeef
96
+ end
97
+ it "Struct#layout works with :name, :type, offset tuples" do
98
+ class PairLayout < FFI::Struct
99
+ layout :a, :int, 0, :b, :long_long, 4
100
+ end
101
+ PairLayout.size.should == (FFI::Platform::ADDRESS_SIZE == 32 ? 12 : 16)
102
+ mp = MemoryPointer.new(PairLayout.size)
103
+ s = PairLayout.new mp
104
+ s[:a] = 0x12345678
105
+ mp.get_int(0).should == 0x12345678
106
+ s[:b] = 0xfee1deadbeef
107
+ mp.get_int64(4).should == 0xfee1deadbeef
108
+ end
109
+ it "Struct#layout works with mixed :name,:type and :name,:type,offset" do
110
+ class MixedLayout < FFI::Struct
111
+ layout :a, :int, :b, :long_long, 4
112
+ end
113
+ MixedLayout.size.should == (FFI::Platform::ADDRESS_SIZE == 32 ? 12 : 16)
114
+ mp = MemoryPointer.new(MixedLayout.size)
115
+ s = MixedLayout.new mp
116
+ s[:a] = 0x12345678
117
+ mp.get_int(0).should == 0x12345678
118
+ s[:b] = 0xfee1deadbeef
119
+ mp.get_int64(4).should == 0xfee1deadbeef
120
+ end
121
+ rb_maj, rb_min = RUBY_VERSION.split('.')
122
+ if rb_maj.to_i >= 1 && rb_min.to_i >= 9 || RUBY_PLATFORM =~ /java/
123
+ it "Struct#layout withs with a hash of :name => type" do
124
+ class HashLayout < FFI::Struct
125
+ layout :a => :int, :b => :long_long
126
+ end
127
+ ll_off = (FFI::Platform::ADDRESS_SIZE == 32 ? 4 : 8)
128
+ HashLayout.size.should == (ll_off + 8)
129
+ mp = MemoryPointer.new(HashLayout.size)
130
+ s = HashLayout.new mp
131
+ s[:a] = 0x12345678
132
+ mp.get_int(0).should == 0x12345678
133
+ s[:b] = 0xfee1deadbeef
134
+ mp.get_int64(ll_off).should == 0xfee1deadbeef
135
+ end
136
+ end
137
+ it "Can use Struct subclass as parameter type" do
138
+ module StructParam
139
+ extend FFI::Library
140
+ ffi_lib TestLibrary::PATH
141
+ class TestStruct < FFI::Struct
142
+ layout :c, :char
143
+ end
144
+ attach_function :struct_field_s8, [ TestStruct ], :char
145
+ end
146
+ end
147
+ it "Can use Struct subclass as IN parameter type" do
148
+ module StructParam
149
+ extend FFI::Library
150
+ ffi_lib TestLibrary::PATH
151
+ class TestStruct < FFI::Struct
152
+ layout :c, :char
153
+ end
154
+ attach_function :struct_field_s8, [ TestStruct.in ], :char
155
+ end
156
+ end
157
+ it "Can use Struct subclass as OUT parameter type" do
158
+ module StructParam
159
+ extend FFI::Library
160
+ ffi_lib TestLibrary::PATH
161
+ class TestStruct < FFI::Struct
162
+ layout :c, :char
163
+ end
164
+ attach_function :struct_field_s8, [ TestStruct.out ], :char
165
+ end
166
+ end
167
+ it "can be passed directly as a :pointer parameter" do
168
+ class TestStruct < FFI::Struct
169
+ layout :i, :int
170
+ end
171
+ s = TestStruct.new
172
+ s[:i] = 0x12
173
+ LibTest.ptr_ret_int32_t(s, 0).should == 0x12
174
+ end
175
+ it ":char member aligned correctly" do
176
+ class AlignChar < FFI::Struct
177
+ layout :c, :char, :v, :char
178
+ end
179
+ s = AlignChar.new
180
+ s[:v] = 0x12
181
+ LibTest.struct_align_s8(s.pointer).should == 0x12
182
+ end
183
+ it ":short member aligned correctly" do
184
+ class AlignShort < FFI::Struct
185
+ layout :c, :char, :v, :short
186
+ end
187
+ s = AlignShort.alloc_in
188
+ s[:v] = 0x1234
189
+ LibTest.struct_align_s16(s.pointer).should == 0x1234
190
+ end
191
+ it ":int member aligned correctly" do
192
+ class AlignInt < FFI::Struct
193
+ layout :c, :char, :v, :int
194
+ end
195
+ s = AlignInt.alloc_in
196
+ s[:v] = 0x12345678
197
+ LibTest.struct_align_s32(s.pointer).should == 0x12345678
198
+ end
199
+ it ":long_long member aligned correctly" do
200
+ class AlignLongLong < FFI::Struct
201
+ layout :c, :char, :v, :long_long
202
+ end
203
+ s = AlignLongLong.alloc_in
204
+ s[:v] = 0x123456789abcdef0
205
+ LibTest.struct_align_s64(s.pointer).should == 0x123456789abcdef0
206
+ end
207
+ it ":long member aligned correctly" do
208
+ class AlignLong < FFI::Struct
209
+ layout :c, :char, :v, :long
210
+ end
211
+ s = AlignLong.alloc_in
212
+ s[:v] = 0x12345678
213
+ LibTest.struct_align_long(s.pointer).should == 0x12345678
214
+ end
215
+ it ":float member aligned correctly" do
216
+ class AlignFloat < FFI::Struct
217
+ layout :c, :char, :v, :float
218
+ end
219
+ s = AlignFloat.alloc_in
220
+ s[:v] = 1.23456
221
+ (LibTest.struct_align_f32(s.pointer) - 1.23456).abs.should < 0.00001
222
+ end
223
+ it ":double member aligned correctly" do
224
+ class AlignDouble < FFI::Struct
225
+ layout :c, :char, :v, :double
226
+ end
227
+ s = AlignDouble.alloc_in
228
+ s[:v] = 1.23456789
229
+ (LibTest.struct_align_f64(s.pointer) - 1.23456789).abs.should < 0.00000001
230
+ end
231
+ it ":ulong, :pointer struct" do
232
+ class ULPStruct < FFI::Struct
233
+ layout :ul, :ulong, :p, :pointer
234
+ end
235
+ s = ULPStruct.alloc_in
236
+ s[:ul] = 0xdeadbeef
237
+ s[:p] = LibTest.ptr_from_address(0x12345678)
238
+ s.pointer.get_ulong(0).should == 0xdeadbeef
239
+ end
240
+ def test_num_field(type, v)
241
+ klass = Class.new(FFI::Struct)
242
+ klass.layout :v, type, :dummy, :long
243
+
244
+ s = klass.new
245
+ s[:v] = v
246
+ s.pointer.send("get_#{type.to_s}", 0).should == v
247
+ s.pointer.send("put_#{type.to_s}", 0, 0)
248
+ s[:v].should == 0
249
+ end
250
+ def self.int_field_test(type, values)
251
+ values.each do |v|
252
+ it "#{type} field r/w (#{v.to_s(16)})" do
253
+ test_num_field(type, v)
254
+ end
255
+ end
256
+ end
257
+ int_field_test(:char, [ 0, 127, -128, -1 ])
258
+ int_field_test(:uchar, [ 0, 0x7f, 0x80, 0xff ])
259
+ int_field_test(:short, [ 0, 0x7fff, -0x8000, -1 ])
260
+ int_field_test(:ushort, [ 0, 0x7fff, 0x8000, 0xffff ])
261
+ int_field_test(:int, [ 0, 0x7fffffff, -0x80000000, -1 ])
262
+ int_field_test(:uint, [ 0, 0x7fffffff, 0x80000000, 0xffffffff ])
263
+ int_field_test(:long_long, [ 0, 0x7fffffffffffffff, -0x8000000000000000, -1 ])
264
+ int_field_test(:ulong_long, [ 0, 0x7fffffffffffffff, 0x8000000000000000, 0xffffffffffffffff ])
265
+ if FFI::Platform::LONG_SIZE == 32
266
+ int_field_test(:long, [ 0, 0x7fffffff, -0x80000000, -1 ])
267
+ int_field_test(:ulong, [ 0, 0x7fffffff, 0x80000000, 0xffffffff ])
268
+ else
269
+ int_field_test(:long, [ 0, 0x7fffffffffffffff, -0x8000000000000000, -1 ])
270
+ int_field_test(:ulong, [ 0, 0x7fffffffffffffff, 0x8000000000000000, 0xffffffffffffffff ])
271
+ end
272
+ it ":float field r/w" do
273
+ klass = Class.new(FFI::Struct)
274
+ klass.layout :v, :float, :dummy, :long
275
+
276
+ s = klass.new
277
+ value = 1.23456
278
+ s[:v] = value
279
+ (s.pointer.get_float(0) - value).abs.should < 0.0001
280
+ end
281
+ it ":double field r/w" do
282
+ klass = Class.new(FFI::Struct)
283
+ klass.layout :v, :double, :dummy, :long
284
+
285
+ s = klass.new
286
+ value = 1.23456
287
+ s[:v] = value
288
+ (s.pointer.get_double(0) - value).abs.should < 0.0001
289
+ end
290
+ module CallbackMember
291
+ extend FFI::Library
292
+ ffi_lib TestLibrary::PATH
293
+ callback :add, [ :int, :int ], :int
294
+ callback :sub, [ :int, :int ], :int
295
+ class TestStruct < FFI::Struct
296
+ layout :add, :add,
297
+ :sub, :sub
298
+ end
299
+ attach_function :struct_call_add_cb, [TestStruct, :int, :int], :int
300
+ attach_function :struct_call_sub_cb, [TestStruct, :int, :int], :int
301
+ end
302
+ it "Can have CallbackInfo struct field" do
303
+ s = CallbackMember::TestStruct.new
304
+ add_proc = lambda { |a, b| a+b }
305
+ sub_proc = lambda { |a, b| a-b }
306
+ s[:add] = add_proc
307
+ s[:sub] = sub_proc
308
+ CallbackMember.struct_call_add_cb(s.pointer, 40, 2).should == 42
309
+ CallbackMember.struct_call_sub_cb(s.pointer, 44, 2).should == 42
310
+ end
311
+ it "Can return its members as a list" do
312
+ class TestStruct < FFI::Struct
313
+ layout :a, :int, :b, :int, :c, :int
314
+ end
315
+ TestStruct.members.should include(:a, :b, :c)
316
+ end
317
+ it "Can return its instance members and values as lists" do
318
+ class TestStruct < FFI::Struct
319
+ layout :a, :int, :b, :int, :c, :int
320
+ end
321
+ s = TestStruct.new
322
+ s.members.should include(:a, :b, :c)
323
+ s[:a] = 1
324
+ s[:b] = 2
325
+ s[:c] = 3
326
+ s.values.should include(1, 2, 3)
327
+ end
328
+ it 'should return an ordered field/offset pairs array' do
329
+ class TestStruct < FFI::Struct
330
+ layout :a, :int, :b, :int, :c, :int
331
+ end
332
+ s = TestStruct.new
333
+ s.offsets.should == [[:a, 0], [:b, 4], [:c, 8]]
334
+ TestStruct.offsets.should == [[:a, 0], [:b, 4], [:c, 8]]
335
+ end
336
+ it "Struct#offset_of returns offset of field within struct" do
337
+ class TestStruct < FFI::Struct
338
+ layout :a, :int, :b, :int, :c, :int
339
+ end
340
+ TestStruct.offset_of(:a).should == 0
341
+ TestStruct.offset_of(:b).should == 4
342
+ TestStruct.offset_of(:c).should == 8
343
+ end
344
+ end
345
+
346
+ describe FFI::Struct, ' with a nested struct field' do
347
+ module LibTest
348
+ extend FFI::Library
349
+ ffi_lib TestLibrary::PATH
350
+ class NestedStruct < FFI::Struct
351
+ layout :i, :int
352
+ end
353
+ class ContainerStruct < FFI::Struct
354
+ layout :first, :char, :ns, NestedStruct
355
+ end
356
+ attach_function :struct_align_nested_struct, [ :pointer ], :int
357
+ attach_function :struct_make_container_struct, [ :int ], :pointer
358
+ end
359
+ before do
360
+ @cs = LibTest::ContainerStruct.new
361
+ end
362
+ it 'should align correctly nested struct field' do
363
+ @cs[:ns][:i] = 123
364
+ LibTest.struct_align_nested_struct(@cs.to_ptr).should == 123
365
+ end
366
+ it 'should correctly calculate Container size (in bytes)' do
367
+ LibTest::ContainerStruct.size.should == 8
368
+ end
369
+ it 'should return a Struct object when the field is accessed' do
370
+ @cs[:ns].is_a?(FFI::Struct).should be_true
371
+ end
372
+ it 'should read a value from memory' do
373
+ @cs = LibTest::ContainerStruct.new(LibTest.struct_make_container_struct(123))
374
+ @cs[:ns][:i].should == 123
375
+ end
376
+ it 'should write a value to memory' do
377
+ @cs = LibTest::ContainerStruct.new(LibTest.struct_make_container_struct(123))
378
+ @cs[:ns][:i] = 456
379
+ LibTest.struct_align_nested_struct(@cs.to_ptr).should == 456
380
+ end
381
+ end
382
+
383
+ describe FFI::Struct, ' with an array field' do
384
+ module LibTest
385
+ extend FFI::Library
386
+ ffi_lib TestLibrary::PATH
387
+ class StructWithArray < FFI::Struct
388
+ layout :first, :char, :a, [:int, 5]
389
+ end
390
+ attach_function :struct_make_struct_with_array, [:int, :int, :int, :int, :int], :pointer
391
+ attach_function :struct_field_array, [:pointer], :pointer
392
+ end
393
+ before do
394
+ @s = LibTest::StructWithArray.new
395
+ end
396
+ it 'should align correctly array field'
397
+ it 'should correctly calculate StructWithArray size (in bytes)' do
398
+ LibTest::StructWithArray.size.should == 24
399
+ end
400
+ it 'should read values from memory' do
401
+ @s = LibTest::StructWithArray.new(LibTest.struct_make_struct_with_array(0, 1, 2, 3, 4))
402
+ @s[:a].to_a.should == [0, 1, 2, 3, 4]
403
+ end
404
+ it 'should cache array object for successive calls' do
405
+ @s[:a].object_id.should == @s[:a].object_id
406
+ end
407
+ it 'should return the size of the array field in bytes' do
408
+ @s = LibTest::StructWithArray.new(LibTest.struct_make_struct_with_array(0, 1, 2, 3, 4))
409
+ @s[:a].size.should == 20
410
+ end
411
+ it 'should allow iteration through the array elements' do
412
+ @s = LibTest::StructWithArray.new(LibTest.struct_make_struct_with_array(0, 1, 2, 3, 4))
413
+ @s[:a].each_with_index { |elem, i| elem.should == i }
414
+ end
415
+ it 'should return the pointer to the array' do
416
+ @s = LibTest::StructWithArray.new(LibTest.struct_make_struct_with_array(0, 1, 2, 3, 4))
417
+ @s[:a].to_ptr.should == LibTest::struct_field_array(@s.to_ptr)
418
+ end
419
+ end
420
+
421
+ describe 'BuggedStruct' do
422
+ module LibTest
423
+ extend FFI::Library
424
+ ffi_lib TestLibrary::PATH
425
+ class BuggedStruct < FFI::Struct
426
+ layout :visible, :uchar,
427
+ :x, :uint,
428
+ :y, :uint,
429
+ :rx, :short,
430
+ :ry, :short,
431
+ :order, :uchar,
432
+ :size, :uchar
433
+ end
434
+ attach_function :bugged_struct_size, [], :uint
435
+ end
436
+ it 'should return its correct size' do
437
+ LibTest::BuggedStruct.size.should == LibTest.bugged_struct_size
438
+ end
439
+ it "offsets within struct should be correct" do
440
+ LibTest::BuggedStruct.offset_of(:visible).should == 0
441
+ LibTest::BuggedStruct.offset_of(:x).should == 4
442
+ LibTest::BuggedStruct.offset_of(:y).should == 8
443
+ LibTest::BuggedStruct.offset_of(:rx).should == 12
444
+ LibTest::BuggedStruct.offset_of(:ry).should == 14
445
+ LibTest::BuggedStruct.offset_of(:order).should == 16
446
+ LibTest::BuggedStruct.offset_of(:size).should == 17
447
+ end
448
+ it 'should return correct field/offset pairs' do
449
+ LibTest::BuggedStruct.offsets.sort do |a, b|
450
+ a[1] <=> b[1]
451
+ end.should == [[:visible, 0], [:x, 4], [:y, 8], [:rx, 12], [:ry, 14], [:order, 16], [:size, 17]]
452
+ end
453
+ end