Module: HexaPDF::Utils::BitField
- Included in:
- Font::TrueType::Table::Head, Font::TrueType::Table::OS2, Type::AcroForm::Field, Type::AcroForm::Form, Type::AcroForm::SignatureField::CertificateSeedValueDictionary, Type::AcroForm::SignatureField::SeedValueDictionary, Type::Annotation, Type::FontDescriptor, Type::OutlineItem
- Defined in:
- lib/hexapdf/utils/bit_field.rb
Overview
This module is intended to be used to extend class objects. It provides the method #bit_field for declaring a bit field.
Instance Method Summary collapse
-
#bit_field(name, mapping, lister: "#{name}_values", getter: "#{name}_include?", setter: "set_#{name}", unsetter: "unset_#{name}", value_getter: name, value_setter: "self.#{name}") ⇒ Object
Creates a bit field for managing the integer attribute
name
.
Instance Method Details
#bit_field(name, mapping, lister: "#{name}_values", getter: "#{name}_include?", setter: "set_#{name}", unsetter: "unset_#{name}", value_getter: name, value_setter: "self.#{name}") ⇒ Object
Creates a bit field for managing the integer attribute name
.
The mapping
argument specifies the mapping of names to zero-based bit indices which allows one to use either the bit name or its index when getting or setting. When using an unknown bit name or bit index, an error is raised.
The calling class needs to respond to #name and #name= because these methods are used to get and set the raw integer value; or provide custom method names using the value_getter
and value_setter
arguments.
After invoking the method the calling class has four new instance methods:
-
NAME_values which returns an array of bit names representing the set bits.
-
NAME_include?(bit) which returns true if the given bit is set.
-
set_NAME(*bits, clear_existing: false) for setting the given bits.
-
unset_NAME(*bits) for clearing the given bits.
The method names can be overridden using the arguments lister
, getter
, setter
and unsetter
.
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/hexapdf/utils/bit_field.rb', line 63 def bit_field(name, mapping, lister: "#{name}_values", getter: "#{name}_include?", setter: "set_#{name}", unsetter: "unset_#{name}", value_getter: name, value_setter: "self.#{name}") mapping.default_proc = proc do |h, k| if h.value?(k) k else raise ArgumentError, "Invalid bit field name or index '#{k}' for #{self.name}##{name}" end end module_eval(<<-EOF, __FILE__, __LINE__ + 1) #{name.upcase}_BIT_MAPPING = mapping.freeze def #{lister} self.class::#{name.upcase}_BIT_MAPPING.keys.map {|n| #{getter}(n) ? n : nil }.compact end def #{getter}(bit) (#{value_getter} || 0)[self.class::#{name.upcase}_BIT_MAPPING[bit]] == 1 end def #{setter}(*bits, clear_existing: false) #{value_setter} = 0 if clear_existing || #{value_getter}.nil? result = #{value_getter} bits.each {|bit| result |= 1 << self.class::#{name.upcase}_BIT_MAPPING[bit] } #{value_setter} = result end def #{unsetter}(*bits) result = #{value_getter} || 0 return if result == 0 bits.each {|bit| result &= ~(1 << self.class::#{name.upcase}_BIT_MAPPING[bit]) } #{value_setter} = result end EOF end |