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 CHANGED
@@ -3,3 +3,4 @@
3
3
  coverage
4
4
  rdoc
5
5
  pkg
6
+ .yardoc
@@ -1,3 +1,7 @@
1
+ === 0.1.5 / 2010-1-4
2
+ * Added p_struct dsl directive sugar for creating FFI::Struct accessors to
3
+ handle pointers to structs.
4
+
1
5
  === 0.1.4 / 2010-1-1
2
6
  * Support for FFI 0.5.0 final and up.
3
7
  * Added NetStructHelper with accessors to provide automatic network byte
@@ -5,14 +5,14 @@ things and add support for some uncommon ones.
5
5
 
6
6
  == Requirements
7
7
 
8
- * ffi-ffi (>= 0.5.0) - github.com/ffi/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
- A major feature is a DSL"-like" syntax for declaring structure members
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
- Let's check out in our instance.
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
- ss1,
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 will produce...
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 struct
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 helpers for collecting lookup maps for constants, a common
194
- and handy thing when porting various libraries. We use Socket here just for
195
- example purposes, you can 'slurp' constants form any namespace this way.
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.4
1
+ 0.1.5
@@ -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.4"
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-02}
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 = [
@@ -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 DryStruct class and passing it a Hash as its only
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
- type = spec[:type]
173
- define_method(:"#{name}") do
174
- self[name]
175
- end unless instance_methods.include?(:"#{name}")
176
- define_method(:"#{name}=") do |val|
177
- self[name]=val
178
- end unless instance_methods.include?(:"#{name}=")
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
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-02 00:00:00 -06:00
12
+ date: 2010-01-15 00:00:00 -06:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency