Class: Codec::Bitmap

Inherits:
Base
  • Object
show all
Defined in:
lib/codec/bitmap.rb

Constant Summary collapse

NB_BITS_BY_BYTE =
8

Instance Method Summary collapse

Methods inherited from Base

#add_sub_codec, #get_sub_codecs

Constructor Details

#initialize(length) ⇒ Bitmap

Returns a new instance of Bitmap.

[View source]

4
5
6
7
8
# File 'lib/codec/bitmap.rb', line 4

def initialize(length)
  @length=length
  @num_extended_bitmaps=[]
  @subCodecs = {}
end

Instance Method Details

#add_extended_bitmap(num_extention) ⇒ Object

[View source]

14
15
16
# File 'lib/codec/bitmap.rb', line 14

def add_extended_bitmap(num_extention)
  @num_extended_bitmaps << num_extention.to_i
end

#bitmap_lengthObject

[View source]

10
11
12
# File 'lib/codec/bitmap.rb', line 10

def bitmap_length
  @length * NB_BITS_BY_BYTE
end

#decode(buf, msg, length = nil) ⇒ Object

[View source]

80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/codec/bitmap.rb', line 80

def decode(buf,msg, length=nil)
  buf = buf.slice!(0...length) if length && length > 0
  field_num = 1
  # 1. read bitmap
  fields_list = decode_bitmap(buf,field_num)
  field_num += bitmap_length
  # 2. decode each field present
  while fields_list.length > 0
    # get next field number in bitmap
    field_id = fields_list.slice!(0)
    field_tag = field_id.to_s
    if @num_extended_bitmaps.include?(field_id)
      nextFields = decode_bitmap(buf,field_num)
      fields_list = fields_list + nextFields
    elsif @subCodecs[field_tag].respond_to?(:decode)
      Logger.debug "Parsing bitmap field #{field_tag}"
      f = Field.new(field_tag)
      @subCodecs[field_tag].decode(buf,f)
      msg.add_sub_field(f)
    else
     f = Field.new("ERR") 
     f.set_value(buf.unpack("H*").first)
     msg.add_sub_field(f)
      raise ParsingException.new "#{msg}\nError unknown field #{field_tag} : "
    end
  end
end

#decode_bitmap(buffer, first_field_num) ⇒ Object

[View source]

18
19
20
21
22
23
24
25
26
27
# File 'lib/codec/bitmap.rb', line 18

def decode_bitmap(buffer,first_field_num)
  fields_ids = []
  bitmap = buffer.slice!(0...@length).unpack("B*").first
  field_num = first_field_num
  until(bitmap.empty?)
    fields_ids << field_num if bitmap.slice!(0) == "1"
    field_num += 1
  end
  return fields_ids
end

#encode(buf, field) ⇒ Object

[View source]

46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/codec/bitmap.rb', line 46

def encode(buf, field)
  Logger.debug { "Start bitmap encoding\n" }
  initial_length = buf.length
  fields = field.get_value 
  encoded_fields = []
  fields_list = fields.collect{|sf| sf.get_id.to_i}
  fields_list.sort!
  nb_additionnal_bitmaps = (fields_list.last - 1) / bitmap_length
  @num_extended_bitmaps[0...nb_additionnal_bitmaps].each{ |bitmap_field_id|
    Logger.debug{"adding bitmap = #{bitmap_field_id}\n"}
    fields_list << bitmap_field_id
    fields << Field.new(bitmap_field_id)
  }
  fields.sort!{|a,b| a.get_id.to_i <=> b.get_id.to_i}
  # Encode first bitmap
  bitmap_itt = 0
  encode_bitmap(buf,fields_list,bitmap_itt)
  fields.each do |sf|
    codec = @subCodecs[sf.get_id]
    if @num_extended_bitmaps.include?(sf.get_id)
      bitmap_itt += 1
      encode_bitmap(buf, fields_list, bitmap_itt)
    elsif codec.nil?
      raise EncodingException, "unknown codec for subfield #{sf.get_id}"
    elsif encoded_fields.include?(sf.get_id.to_i)
      raise EncodingException, "Multiple subfield #{sf.get_id} is invalid for Codec::Bitmap"
    else
      codec.encode(buf,sf)
    end
    encoded_fields << sf.get_id.to_i
  end
  return buf.length - initial_length      
end

#encode_bitmap(buf, fields_list, bitmap_index) ⇒ Object

[View source]

29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/codec/bitmap.rb', line 29

def encode_bitmap(buf,fields_list,bitmap_index)
  offset_id = bitmap_index * bitmap_length + 1
  bitmap = ""
  (offset_id...(offset_id + bitmap_length)).each do |i|
    if fields_list.include?(i)
      bitmap << "1"
    else
      bitmap << "0"
    end
  end
  Logger.debug { "Encoding bitmap #{bitmap_index} 
    form #{offset_id} to #{offset_id + bitmap_length - 1} 
    with #{fields_list.collect{|id| id.to_s}.join(',')}
    result #{bitmap}" }
  buf << [bitmap].pack("B*")
end