ffi 1.9.21 → 1.9.22

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 (151) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +3 -0
  3. data.tar.gz.sig +0 -0
  4. data/.gitignore +22 -0
  5. data/.gitmodules +3 -0
  6. data/.travis.yml +52 -0
  7. data/.yardopts +5 -0
  8. data/Gemfile +15 -0
  9. data/{spec/ffi/LICENSE.SPECS → LICENSE.SPECS} +1 -1
  10. data/README.md +1 -1
  11. data/Rakefile +28 -3
  12. data/appveyor.yml +22 -0
  13. data/ext/ffi_c/Call.c +1 -22
  14. data/ext/ffi_c/Call.h +0 -9
  15. data/ext/ffi_c/Closure.c +54 -0
  16. data/ext/ffi_c/{ClosurePool.h → Closure.h} +13 -23
  17. data/ext/ffi_c/Function.c +16 -25
  18. data/ext/ffi_c/Function.h +1 -2
  19. data/ext/ffi_c/FunctionInfo.c +0 -4
  20. data/ext/ffi_c/MethodHandle.c +33 -268
  21. data/ext/ffi_c/extconf.rb +3 -3
  22. data/ext/ffi_c/ffi.c +2 -2
  23. data/ext/ffi_c/libffi.bsd.mk +3 -3
  24. data/ext/ffi_c/libffi.darwin.mk +1 -1
  25. data/ext/ffi_c/libffi.gnu.mk +1 -1
  26. data/ext/ffi_c/libffi.mk +2 -2
  27. data/ext/ffi_c/libffi.vc.mk +1 -1
  28. data/ext/ffi_c/libffi.vc64.mk +1 -1
  29. data/ext/ffi_c/libffi/.appveyor.yml +48 -0
  30. data/ext/ffi_c/libffi/.gitignore +36 -0
  31. data/ext/ffi_c/libffi/.travis.yml +30 -0
  32. data/ext/ffi_c/libffi/.travis/install.sh +14 -0
  33. data/ext/ffi_c/libffi/Makefile.am +5 -3
  34. data/ext/ffi_c/libffi/acinclude.m4 +6 -0
  35. data/ext/ffi_c/libffi/autogen.sh +1 -1
  36. data/ext/ffi_c/libffi/config.guess +1466 -0
  37. data/ext/ffi_c/libffi/config.sub +1836 -0
  38. data/ext/ffi_c/libffi/configure.ac +2 -2
  39. data/ext/ffi_c/libffi/configure.host +15 -3
  40. data/ext/ffi_c/libffi/generate-darwin-source-and-headers.py +11 -15
  41. data/ext/ffi_c/libffi/include/ffi.h.in +6 -1
  42. data/ext/ffi_c/libffi/libffi.xcodeproj/project.pbxproj +465 -59
  43. data/ext/ffi_c/libffi/src/aarch64/ffi.c +33 -10
  44. data/ext/ffi_c/libffi/src/aarch64/sysv.S +2 -2
  45. data/ext/ffi_c/libffi/src/arm/ffi.c +12 -1
  46. data/ext/ffi_c/libffi/src/arm/sysv.S +1 -1
  47. data/ext/ffi_c/libffi/src/closures.c +143 -97
  48. data/ext/ffi_c/libffi/src/ia64/unix.S +2 -0
  49. data/ext/ffi_c/libffi/src/mips/ffi.c +8 -0
  50. data/ext/ffi_c/libffi/src/mips/ffitarget.h +1 -1
  51. data/ext/ffi_c/libffi/src/mips/n32.S +2 -0
  52. data/ext/ffi_c/libffi/src/powerpc/aix.S +239 -1
  53. data/ext/ffi_c/libffi/src/powerpc/aix_closure.S +250 -3
  54. data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +86 -5
  55. data/ext/ffi_c/libffi/src/powerpc/ffitarget.h +3 -0
  56. data/ext/ffi_c/libffi/src/x86/ffi.c +3 -1
  57. data/ext/ffi_c/libffi/src/x86/ffi64.c +26 -5
  58. data/ext/ffi_c/libffi/src/x86/sysv.S +2 -2
  59. data/ext/ffi_c/libffi/src/x86/unix64.S +1 -1
  60. data/ext/ffi_c/libffi/src/x86/win64.S +1 -1
  61. data/ext/ffi_c/libffi/testsuite/Makefile.am +2 -1
  62. data/ext/ffi_c/libffi/testsuite/lib/libffi.exp +2 -1
  63. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3float.c +95 -0
  64. data/ffi.gemspec +14 -1
  65. data/lib/ffi/library.rb +1 -1
  66. data/lib/ffi/version.rb +1 -1
  67. data/samples/getlogin.rb +8 -0
  68. data/samples/getpid.rb +8 -0
  69. data/samples/gettimeofday.rb +18 -0
  70. data/samples/hello.rb +7 -0
  71. data/samples/inotify.rb +60 -0
  72. data/samples/pty.rb +76 -0
  73. data/samples/qsort.rb +21 -0
  74. data/samples/sample_helper.rb +6 -0
  75. metadata +59 -81
  76. metadata.gz.sig +0 -0
  77. data/ext/ffi_c/ClosurePool.c +0 -283
  78. data/gen/Rakefile +0 -30
  79. data/libtest/Benchmark.c +0 -52
  80. data/libtest/BoolTest.c +0 -34
  81. data/libtest/BufferTest.c +0 -31
  82. data/libtest/ClosureTest.c +0 -205
  83. data/libtest/EnumTest.c +0 -51
  84. data/libtest/FunctionTest.c +0 -70
  85. data/libtest/GNUmakefile +0 -149
  86. data/libtest/GlobalVariable.c +0 -62
  87. data/libtest/LastErrorTest.c +0 -21
  88. data/libtest/NumberTest.c +0 -132
  89. data/libtest/PointerTest.c +0 -63
  90. data/libtest/ReferenceTest.c +0 -23
  91. data/libtest/StringTest.c +0 -34
  92. data/libtest/StructTest.c +0 -243
  93. data/libtest/UnionTest.c +0 -43
  94. data/libtest/VariadicTest.c +0 -99
  95. data/spec/ffi/async_callback_spec.rb +0 -35
  96. data/spec/ffi/bitmask_spec.rb +0 -575
  97. data/spec/ffi/bool_spec.rb +0 -32
  98. data/spec/ffi/buffer_spec.rb +0 -279
  99. data/spec/ffi/callback_spec.rb +0 -773
  100. data/spec/ffi/custom_param_type.rb +0 -37
  101. data/spec/ffi/custom_type_spec.rb +0 -74
  102. data/spec/ffi/dup_spec.rb +0 -52
  103. data/spec/ffi/enum_spec.rb +0 -423
  104. data/spec/ffi/errno_spec.rb +0 -20
  105. data/spec/ffi/ffi_spec.rb +0 -28
  106. data/spec/ffi/fixtures/Benchmark.c +0 -52
  107. data/spec/ffi/fixtures/BitmaskTest.c +0 -51
  108. data/spec/ffi/fixtures/BoolTest.c +0 -34
  109. data/spec/ffi/fixtures/BufferTest.c +0 -31
  110. data/spec/ffi/fixtures/ClosureTest.c +0 -205
  111. data/spec/ffi/fixtures/EnumTest.c +0 -51
  112. data/spec/ffi/fixtures/FunctionTest.c +0 -142
  113. data/spec/ffi/fixtures/GNUmakefile +0 -149
  114. data/spec/ffi/fixtures/GlobalVariable.c +0 -62
  115. data/spec/ffi/fixtures/LastErrorTest.c +0 -21
  116. data/spec/ffi/fixtures/NumberTest.c +0 -132
  117. data/spec/ffi/fixtures/PipeHelper.h +0 -21
  118. data/spec/ffi/fixtures/PipeHelperPosix.c +0 -41
  119. data/spec/ffi/fixtures/PipeHelperWindows.c +0 -72
  120. data/spec/ffi/fixtures/PointerTest.c +0 -63
  121. data/spec/ffi/fixtures/ReferenceTest.c +0 -23
  122. data/spec/ffi/fixtures/StringTest.c +0 -34
  123. data/spec/ffi/fixtures/StructTest.c +0 -243
  124. data/spec/ffi/fixtures/UnionTest.c +0 -43
  125. data/spec/ffi/fixtures/VariadicTest.c +0 -99
  126. data/spec/ffi/fixtures/classes.rb +0 -438
  127. data/spec/ffi/function_spec.rb +0 -97
  128. data/spec/ffi/io_spec.rb +0 -16
  129. data/spec/ffi/library_spec.rb +0 -286
  130. data/spec/ffi/long_double.rb +0 -30
  131. data/spec/ffi/managed_struct_spec.rb +0 -68
  132. data/spec/ffi/memorypointer_spec.rb +0 -78
  133. data/spec/ffi/number_spec.rb +0 -247
  134. data/spec/ffi/platform_spec.rb +0 -114
  135. data/spec/ffi/pointer_spec.rb +0 -285
  136. data/spec/ffi/rbx/attach_function_spec.rb +0 -34
  137. data/spec/ffi/rbx/memory_pointer_spec.rb +0 -198
  138. data/spec/ffi/rbx/spec_helper.rb +0 -6
  139. data/spec/ffi/rbx/struct_spec.rb +0 -18
  140. data/spec/ffi/spec_helper.rb +0 -93
  141. data/spec/ffi/string_spec.rb +0 -118
  142. data/spec/ffi/strptr_spec.rb +0 -50
  143. data/spec/ffi/struct_by_ref_spec.rb +0 -43
  144. data/spec/ffi/struct_callback_spec.rb +0 -69
  145. data/spec/ffi/struct_initialize_spec.rb +0 -35
  146. data/spec/ffi/struct_packed_spec.rb +0 -50
  147. data/spec/ffi/struct_spec.rb +0 -882
  148. data/spec/ffi/typedef_spec.rb +0 -91
  149. data/spec/ffi/union_spec.rb +0 -67
  150. data/spec/ffi/variadic_spec.rb +0 -132
  151. data/spec/spec.opts +0 -4
@@ -1,34 +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
- unless FFI::Platform.windows?
9
- class Timeval < FFI::Struct
10
- layout :tv_sec, :ulong, 0, :tv_usec, :ulong, 4
11
- end
12
-
13
- module LibC
14
- extend FFI::Library
15
- ffi_lib FFI::Library::LIBC
16
-
17
- attach_function :gettimeofday, [:pointer, :pointer], :int
18
- end
19
-
20
- describe FFI::Library, "#attach_function" do
21
- it "correctly returns a value for gettimeofday" do
22
- t = Timeval.new
23
- time = LibC.gettimeofday(t.pointer, nil)
24
- expect(time).to be_kind_of(Integer)
25
- end
26
-
27
- it "correctly populates a struct for gettimeofday" do
28
- t = Timeval.new
29
- LibC.gettimeofday(t.pointer, nil)
30
- expect(t[:tv_sec]).to be_kind_of(Numeric)
31
- expect(t[:tv_usec]).to be_kind_of(Numeric)
32
- end
33
- end
34
- end
@@ -1,198 +0,0 @@
1
- # coding: utf-8
2
- #
3
- # This file is part of ruby-ffi.
4
- # For licensing, see LICENSE.SPECS
5
- #
6
-
7
- require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
8
-
9
- module CTest
10
- extend FFI::Library
11
- ffi_lib FFI::Library::LIBC
12
-
13
- attach_function :strcat, [:pointer, :pointer], :pointer
14
- end
15
-
16
- describe "MemoryPointer" do
17
- it "makes a pointer from a string" do
18
- m = FFI::MemoryPointer.from_string("FFI is Awesome")
19
- expect(m.total).to eq(15)
20
- expect(m.type_size).to eq(1)
21
- end
22
-
23
- it "does not make a pointer from non-strings" do
24
- expect { FFI::MemoryPointer.from_string(nil) }.to raise_error(TypeError)
25
- end
26
-
27
- it "makes a pointer from a string with multibyte characters" do
28
- m = FFI::MemoryPointer.from_string("ぱんだ")
29
- expect(m.total).to eq(10)
30
- expect(m.type_size).to eq(1)
31
- end
32
-
33
- it "reads back a string" do
34
- m = FFI::MemoryPointer.from_string("FFI is Awesome")
35
- expect(m.read_string).to eq("FFI is Awesome")
36
- end
37
-
38
- it "reads back an empty string" do
39
- expect(FFI::Pointer::NULL.read_string(0)).to eq('')
40
- end
41
-
42
- it "makes a pointer for a certain number of bytes" do
43
- m = FFI::MemoryPointer.new(8)
44
- m.write_array_of_int([1,2])
45
- expect(m.read_array_of_int(2)).to eq([1,2])
46
- end
47
-
48
- it "allows access to an element of the pointer (as an array)" do
49
- m = FFI::MemoryPointer.new(:int, 2)
50
- m.write_array_of_int([1,2])
51
- expect(m[0].read_int).to eq(1)
52
- expect(m[1].read_int).to eq(2)
53
- end
54
-
55
- it "allows writing as an int" do
56
- m = FFI::MemoryPointer.new(:int)
57
- m.write_int(1)
58
- expect(m.read_int).to eq(1)
59
- expect(m.read :int).to eq(1)
60
- expect(m.read FFI::Type::INT).to eq(1)
61
- end
62
-
63
- it "allows writing as a sized int" do
64
- m = FFI::MemoryPointer.new(:uint32)
65
- m.write_uint32(1)
66
- expect(m.read_uint32).to eq(1)
67
- expect(m.read :uint32).to eq(1)
68
- expect(m.read FFI::Type::UINT32).to eq(1)
69
-
70
- m = FFI::MemoryPointer.new(:uint32)
71
- m.write :uint32, 1
72
- expect(m.read :uint32).to eq(1)
73
-
74
- m = FFI::MemoryPointer.new(:int64)
75
- m.write_int64(1)
76
- expect(m.read_int64).to eq(1)
77
- expect(m.read :int64).to eq(1)
78
- expect(m.read FFI::Type::INT64).to eq(1)
79
-
80
- m = FFI::MemoryPointer.new(:int64)
81
- m.write :int64, 1
82
- expect(m.read :int64).to eq(1)
83
- end
84
-
85
- it "allows writing as a long" do
86
- m = FFI::MemoryPointer.new(:long)
87
- m.write_long(10)
88
- expect(m.read_long).to eq(10)
89
- expect(m.read :long).to eq(10)
90
- expect(m.read FFI::Type::LONG).to eq(10)
91
-
92
- m.write :long, 10
93
- expect(m.read :long).to eq(10)
94
- end
95
-
96
- it "allows writing as a size_t" do
97
- m = FFI::MemoryPointer.new(:size_t)
98
- m.write(:size_t, 10)
99
- expect(m.read :size_t).to eq(10)
100
- end
101
-
102
- it "allows writing as a bool" do
103
- m = FFI::MemoryPointer.new(:bool)
104
- m.write(:bool, true)
105
- expect(m.read :bool).to eq(true)
106
- expect(m.read FFI::Type::BOOL).to eq(true)
107
-
108
- m.write(:bool, false)
109
- expect(m.read :bool).to eq(false)
110
- expect(m.read FFI::Type::BOOL).to eq(false)
111
- end
112
-
113
- it "allows writing a custom typedef" do
114
- FFI.typedef :uint, :fubar_t
115
- FFI.typedef :size_t, :fubar2_t
116
-
117
- m = FFI::MemoryPointer.new(:fubar_t)
118
- m.write(:fubar_t, 10)
119
- expect(m.read :fubar_t).to eq(10)
120
-
121
- m = FFI::MemoryPointer.new(:fubar2_t)
122
- m.write(:fubar2_t, 10)
123
- expect(m.read :fubar2_t).to eq(10)
124
- end
125
-
126
- it "raises an error if you try to read an undefined type" do
127
- m = FFI::MemoryPointer.new(:long)
128
- expect { m.read(:undefined_type) }.to raise_error(ArgumentError)
129
- end
130
-
131
- it "raises an error if you try putting a long into a pointer of size 1" do
132
- m = FFI::MemoryPointer.new(1)
133
- expect { m.write_long(10) }.to raise_error
134
- end
135
-
136
- it "raises an error if you try putting an int into a pointer of size 1" do
137
- m = FFI::MemoryPointer.new(1)
138
- expect { m.write_int(10) }.to raise_error
139
- end
140
- # it "does not raise IndexError for opaque pointers" do
141
- # m = FFI::MemoryPointer.new(8)
142
- # p2 = FFI::MemoryPointer.new(1024)
143
- # m.write_long(p2.address)
144
- # p = m.read_pointer
145
- # lambda { p.write_int(10) }.should_not raise_error
146
- # end
147
-
148
- it "makes a pointer for a certain type" do
149
- m = FFI::MemoryPointer.new(:int)
150
- m.write_int(10)
151
- expect(m.read_int).to eq(10)
152
- end
153
-
154
- it "makes a memory pointer for a number of a certain type" do
155
- m = FFI::MemoryPointer.new(:int, 2)
156
- m.write_array_of_int([1,2])
157
- expect(m.read_array_of_int(2)).to eq([1,2])
158
- end
159
-
160
- it "makes a pointer for an object responding to #size" do
161
- m = FFI::MemoryPointer.new(Struct.new(:size).new(8))
162
- m.write_array_of_int([1,2])
163
- expect(m.read_array_of_int(2)).to eq([1,2])
164
- end
165
-
166
- it "makes a pointer for a number of an object responding to #size" do
167
- m = FFI::MemoryPointer.new(Struct.new(:size).new(4), 2)
168
- m.write_array_of_int([1,2])
169
- expect(m.read_array_of_int(2)).to eq([1,2])
170
- end
171
-
172
- it "MemoryPointer#address returns correct value" do
173
- m = FFI::MemoryPointer.new(:long_long)
174
- magic = 0x12345678
175
- m.write_long(magic)
176
- expect(m.read_pointer.address).to eq(magic)
177
- end
178
-
179
- it "MemoryPointer#null? returns true for zero value" do
180
- m = FFI::MemoryPointer.new(:long_long)
181
- m.write_long(0)
182
- expect(m.read_pointer.null?).to be true
183
- end
184
-
185
- it "MemoryPointer#null? returns false for non-zero value" do
186
- m = FFI::MemoryPointer.new(:long_long)
187
- m.write_long(0x12345678)
188
- expect(m.read_pointer.null?).to be false
189
- end
190
-
191
- it "initialize with block should execute block" do
192
- block_executed = false
193
- FFI::MemoryPointer.new(:pointer) do |ptr|
194
- block_executed = true
195
- end
196
- expect(block_executed).to be true
197
- end
198
- end
@@ -1,6 +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"))
@@ -1,18 +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
- class Timeval < FFI::Struct
9
- layout :tv_sec, :ulong, 0, :tv_usec, :ulong, 4
10
- end
11
-
12
- describe FFI::Struct do
13
- it "allows setting fields" do
14
- t = Timeval.new
15
- t[:tv_sec] = 12
16
- expect(t[:tv_sec]).to eq(12)
17
- end
18
- end
@@ -1,93 +0,0 @@
1
- #
2
- # This file is part of ruby-ffi.
3
- # For licensing, see LICENSE.SPECS
4
- #
5
-
6
- require 'rbconfig'
7
- require 'fileutils'
8
- require 'ffi'
9
-
10
- RSpec.configure do |c|
11
- c.filter_run_excluding :broken => true
12
- end
13
-
14
- CPU = case RbConfig::CONFIG['host_cpu'].downcase
15
- when /i[3456]86/
16
- # Darwin always reports i686, even when running in 64bit mode
17
- if RbConfig::CONFIG['host_os'] =~ /darwin/ && 0xfee1deadbeef.is_a?(Fixnum)
18
- "x86_64"
19
- else
20
- "i386"
21
- end
22
-
23
- when /amd64|x86_64/
24
- "x86_64"
25
-
26
- when /ppc64|powerpc64/
27
- "powerpc64"
28
-
29
- when /ppc|powerpc/
30
- "powerpc"
31
-
32
- when /^arm/
33
- "arm"
34
-
35
- else
36
- RbConfig::CONFIG['host_cpu']
37
- end
38
-
39
- OS = case RbConfig::CONFIG['host_os'].downcase
40
- when /linux/
41
- "linux"
42
- when /darwin/
43
- "darwin"
44
- when /freebsd/
45
- "freebsd"
46
- when /openbsd/
47
- "openbsd"
48
- when /sunos|solaris/
49
- "solaris"
50
- when /mswin|mingw/
51
- "win32"
52
- else
53
- RbConfig::CONFIG['host_os'].downcase
54
- end
55
-
56
- def compile_library(path, lib)
57
-
58
- dir = File.expand_path(path, File.dirname(__FILE__))
59
- lib = "#{dir}/#{lib}"
60
- if !File.exist?(lib)
61
- output = nil
62
- FileUtils.cd(dir) do
63
- output = system(*%{#{system('which gmake >/dev/null') && 'gmake' || 'make'} CPU=#{CPU} OS=#{OS} }.tap{|x| puts x.inspect})
64
- end
65
-
66
- if $?.exitstatus != 0
67
- puts "ERROR:\n#{output}"
68
- raise "Unable to compile \"#{lib}\""
69
- end
70
- end
71
-
72
- lib
73
- end
74
-
75
- require "ffi"
76
-
77
- module TestLibrary
78
- PATH = compile_library("fixtures", "libtest.#{FFI::Platform::LIBSUFFIX}")
79
-
80
- def self.force_gc
81
- if RUBY_PLATFORM =~ /java/
82
- java.lang.System.gc
83
- elsif defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx'
84
- GC.run(true)
85
- else
86
- GC.start
87
- end
88
- end
89
- end
90
- module LibTest
91
- extend FFI::Library
92
- ffi_lib TestLibrary::PATH
93
- end
@@ -1,118 +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
- describe "String tests" do
8
- include FFI
9
- module StrLibTest
10
- extend FFI::Library
11
- ffi_lib TestLibrary::PATH
12
- attach_function :ptr_ret_pointer, [ :pointer, :int], :string
13
- attach_function :string_equals, [ :string, :string ], :int
14
- attach_function :string_dummy, [ :string ], :void
15
- attach_function :string_null, [ ], :string
16
- end
17
-
18
- it "MemoryPointer#get_string returns a tainted string" do
19
- mp = FFI::MemoryPointer.new 1024
20
- mp.put_string(0, "test\0")
21
- str = mp.get_string(0)
22
- expect(str.tainted?).to be true
23
- end
24
-
25
- it "String returned by a method is tainted" do
26
- mp = FFI::MemoryPointer.new :pointer
27
- sp = FFI::MemoryPointer.new 1024
28
- sp.put_string(0, "test")
29
- mp.put_pointer(0, sp)
30
- str = StrLibTest.ptr_ret_pointer(mp, 0)
31
- expect(str).to eq("test")
32
- expect(str).to be_tainted
33
- end
34
-
35
- it "Poison null byte raises error" do
36
- s = "123\0abc"
37
- expect { StrLibTest.string_equals(s, s) }.to raise_error
38
- end
39
-
40
- it "Tainted String parameter should throw a SecurityError" do
41
- $SAFE = 1
42
- str = "test"
43
- str.taint
44
- begin
45
- expect(LibTest.string_equals(str, str)).to be false
46
- rescue SecurityError
47
- end
48
- end if false
49
- it "casts nil as NULL pointer" do
50
- expect(StrLibTest.string_dummy(nil)).to be_nil
51
- end
52
-
53
- it "return nil for NULL char*" do
54
- expect(StrLibTest.string_null).to be_nil
55
- end
56
-
57
- it "reads an array of strings until encountering a NULL pointer" do
58
- strings = ["foo", "bar", "baz", "testing", "ffi"]
59
- ptrary = FFI::MemoryPointer.new(:pointer, 6)
60
- ary = strings.inject([]) do |a, str|
61
- f = FFI::MemoryPointer.new(1024)
62
- f.put_string(0, str)
63
- a << f
64
- end
65
- ary.insert(3, nil)
66
- ptrary.write_array_of_pointer(ary)
67
- expect(ptrary.get_array_of_string(0)).to eq(["foo", "bar", "baz"])
68
- end
69
-
70
- it "reads an array of strings of the size specified, substituting nil when a pointer is NULL" do
71
- strings = ["foo", "bar", "baz", "testing", "ffi"]
72
- ptrary = FFI::MemoryPointer.new(:pointer, 6)
73
- ary = strings.inject([]) do |a, str|
74
- f = FFI::MemoryPointer.new(1024)
75
- f.put_string(0, str)
76
- a << f
77
- end
78
- ary.insert(2, nil)
79
- ptrary.write_array_of_pointer(ary)
80
- expect(ptrary.get_array_of_string(0, 4)).to eq(["foo", "bar", nil, "baz"])
81
- end
82
-
83
- it "reads an array of strings, taking a memory offset parameter" do
84
- strings = ["foo", "bar", "baz", "testing", "ffi"]
85
- ptrary = FFI::MemoryPointer.new(:pointer, 5)
86
- ary = strings.inject([]) do |a, str|
87
- f = FFI::MemoryPointer.new(1024)
88
- f.put_string(0, str)
89
- a << f
90
- end
91
- ptrary.write_array_of_pointer(ary)
92
- expect(ptrary.get_array_of_string(2 * FFI.type_size(:pointer), 3)).to eq(["baz", "testing", "ffi"])
93
- end
94
-
95
- it "raises an IndexError when trying to read an array of strings out of bounds" do
96
- strings = ["foo", "bar", "baz", "testing", "ffi"]
97
- ptrary = FFI::MemoryPointer.new(:pointer, 5)
98
- ary = strings.inject([]) do |a, str|
99
- f = FFI::MemoryPointer.new(1024)
100
- f.put_string(0, str)
101
- a << f
102
- end
103
- ptrary.write_array_of_pointer(ary)
104
- expect { ptrary.get_array_of_string(0, 6) }.to raise_error
105
- end
106
-
107
- it "raises an IndexError when trying to read an array of strings using a negative offset" do
108
- strings = ["foo", "bar", "baz", "testing", "ffi"]
109
- ptrary = FFI::MemoryPointer.new(:pointer, 5)
110
- ary = strings.inject([]) do |a, str|
111
- f = FFI::MemoryPointer.new(1024)
112
- f.put_string(0, str)
113
- a << f
114
- end
115
- ptrary.write_array_of_pointer(ary)
116
- expect { ptrary.get_array_of_string(-1) }.to raise_error
117
- end
118
- end