Class: CTypes::Bitfield
- Inherits:
-
Object
- Object
- CTypes::Bitfield
- Extended by:
- Type
- Defined in:
- lib/ctypes/bitfield.rb
Overview
define a bit-field type for use in structures
Defined Under Namespace
Classes: Builder
Instance Attribute Summary
Attributes included from Type
Class Method Summary collapse
- .==(other) ⇒ Object
-
._new ⇒ Bitfield
private
allocate an uninitialized instance of the bitfield.
- .builder ⇒ Object private
-
.export_type(q) ⇒ Object
generate ruby code needed to create this type.
- .field_layout ⇒ Object private
-
.fields ⇒ Object
get the list of fields defined in this bitfield.
-
.fixed_size? ⇒ Boolean
check if bitfield is a fixed size.
-
.greedy? ⇒ Boolean
check if bitfield is greedy.
-
.has_field?(name) ⇒ Boolean
check if the bitfield declared a specific field.
-
.layout(&block) ⇒ Object
describe the layout of the bitfield.
-
.new(fields = nil) ⇒ Bitfield
allocate an instance of the Bitfield and initialize default values.
-
.pack(value, endian: default_endian, validate: true) ⇒ ::String
pack a ruby hash containing bitfield values into a binary string.
- .pretty_print(q) ⇒ Object
-
.size ⇒ Object
get the size of the bitfield in bytes.
-
.unpack_one(buf, endian: default_endian) ⇒ Bitfield
convert a String containing the binary represention of a c type into the equivalent ruby type.
Instance Method Summary collapse
-
#==(other) ⇒ Object
determine if this instance of the bitfield is equal to another instance.
-
#[](k) ⇒ Object
get an bitfield value.
-
#[]=(k, v) ⇒ Object
set a bitfield value.
- #has_key?(name) ⇒ Boolean
-
#pretty_print(q) ⇒ Object
:nodoc:.
-
#to_binstr(endian: self.class.default_endian) ⇒ ::String
return the binary representation of this Bitfield instance.
- #to_h(shallow: false) ⇒ Object (also: #to_hash)
Methods included from Type
default_endian, default_value, fixed_size?, greedy?, pack, pread, read, unpack, unpack_all, unpack_one, with_endian, without_endian
Class Method Details
.==(other) ⇒ Object
195 196 197 198 199 200 201 |
# File 'lib/ctypes/bitfield.rb', line 195 def self.==(other) return true if super return false unless other.is_a?(Class) && other < Bitfield other.field_layout == @bits && other.default_endian == default_endian && other.size == size end |
._new ⇒ Bitfield
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
allocate an uninitialized instance of the bitfield
183 |
# File 'lib/ctypes/bitfield.rb', line 183 alias_method :_new, :new |
.builder ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
74 75 76 |
# File 'lib/ctypes/bitfield.rb', line 74 def self.builder Builder.new end |
.export_type(q) ⇒ Object
generate ruby code needed to create this type
165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'lib/ctypes/bitfield.rb', line 165 def self.export_type(q) q << "bitfield {" q.break q.nest(2) do @layout.each do |cmd| q << cmd q.break end end q << "}" q << ".with_endian(%p)" % [@endian] if @endian end |
.field_layout ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
204 205 206 |
# File 'lib/ctypes/bitfield.rb', line 204 def self.field_layout # :nodoc: @bits end |
.fields ⇒ Object
get the list of fields defined in this bitfield
144 145 146 |
# File 'lib/ctypes/bitfield.rb', line 144 def self.fields @fields.keys end |
.fixed_size? ⇒ Boolean
check if bitfield is a fixed size
101 102 103 |
# File 'lib/ctypes/bitfield.rb', line 101 def self.fixed_size? true end |
.greedy? ⇒ Boolean
check if bitfield is greedy
106 107 108 |
# File 'lib/ctypes/bitfield.rb', line 106 def self.greedy? false end |
.has_field?(name) ⇒ Boolean
check if the bitfield declared a specific field
149 150 151 |
# File 'lib/ctypes/bitfield.rb', line 149 def self.has_field?(name) @fields.has_key?(name) end |
.layout(&block) ⇒ Object
describe the layout of the bitfield
66 67 68 69 70 71 |
# File 'lib/ctypes/bitfield.rb', line 66 def self.layout(&block) raise Error, "no block given" unless block builder = Builder.new(&block) builder.instance_eval(&block) apply_layout(builder) end |
.new(fields = nil) ⇒ Bitfield
allocate an instance of the Bitfield and initialize default values
190 191 192 193 |
# File 'lib/ctypes/bitfield.rb', line 190 def self.new(fields = nil) buf = fields.nil? ? ("\0" * size) : pack(fields) unpack(buf) end |
.pack(value, endian: default_endian, validate: true) ⇒ ::String
pack a ruby hash containing bitfield values into a binary string
115 116 117 118 119 120 121 122 123 |
# File 'lib/ctypes/bitfield.rb', line 115 def self.pack(value, endian: default_endian, validate: true) value = value.to_hash.freeze value = @dry_type[value] unless validate == false out = 0 @bits.each do |(name, offset, mask, _)| out |= (value[name] & mask) << offset end @type.pack(out, endian:, validate:) end |
.pretty_print(q) ⇒ Object
153 154 155 156 157 158 159 |
# File 'lib/ctypes/bitfield.rb', line 153 def self.pretty_print(q) q.ctype("bitfield", @endian) do q.seplist(@layout, -> { q.breakable(";") }) do |cmd| q.text(cmd) end end end |
.size ⇒ Object
get the size of the bitfield in bytes
96 97 98 |
# File 'lib/ctypes/bitfield.rb', line 96 def self.size @type&.size end |
.unpack_one(buf, endian: default_endian) ⇒ Bitfield
convert a String containing the binary represention of a c type into the equivalent ruby type
131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/ctypes/bitfield.rb', line 131 def self.unpack_one(buf, endian: default_endian) value, rest = @type.unpack_one(buf, endian:) out = _new @bits.each do |(name, offset, mask, signed, var)| v = (value >> offset) & mask v |= (-1 << signed) | v if signed && v[signed - 1] == 1 out.instance_variable_set(var, v) end [out, rest] end |
Instance Method Details
#==(other) ⇒ Object
this implementation also supports Hash equality through #to_h
determine if this instance of the bitfield is equal to another instance
263 264 265 266 267 268 269 270 271 272 273 274 |
# File 'lib/ctypes/bitfield.rb', line 263 def ==(other) case other when self.class self.class.field_layout.all? do |name, _, _, _, var| instance_variable_get(var) == other[name] end when Hash other == to_h else super end end |
#[](k) ⇒ Object
get an bitfield value
219 220 221 222 |
# File 'lib/ctypes/bitfield.rb', line 219 def [](k) has_field!(k) instance_variable_get(:"@#{k}") end |
#[]=(k, v) ⇒ Object
set a bitfield value
211 212 213 214 |
# File 'lib/ctypes/bitfield.rb', line 211 def []=(k, v) has_field!(k) instance_variable_set(:"@#{k}", v) end |
#has_key?(name) ⇒ Boolean
224 225 226 |
# File 'lib/ctypes/bitfield.rb', line 224 def has_key?(name) self.class.has_field?(name) end |
#pretty_print(q) ⇒ Object
:nodoc:
243 244 245 246 247 248 249 250 251 |
# File 'lib/ctypes/bitfield.rb', line 243 def pretty_print(q) # :nodoc: q.group(4, "bitfield {", "}") do q.seplist(self.class.field_layout, -> { q.breakable("") }) do |name, _| q.text(".#{name} = ") q.pp(instance_variable_get(:"@#{name}")) q.text(", ") end end end |
#to_binstr(endian: self.class.default_endian) ⇒ ::String
return the binary representation of this Bitfield instance
256 257 258 |
# File 'lib/ctypes/bitfield.rb', line 256 def to_binstr(endian: self.class.default_endian) self.class.pack(to_h, endian:) end |
#to_h(shallow: false) ⇒ Object Also known as: to_hash
234 235 236 237 238 239 240 |
# File 'lib/ctypes/bitfield.rb', line 234 def to_h(shallow: false) out = {} self.class.field_layout.each do |name, _, _, _, var| out[name] = instance_variable_get(var) end out end |