ffi-bitfield 0.0.3 → 0.0.4
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.
- checksums.yaml +4 -4
- data/README.md +1 -2
- data/lib/ffi/bit_field.rb +1 -0
- data/lib/ffi/bit_field/layout.rb +13 -8
- data/lib/ffi/bit_field/property.rb +27 -3
- data/lib/ffi/bit_field/version.rb +1 -1
- data/lib/ffi/bit_struct.rb +2 -0
- data/lib/ffi/managed_bit_struct.rb +2 -0
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 811ea7a9da659976db52363a7e2702e0b377ab4881393e0559cd6aa5cab91117
|
4
|
+
data.tar.gz: d9ba1cb6673e6e332a85050479c9e7307870a5dfa26bddf22ff0aeb313428f38
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
data/lib/ffi/bit_field/layout.rb
CHANGED
@@ -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
|
-
|
7
|
-
|
8
|
-
|
9
|
-
#
|
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 =
|
15
|
+
parent_name = layout_args.shift.to_sym
|
13
16
|
member_names = []
|
14
17
|
widths = []
|
15
|
-
|
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
|
-
|
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
|
-
|
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
|
data/lib/ffi/bit_struct.rb
CHANGED
@@ -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
|