codec 0.0.2 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.travis.yml +4 -0
- data/codec.gemspec +1 -0
- data/lib/codec/base.rb +16 -18
- data/lib/codec/bitmap.rb +102 -0
- data/lib/codec/composed.rb +83 -0
- data/lib/codec/exceptions.rb +7 -0
- data/lib/codec/factory.rb +4 -0
- data/lib/codec/field.rb +21 -3
- data/lib/codec/fix.rb +59 -19
- data/lib/codec/packed.rb +68 -0
- data/lib/codec/prefix.rb +136 -0
- data/lib/codec/tlv.rb +176 -0
- data/lib/codec/version.rb +1 -1
- data/lib/codec.rb +5 -4
- data/test/lib/codec/bitmap_test.rb +71 -0
- data/test/lib/codec/composed_test.rb +79 -0
- data/test/lib/codec/field_test.rb +60 -0
- data/test/lib/codec/fix_test.rb +86 -1
- data/test/lib/codec/pckd_test.rb +71 -0
- data/test/lib/codec/prefix_test.rb +104 -0
- data/test/lib/codec/tlv_test.rb +82 -0
- metadata +37 -3
- data/lib/codec/protocols/core.rb +0 -0
data/.travis.yml
ADDED
data/codec.gemspec
CHANGED
data/lib/codec/base.rb
CHANGED
@@ -6,47 +6,45 @@ module Codec
|
|
6
6
|
@id = id
|
7
7
|
end
|
8
8
|
|
9
|
-
def build_field
|
9
|
+
def build_field(buf,length)
|
10
10
|
f = Field.new(@id)
|
11
|
-
f.set_value(
|
11
|
+
f.set_value(buf[0,length])
|
12
12
|
return f
|
13
13
|
end
|
14
14
|
|
15
15
|
def decode_with_length(buf,length)
|
16
|
-
|
17
|
-
return build_field
|
16
|
+
l = eval_length(buf,length)
|
17
|
+
return build_field(buf,l),buf[l,buf.length]
|
18
18
|
end
|
19
19
|
|
20
20
|
def decode(buf)
|
21
|
-
|
22
|
-
return build_field
|
21
|
+
l = eval_length(buf,@length)
|
22
|
+
return build_field(buf,l),buf[l,buf.length]
|
23
23
|
end
|
24
24
|
|
25
|
-
def
|
25
|
+
def eval_length(buf,length)
|
26
26
|
length = 0 if length.nil?
|
27
27
|
if(length != 0)
|
28
28
|
if buf.length < length
|
29
29
|
raise BufferUnderflow, "Not enough data for parsing #{@id} (#{length}/#{buf.length})"
|
30
30
|
end
|
31
|
-
|
32
|
-
@remain = buf[length,buf.length]
|
31
|
+
return length
|
33
32
|
else
|
34
|
-
|
35
|
-
@remain = ""
|
33
|
+
return buf.length
|
36
34
|
end
|
37
35
|
end
|
38
36
|
|
39
|
-
def
|
40
|
-
if
|
41
|
-
raise InitializeException, "Invalid codec reference in
|
37
|
+
def add_sub_codec(id_field,codec)
|
38
|
+
if codec.nil?
|
39
|
+
raise InitializeException, "Invalid codec reference in subcodec #{id_field} for codec #{@id}"
|
42
40
|
end
|
43
|
-
if @
|
44
|
-
@
|
41
|
+
if @subCodecs.kind_of? Hash
|
42
|
+
@subCodecs[id_field] = codec
|
45
43
|
end
|
46
44
|
end
|
47
45
|
|
48
|
-
def
|
49
|
-
return @
|
46
|
+
def get_sub_codecs
|
47
|
+
return @subCodecs
|
50
48
|
end
|
51
49
|
end
|
52
50
|
end
|
data/lib/codec/bitmap.rb
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
module Codec
|
2
|
+
class Bitmap < Base
|
3
|
+
NB_BITS_BY_BYTE = 8
|
4
|
+
def initialize(id,length)
|
5
|
+
super(id,length)
|
6
|
+
@num_extended_bitmaps=[]
|
7
|
+
@subCodecs = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
def bitmap_length
|
11
|
+
@length * NB_BITS_BY_BYTE
|
12
|
+
end
|
13
|
+
def add_extended_bitmap(num_extention)
|
14
|
+
@num_extended_bitmaps << num_extention.to_i
|
15
|
+
end
|
16
|
+
|
17
|
+
def decodeBitmap(buffer,first_field_num)
|
18
|
+
fieldsList = []
|
19
|
+
|
20
|
+
bitmapBuffer = buffer[0,@length].unpack("B*").first
|
21
|
+
buf = buffer[@length,buffer.length]
|
22
|
+
field_num = first_field_num
|
23
|
+
while(bitmapBuffer.length > 0)
|
24
|
+
fieldsList << field_num if bitmapBuffer.start_with?('1')
|
25
|
+
bitmapBuffer.slice!(0)
|
26
|
+
field_num += 1
|
27
|
+
end
|
28
|
+
return fieldsList, buf
|
29
|
+
end
|
30
|
+
|
31
|
+
def encode_bitmap(fields_list,bitmap_index)
|
32
|
+
offset = bitmap_index * bitmap_length
|
33
|
+
bitmap = ""
|
34
|
+
((offset + 1)..(offset + bitmap_length)).each do |i|
|
35
|
+
if fields_list.include?(i)
|
36
|
+
bitmap += "1"
|
37
|
+
else
|
38
|
+
bitmap += "0"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
return [bitmap].pack("B*")
|
42
|
+
end
|
43
|
+
|
44
|
+
def encode(field)
|
45
|
+
fields = field.get_value
|
46
|
+
encoded_fields = []
|
47
|
+
fields_list = fields.collect{|id,sf| id.to_i}
|
48
|
+
# Add field for bitmaps
|
49
|
+
bitmap_fields = @num_extended_bitmaps[0,(fields_list.last - 1) / bitmap_length]
|
50
|
+
fields_list += bitmap_fields
|
51
|
+
fields += bitmap_fields.collect {|id| [id,nil]}
|
52
|
+
fields.sort!{|a,b| a.first.to_i <=> b.first.to_i}
|
53
|
+
# Encode first bitmap
|
54
|
+
out = encode_bitmap(fields_list,0)
|
55
|
+
bitmap_index = 1
|
56
|
+
fields.each do |id,sf|
|
57
|
+
codec = @subCodecs[id]
|
58
|
+
if @num_extended_bitmaps.include?(id)
|
59
|
+
out += encode_bitmap(fields_list,bitmap_index)
|
60
|
+
bitmap_index += 1
|
61
|
+
elsif codec.nil?
|
62
|
+
raise EncodingException, "unknown codec for subfield #{id}"
|
63
|
+
elsif encoded_fields.include?(id.to_i)
|
64
|
+
raise EncodingException, "Multiple subfield #{id} is invalid for Codec::Bitmap"
|
65
|
+
else
|
66
|
+
out += codec.encode(sf)
|
67
|
+
end
|
68
|
+
encoded_fields << id.to_i
|
69
|
+
end
|
70
|
+
return out
|
71
|
+
end
|
72
|
+
|
73
|
+
def decode(buffer)
|
74
|
+
msg = Field.new(@id)
|
75
|
+
field_num = 1
|
76
|
+
# 1. read bitmap
|
77
|
+
fields_list,buf = decodeBitmap(buffer,field_num)
|
78
|
+
field_num += bitmap_length
|
79
|
+
# 2. decode each field present
|
80
|
+
while fields_list.length > 0
|
81
|
+
# get next field number in bitmap
|
82
|
+
field_id = fields_list.slice!(0)
|
83
|
+
field_tag = field_id.to_s
|
84
|
+
if @num_extended_bitmaps.include?(field_id)
|
85
|
+
nextFields,buf = decodeBitmap(buf,field_num)
|
86
|
+
fields_list = fields_list + nextFields
|
87
|
+
elsif @subCodecs[field_tag].respond_to?(:decode)
|
88
|
+
Logger.debug "Parsing bitmap field #{field_tag}"
|
89
|
+
f,buf = @subCodecs[field_tag].decode(buf)
|
90
|
+
f.set_id(field_tag)
|
91
|
+
msg.add_sub_field(f)
|
92
|
+
else
|
93
|
+
f = Field.new("ERR")
|
94
|
+
f.set_value(buf.unpack("H*").first)
|
95
|
+
msg.add_sub_field(f)
|
96
|
+
raise ParsingException,msg.to_yaml + "\nError unknown field #{field_tag} : "
|
97
|
+
end
|
98
|
+
end
|
99
|
+
return msg,buf
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module Codec
|
2
|
+
class BaseComposed < Base
|
3
|
+
def initialize(id)
|
4
|
+
@id = id
|
5
|
+
@subCodecs = []
|
6
|
+
end
|
7
|
+
|
8
|
+
def decode(buf)
|
9
|
+
return build_each_field(buf,buf.length)
|
10
|
+
end
|
11
|
+
|
12
|
+
def encode(field)
|
13
|
+
subfields = field.get_value
|
14
|
+
composed_encoder = subfields.zip(@subCodecs).collect {|sf,sc|
|
15
|
+
if sf.first != sc.first
|
16
|
+
raise EncodingException, "subfield #{sf.first} not correspond to subcodec #{sc.first}"
|
17
|
+
end
|
18
|
+
[sc.last,sf.last]
|
19
|
+
}
|
20
|
+
out = ""
|
21
|
+
composed_encoder.each do |subcodec,subfield|
|
22
|
+
out += subcodec.encode(subfield)
|
23
|
+
end
|
24
|
+
return out
|
25
|
+
end
|
26
|
+
|
27
|
+
def build_each_field(buf,length)
|
28
|
+
msg = Field.new(@id)
|
29
|
+
working_buf = buf[0,length]
|
30
|
+
@subCodecs.each{|id,codec|
|
31
|
+
Logger.debug "Parsing struct field #{@id} : #{id}"
|
32
|
+
if working_buf.length == 0
|
33
|
+
Logger.debug "Not enough data to decode #{@id} : #{id}"
|
34
|
+
else
|
35
|
+
f,working_buf = codec.decode(working_buf)
|
36
|
+
f.set_id(id)
|
37
|
+
msg.add_sub_field(f)
|
38
|
+
end
|
39
|
+
}
|
40
|
+
return msg,working_buf
|
41
|
+
end
|
42
|
+
|
43
|
+
def build_field(buf,length)
|
44
|
+
msg,working_buf = build_each_field(buf,length)
|
45
|
+
|
46
|
+
if working_buf.length > 0
|
47
|
+
if @length_unknown
|
48
|
+
@remain = working_buf
|
49
|
+
else
|
50
|
+
f = Field.new("PADDING")
|
51
|
+
f.set_value(working_buf.unpack("H*").first)
|
52
|
+
msg.add_sub_field(f)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
return msg
|
56
|
+
end
|
57
|
+
|
58
|
+
def add_sub_codec(id_field,codec)
|
59
|
+
if codec.nil?
|
60
|
+
raise InitializeException, "Invalid codec reference in subcodec #{id_field} for codec #{@id}"
|
61
|
+
end
|
62
|
+
@subCodecs << [id_field, codec]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class CompleteComposed < BaseComposed
|
67
|
+
def build_each_field(buf,length)
|
68
|
+
f,r = super(buf,length)
|
69
|
+
# Check if all struct's fields have been parsed
|
70
|
+
if f.get_value.size < @subCodecs.size
|
71
|
+
raise BufferUnderflow, "Not enough data for parsing Struct #{@id}"
|
72
|
+
end
|
73
|
+
return f,r
|
74
|
+
end
|
75
|
+
|
76
|
+
def encode(field)
|
77
|
+
if @subCodecs.size != field.get_value.size
|
78
|
+
raise EncodingException, "Not enough subfields to encode #{@id}"
|
79
|
+
end
|
80
|
+
super(field)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
data/lib/codec/exceptions.rb
CHANGED
data/lib/codec/field.rb
CHANGED
@@ -8,11 +8,28 @@ module Codec
|
|
8
8
|
end
|
9
9
|
|
10
10
|
class Field
|
11
|
-
def initialize(id="*")
|
11
|
+
def initialize(id="*",value="")
|
12
12
|
@id = (id.nil? ? "*" : id)
|
13
|
-
@value =
|
13
|
+
@value = value
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
|
+
def self.from_array(id,fields_array)
|
17
|
+
f = Field.new(id)
|
18
|
+
fields_array.each do |id,value|
|
19
|
+
if value.kind_of?(Array)
|
20
|
+
sf = Field.from_array(id,value)
|
21
|
+
else
|
22
|
+
sf = Field.new(id,value)
|
23
|
+
end
|
24
|
+
f.add_sub_field(sf)
|
25
|
+
end
|
26
|
+
return f
|
27
|
+
end
|
28
|
+
|
29
|
+
def ==(other)
|
30
|
+
(@id == other.get_id && @value == other.get_value)
|
31
|
+
end
|
32
|
+
|
16
33
|
def get_id ; @id; end
|
17
34
|
|
18
35
|
def set_id id ; @id = id ; end
|
@@ -22,6 +39,7 @@ module Codec
|
|
22
39
|
def set_value(value)
|
23
40
|
raise "Error can not set value that is instance of Array" if value.kind_of? Array
|
24
41
|
@value = value
|
42
|
+
return self
|
25
43
|
end
|
26
44
|
|
27
45
|
def add_sub_field(sf)
|
data/lib/codec/fix.rb
CHANGED
@@ -1,48 +1,88 @@
|
|
1
1
|
module Codec
|
2
2
|
class Numbin < Base
|
3
|
-
def build_field
|
3
|
+
def build_field(buf,length)
|
4
4
|
f = Field.new(@id)
|
5
5
|
res = 0
|
6
|
-
|
6
|
+
buf[0,length].unpack("C*").each{ |ubyte|
|
7
7
|
res *= 256
|
8
8
|
res += ubyte
|
9
9
|
}
|
10
10
|
f.set_value(res)
|
11
11
|
return f
|
12
12
|
end
|
13
|
+
|
14
|
+
def encode(field)
|
15
|
+
val = field.get_value.to_i
|
16
|
+
out = Numbin.numbin(val,@length)
|
17
|
+
return out
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.numbin(number,maxlength)
|
21
|
+
out = ""
|
22
|
+
while number > 0
|
23
|
+
out << (number % 256).chr
|
24
|
+
number /= 256
|
25
|
+
end
|
26
|
+
|
27
|
+
# handle length if defined
|
28
|
+
if maxlength > 0
|
29
|
+
while out.length < maxlength
|
30
|
+
out << 0.chr
|
31
|
+
end
|
32
|
+
out = out[0,maxlength]
|
33
|
+
end
|
34
|
+
return out.reverse
|
35
|
+
end
|
13
36
|
end
|
14
37
|
|
15
|
-
|
16
|
-
|
17
|
-
class Numstr < Base
|
18
|
-
def build_field
|
38
|
+
class Numasc < Base
|
39
|
+
def build_field(buf,length)
|
19
40
|
f = Field.new(@id)
|
20
|
-
|
21
|
-
if IsEbcdic(@data)
|
22
|
-
@data = Ebcdic2Ascii(@data)
|
23
|
-
end
|
24
|
-
|
25
|
-
f.set_value(@data.to_i)
|
41
|
+
f.set_value(buf[0,length].to_i)
|
26
42
|
return f
|
27
43
|
end
|
44
|
+
|
45
|
+
def encode(field)
|
46
|
+
out = field.get_value.to_s
|
47
|
+
if @length > 0
|
48
|
+
out = out.rjust(@length,"0")
|
49
|
+
raise TooLongDataException if out.length > @length
|
50
|
+
end
|
51
|
+
return out
|
52
|
+
end
|
28
53
|
end
|
29
54
|
|
30
55
|
class String < Base
|
31
|
-
def build_field
|
56
|
+
def build_field(buf,length)
|
32
57
|
f = Field.new(@id)
|
33
|
-
|
34
|
-
@data = Ebcdic2Ascii(@data)
|
35
|
-
end
|
36
|
-
f.set_value(@data)
|
58
|
+
f.set_value(buf[0,length])
|
37
59
|
return f
|
38
60
|
end
|
61
|
+
|
62
|
+
def encode(f)
|
63
|
+
out = f.get_value
|
64
|
+
if @length > 0
|
65
|
+
raise TooLongDataException if out.length > @length
|
66
|
+
out = out.ljust(@length," ")
|
67
|
+
end
|
68
|
+
return out
|
69
|
+
end
|
39
70
|
end
|
40
71
|
|
41
72
|
class Binary < Base
|
42
|
-
def build_field
|
73
|
+
def build_field(buf,length)
|
43
74
|
f = Field.new(@id)
|
44
|
-
f.set_value(
|
75
|
+
f.set_value(buf[0,length].unpack("H*").first.upcase)
|
45
76
|
return f
|
46
77
|
end
|
78
|
+
|
79
|
+
def encode(f)
|
80
|
+
out = [f.get_value].pack("H*")
|
81
|
+
if @length > 0
|
82
|
+
raise TooLongDataException if out.length > @length
|
83
|
+
out = out.ljust(@length,0.chr)
|
84
|
+
end
|
85
|
+
return out
|
86
|
+
end
|
47
87
|
end
|
48
88
|
end
|
data/lib/codec/packed.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
module Codec
|
2
|
+
class Packed < Base
|
3
|
+
def get_pck_length(length)
|
4
|
+
((length + 1) / 2)
|
5
|
+
end
|
6
|
+
|
7
|
+
def eval_pck_length(field)
|
8
|
+
if @length > 0
|
9
|
+
return @length
|
10
|
+
else
|
11
|
+
return field.get_value.to_s.length
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def decode_with_length(buf,length)
|
16
|
+
l = eval_length(buf,get_pck_length(length))
|
17
|
+
return build_field(buf,l),buf[l,buf.length]
|
18
|
+
end
|
19
|
+
|
20
|
+
def decode(buf)
|
21
|
+
return decode_with_length(buf,@length)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class Numpck < Packed
|
26
|
+
def build_field(buf,length)
|
27
|
+
f = Field.new(@id)
|
28
|
+
f.set_value(buf[0,length].unpack("H*").first.to_i)
|
29
|
+
return f
|
30
|
+
end
|
31
|
+
|
32
|
+
def encode(field)
|
33
|
+
out = field.get_value.to_s
|
34
|
+
if @length > 0
|
35
|
+
out = out.rjust(@length,"0")
|
36
|
+
raise TooLongDataException if out.length > @length
|
37
|
+
end
|
38
|
+
l = out.length
|
39
|
+
out.prepend("0") if out.length.odd?
|
40
|
+
out = [out].pack("H*")
|
41
|
+
return out
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class Strpck < Packed
|
46
|
+
def build_field(buf,length)
|
47
|
+
f = Field.new(@id)
|
48
|
+
val = buf[0,length].unpack("H*").first
|
49
|
+
# TODO : handle odd length for packed field with prefixed length
|
50
|
+
val.chop! if @length.odd?
|
51
|
+
f.set_value(val)
|
52
|
+
return f
|
53
|
+
end
|
54
|
+
|
55
|
+
def encode(field)
|
56
|
+
out = field.get_value.to_s
|
57
|
+
if @length > 0
|
58
|
+
out = out.ljust(@length,"F")
|
59
|
+
raise TooLongDataException if out.length > @length
|
60
|
+
end
|
61
|
+
l = out.length
|
62
|
+
out += "F" if out.length.odd?
|
63
|
+
out = [out].pack("H*")
|
64
|
+
return out
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
data/lib/codec/prefix.rb
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
module Codec
|
2
|
+
class Prefixedlength < Base
|
3
|
+
def initialize(id,length,content)
|
4
|
+
# TODO : Check that value_codec has a null length attribute
|
5
|
+
@length_codec = length
|
6
|
+
@value_codec = content
|
7
|
+
@id = id
|
8
|
+
end
|
9
|
+
|
10
|
+
def get_length(length_field)
|
11
|
+
length_field.get_value.to_i
|
12
|
+
end
|
13
|
+
|
14
|
+
def decode(buffer)
|
15
|
+
l, buf = @length_codec.decode(buffer)
|
16
|
+
len = get_length(l)
|
17
|
+
if len == 0
|
18
|
+
f = Field.new
|
19
|
+
f.set_id(@id)
|
20
|
+
f.set_value(nil)
|
21
|
+
return f,buf
|
22
|
+
else
|
23
|
+
begin
|
24
|
+
f,remain = @value_codec.decode_with_length(buf,len)
|
25
|
+
rescue => e
|
26
|
+
Logger.error "Error in #{@id} decoder \n #{e.message}\n#{e.backtrace.join(10.chr)}"
|
27
|
+
raise ParsingException, e.message
|
28
|
+
end
|
29
|
+
|
30
|
+
f.set_id(@id)
|
31
|
+
return f,remain
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def build_field(buf,length)
|
36
|
+
begin
|
37
|
+
f,r = decode(buf[0,length])
|
38
|
+
rescue ErrorBufferUnderflow => e
|
39
|
+
raise ParsingException, e.message
|
40
|
+
end
|
41
|
+
Logger.error "Error remain data in Prefixedlength" if r != ""
|
42
|
+
return f
|
43
|
+
end
|
44
|
+
|
45
|
+
def encode(field)
|
46
|
+
val = @value_codec.encode(field)
|
47
|
+
length = @length_codec.encode(Field.new.set_value(val.length))
|
48
|
+
out = length + val
|
49
|
+
return out
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class Headerlength < Prefixedlength
|
54
|
+
def initialize(id,header,content,length_path)
|
55
|
+
@path = length_path # length attribute contain the path for length field in header
|
56
|
+
@separator = @path.slice!(0).chr # first character contain the separator
|
57
|
+
super(id,header,content)
|
58
|
+
end
|
59
|
+
|
60
|
+
def get_length(header_field)
|
61
|
+
return header_field.get_value.to_i if @path.length == 0 # Handle simple numeric header field
|
62
|
+
length_field = header_field.get_deep_field(@path,@separator)
|
63
|
+
if length_field.nil?
|
64
|
+
return 0
|
65
|
+
else
|
66
|
+
length_field.get_value.to_i
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def decode(buffer)
|
71
|
+
f = Field.new
|
72
|
+
f.set_id(@id)
|
73
|
+
head, buf = @length_codec.decode(buffer)
|
74
|
+
head.set_id(@length_codec.id)
|
75
|
+
f.add_sub_field(head)
|
76
|
+
len = get_length(head)
|
77
|
+
if len == 0
|
78
|
+
return f,buf
|
79
|
+
else
|
80
|
+
len -= (buffer.length - buf.length) if @header_length_include
|
81
|
+
val,remain = @value_codec.decode_with_length(buf,len)
|
82
|
+
val.set_id(@value_codec.id)
|
83
|
+
f.add_sub_field(val)
|
84
|
+
return f,remain
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def encode(field)
|
89
|
+
# encode content
|
90
|
+
content = @value_codec.encode(field.get_sub_field(@value_codec.id))
|
91
|
+
head_field = field.get_sub_field(@length_codec.id)
|
92
|
+
length_field = head_field.get_deep_field(@path,@separator)
|
93
|
+
if length_field.nil?
|
94
|
+
raise EncodingException,"Length field #{@path} is not present in header for encoding #{@id} =>
|
95
|
+
#{field.to_yaml}"
|
96
|
+
end
|
97
|
+
# update length field in header
|
98
|
+
length_field.set_value(content.length)
|
99
|
+
# encode header
|
100
|
+
header = @length_codec.encode(head_field)
|
101
|
+
return header + content
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
class Headerfulllength < Headerlength
|
106
|
+
# TODO : to implement
|
107
|
+
end
|
108
|
+
|
109
|
+
class Tagged < Base
|
110
|
+
def initialize(id,tag_codec)
|
111
|
+
@subCodecs = {}
|
112
|
+
@tag_codec = tag_codec
|
113
|
+
@id = id
|
114
|
+
end
|
115
|
+
|
116
|
+
def decode(buffer)
|
117
|
+
tag,buf = @tag_codec.decode(buffer)
|
118
|
+
if @subCodecs[tag.get_value.to_s].nil?
|
119
|
+
raise ParsingException, "Unknown tag #{tag.get_value.to_s} for #{@id} decoder"
|
120
|
+
end
|
121
|
+
f,buf = @subCodecs[tag.get_value.to_s].decode(buf)
|
122
|
+
f.set_id(tag.get_value.to_s)
|
123
|
+
return f,buf
|
124
|
+
end
|
125
|
+
|
126
|
+
def encode(field)
|
127
|
+
head = Field.new(@tag_codec.id, field.get_id)
|
128
|
+
out = @tag_codec.encode(head)
|
129
|
+
if @subCodecs[field.get_id].nil?
|
130
|
+
raise EncodingException, "Unknown tag #{field.get_id} for #{@id} encoder"
|
131
|
+
end
|
132
|
+
out += @subCodecs[field.get_id].encode(field)
|
133
|
+
return out
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|