28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
# File 'lib/otnetstring.rb', line 28
def parse(io, encoding = 'internal', fallback_encoding = nil)
fallback_encoding = io.encoding if io.respond_to? :encoding
io = StringIO.new(io) if io.respond_to? :to_str
length, byte = String.new, nil
while byte.nil? || byte =~ /\d/
length << byte if byte
byte = io.read(1)
end
if length.size > 9
raise Error, "#{length} is longer than 9 digits"
elsif length !~ /\d+/
raise Error, "Expected '#{byte}' to be a digit"
end
length = Integer(length)
case byte
when '#' then Integer io.read(length)
when ',' then with_encoding io.read(length), encoding, fallback_encoding
when '~' then
raise Error, "nil has length of 0, #{length} given" unless length == 0
when '!' then io.read(length) == 'true'
when '[', '{'
array = []
start = io.pos
array << parse(io, encoding, fallback_encoding) while io.pos - start < length
raise Error, 'Nested element longer than container' if io.pos - start != length
byte == "{" ? Hash[*array] : array
else
raise Error, "Unknown type '#{byte}'"
end
end
|