Class: Fields::UnsignedField

Inherits:
Field show all
Defined in:
lib/fields.rb

Overview

Accepts negative numbers on assignment, but stores them as 2s complement.

Instance Attribute Summary

Attributes inherited from Field

#bitstring, #default_value, #desc, #endianness, #length, #length_type, #name, #type

Instance Method Summary collapse

Methods inherited from Field

#parse_buffer, #parse_buffer_lazy, #parse_buffer_strict, #randomize!, #set_raw, #set_value, #to_s

Constructor Details

#initialize(*args) ⇒ UnsignedField

Returns a new instance of UnsignedField.



121
122
123
124
# File 'lib/fields.rb', line 121

def initialize *args
    @length_type="fixed"
    super
end

Instance Method Details

#get_valueObject



146
147
148
149
150
151
152
153
154
# File 'lib/fields.rb', line 146

def get_value
    tempstring=@bitstring
    if self.endianness==:little
        if tempstring.length > 8 && tempstring.length % 8 ==0
            tempstring=tempstring.scan(/.{8}/).reverse.join
        end
    end
    tempstring.to_i(2)
end

#input_to_bitstring(value) ⇒ Object



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/fields.rb', line 126

def input_to_bitstring( value )
    unless value.kind_of? Integer
        raise ArgumentError, "UnsignedField (#{@name}): attempted to assign non-integer"
    end
    if value.to_s(2).length > @length
        # works for negative assignments as well, since to_s(2) adds a '-' to the start of the binary string
        raise ArgumentError, "UnsignedField (#{@name}): value too big for field length"
    end
    # accept negative numbers, but store them as their two's complement representation for this bitlength
    # (get_value will return the positive interpretation)
    unpadded=value < 0 ? (("1"+"0"*@length).to_i(2)-value.abs).to_s(2) : value.to_s(2)
    value="0"*(@length-unpadded.length)+unpadded # left pad with zeroes to full length
    if self.endianness==:little
        if value.length > 8 && value.length % 8 ==0
            value=value.scan(/.{8}/).reverse.join
        end
    end
    value
end