ffi 0.4.0-x86-mswin32

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