def decode(io)
c = io.getc
case c.chr
when 'i'
i = ''
while c = io.getc
if c.chr == 'e'
if i.match(/^(0|-?[1-9][0-9]*)$/)
return i.to_i
else
raise InvalidInteger
end
else
i += c.chr
end
end
raise EOFError
when '0'..'9'
n = c.chr
while b = io.getc
case b.chr
when '0'..'9'
n += b.chr
when ':'
strlen = n.to_i
str = io.read(strlen)
if str.length == strlen
return str
else
raise EOFError
end
else
raise InvalidString
end
end
when 'l'
list = []
while item = decode(io)
list.push(item)
end
return list
when 'd'
dict = {}
while key = decode(io)
raise InvalidKey unless key.instance_of?(String)
val = decode(io)
dict[key] = val
end
return dict
when 'e'
return false
else
raise UnknownData
end
end