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

- old
+ new

@@ -1,6 +1,10 @@ require 'stringio' + +class InvalidEncodingError < StandardError; end +class UnencodableTypeError < StandardError; end + class BEncoder class << self def encode(object) case object when Symbol @@ -11,10 +15,12 @@ encode_int object when Array encode_array object when Hash encode_hash object + else + raise UnencodableTypeError, "Cannot encode instance of type #{object.class}" end end def decode(string) parse string @@ -22,12 +28,10 @@ private - class InvalidEncodingError < StandardError; end - def parse(string) case string[0] when 'i' parse_int string when 'l' @@ -44,23 +48,23 @@ str = string str.getc if peek(str) == 'l' elsif string[0] == 'l' && string[-1] == 'e' str = StringIO.new string[1..-2] else - raise InvalidEncodingError + raise InvalidEncodingError, 'List does not have a closing e' 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") + list_of_keys_and_values = parse_list("l#{ string[1..-2] }e") else - raise InvalidEncodingError + raise InvalidEncodingError, 'Dict does not have a closing e' end make_hash_from_array list_of_keys_and_values end def parse_io_list(io) @@ -75,11 +79,11 @@ list << parse_dict(io) when ->(e) { e =~ /\d/ } length = io.gets(sep=':').to_i list << io.gets(length) else - raise InvalidEncodingError + raise InvalidEncodingError, "Encountered unexpected identifier #{ peek io }" end end io.getc list end @@ -94,36 +98,36 @@ def parse_int(string) if string[0] == 'i' && string[-1] == 'e' string[1..-2].to_i else - raise InvalidEncodingError + raise InvalidEncodingError, 'Integer does not have closing e' end end def parse_string(string) length, content = string.split ':' if content.length == length.to_i content else - raise InvalidEncodingError + raise InvalidEncodingError, "String length declared as #{length.to_i}, but was #{content.length} " end end def encode_string(string) - "#{string.length}:#{string}" + "#{ string.length }:#{ string }" end def encode_int(int) - "i#{int}e" + "i#{ int }e" end def encode_array(array) array.inject("l") { |result, el| result += encode(el) } + "e" end def encode_hash(hash) - hash.inject("d") { |result, (k,v)| result += "#{encode(k.to_s)}#{encode(v)}" } + 'e' + hash.inject("d") { |result, (k,v)| result += "#{ encode(k.to_s) }#{ encode(v) }" } + 'e' end def peek(io) char = io.getc io.ungetc char \ No newline at end of file