Module: BCodec

Defined in:
lib/bcodec.rb,
lib/bcodec/decode.rb,
lib/bcodec/encode.rb

Overview

BCodec - Ruby module to decode/encode bencoded data Copyright © 2006 Thomas <[email protected]>

This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

Defined Under Namespace

Classes: InvalidDataType, InvalidInteger, InvalidKey, InvalidString, UnknownData

Class Method Summary collapse

Class Method Details

.decode(io) ⇒ Object

Decodes bencoded data from an IO-like object (IO, File, StringIO or similar that has a .getc method).

Returns the decoded object which is either of these:

  • Array

  • Fixnum (or Bignum)

  • Hash

  • String



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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/bcodec/decode.rb', line 34

def BCodec.decode(io)
  c = io.getc

  case c.chr
  when 'i'
    i = ''
    while c = io.getc
      if c.chr == 'e'
        if i.match(/^(0|-?[1-9][0-9]*)$/)
          return i.to_i
        else
          raise InvalidInteger
        end
      else
        i += c.chr
      end
    end
    raise EOFError
  when '0'..'9'
    n = c.chr
    while b = io.getc
      case b.chr
      when '0'..'9'
        n += b.chr
      when ':'
        strlen = n.to_i
        str = io.read(strlen)
        if str.length == strlen
          return str
        else
          raise EOFError
        end
      else
        raise InvalidString
      end
    end
  when 'l'
    list = []
    
    while item = decode(io)
      list.push(item)
    end

    return list
  when 'd'
    dict = {}

    while key = decode(io)
      raise InvalidKey unless key.instance_of?(String)
      val = decode(io)
      dict[key] = val
    end

    return dict
  when 'e'
    return false
  else
    raise UnknownData
  end
end

.encode(obj) ⇒ Object

Bencodes a Ruby object which must be either of these:

  • Array

  • Fixnum (or Bignum)

  • Hash

  • String

Returns the encoded object(s) as a String



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/bcodec/encode.rb', line 31

def BCodec.encode(obj)
  str = ""
  if obj.class == String
    str << "%d:%s" % [ obj.length, obj ]
  elsif obj.class == Fixnum or obj.class == Integer or obj.class == Bignum
    str << "i" <<  obj.to_s << "e"
  elsif obj.class == Array
    str << "l"
    obj.each { |i| str += encode(i) }
    str << "e"
  elsif obj.class == Hash
    str << "d"
    obj.sort.each do |k, v|
      raise InvalidKey unless k.instance_of?(String)
      str << encode(k)
      str << encode(v)
    end
    str << "e"
  else
    raise InvalidDataType
  end

  return str
end