Class: BitStream::Unsigned

Inherits:
Object
  • Object
show all
Defined in:
lib/types/integer.rb

Constant Summary collapse

BE_SYMBOLS =
[:big_endian, :be, :msb_first, :motorola, nil]
LE_SYMBOLS =
[:little_endian, :le, :lsb_first, :intel]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(bit_width, big_endian) ⇒ Unsigned

Returns a new instance of Unsigned.



37
38
39
40
# File 'lib/types/integer.rb', line 37

def initialize(bit_width, big_endian)
  @bit_width = bit_width
  @big_endian = big_endian
end

Instance Attribute Details

#bit_widthObject (readonly)

Returns the value of attribute bit_width.



35
36
37
# File 'lib/types/integer.rb', line 35

def bit_width
  @bit_width
end

Class Method Details

.instance(props, bit_width) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/types/integer.rb', line 22

def self.instance(props, bit_width)
  byte_order = props[:byte_order]
  if BE_SYMBOLS.include?(byte_order)
    @be_instances[bit_width]
  elsif LE_SYMBOLS.include?(byte_order)
    @le_instances[bit_width]
  else
    STDERR.puts("Unknown byte order #{byte_order.inspect}.",
                "Assuming that the byte order is big endian.")
    @be_instances[bit_width]
  end
end

Instance Method Details

#lengthObject



42
43
44
# File 'lib/types/integer.rb', line 42

def length
  @bit_width
end

#read(s, offset) ⇒ Object



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/types/integer.rb', line 46

def read(s, offset)
  value = 0
  byteoffset = offset / 8
  bitoffset  = offset % 8
  bytelength = (@bit_width + bitoffset + 7) / 8

  bytes = s[byteoffset, bytelength].unpack('C*')
  bytes.reverse! unless @big_endian

  bytes.each do |b|
    value <<= 8
    value |= b
  end

  value &= ~(-1 << (bytelength * 8 - bitoffset))
  value >>= (8 - (@bit_width + bitoffset) % 8) % 8

  return FieldInfo.new(value, @bit_width)
end

#write(s, offset, value) ⇒ Object



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
# File 'lib/types/integer.rb', line 66

def write(s, offset, value)
  byteoffset = offset / 8
  bitoffset  = offset % 8

  if bitoffset != 0
    raise "#{self.class.name}#write has not supported non-byte-aligned fields yet."
  end
  unless @big_endian
    raise "#{self.class.name}#write has not supported little endian yet."
  end

  i = 0
  tail = ""
  while value != 0
    index = byteoffset + @bit_width / 8 + i - 1
    if s.bytesize <= index
      tail.insert(0, [value & 0xff].pack('C'))
    else
      s[index] = [value & 0xff].pack('C')
    end
    value >>= 8
    i -= 1
  end
  s << tail

  return @bit_width
end