codec 0.0.12 → 1.0.0
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/.gitignore +1 -0
- data/Rakefile +6 -0
- data/codec.gemspec +1 -1
- data/lib/codec.rb +8 -0
- data/lib/codec/base.rb +8 -47
- data/lib/codec/bitmap.rb +42 -36
- data/lib/codec/composed.rb +39 -66
- data/lib/codec/field.rb +1 -1
- data/lib/codec/fix.rb +83 -65
- data/lib/codec/logger.rb +2 -2
- data/lib/codec/packed.rb +40 -91
- data/lib/codec/prefix.rb +71 -71
- data/lib/codec/tlv.rb +116 -111
- data/lib/codec/version.rb +1 -1
- data/test/lib/codec/bitmap_test.rb +29 -20
- data/test/lib/codec/composed_test.rb +37 -23
- data/test/lib/codec/eightbits_test.rb +18 -14
- data/test/lib/codec/fix_test.rb +47 -35
- data/test/lib/codec/pckd_test.rb +33 -37
- data/test/lib/codec/prefix_test.rb +45 -67
- data/test/lib/codec/tlv_test.rb +41 -36
- data/test/test_helper.rb +3 -0
- metadata +14 -14
data/.gitignore
CHANGED
data/Rakefile
CHANGED
@@ -3,6 +3,12 @@ require "bundler/gem_tasks"
|
|
3
3
|
|
4
4
|
require 'rake/testtask'
|
5
5
|
|
6
|
+
desc "Open an irb session preloaded with this library"
|
7
|
+
task :console do
|
8
|
+
sh "irb -rubygems -I lib -r codec.rb"
|
9
|
+
end
|
10
|
+
|
11
|
+
|
6
12
|
Rake::TestTask.new do |t|
|
7
13
|
t.libs << 'lib/codec'
|
8
14
|
t.test_files = FileList['test/lib/codec/*_test.rb']
|
data/codec.gemspec
CHANGED
@@ -17,7 +17,7 @@ Gem::Specification.new do |spec|
|
|
17
17
|
spec.name = "codec"
|
18
18
|
spec.require_paths = ["lib"]
|
19
19
|
spec.version = Codec::VERSION
|
20
|
+
spec.add_dependency "log4r"
|
20
21
|
spec.add_development_dependency "bundler", "~> 1.3"
|
21
22
|
spec.add_development_dependency "rake"
|
22
|
-
spec.add_development_dependency "log4r"
|
23
23
|
end
|
data/lib/codec.rb
CHANGED
@@ -14,4 +14,12 @@ require 'codec/tlv'
|
|
14
14
|
|
15
15
|
module Codec
|
16
16
|
# TODO : here implements Module constants and methods
|
17
|
+
|
18
|
+
# method use to log deprecation warning
|
19
|
+
def self.deprecated(msg)
|
20
|
+
stack = Kernel.caller
|
21
|
+
stack.shift
|
22
|
+
Logger.warn "DEPRECATED: #{msg} | Call stack :
|
23
|
+
#{stack.select{|l| l =~ /codec\/lib/}.each{|l| l}.join("\n")}"
|
24
|
+
end
|
17
25
|
end
|
data/lib/codec/base.rb
CHANGED
@@ -1,59 +1,20 @@
|
|
1
1
|
module Codec
|
2
2
|
class Base
|
3
|
-
attr_reader :id
|
4
|
-
def initialize(id,length)
|
5
|
-
@length = length.to_i
|
6
|
-
@id = id
|
7
|
-
end
|
8
|
-
|
9
|
-
def build_field(buf,length)
|
10
|
-
f = Field.new(@id)
|
11
|
-
f.set_value(buf[0,length])
|
12
|
-
return f
|
13
|
-
end
|
14
3
|
|
15
|
-
def
|
16
|
-
|
17
|
-
return build_field(buf,l),buf[l,buf.length]
|
18
|
-
end
|
19
|
-
|
20
|
-
def decode(buf)
|
21
|
-
l = eval_length(buf,@length)
|
22
|
-
return build_field(buf,l),buf[l,buf.length]
|
4
|
+
def decode(buf,field)
|
5
|
+
raise "Abstract Codec"
|
23
6
|
end
|
24
7
|
|
25
|
-
def encode(field)
|
26
|
-
|
27
|
-
end
|
28
|
-
|
29
|
-
def encode_with_length(field)
|
30
|
-
buf = encode(field)
|
31
|
-
return buf.length, buf
|
32
|
-
end
|
33
|
-
|
34
|
-
def get_length(field)
|
35
|
-
field.get_value.length
|
8
|
+
def encode(buf,field)
|
9
|
+
raise "Abstract Codec"
|
36
10
|
end
|
37
11
|
|
38
|
-
def
|
39
|
-
length = 0 if length.nil?
|
40
|
-
if(length != 0)
|
41
|
-
if buf.length < length
|
42
|
-
raise BufferUnderflow, "Not enough data for parsing #{@id} (#{length}/#{buf.length})"
|
43
|
-
end
|
44
|
-
return length
|
45
|
-
else
|
46
|
-
return buf.length
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def add_sub_codec(id_field,codec)
|
12
|
+
def add_sub_codec(field_id,codec)
|
51
13
|
if codec.nil?
|
52
|
-
raise InitializeException, "Invalid codec reference in subcodec #{
|
14
|
+
raise InitializeException, "Invalid codec reference in subcodec #{field_id} for codec #{@id}"
|
53
15
|
end
|
54
|
-
|
55
|
-
|
56
|
-
end
|
16
|
+
@subCodecs ||= {}
|
17
|
+
@subCodecs[field_id] = codec
|
57
18
|
end
|
58
19
|
|
59
20
|
def get_sub_codecs
|
data/lib/codec/bitmap.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
module Codec
|
2
2
|
class Bitmap < Base
|
3
3
|
NB_BITS_BY_BYTE = 8
|
4
|
-
def initialize(
|
5
|
-
|
4
|
+
def initialize(length)
|
5
|
+
@length=length
|
6
6
|
@num_extended_bitmaps=[]
|
7
7
|
@subCodecs = {}
|
8
8
|
end
|
@@ -10,71 +10,78 @@ module Codec
|
|
10
10
|
def bitmap_length
|
11
11
|
@length * NB_BITS_BY_BYTE
|
12
12
|
end
|
13
|
+
|
13
14
|
def add_extended_bitmap(num_extention)
|
14
15
|
@num_extended_bitmaps << num_extention.to_i
|
15
16
|
end
|
16
17
|
|
17
|
-
def
|
18
|
-
|
19
|
-
|
20
|
-
bitmapBuffer = buffer[0,@length].unpack("B*").first
|
21
|
-
buf = buffer[@length,buffer.length]
|
18
|
+
def decode_bitmap(buffer,first_field_num)
|
19
|
+
fields_ids = []
|
20
|
+
bitmap = buffer.slice!(0...@length).unpack("B*").first
|
22
21
|
field_num = first_field_num
|
23
|
-
|
24
|
-
|
25
|
-
bitmapBuffer.slice!(0)
|
22
|
+
until(bitmap.empty?)
|
23
|
+
fields_ids << field_num if bitmap.slice!(0) == "1"
|
26
24
|
field_num += 1
|
27
25
|
end
|
28
|
-
return
|
26
|
+
return fields_ids
|
29
27
|
end
|
30
28
|
|
31
|
-
def encode_bitmap(fields_list,bitmap_index)
|
32
|
-
|
29
|
+
def encode_bitmap(buf,fields_list,bitmap_index)
|
30
|
+
offset_id = bitmap_index * bitmap_length + 1
|
33
31
|
bitmap = ""
|
34
|
-
((
|
32
|
+
(offset_id...(offset_id + bitmap_length)).each do |i|
|
35
33
|
if fields_list.include?(i)
|
36
|
-
bitmap
|
34
|
+
bitmap << "1"
|
37
35
|
else
|
38
|
-
bitmap
|
36
|
+
bitmap << "0"
|
39
37
|
end
|
40
38
|
end
|
41
|
-
|
39
|
+
Logger.debug { "Encoding bitmap #{bitmap_index}
|
40
|
+
form #{offset_id} to #{offset_id + bitmap_length - 1}
|
41
|
+
with #{fields_list.collect{|id| id.to_s}.join(',')}
|
42
|
+
result #{bitmap}" }
|
43
|
+
buf << [bitmap].pack("B*")
|
42
44
|
end
|
43
45
|
|
44
|
-
def encode(field)
|
46
|
+
def encode(buf, field)
|
47
|
+
Logger.debug { "Start bitmap encoding\n" }
|
48
|
+
initial_length = buf.length
|
45
49
|
fields = field.get_value
|
46
50
|
encoded_fields = []
|
47
51
|
fields_list = fields.collect{|sf| sf.get_id.to_i}
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
+
fields_list.sort!
|
53
|
+
nb_additionnal_bitmaps = (fields_list.last - 1) / bitmap_length
|
54
|
+
@num_extended_bitmaps[0...nb_additionnal_bitmaps].each{ |bitmap_field_id|
|
55
|
+
Logger.debug{"adding bitmap = #{bitmap_field_id}\n"}
|
56
|
+
fields_list << bitmap_field_id
|
57
|
+
fields << Field.new(bitmap_field_id)
|
58
|
+
}
|
52
59
|
fields.sort!{|a,b| a.get_id.to_i <=> b.get_id.to_i}
|
53
60
|
# Encode first bitmap
|
54
|
-
|
55
|
-
|
61
|
+
bitmap_itt = 0
|
62
|
+
encode_bitmap(buf,fields_list,bitmap_itt)
|
56
63
|
fields.each do |sf|
|
57
64
|
codec = @subCodecs[sf.get_id]
|
58
65
|
if @num_extended_bitmaps.include?(sf.get_id)
|
59
|
-
|
60
|
-
|
66
|
+
bitmap_itt += 1
|
67
|
+
encode_bitmap(buf, fields_list, bitmap_itt)
|
61
68
|
elsif codec.nil?
|
62
69
|
raise EncodingException, "unknown codec for subfield #{sf.get_id}"
|
63
70
|
elsif encoded_fields.include?(sf.get_id.to_i)
|
64
71
|
raise EncodingException, "Multiple subfield #{sf.get_id} is invalid for Codec::Bitmap"
|
65
72
|
else
|
66
|
-
|
73
|
+
codec.encode(buf,sf)
|
67
74
|
end
|
68
75
|
encoded_fields << sf.get_id.to_i
|
69
76
|
end
|
70
|
-
return
|
77
|
+
return buf.length - initial_length
|
71
78
|
end
|
72
|
-
|
73
|
-
def decode(
|
74
|
-
|
79
|
+
|
80
|
+
def decode(buf,msg, length=nil)
|
81
|
+
buf = buf.slice!(0...length) if length && length > 0
|
75
82
|
field_num = 1
|
76
83
|
# 1. read bitmap
|
77
|
-
fields_list
|
84
|
+
fields_list = decode_bitmap(buf,field_num)
|
78
85
|
field_num += bitmap_length
|
79
86
|
# 2. decode each field present
|
80
87
|
while fields_list.length > 0
|
@@ -82,12 +89,12 @@ module Codec
|
|
82
89
|
field_id = fields_list.slice!(0)
|
83
90
|
field_tag = field_id.to_s
|
84
91
|
if @num_extended_bitmaps.include?(field_id)
|
85
|
-
nextFields
|
92
|
+
nextFields = decode_bitmap(buf,field_num)
|
86
93
|
fields_list = fields_list + nextFields
|
87
94
|
elsif @subCodecs[field_tag].respond_to?(:decode)
|
88
95
|
Logger.debug "Parsing bitmap field #{field_tag}"
|
89
|
-
f
|
90
|
-
|
96
|
+
f = Field.new(field_tag)
|
97
|
+
@subCodecs[field_tag].decode(buf,f)
|
91
98
|
msg.add_sub_field(f)
|
92
99
|
else
|
93
100
|
f = Field.new("ERR")
|
@@ -96,7 +103,6 @@ module Codec
|
|
96
103
|
raise ParsingException.new "#{msg}\nError unknown field #{field_tag} : "
|
97
104
|
end
|
98
105
|
end
|
99
|
-
return msg,buf
|
100
106
|
end
|
101
107
|
end
|
102
108
|
end
|
data/lib/codec/composed.rb
CHANGED
@@ -1,84 +1,57 @@
|
|
1
1
|
module Codec
|
2
2
|
class BaseComposed < Base
|
3
|
-
def initialize(
|
4
|
-
@
|
5
|
-
@subCodecs =
|
3
|
+
def initialize(isComplete = false)
|
4
|
+
@is_complete = isComplete
|
5
|
+
@subCodecs = {}
|
6
6
|
end
|
7
7
|
|
8
|
-
def decode(buf)
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
def encode(field)
|
13
|
-
return "" if field.empty?
|
14
|
-
subfields = field.get_value
|
15
|
-
composed_encoder = subfields.zip(@subCodecs).collect {|sf,sc|
|
16
|
-
if sf.get_id != sc.first
|
17
|
-
raise EncodingException, "subfield #{sf.first} not correspond to subcodec #{sc.first}"
|
18
|
-
end
|
19
|
-
[sc.last,sf]
|
20
|
-
}
|
21
|
-
out = ""
|
22
|
-
composed_encoder.each do |subcodec,subfield|
|
23
|
-
out += subcodec.encode(subfield)
|
8
|
+
def decode(buf,msg, length = nil)
|
9
|
+
unless length.nil?
|
10
|
+
Logger.debug {"build composed for [#{buf.unpack("H*").first}] on #{length} bytes for #{msg.get_id} field"}
|
11
|
+
buf = buf.slice!(0...length)
|
24
12
|
end
|
25
|
-
|
26
|
-
end
|
27
|
-
|
28
|
-
def build_each_field(buf,length)
|
29
|
-
msg = Field.new(@id)
|
30
|
-
working_buf = buf[0,length]
|
13
|
+
|
31
14
|
@subCodecs.each{|id,codec|
|
32
|
-
Logger.debug "Parsing struct field #{
|
33
|
-
if
|
34
|
-
Logger.debug "Not enough data to decode #{
|
15
|
+
Logger.debug "Parsing struct field #{msg.get_id} - #{id} with [#{buf.unpack("H*").first}]"
|
16
|
+
if buf.empty?
|
17
|
+
Logger.debug "Not enough data to decode #{msg.get_id} : #{id}"
|
35
18
|
else
|
36
|
-
f
|
37
|
-
|
19
|
+
f = Field.new(id)
|
20
|
+
codec.decode(buf,f)
|
38
21
|
msg.add_sub_field(f)
|
39
22
|
end
|
40
23
|
}
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
msg,working_buf = build_each_field(buf,length)
|
46
|
-
|
47
|
-
if working_buf.length > 0
|
48
|
-
if @length_unknown
|
49
|
-
@remain = working_buf
|
50
|
-
else
|
51
|
-
f = Field.new("PADDING")
|
52
|
-
f.set_value(working_buf.unpack("H*").first)
|
53
|
-
msg.add_sub_field(f)
|
54
|
-
end
|
24
|
+
unless buf.empty? || length.nil?
|
25
|
+
f = Field.new("PADDING")
|
26
|
+
f.set_value(buf.unpack("H*").first)
|
27
|
+
msg.add_sub_field(f)
|
55
28
|
end
|
56
|
-
|
57
|
-
end
|
58
|
-
|
59
|
-
def add_sub_codec(id_field,codec)
|
60
|
-
if codec.nil?
|
61
|
-
raise InitializeException, "Invalid codec reference in subcodec #{id_field} for codec #{@id}"
|
62
|
-
end
|
63
|
-
@subCodecs << [id_field, codec]
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
class CompleteComposed < BaseComposed
|
68
|
-
def build_each_field(buf,length)
|
69
|
-
f,r = super(buf,length)
|
29
|
+
|
70
30
|
# Check if all struct's fields have been parsed
|
71
|
-
if
|
72
|
-
raise BufferUnderflow, "Not enough data for parsing Struct #{
|
73
|
-
end
|
74
|
-
return f,r
|
31
|
+
if @is_complete && msg.get_value.size < @subCodecs.size
|
32
|
+
raise BufferUnderflow, "Not enough data for parsing Struct #{msg.get_id}"
|
33
|
+
end
|
75
34
|
end
|
76
35
|
|
77
|
-
def encode(field)
|
78
|
-
|
79
|
-
|
36
|
+
def encode(buf, field)
|
37
|
+
|
38
|
+
if @is_complete && @subCodecs.size != field.get_value.size
|
39
|
+
raise EncodingException, "Not enough subfields to encode #{field.get_id}"
|
40
|
+
end
|
41
|
+
|
42
|
+
return if field.empty?
|
43
|
+
initial_length = buf.length
|
44
|
+
subfields = field.get_value
|
45
|
+
composed_encoder = subfields.zip(@subCodecs).collect {|sf,sc|
|
46
|
+
if sf.get_id != sc.first
|
47
|
+
raise EncodingException, "subfield #{sf.first} not correspond to subcodec #{sc.first}"
|
48
|
+
end
|
49
|
+
[sc.last,sf]
|
50
|
+
}
|
51
|
+
composed_encoder.each do |subcodec,subfield|
|
52
|
+
subcodec.encode(buf,subfield)
|
80
53
|
end
|
81
|
-
|
54
|
+
return buf.length - initial_length
|
82
55
|
end
|
83
56
|
end
|
84
57
|
end
|
data/lib/codec/field.rb
CHANGED
@@ -63,7 +63,7 @@ module Codec
|
|
63
63
|
|
64
64
|
def add_sub_field(sf)
|
65
65
|
@value = [] if @value == ""
|
66
|
-
raise "Add impossible on
|
66
|
+
raise "Add sub field impossible on #{@value.class} value class" unless @value.kind_of? Array
|
67
67
|
@value << [sf.id,sf.value]
|
68
68
|
end
|
69
69
|
|
data/lib/codec/fix.rb
CHANGED
@@ -1,21 +1,48 @@
|
|
1
1
|
module Codec
|
2
|
-
|
3
|
-
|
4
|
-
def
|
5
|
-
|
2
|
+
class Fix < Base
|
3
|
+
|
4
|
+
def initialize(length=nil)
|
5
|
+
@length = length || 0
|
6
|
+
end
|
7
|
+
|
8
|
+
def check_length(buf,length)
|
9
|
+
raise "Length is nil" if length.nil?
|
10
|
+
if(length != 0)
|
11
|
+
if buf.length < length
|
12
|
+
raise BufferUnderflow, "Not enough data for decoding (#{length}/#{buf.length})"
|
13
|
+
end
|
14
|
+
return length
|
15
|
+
else
|
16
|
+
return buf.length
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def decode(buf,field,length=nil)
|
21
|
+
length ||= @length
|
22
|
+
l = check_length(buf,length)
|
23
|
+
wbuf = buf.slice!(0...l)
|
24
|
+
build_field(wbuf,field,l)
|
25
|
+
end
|
26
|
+
|
27
|
+
def build_field(w,f,l)
|
28
|
+
raise "Abstract Codec : build field not defined for #{self.class.name}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
class Numbin < Fix
|
32
|
+
def build_field(buf,f,length)
|
6
33
|
res = 0
|
7
|
-
buf
|
34
|
+
buf.slice!(0...length).unpack("C*").each{ |ubyte|
|
8
35
|
res *= 256
|
9
36
|
res += ubyte
|
10
37
|
}
|
11
38
|
f.set_value(res)
|
12
|
-
return f
|
13
39
|
end
|
14
40
|
|
15
|
-
def encode(field)
|
41
|
+
def encode(buf, field)
|
16
42
|
val = field.get_value.to_i
|
17
43
|
out = Numbin.numbin(val,@length)
|
18
|
-
|
44
|
+
buf << out
|
45
|
+
return out.length
|
19
46
|
end
|
20
47
|
|
21
48
|
def self.numbin(number,maxlength)
|
@@ -37,20 +64,19 @@ module Codec
|
|
37
64
|
end
|
38
65
|
end
|
39
66
|
|
40
|
-
class Numstr <
|
41
|
-
def build_field(buf,length)
|
42
|
-
f
|
43
|
-
f.set_value(buf[0,length].to_i)
|
44
|
-
return f
|
67
|
+
class Numstr < Fix
|
68
|
+
def build_field(buf, f, length)
|
69
|
+
f.set_value(buf.slice!(0...length).to_i)
|
45
70
|
end
|
46
71
|
|
47
|
-
def encode(field)
|
72
|
+
def encode(buf,field)
|
48
73
|
out = field.get_value.to_s
|
49
74
|
if @length > 0
|
50
75
|
out = out.rjust(@length,"0")
|
51
76
|
raise TooLongDataException if out.length > @length
|
52
77
|
end
|
53
|
-
|
78
|
+
buf << out
|
79
|
+
return out.length
|
54
80
|
end
|
55
81
|
end
|
56
82
|
|
@@ -59,90 +85,85 @@ module Codec
|
|
59
85
|
# have the same encoding for digits number
|
60
86
|
end
|
61
87
|
|
62
|
-
class Numebc <
|
63
|
-
def build_field(buf,length)
|
64
|
-
f
|
65
|
-
f.set_value(EightBitsEncoding::EBCDIC_2_UTF8(buf[0,length]).to_i)
|
66
|
-
return f
|
88
|
+
class Numebc < Fix
|
89
|
+
def build_field(buf,f,length)
|
90
|
+
f.set_value(EightBitsEncoding::EBCDIC_2_UTF8(buf.slice!(0...length)).to_i)
|
67
91
|
end
|
68
92
|
|
69
|
-
def encode(field)
|
93
|
+
def encode(buf, field)
|
70
94
|
out = field.get_value.to_s
|
71
95
|
if @length > 0
|
72
96
|
out = out.rjust(@length,"0")
|
73
97
|
raise TooLongDataException if out.length > @length
|
74
98
|
end
|
75
|
-
|
99
|
+
buf << EightBitsEncoding::UTF8_2_EBCDIC(out)
|
100
|
+
return out.length
|
76
101
|
end
|
77
102
|
|
78
103
|
end
|
79
104
|
|
80
|
-
class Ebcdic <
|
81
|
-
def build_field(buf,length)
|
82
|
-
f
|
83
|
-
f.set_value(EightBitsEncoding::EBCDIC_2_UTF8(buf[0,length]))
|
84
|
-
return f
|
105
|
+
class Ebcdic < Fix
|
106
|
+
def build_field(buf, f, length)
|
107
|
+
f.set_value(EightBitsEncoding::EBCDIC_2_UTF8(buf.slice!(0...length)))
|
85
108
|
end
|
86
109
|
|
87
|
-
def encode(f)
|
110
|
+
def encode(buf, f)
|
88
111
|
out = f.get_value
|
89
112
|
if @length > 0
|
90
113
|
raise TooLongDataException if out.length > @length
|
91
114
|
out = out.ljust(@length," ")
|
92
115
|
end
|
93
|
-
|
116
|
+
buf << EightBitsEncoding::UTF8_2_EBCDIC(out)
|
117
|
+
return out.length
|
94
118
|
end
|
95
119
|
end
|
96
120
|
|
97
|
-
class Ascii <
|
98
|
-
def build_field(buf,length)
|
99
|
-
f
|
100
|
-
f.set_value(EightBitsEncoding::ASCII_2_UTF8(buf[0,length]))
|
101
|
-
return f
|
121
|
+
class Ascii < Fix
|
122
|
+
def build_field(buf, f, length)
|
123
|
+
f.set_value(EightBitsEncoding::ASCII_2_UTF8(buf.slice!(0...length)))
|
102
124
|
end
|
103
125
|
|
104
|
-
def encode(f)
|
126
|
+
def encode(buf, f)
|
105
127
|
out = f.get_value
|
106
128
|
if @length > 0
|
107
129
|
raise TooLongDataException if out.length > @length
|
108
130
|
out = out.ljust(@length," ")
|
109
131
|
end
|
110
|
-
|
132
|
+
buf << EightBitsEncoding::UTF8_2_ASCII(out)
|
133
|
+
return out.length
|
111
134
|
end
|
112
135
|
end
|
113
136
|
|
114
137
|
|
115
|
-
class String <
|
116
|
-
def build_field(buf,length)
|
117
|
-
f
|
118
|
-
f.set_value(buf[0,length])
|
119
|
-
return f
|
138
|
+
class String < Fix
|
139
|
+
def build_field(buf, f, length)
|
140
|
+
f.set_value(buf.slice!(0...length))
|
120
141
|
end
|
121
142
|
|
122
|
-
def encode(f)
|
143
|
+
def encode(buf, f)
|
123
144
|
out = f.get_value
|
124
145
|
if @length > 0
|
125
146
|
raise TooLongDataException if out.length > @length
|
126
147
|
out = out.ljust(@length," ")
|
127
148
|
end
|
128
|
-
|
149
|
+
buf << out
|
150
|
+
return out.length
|
129
151
|
end
|
130
152
|
end
|
131
153
|
|
132
|
-
class Binary <
|
133
|
-
def build_field(buf,length)
|
134
|
-
|
135
|
-
f.set_value(buf[0,length].unpack("H*").first.upcase)
|
136
|
-
return f
|
154
|
+
class Binary < Fix
|
155
|
+
def build_field(buf, field, length)
|
156
|
+
field.set_value(buf.slice!(0...length).unpack("H*").first.upcase)
|
137
157
|
end
|
138
158
|
|
139
|
-
def encode(f)
|
159
|
+
def encode(buf, f)
|
140
160
|
out = [f.get_value].pack("H*")
|
141
161
|
if @length > 0
|
142
162
|
raise TooLongDataException if out.length > @length
|
143
163
|
out = out.ljust(@length,0.chr)
|
144
164
|
end
|
145
|
-
|
165
|
+
buf << out
|
166
|
+
return out.length
|
146
167
|
end
|
147
168
|
end
|
148
169
|
|
@@ -157,33 +178,30 @@ module Codec
|
|
157
178
|
"5C9F535455565758595AF4F5F6F7F8F930313233343536373839FAFBFCFDFEFF"].pack("H*")
|
158
179
|
|
159
180
|
class Numace < Numstr
|
160
|
-
def build_field(
|
161
|
-
f = Field.new(@id)
|
162
|
-
|
181
|
+
def build_field(buffer, field, length)
|
163
182
|
data = ""
|
183
|
+
buf = buffer.slice!(0...length)
|
164
184
|
# if buf to decode is in EBCDIC then convert buf in ASCII
|
165
|
-
if ( buf
|
166
|
-
buf
|
185
|
+
if ( buf.unpack("C*").select{|c| c >= 128}.size > 0)
|
186
|
+
buf.unpack("C*").each { |c| data << EBCDIC_2_ASCII[c] }
|
167
187
|
else
|
168
|
-
data = buf
|
188
|
+
data = buf
|
169
189
|
end
|
170
|
-
|
171
|
-
return f
|
190
|
+
field.set_value(data.to_i)
|
172
191
|
end
|
173
192
|
end
|
174
193
|
|
175
194
|
class Strace < String
|
176
|
-
def build_field(
|
177
|
-
f = Field.new(@id)
|
195
|
+
def build_field(buffer, field, length)
|
178
196
|
data = ""
|
197
|
+
buf = buffer.slice!(0...length)
|
179
198
|
# if buf to decode is in EBCDIC then convert buf in ASCII
|
180
|
-
if ( buf
|
181
|
-
buf
|
199
|
+
if ( buf.unpack("C*").select{|c| c >= 128}.size > 0)
|
200
|
+
buf.unpack("C*").each { |c| data += EBCDIC_2_ASCII[c] }
|
182
201
|
else
|
183
|
-
data = buf
|
202
|
+
data = buf
|
184
203
|
end
|
185
|
-
|
186
|
-
return f
|
204
|
+
field.set_value(data)
|
187
205
|
end
|
188
206
|
end
|
189
207
|
end
|