Class: Codec::Bitmap

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

Constant Summary collapse

NB_BITS_BY_BYTE =
8

Instance Attribute Summary

Attributes inherited from Base

#id

Instance Method Summary collapse

Methods inherited from Base

#add_sub_codec, #build_field, #decode_with_length, #encode_with_length, #eval_length, #get_length, #get_sub_codecs

Constructor Details

#initialize(id, length) ⇒ Bitmap

Returns a new instance of Bitmap.



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

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

Instance Method Details

#add_extended_bitmap(num_extention) ⇒ Object



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

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

#bitmap_lengthObject



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

def bitmap_length
  @length * NB_BITS_BY_BYTE
end

#decode(buffer) ⇒ Object



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
100
# File 'lib/codec/bitmap.rb', line 73

def decode(buffer)
  msg = Field.new(@id)
  field_num = 1
  # 1. read bitmap
  fields_list,buf = decodeBitmap(buffer,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,buf = decodeBitmap(buf,field_num)
      fields_list = fields_list + nextFields
    elsif @subCodecs[field_tag].respond_to?(:decode)
      Logger.debug "Parsing bitmap field #{field_tag}"
      f,buf = @subCodecs[field_tag].decode(buf)
      f.set_id(field_tag)
      msg.add_sub_field(f)
    else
     f = Field.new("ERR") 
     f.set_value(buf.unpack("H*").first)
     msg.add_sub_field(f)
      raise ParsingException,msg.to_yaml + "\nError unknown field #{field_tag} : "
    end
  end
  return msg,buf
end

#decodeBitmap(buffer, first_field_num) ⇒ Object



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

def decodeBitmap(buffer,first_field_num)
  fieldsList = []
  
  bitmapBuffer = buffer[0,@length].unpack("B*").first
  buf = buffer[@length,buffer.length]
  field_num = first_field_num
  while(bitmapBuffer.length > 0)
    fieldsList << field_num if bitmapBuffer.start_with?('1')
    bitmapBuffer.slice!(0)
    field_num += 1
  end
  return fieldsList, buf
end

#encode(field) ⇒ Object



44
45
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
# File 'lib/codec/bitmap.rb', line 44

def encode(field)
  fields = field.get_value 
  encoded_fields = []
  fields_list = fields.collect{|sf| sf.get_id.to_i}
  # Add field for bitmaps
  bitmap_fields = @num_extended_bitmaps[0,(fields_list.last - 1) / bitmap_length]
  fields_list +=  bitmap_fields
  fields += bitmap_fields.collect {|id| Field.new(id)}
  fields.sort!{|a,b| a.get_id.to_i <=> b.get_id.to_i}
  # Encode first bitmap
  out = encode_bitmap(fields_list,0)
  bitmap_index = 1
  fields.each do |sf|
    codec = @subCodecs[sf.get_id]
    if @num_extended_bitmaps.include?(sf.get_id)
      out += encode_bitmap(fields_list,bitmap_index)
      bitmap_index += 1
    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
      out += codec.encode(sf)
    end
    encoded_fields << sf.get_id.to_i
  end
  return out
end

#encode_bitmap(fields_list, bitmap_index) ⇒ Object



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

def encode_bitmap(fields_list,bitmap_index)
  offset = bitmap_index * bitmap_length
  bitmap = ""
  ((offset + 1)..(offset + bitmap_length)).each do |i|
    if fields_list.include?(i)
      bitmap += "1"
    else
      bitmap += "0"
    end
  end
  return [bitmap].pack("B*")
end