Class: Codec::Bertlv
Instance Attribute Summary
Attributes inherited from Base
#id
Instance Method Summary
collapse
Methods inherited from Base
#add_sub_codec, #decode_with_length, #encode_with_length, #eval_length, #get_length, #get_sub_codecs
Constructor Details
#initialize(id) ⇒ Bertlv
Returns a new instance of Bertlv.
73
74
75
76
|
# File 'lib/codec/tlv.rb', line 73
def initialize(id)
@id = id
@length = 0
end
|
Instance Method Details
#build_field(buf, length) ⇒ Object
145
146
147
148
149
150
151
152
153
154
155
156
157
|
# File 'lib/codec/tlv.rb', line 145
def build_field(buf,length)
msg = Field.new(@id)
buffer = buf[0,length]
while buffer.length > 0
tag,buffer = tag_decode(buffer)
f = Field.new(tag)
value_length,buffer = length_decode(buffer)
value, buffer = value_decode(buffer,value_length)
f.set_value(value)
msg.add_sub_field(f)
end
return msg
end
|
#decode(buffer) ⇒ Object
159
160
161
|
# File 'lib/codec/tlv.rb', line 159
def decode(buffer)
return build_field(buffer,buffer.length),""
end
|
#encode(field) ⇒ Object
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
|
# File 'lib/codec/tlv.rb', line 163
def encode(field)
out = ""
subfields = field.get_value
unless subfields.kind_of?(Array)
raise EncodingException, "Invalid field #{field.to_yaml} for BER Tlv encoding"
end
while subfields.size > 0
subfield = subfields.shift
out += tag_encode(subfield.get_id)
value = value_encode(subfield.get_value)
out += length_encode(value.length)
out += value
end
return out
end
|
#length_decode(buffer) ⇒ Object
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
# File 'lib/codec/tlv.rb', line 101
def length_decode(buffer)
buf = buffer.dup
b = buf.slice!(0).getbyte(0)
if b & 0x80 == 0x80
loencl = b & 0x7F
lb = buf[0,loencl]
buf = buf[loencl,buf.length]
length = 0
while(lb.length > 0)
length *= 256
length += lb.slice!(0).getbyte(0)
end
return length,buf
else
return b,buf
end
end
|
#length_encode(length) ⇒ Object
121
122
123
124
125
126
127
128
129
|
# File 'lib/codec/tlv.rb', line 121
def length_encode(length)
out = Numbin.numbin(length,0)
if out.length > 127
raise EncodingException,"Invalid length for BER Tlv #{length}"
elsif out.length > 1
out = (128 + out.length).chr + out
end
return out
end
|
#tag_decode(buffer) ⇒ Object
78
79
80
81
82
83
84
85
86
87
88
89
90
|
# File 'lib/codec/tlv.rb', line 78
def tag_decode(buffer)
buf = buffer.dup
begin ; b = buf.slice!(0).getbyte(0) ; end while (b == 0 || b == 255)
tag = b.chr
if (b & 0x1F == 0x1F)
begin
nb = buf.slice!(0).getbyte(0)
tag += nb.chr
end while nb & 0x80 == 0x80
end
return tag.unpack("H*").first.upcase, buf
end
|
#tag_encode(tag) ⇒ Object
92
93
94
95
96
97
98
99
|
# File 'lib/codec/tlv.rb', line 92
def tag_encode(tag)
buf = [tag].pack("H*")
check_tag, remain = tag_decode(buf)
if tag != check_tag || remain != ""
raise EncodingException, "Invalid BER tag [#{tag}]"
end
return buf
end
|
#value_decode(buf, length) ⇒ Object
131
132
133
134
135
136
137
138
139
|
# File 'lib/codec/tlv.rb', line 131
def value_decode(buf,length)
if length > buf.length
raise ErrorBufferUnderflow,"Not enough data for parsing BER TLV
#{@id} length value #{length} remaining only #{buf.length}"
end
value = buf[0,length]
buf = buf[length,buf.length]
return value.unpack("H*").first.upcase,buf
end
|
#value_encode(unpack_buffer) ⇒ Object
141
142
143
|
# File 'lib/codec/tlv.rb', line 141
def value_encode(unpack_buffer)
[unpack_buffer].pack("H*")
end
|