Module: BCodec

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

Overview

bcodec - Ruby library to decode/encode bencoded data Copyright © 2006,2007 Thomas <[email protected]>

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

This program 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 General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see <www.gnu.org/licenses/>.

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)

Returns the decoded object which is either of these: Array, Integer (Fixnum or Bignum), Hash or String



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

def 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

Encodes a Ruby object which must be either of these: Array, Integer (Fixnum or Bignum), Hash or String

Returns the encoded object(s) as a String



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/bcodec/encode.rb', line 26

def encode(obj)
  str = ""
  if obj.class == String
    str << "%d:%s" % [ obj.length, obj ]
  elsif obj.class == Fixnum 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