ffi_dry 0.1.4 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/History.txt +4 -0
- data/README.rdoc +13 -17
- data/VERSION +1 -1
- data/ffi_dry.gemspec +2 -2
- data/lib/ffi/dry.rb +40 -8
- metadata +2 -2
data/.gitignore
CHANGED
data/History.txt
CHANGED
data/README.rdoc
CHANGED
@@ -5,14 +5,14 @@ things and add support for some uncommon ones.
|
|
5
5
|
|
6
6
|
== Requirements
|
7
7
|
|
8
|
-
* ffi
|
8
|
+
* ffi (>= 0.5.0) - github.com/ffi/ffi
|
9
9
|
|
10
10
|
|
11
11
|
== Synopsis
|
12
12
|
|
13
13
|
(samples/ in the package for code)
|
14
14
|
|
15
|
-
|
15
|
+
One major feature is a DSL"-like" syntax for declaring structure members
|
16
16
|
in FFI::Struct or FFI::ManagedStruct definitions.
|
17
17
|
|
18
18
|
require 'rubygems'
|
@@ -34,16 +34,14 @@ in FFI::Struct or FFI::ManagedStruct definitions.
|
|
34
34
|
|
35
35
|
ss0=SomeStruct.new
|
36
36
|
|
37
|
-
With the declarations above, we specified :desc hash value in metadata
|
38
|
-
|
37
|
+
With the declarations above, we specified :desc hash value in metadata. Extra
|
38
|
+
metadata can have arbitrary keys and is accessible in every instance and class.
|
39
39
|
|
40
40
|
pp ss0.dsl_metadata
|
41
41
|
[{:type=>:uint16, :name=>:field1, :desc=>"this is field 1"},
|
42
42
|
{:type=>:uint16, :name=>:field2, :desc=>"this is field 2"}]
|
43
43
|
# => nil
|
44
44
|
|
45
|
-
Or class.
|
46
|
-
|
47
45
|
pp SomeStruct.dsl_metadata
|
48
46
|
#...
|
49
47
|
|
@@ -57,13 +55,10 @@ during initialization. (The FFI standard ways still work too)
|
|
57
55
|
ss3=SomeStruct.new {|x| x.field1=1 }
|
58
56
|
ss4=SomeStruct.new(:raw => raw_data) {|x| x.field1=1 }
|
59
57
|
|
60
|
-
[ ss0,
|
61
|
-
|
62
|
-
ss2,
|
63
|
-
ss3,
|
64
|
-
ss4 ].each_with_index {|x,i| p ["ss#{i}",[x.field1, x.field2]]}
|
58
|
+
[ ss0, ss1, ss2, ss3, ss4
|
59
|
+
].each_with_index {|x,i| p ["ss#{i}",[x.field1, x.field2]]}
|
65
60
|
|
66
|
-
# which
|
61
|
+
# which produces...
|
67
62
|
# ["ss0", [0, 0]]
|
68
63
|
# ["ss1", [0, 65535]]
|
69
64
|
# ["ss2", [1, 2]]
|
@@ -72,8 +67,8 @@ during initialization. (The FFI standard ways still work too)
|
|
72
67
|
|
73
68
|
|
74
69
|
Here's a broader example which utilizes that arbitrary ':desc' parameter in a
|
75
|
-
"neighborly" way. This also demonstrates superclasses to add common
|
76
|
-
features, declaring array fields, as well as nesting other structs.
|
70
|
+
"neighborly" way. This also demonstrates using superclasses to add common
|
71
|
+
struct features, declaring array fields, as well as nesting other structs.
|
77
72
|
|
78
73
|
require 'rubygems'
|
79
74
|
require 'ffi'
|
@@ -190,9 +185,10 @@ features, declaring array fields, as well as nesting other structs.
|
|
190
185
|
# type: :uint8
|
191
186
|
# desc: test field 2
|
192
187
|
|
193
|
-
There's also some
|
194
|
-
and handy thing when porting various libraries. We use
|
195
|
-
|
188
|
+
There's also some helper modules for collecting lookup maps for constants, a
|
189
|
+
common and handy thing when porting various libraries. We use the Ruby Socket
|
190
|
+
socket namespace here for demonstration purposes. You can 'slurp' constants
|
191
|
+
from any namespace this way.
|
196
192
|
|
197
193
|
require 'ffi/dry'
|
198
194
|
require 'socket'
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.5
|
data/ffi_dry.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{ffi_dry}
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.5"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Eric Monti"]
|
12
|
-
s.date = %q{2010-01-
|
12
|
+
s.date = %q{2010-01-15}
|
13
13
|
s.description = %q{Provides some useful modules, classes, and methods for FFI bindings as well as a DSL-like syntax for FFI::Struct layouts}
|
14
14
|
s.email = %q{emonti@matasano.com}
|
15
15
|
s.extra_rdoc_files = [
|
data/lib/ffi/dry.rb
CHANGED
@@ -108,7 +108,7 @@ module FFI::DRY
|
|
108
108
|
# the layout.
|
109
109
|
#
|
110
110
|
# This method is called automatically if you are using the initialize()
|
111
|
-
# method provided in the
|
111
|
+
# method provided in the Struct class and passing it a Hash as its only
|
112
112
|
# argument.
|
113
113
|
def set_fields(params=nil)
|
114
114
|
(params || {}).keys.each do |p|
|
@@ -169,13 +169,20 @@ module FFI::DRY
|
|
169
169
|
def _class_meths_from_dsl_metadata(meta)
|
170
170
|
(@dsl_metadata = meta).each do |spec|
|
171
171
|
name = spec[:name]
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
172
|
+
ftype = spec[:type]
|
173
|
+
unless instance_methods.include?(:"#{name}")
|
174
|
+
if p=spec[:p_struct] and p.kind_of?(Class)
|
175
|
+
define_method(:"#{name}") do
|
176
|
+
p.new(self[name]) unless self[name].null?
|
177
|
+
end
|
178
|
+
else
|
179
|
+
define_method(:"#{name}") { self[name] }
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
unless instance_methods.include?(:"#{name}=")
|
184
|
+
define_method(:"#{name}=") {|val| self[name]=val }
|
185
|
+
end
|
179
186
|
end
|
180
187
|
end
|
181
188
|
end
|
@@ -183,6 +190,19 @@ module FFI::DRY
|
|
183
190
|
def self.included(base)
|
184
191
|
base.extend(ClassMethods)
|
185
192
|
end
|
193
|
+
|
194
|
+
alias inspect_orig inspect
|
195
|
+
|
196
|
+
# Overrides inspect to show field names and values
|
197
|
+
def inspect
|
198
|
+
ret = "#<#{self.class}"
|
199
|
+
if not @_inspecting_in_progress
|
200
|
+
@_inspecting_in_progress = true
|
201
|
+
ret << " " << members.map {|m| "#{m}=#{self[m].inspect}"}.join(', ')
|
202
|
+
@_inspecting_in_progress = nil
|
203
|
+
end
|
204
|
+
ret << ">"
|
205
|
+
end
|
186
206
|
end # class StructHelper
|
187
207
|
|
188
208
|
# This is a wrapper around the FFI::StructLayoutBuilder. Its goal is to
|
@@ -235,6 +255,18 @@ module FFI::DRY
|
|
235
255
|
return ret
|
236
256
|
end
|
237
257
|
|
258
|
+
# A pointer to a structure. The structure does not allocate the entire
|
259
|
+
# space for the structure, just a pointer. When calling the accessors for
|
260
|
+
# a p_struct field, a new instance of the FFI::Struct will be returned.
|
261
|
+
def p_struct(name, klass, o={})
|
262
|
+
unless klass.kind_of?(Class)
|
263
|
+
raise(::ArgumentError, "klass must be a Class")
|
264
|
+
end
|
265
|
+
opts = o.merge(:p_struct => klass)
|
266
|
+
offset = opts[:offset]
|
267
|
+
field(name, :pointer, opts)
|
268
|
+
end
|
269
|
+
|
238
270
|
# Calls StructLayoutBuider.add_array() on the builder and stores
|
239
271
|
# a metadata hash entry (the opts hash with name and type overridden)
|
240
272
|
#
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ffi_dry
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eric Monti
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-01-
|
12
|
+
date: 2010-01-15 00:00:00 -06:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|