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