lib/bencoder.rb in bencoder-0.0.3 vs lib/bencoder.rb in bencoder-0.0.4

- old
+ new

@@ -22,10 +22,12 @@ private + class InvalidEncodingError < StandardError; end + def parse(string) case string[0] when 'i' parse_int string when 'l' @@ -42,62 +44,70 @@ str = string str.getc if peek(str) == 'l' elsif string[0] == 'l' && string[-1] == 'e' str = StringIO.new string[1..-2] else - raise 'Not a list' + raise InvalidEncodingError end + parse_io_list str + end + + def parse_dict(string) + if string.is_a? StringIO + string.getc if peek(string) == 'd' + list_of_keys_and_values = parse_list(string) + elsif string[0] == 'd' && string[-1] == 'e' + list_of_keys_and_values = parse_list("l#{string[1..-2]}e") + else + raise InvalidEncodingError + end + make_hash_from_array list_of_keys_and_values + end + + def parse_io_list(io) list = [] - until peek(str) == 'e' || str.eof? - case peek(str) + until peek(io) == 'e' || io.eof? + case peek(io) when 'i' - list << parse_int(str.gets sep='e') + list << parse_int(io.gets sep='e') when 'l' - list << parse_list(str) + list << parse_list(io) when 'd' - list << parse_dict(str) + list << parse_dict(io) when ->(e) { e =~ /\d/ } - length = str.gets(sep=':').to_i - list << str.gets(length) + length = io.gets(sep=':').to_i + list << io.gets(length) else - raise str.read + raise InvalidEncodingError end end - str.getc + io.getc list end - def parse_dict(string) - if string.is_a? StringIO - string.getc if peek(string) == 'd' - list_of_keys_and_values = parse_list(string) - elsif string[0] == 'd' && string[-1] == 'e' - list_of_keys_and_values = parse_list("l#{string[1..-2]}e") - else - raise 'Something in hash is wrong!' - end + def make_hash_from_array(list) hash = {} - list_of_keys_and_values.each_slice(2) do |k,v| + list.each_slice(2) do |k,v| hash[k] = v end hash end def parse_int(string) if string[0] == 'i' && string[-1] == 'e' string[1..-2].to_i else - raise 'Int is formatted wrong' + raise InvalidEncodingError end end def parse_string(string) length, content = string.split ':' if content.length == length.to_i content else - raise 'String length is messed up' + raise InvalidEncodingError end end def encode_string(string) "#{string.length}:#{string}" @@ -116,10 +126,9 @@ end def peek(io) char = io.getc io.ungetc char - puts char char end end end \ No newline at end of file