Class: BinaryParser::AbstractBinary

Inherits:
Object
  • Object
show all
Defined in:
lib/general_class/abstract_binary.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(binary_string, bit_index = nil, bit_length = nil) ⇒ AbstractBinary

Returns a new instance of AbstractBinary.



6
7
8
9
10
# File 'lib/general_class/abstract_binary.rb', line 6

def initialize(binary_string, bit_index=nil, bit_length=nil)
  @bin_str = binary_string
  @bit_index = bit_index || 0
  @bit_length = bit_length || binary_string.length * 8 - @bit_index
end

Instance Attribute Details

#bit_lengthObject (readonly)

Returns the value of attribute bit_length.



4
5
6
# File 'lib/general_class/abstract_binary.rb', line 4

def bit_length
  @bit_length
end

Instance Method Details

#+(other) ⇒ Object



92
93
94
95
96
97
98
# File 'lib/general_class/abstract_binary.rb', line 92

def +(other)
  if self.byte_position? && other.byte_position?
    binary_concat(other) 
  else
    naive_concat(other)
  end
end

#alt(binary_or_uint) ⇒ Object

Methods for generating modified binary.



44
45
46
47
48
49
50
51
52
53
# File 'lib/general_class/abstract_binary.rb', line 44

def alt(binary_or_uint)
  case binary_or_uint
  when Integer
    alt_uint(binary_or_uint)
  when String
    alt_binary(binary_or_uint)
  else
    raise BadManipulationError, "Argument shouled be Integer or binary-encoded String."
  end
end

#alt_binary(binary) ⇒ Object



68
69
70
71
72
73
# File 'lib/general_class/abstract_binary.rb', line 68

def alt_binary(binary)
  unless binary.length * 8 == @bit_length
    raise BadBinaryManipulationError, "Given binary'length doesn't match self."
  end
  return self.class.new(binary)
end

#alt_uint(uint) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/general_class/abstract_binary.rb', line 55

def alt_uint(uint)
  unless uint.is_a?(Integer) && uint >= 0
    raise BadManipulationError, "Specified arg #{uint} is not number of unsigned int."
  end
  unless uint < 2 ** @bit_length
    raise BadBinaryManipulationError, "Specified arg #{uint} is too big to " +
      "express by #{@bit_length} bit."
  end
  alt_binary = BinaryManipulateFunction.convert_uint_into_binary(uint, @bit_length)
  alt_shift = 7 - ((@bit_length - 1) % 8)
  return self.class.new(alt_binary, alt_shift)
end

#binary_concat(other) ⇒ Object



88
89
90
# File 'lib/general_class/abstract_binary.rb', line 88

def binary_concat(other)
  self.class.new(self.to_s + other.to_s)
end

#byte_position?Boolean

Returns:

  • (Boolean)


38
39
40
# File 'lib/general_class/abstract_binary.rb', line 38

def byte_position?
  @bit_index % 8 == 0 && @bit_length % 8 == 0
end

#check_invalid_sub_position(new_bit_index, new_bit_length) ⇒ Object



115
116
117
118
119
120
121
122
123
# File 'lib/general_class/abstract_binary.rb', line 115

def check_invalid_sub_position(new_bit_index, new_bit_length)
  if new_bit_length < 0
    raise BadBinaryManipulationError, "Specified new bit length is negative (#{new_bit_length})."
  end
  unless @bit_index <= new_bit_index && new_bit_index + new_bit_length <= @bit_index + @bit_length
    raise BadBinaryManipulationError, "Specified new bit index #{new_bit_index} is " +
      "out of current binary bit_index=#{@bit_index}, bit_length=#{@bit_length}."
  end
end

#check_non_byte_position(bit_index, bit_length) ⇒ Object



125
126
127
128
129
130
# File 'lib/general_class/abstract_binary.rb', line 125

def check_non_byte_position(bit_index, bit_length)
  unless bit_index % 8 == 0 && bit_length % 8 == 0
    raise BadBinaryManipulationError, "Position {bit_index=#{bit_index}, " +
      "bit_length=#{bit_length}} is not byte-position."
  end
end

#decode_spec(spec) ⇒ Object

Sub methods (helpers)



103
104
105
106
107
108
109
110
111
112
113
# File 'lib/general_class/abstract_binary.rb', line 103

def decode_spec(spec)
  new_bit_index  = @bit_index + spec[:bit_index].to_i + spec[:byte_index].to_i * 8
  
  if !spec[:bit_length] && !spec[:byte_length]
    new_bit_length = @bit_length - (new_bit_index - @bit_index)
  else
    new_bit_length = spec[:bit_length].to_i + spec[:byte_length].to_i * 8
  end
  
  return new_bit_index, new_bit_length
end

#naive_concat(other) ⇒ Object



75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/general_class/abstract_binary.rb', line 75

def naive_concat(other)
  left_shift = 7 - ((self.bit_length - 1) % 8)
  left_binary  = BinaryManipulateFunction.convert_uint_into_binary(self.to_i, self.bit_length)
  
  right_shift = 7 - ((other.bit_length - 1) % 8)
  right_binary = BinaryManipulateFunction.convert_uint_into_binary(other.to_i << right_shift,
                                                                   other.bit_length)

  return self.class.new(left_binary + right_binary,
                        left_shift,
                        self.bit_length + other.bit_length)
end

#sub(spec) ⇒ Object



12
13
14
15
16
# File 'lib/general_class/abstract_binary.rb', line 12

def sub(spec)
  new_bit_index, new_bit_length = decode_spec(spec)
  check_invalid_sub_position(new_bit_index, new_bit_length)
  return self.class.new(@bin_str, new_bit_index, new_bit_length)
end

#to_charsObject



28
29
30
31
# File 'lib/general_class/abstract_binary.rb', line 28

def to_chars
  check_non_byte_position(@bit_index, @bit_length)
  return @bin_str[@bit_index / 8, @bit_length / 8].unpack("C*")
end

#to_iObject



18
19
20
21
22
23
24
25
26
# File 'lib/general_class/abstract_binary.rb', line 18

def to_i
  if @bit_length == 0
    raise BadBinaryManipulationError, "Cannot convert empty binary into integer."
  end
  str, ml, mr = BinaryManipulateFunction.needed_sub_string(@bin_str, 
                                                           @bit_index,
                                                           @bit_index + @bit_length - 1)
  return BinaryManipulateFunction.to_unsigned_int(str, ml, mr)
end

#to_sObject



33
34
35
36
# File 'lib/general_class/abstract_binary.rb', line 33

def to_s
  check_non_byte_position(@bit_index, @bit_length)
  return @bin_str[@bit_index / 8, @bit_length / 8]
end