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 +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
|