Module: BEncode

Defined in:
lib/bencode.rb,
lib/bencode/decode.rb

Overview

TODO: Write some documentation here.

Constant Summary collapse

VERSION =
'0.5.0'
DecodeError =
Class.new(StandardError)
EncodeError =
Class.new(StandardError)

Class Method Summary collapse

Class Method Details

.dump(obj) ⇒ Object

BEncodes obj



5
6
7
# File 'lib/bencode/decode.rb', line 5

def dump(obj)
  obj.bencode
end

.load(str) ⇒ Object

Bdecodes str



10
11
12
13
14
15
16
17
# File 'lib/bencode/decode.rb', line 10

def load(str)
  require 'strscan'

  scanner = StringScanner.new(str)
  obj = parse(scanner)
  raise BEncode::DecodeError unless scanner.eos?
  return obj
end

.load_file(path) ⇒ Object

Bdecodes the file located at path



20
21
22
23
24
25
26
# File 'lib/bencode/decode.rb', line 20

def load_file(path)
  if RUBY_PLATFORM =~ /(win|w)32$/
    load(File.open(path, 'rb').read)
  else
    load(File.open(path).read)
  end
end

.parse(scanner) ⇒ Object

:nodoc:



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/bencode/decode.rb', line 28

def parse(scanner) # :nodoc:
  case scanner.scan(/[ild]|\d+:/)
  when "i"
    number = scanner.scan(/0|(?:-?[1-9][0-9]*)/)
    raise BEncode::DecodeError unless number and scanner.scan(/e/)
    return number.to_i
  when "l"
    ary = []
    # TODO: There must be a smarter way of doing this...
    ary.push(parse(scanner)) until scanner.peek(1) == "e"
    scanner.pos += 1
    return ary
  when "d"
    hsh = {}
    until scanner.peek(1) == "e"
      key, value = parse(scanner), parse(scanner)

      unless key.is_a? String
        raise BEncode::DecodeError, "key must be a string"
      end

      hsh.store(key, value)
    end
    scanner.pos += 1
    return hsh
  when /\d+:/
    length = Integer($~.string.chop)
    str = scanner.peek(length)

    begin
      scanner.pos += length
    rescue RangeError
      raise BEncode::DecodeError, "invalid string length"
    end

    return str
  else
    raise BEncode::DecodeError
  end
end