Module: BEncodr::Parser
- Defined in:
- lib/bencodr/parser.rb
Class Method Summary collapse
-
.parse_dictionary(scanner) ⇒ ::Hash
This method parases a bencoded dictionary.
-
.parse_integer(scanner) ⇒ ::Integer
This method parases a bencoded integer.
-
.parse_key_value(scanner) ⇒ Object
:nodoc:.
-
.parse_list(scanner) ⇒ ::Array
This method parases a bencoded list.
-
.parse_object(scanner) ⇒ ::String, ...
This method parases a bencoded object.
-
.parse_string(scanner) ⇒ ::String
This method parases a bencoded string.
Class Method Details
.parse_dictionary(scanner) ⇒ ::Hash
93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/bencodr/parser.rb', line 93 def parse_dictionary(scanner) dictionary = {} scanner.scan(/d/) or raise BEncodeError, "Invalid dictionary: missing opening d. #{scanner.pos}" while true key_value = parse_key_value(scanner) break unless key_value dictionary.store(*key_value) end scanner.scan(/e/) or raise BEncodeError, "Invalid dictionary: missing closing e. #{scanner.pos}" dictionary end |
.parse_integer(scanner) ⇒ ::Integer
58 59 60 61 62 63 |
# File 'lib/bencodr/parser.rb', line 58 def parse_integer(scanner) scanner.scan(/i/) or raise BEncodeError, "Invalid integer: missing opening i. #{scanner.pos}" integer = scanner.scan(/-?[1-9][0-9]*|0/) or raise BEncodeError, "Invalid integer: valid integer not found. #{scanner.pos}" scanner.scan(/e/) or raise BEncodeError, "Invalid integer: missing closing e. #{scanner.pos}" integer.to_i end |
.parse_key_value(scanner) ⇒ Object
:nodoc:
108 109 110 111 112 113 114 115 116 117 |
# File 'lib/bencodr/parser.rb', line 108 def parse_key_value(scanner) # :nodoc: key = parse_object(scanner) return key unless key raise BEncodeError, "Invalid dictionary: key is not a string. #{scanner.pos}" unless key.is_a?(::String) value = parse_object(scanner) raise BEncodeError, "Invalid dictionary: missing value for key (#{key}). #{scanner.pos}" unless value [key, value] end |
.parse_list(scanner) ⇒ ::Array
72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/bencodr/parser.rb', line 72 def parse_list(scanner) list = [] scanner.scan(/l/) or raise BEncodeError, "Invalid list: missing opening l. #{scanner.pos}" while true object = parse_object(scanner) break unless object list << object end scanner.scan(/e/) or raise BEncodeError, "Invalid list: missing closing e. #{scanner.pos}" list end |
.parse_object(scanner) ⇒ ::String, ...
15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/bencodr/parser.rb', line 15 def parse_object(scanner) case scanner.peek(1)[0] when ?0..?9 parse_string(scanner) when ?i parse_integer(scanner) when ?l parse_list(scanner) when ?d parse_dictionary(scanner) else nil end end |
.parse_string(scanner) ⇒ ::String
37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/bencodr/parser.rb', line 37 def parse_string(scanner) length = scanner.scan(/[1-9][0-9]*|0/).to_i or raise BEncodeError, "Invalid string: length invalid. #{scanner.pos}" scanner.scan(/:/) or raise BEncodeError, "Invalid string: missing colon(:). #{scanner.pos}" byte_string = scanner.peek(length) byte_string.length == length or raise BEncodeError, "Invalid string: length too long(#{length}) #{scanner.pos}." scanner.pos = scanner.pos + length if RUBY_VERSION =~ /1\.9/ byte_string.encode('UTF-8') rescue byte_string.force_encoding('UTF-8') else byte_string end end |