class BEncode::Parser
Attributes
stream[R]
Public Class Methods
new(stream)
click to toggle source
# File lib/bencode/parser.rb, line 7 def initialize(stream) @stream = if stream.kind_of?(IO) || stream.kind_of?(StringIO) stream elsif stream.respond_to? :string StringIO.new stream.string elsif stream.respond_to? :to_s StringIO.new stream.to_s end end
Public Instance Methods
eos?()
click to toggle source
# File lib/bencode/parser.rb, line 27 def eos? stream.eof? end
parse!()
click to toggle source
# File lib/bencode/parser.rb, line 18 def parse! case peek when ?i then parse_integer! when ?l then parse_list! when ?d then parse_dict! when ?0 .. ?9 then parse_string! end end
Private Instance Methods
parse_dict!()
click to toggle source
# File lib/bencode/parser.rb, line 47 def parse_dict! stream.getc hsh = {} until peek == ?e key = parse! unless key.is_a? String or key.is_a? Fixnum raise BEncode::DecodeError, "key must be a string or number" end val = parse! hsh.store(key.to_s, val) end stream.getc hsh end
parse_integer!()
click to toggle source
# File lib/bencode/parser.rb, line 33 def parse_integer! stream.getc num = stream.gets("e") or raise BEncode::DecodeError num.chop.to_i end
parse_list!()
click to toggle source
# File lib/bencode/parser.rb, line 39 def parse_list! stream.getc ary = [] ary.push(parse!) until peek == ?e stream.getc ary end
parse_string!()
click to toggle source
# File lib/bencode/parser.rb, line 65 def parse_string! num = stream.gets(":") or raise BEncode::DecodeError, "invalid string length (no colon)" begin length = num.chop.to_i return "" if length == 0 # Workaround for Rubinius bug str = stream.read(length) rescue raise BEncode::DecodeError, "invalid string length" end str end
peek()
click to toggle source
# File lib/bencode/parser.rb, line 80 def peek c = stream.getc stream.ungetc(c) c end