ffi_dry 0.1.4 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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