bencode 0.3.2 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/bencode.rb +14 -14
- data/test/tc_bdecode.rb +13 -0
- data/test/tc_bencode.rb +17 -0
- data/test/test_suite.rb +3 -0
- metadata +2 -1
data/lib/bencode.rb
CHANGED
@@ -21,7 +21,7 @@
|
|
21
21
|
# === Strings
|
22
22
|
#
|
23
23
|
# Strings are sequences of zero or more bytes. They are encoded as
|
24
|
-
# <i
|
24
|
+
# <i><length>:<contents></i>, where _length_ is the length of _contents_. _length_
|
25
25
|
# must be non-negative.
|
26
26
|
#
|
27
27
|
# "".bencode #=> "0:"
|
@@ -71,7 +71,7 @@ class Object
|
|
71
71
|
# Raises an exception. Subclasses of Object must themselves
|
72
72
|
# define meaningful #bencode methods.
|
73
73
|
def bencode
|
74
|
-
raise BencodeError,
|
74
|
+
raise BencodeError, "object cannot be bencoded"
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
@@ -91,7 +91,7 @@ end
|
|
91
91
|
class String
|
92
92
|
#
|
93
93
|
# Bencodes the String object. Bencoded strings are represented
|
94
|
-
# as
|
94
|
+
# as <code>x</code>:<code>y</code>, where +y+ is the string and +x+ is the length of the
|
95
95
|
# string.
|
96
96
|
#
|
97
97
|
# "foo".bencode #=> "3:foo"
|
@@ -130,7 +130,9 @@ class Array
|
|
130
130
|
# [1, "foo"].bencode #=> "li1e3:fooe"
|
131
131
|
#
|
132
132
|
def bencode
|
133
|
-
"l#{map{|obj| obj.bencode}.join('')
|
133
|
+
"l#{map{|obj| obj.bencode }.join('')}e"
|
134
|
+
rescue BencodeError
|
135
|
+
raise BencodeError, "list items must be bencodable"
|
134
136
|
end
|
135
137
|
end
|
136
138
|
|
@@ -142,8 +144,14 @@ class Hash
|
|
142
144
|
# All keys must be strings. The keys of the bencoded hash will
|
143
145
|
# be in lexicographical order.
|
144
146
|
def bencode
|
145
|
-
pairs = sort.map{|key, val| [key.to_str.bencode, val.bencode]}
|
147
|
+
pairs = sort.map{|key, val| [key.to_str.bencode, val.bencode] }
|
146
148
|
"d#{pairs.join('')}e"
|
149
|
+
rescue NoMethodError => error
|
150
|
+
if error.name == :to_str
|
151
|
+
raise BencodeError, "dictionary keys must be strings"
|
152
|
+
else
|
153
|
+
raise
|
154
|
+
end
|
147
155
|
end
|
148
156
|
end
|
149
157
|
|
@@ -165,15 +173,7 @@ class IO
|
|
165
173
|
end
|
166
174
|
end
|
167
175
|
|
168
|
-
class BencodeError < StandardError
|
169
|
-
def initialize(object_class = nil) # :nodoc:
|
170
|
-
@object_class = object_class
|
171
|
-
end
|
172
|
-
|
173
|
-
def to_s # :nodoc:
|
174
|
-
"could not bencode #{@object_class}"
|
175
|
-
end
|
176
|
-
end
|
176
|
+
class BencodeError < StandardError; end
|
177
177
|
|
178
178
|
class BdecodeError < StandardError; end
|
179
179
|
|
data/test/tc_bdecode.rb
CHANGED
@@ -4,11 +4,18 @@ require "#{File.dirname(__FILE__)}/../lib/bencode"
|
|
4
4
|
|
5
5
|
class BdecodeTest < Test::Unit::TestCase
|
6
6
|
def test_string
|
7
|
+
assert_equal "", "0:".bdecode
|
7
8
|
assert_equal "foo", "3:foo".bdecode
|
9
|
+
assert_equal "foo bar", "7:foo bar".bdecode
|
8
10
|
end
|
9
11
|
|
10
12
|
def test_integer
|
13
|
+
assert_equal 0, "i0e".bdecode
|
11
14
|
assert_equal 42, "i42e".bdecode
|
15
|
+
assert_equal -7, "i-7e".bdecode
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_invalid_integer
|
12
19
|
assert_raise BdecodeError do
|
13
20
|
"i01e".bdecode
|
14
21
|
end
|
@@ -18,10 +25,14 @@ class BdecodeTest < Test::Unit::TestCase
|
|
18
25
|
end
|
19
26
|
|
20
27
|
def test_array
|
28
|
+
assert_equal [], "le".bdecode
|
29
|
+
assert_equal ["foo"], "l3:fooe".bdecode
|
21
30
|
assert_equal [1, 2, 3], "li1ei2ei3ee".bdecode
|
22
31
|
end
|
23
32
|
|
24
33
|
def test_hash
|
34
|
+
assert_equal Hash.new, "de".bdecode
|
35
|
+
|
25
36
|
hsh = {"a" => "monkey", "h" => "elephant", "z" => "zebra"}
|
26
37
|
assert_equal hsh, "d1:a6:monkey1:h8:elephant1:z5:zebrae".bdecode
|
27
38
|
end
|
@@ -30,6 +41,8 @@ class BdecodeTest < Test::Unit::TestCase
|
|
30
41
|
assert_raises BdecodeError do
|
31
42
|
"foobar".bdecode
|
32
43
|
"i1ei2e".bdecode
|
44
|
+
"4:foo".bdecode
|
45
|
+
"2:bar".bdecode
|
33
46
|
end
|
34
47
|
end
|
35
48
|
|
data/test/tc_bencode.rb
CHANGED
@@ -8,12 +8,18 @@ class BencodeTest < Test::Unit::TestCase
|
|
8
8
|
assert_equal "0:", "".bencode
|
9
9
|
end
|
10
10
|
|
11
|
+
def test_tab_string
|
12
|
+
assert_equal "1:\t", "\t".bencode
|
13
|
+
assert_equal "2:\t\t", "\t\t".bencode
|
14
|
+
end
|
15
|
+
|
11
16
|
def test_multiline_string
|
12
17
|
assert_equal "1:\n", "\n".bencode
|
13
18
|
assert_equal "2:\n\n", "\n\n".bencode
|
14
19
|
end
|
15
20
|
|
16
21
|
def test_integer
|
22
|
+
assert_equal "i0e", 0.bencode
|
17
23
|
assert_equal "i42e", 42.bencode
|
18
24
|
assert_equal "i-3e", -3.bencode
|
19
25
|
end
|
@@ -25,14 +31,25 @@ class BencodeTest < Test::Unit::TestCase
|
|
25
31
|
end
|
26
32
|
|
27
33
|
def test_array
|
34
|
+
assert_equal "le", [].bencode
|
28
35
|
assert_equal "li1ei2ei3ee", [1, 2, 3].bencode
|
29
36
|
end
|
30
37
|
|
31
38
|
def test_hash
|
39
|
+
assert_equal "de", {}.bencode
|
32
40
|
assert_equal "d1:a3:foo1:g3:bar1:z3:baze",
|
33
41
|
{"a" => "foo", "g" => "bar", "z" => "baz"}.bencode
|
34
42
|
end
|
35
43
|
|
44
|
+
def test_illegal_hash_keys
|
45
|
+
assert_raise BencodeError do
|
46
|
+
{1 => 'foo'}.bencode
|
47
|
+
end
|
48
|
+
assert_raise BencodeError do
|
49
|
+
{1 => 'foo', 2 => 'bar'}.bencode
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
36
53
|
def test_hash_julien
|
37
54
|
assert_equal "d1:ai1e2:bbi1e1:ci1ee",
|
38
55
|
{'a' => 1, 'c' => 1, 'bb' => 1}.bencode
|
data/test/test_suite.rb
ADDED
metadata
CHANGED
@@ -3,7 +3,7 @@ rubygems_version: 0.9.0
|
|
3
3
|
specification_version: 1
|
4
4
|
name: bencode
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
6
|
+
version: 0.4.0
|
7
7
|
date: 2006-12-26 00:00:00 +01:00
|
8
8
|
summary: A Ruby implementation of the Bencode encoding used by BitTorrent
|
9
9
|
require_paths:
|
@@ -31,6 +31,7 @@ authors:
|
|
31
31
|
files:
|
32
32
|
- lib/bencode.rb
|
33
33
|
test_files:
|
34
|
+
- test/test_suite.rb
|
34
35
|
- test/tc_bencode.rb
|
35
36
|
- test/tc_bdecode.rb
|
36
37
|
rdoc_options: []
|