ffi-bitfield 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6d75494c09a1b688169fd2630a7ea299a5c58ad312f9ae369a4c0c11165c46e6
4
- data.tar.gz: 60840b874151b38faa6ef56cf6f7f6f179cf2415053edce96f08f32e82874ceb
3
+ metadata.gz: 811ea7a9da659976db52363a7e2702e0b377ab4881393e0559cd6aa5cab91117
4
+ data.tar.gz: d9ba1cb6673e6e332a85050479c9e7307870a5dfa26bddf22ff0aeb313428f38
5
5
  SHA512:
6
- metadata.gz: 6d1d86bda1e5c71a59bc801eb35ee64522bc5d6bd49452afd01583240d4358d370fadc5b3bfa6c619ebb3b65c3cc116d14e149cce2c8977f923365708a8d20bb
7
- data.tar.gz: 6c7642a18712a0959273d6a46a5c46b3f6c2bd1b0861cace828f9d6fb717aa76ab3643dc9af509c5478e80e05371609a9a5f871132016f9767b50cb77985c794
6
+ metadata.gz: 78437889463ee5752ad5a11969407fd63ba2feaa8687054334e90d5ae040bcd70d85bc6580c6328ff5261c147c36700c3fced1980184cf7f8432f9592420f104
7
+ data.tar.gz: ee046b7f0c9712fd2463be46e62d96e4a75dda6c966d8ab722d344bd8c3396f7f1d77eb3a6fe3181dd9b7f70e286f22adad63b5e493b384729e013f51b12dda4
data/README.md CHANGED
@@ -5,8 +5,6 @@
5
5
 
6
6
  Bit field for [Ruby-FFI](https://github.com/ffi/ffi)
7
7
 
8
- :construction: alpha ー Supports reading bit fields only.
9
-
10
8
  ## Installation
11
9
 
12
10
  ```sh
@@ -75,6 +73,7 @@ bundle exec rake test
75
73
 
76
74
  ## Contributing
77
75
 
76
+ ffi-bitfield is a library under development, so even small improvements like typofix are welcome! Please feel free to send us your pull requests.
78
77
  Bug reports and pull requests are welcome on GitHub at https://github.com/kojix2/bitstruct.
79
78
 
80
79
  ## License
data/lib/ffi/bit_field.rb CHANGED
@@ -5,6 +5,7 @@ require_relative 'bit_struct'
5
5
  require_relative 'managed_bit_struct'
6
6
 
7
7
  module FFI
8
+ # This module is just a namespace.
8
9
  module BitField
9
10
  end
10
11
  end
@@ -2,19 +2,22 @@
2
2
 
3
3
  module FFI
4
4
  module BitField
5
+ # Layout provides the `bit_fields` method for registering field members.
5
6
  module Layout
6
- def bit_fields(*args)
7
- # The reason for using class instance variable here instead of
8
- # class variable is that sub-class of FFI::Struct cannot be inherited again,
9
- # not because class instance variables are clean.
7
+ # @param [Array] layout_args
8
+ # @return [Symbol] parent_name
9
+ def bit_fields(*layout_args)
10
+ # The reason for using class instance variable here instead of class variable
11
+ # is not because class instance variables are clean,
12
+ # but because sub-class of FFI::Struct cannot be inherited again.
10
13
  @bit_field_hash_table = {} unless instance_variable_defined?(:@bit_field_hash_table)
11
14
 
12
- parent_name = args.shift
15
+ parent_name = layout_args.shift.to_sym
13
16
  member_names = []
14
17
  widths = []
15
- args.each_slice(2) do |name, width|
16
- member_names << name
17
- widths << width
18
+ layout_args.each_slice(2) do |name, width|
19
+ member_names << name.to_sym
20
+ widths << width.to_i
18
21
  end
19
22
  starts = widths.inject([0]) do |result, width|
20
23
  result << (result.last + width)
@@ -22,6 +25,8 @@ module FFI
22
25
  member_names.zip(starts, widths).each do |name, start, width|
23
26
  @bit_field_hash_table[name] = [parent_name, start, width]
24
27
  end
28
+
29
+ parent_name
25
30
  end
26
31
  alias bit_field bit_fields
27
32
  end
@@ -2,17 +2,41 @@
2
2
 
3
3
  module FFI
4
4
  module BitField
5
+ # Properties provides methods to read and write bit fields.
5
6
  module Property
7
+ # @param [Symbol] member_name
8
+ # @return [Integer] value
6
9
  def [](member_name)
7
- bit_fields = self.class.instance_variable_get(:@bit_field_hash_table)
8
- parent_name, start, width = bit_fields[member_name]
10
+ parent_name, start, width = member_value_info(member_name)
9
11
  if parent_name
10
12
  value = get_member_value(parent_name)
11
- (value >> start) & ((1 << width) - 1)
13
+ value[start, width]
12
14
  else
13
15
  get_member_value(member_name)
14
16
  end
15
17
  end
18
+
19
+ def []=(member_name, value)
20
+ parent_name, start, width = member_value_info(member_name)
21
+ if parent_name
22
+ raise "Value #{value} is larger than #{(1 << width) - 1}" if value.bit_length > width
23
+
24
+ parent_value = get_member_value(parent_name)
25
+ all = ((1 << parent_value.bit_length) - 1)
26
+ mask = all ^ (((1 << width) - 1) << start)
27
+ masked_value = parent_value & mask
28
+ new_value = masked_value | (value << start)
29
+ set_member_value(parent_name, new_value)
30
+ else
31
+ set_member_value(member_name, value)
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ def member_value_info(member_name)
38
+ self.class.instance_variable_get(:@bit_field_hash_table)[member_name]
39
+ end
16
40
  end
17
41
  end
18
42
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module FFI
4
4
  module BitField
5
- VERSION = '0.0.3'
5
+ VERSION = '0.0.4'
6
6
  end
7
7
  end
@@ -6,9 +6,11 @@ require_relative 'bit_field/layout'
6
6
  require_relative 'bit_field/property'
7
7
 
8
8
  module FFI
9
+ # Subclass of FFI::Struct that support bit fields.
9
10
  class BitStruct < Struct
10
11
  # [] is defined in FFI::Struct
11
12
  alias get_member_value []
13
+ alias set_member_value []=
12
14
  extend BitField::Layout
13
15
  # The Property module included in the FFI::ManagedBitStruct class is
14
16
  # * behind the FFI::ManagedBitStruct class, but is
@@ -6,9 +6,11 @@ require_relative 'bit_field/layout'
6
6
  require_relative 'bit_field/property'
7
7
 
8
8
  module FFI
9
+ # Subclass of FFI::ManagedStruct that support bit fields.
9
10
  class ManagedBitStruct < ManagedStruct
10
11
  # [] is defined in FFI::Struct
11
12
  alias get_member_value []
13
+ alias set_member_value []=
12
14
  extend BitField::Layout
13
15
  # The Property module included in the FFI::BitStruct class is
14
16
  # * behind the FFI::BitStruct class, but is
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ffi-bitfield
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - kojix2