simonmenke-bencoding 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +9 -0
- data/README.txt +5 -0
- data/lib/bencoding.rb +6 -2
- data/lib/bencoding/parser.rb +45 -15
- data/lib/bencoding/version.rb +1 -1
- data/test/test_bencoding.rb +35 -1
- metadata +2 -2
data/History.txt
CHANGED
data/README.txt
CHANGED
data/lib/bencoding.rb
CHANGED
@@ -1,12 +1,16 @@
|
|
1
1
|
$:.unshift(File.dirname(__FILE__)) unless
|
2
2
|
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
3
3
|
|
4
|
-
require
|
4
|
+
require 'stringio'
|
5
|
+
require 'open-uri'
|
5
6
|
|
6
7
|
module Bencoding
|
7
|
-
def self.load(io)
|
8
|
+
def self.load!(io)
|
8
9
|
Parser.load(io)
|
9
10
|
end
|
11
|
+
def self.load(io)
|
12
|
+
return load!(io) rescue nil
|
13
|
+
end
|
10
14
|
def self.dump(object)
|
11
15
|
object.to_bencoding
|
12
16
|
end
|
data/lib/bencoding/parser.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
module Bencoding
|
2
|
-
class ParseError
|
2
|
+
class ParseError < Exception ; end
|
3
|
+
class InvalidInput < Exception ; end
|
3
4
|
|
4
5
|
module Parser
|
5
6
|
|
@@ -8,12 +9,38 @@ module Bencoding
|
|
8
9
|
INTEGER_TOKEN = 105 # i # :nodoc:
|
9
10
|
TERMINATOR_TOKEN = 101 # e # :nodoc:
|
10
11
|
SEPERATOR_TOKEN = 58 # : # :nodoc:
|
11
|
-
ZERO_TOKEN = 48 #
|
12
|
-
NINE_TOKEN = 57 #
|
12
|
+
ZERO_TOKEN = 48 # 0 # :nodoc:
|
13
|
+
NINE_TOKEN = 57 # 9 # :nodoc:
|
14
|
+
MINUS_TOKEN = 45 # - # :nodoc:
|
13
15
|
|
14
16
|
def load(io)
|
15
|
-
|
16
|
-
|
17
|
+
any_io(io) do |io|
|
18
|
+
parse_anytype(io)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def any_io(io)
|
23
|
+
close_io = false
|
24
|
+
if io.is_a? String
|
25
|
+
if io =~ %r{^(http(s?)|file)://}
|
26
|
+
io = open(io)
|
27
|
+
close_io = true
|
28
|
+
elsif File.exist?(io)
|
29
|
+
io = File.open(io)
|
30
|
+
close_io = true
|
31
|
+
else
|
32
|
+
io = StringIO.new(io)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
raise InvalidInput unless io.respond_to?(:getc)
|
37
|
+
raise InvalidInput unless io.respond_to?(:read)
|
38
|
+
raise InvalidInput unless io.respond_to?(:close) or not close_io
|
39
|
+
|
40
|
+
return_value = yield(io)
|
41
|
+
|
42
|
+
io.close if close_io
|
43
|
+
return return_value
|
17
44
|
end
|
18
45
|
|
19
46
|
def parse_anytype(io, typechar=nil) # :nodoc:
|
@@ -23,8 +50,7 @@ module Bencoding
|
|
23
50
|
when LIST_TOKEN then parse_list(io)
|
24
51
|
when INTEGER_TOKEN then parse_integer(io)
|
25
52
|
when (ZERO_TOKEN..NINE_TOKEN)
|
26
|
-
io
|
27
|
-
parse_string(io)
|
53
|
+
parse_string(io, typechar)
|
28
54
|
else
|
29
55
|
raise ParseError
|
30
56
|
end
|
@@ -34,8 +60,7 @@ module Bencoding
|
|
34
60
|
dictionary = ::Hash.new
|
35
61
|
until (c = io.getc) == TERMINATOR_TOKEN
|
36
62
|
raise ParseError if c.nil?
|
37
|
-
io
|
38
|
-
key = parse_string(io)
|
63
|
+
key = parse_string(io, c)
|
39
64
|
val = parse_anytype(io)
|
40
65
|
dictionary[key] = val
|
41
66
|
end
|
@@ -52,18 +77,23 @@ module Bencoding
|
|
52
77
|
list
|
53
78
|
end
|
54
79
|
|
55
|
-
def parse_integer(io, terminator=TERMINATOR_TOKEN) # :nodoc:
|
80
|
+
def parse_integer(io, terminator=TERMINATOR_TOKEN, first_char=nil) # :nodoc:
|
56
81
|
integer_string = ""
|
82
|
+
integer_string << first_char unless first_char.nil?
|
57
83
|
until (c = io.getc) == terminator
|
58
|
-
raise ParseError if c.nil?
|
59
|
-
|
84
|
+
raise ParseError if c.nil?
|
85
|
+
raise ParseError unless (ZERO_TOKEN..NINE_TOKEN).member?(c) or MINUS_TOKEN == c
|
86
|
+
integer_string << c
|
60
87
|
end
|
61
88
|
integer_string.to_i
|
62
89
|
end
|
63
90
|
|
64
|
-
def parse_string(io) # :nodoc:
|
65
|
-
length = parse_integer(io, SEPERATOR_TOKEN)
|
66
|
-
|
91
|
+
def parse_string(io, first_char) # :nodoc:
|
92
|
+
length = parse_integer(io, SEPERATOR_TOKEN, first_char)
|
93
|
+
raise ParseError if length < 0
|
94
|
+
string = io.read(length)
|
95
|
+
raise ParseError if length != string.length
|
96
|
+
string
|
67
97
|
end
|
68
98
|
|
69
99
|
extend self
|
data/lib/bencoding/version.rb
CHANGED
data/test/test_bencoding.rb
CHANGED
@@ -10,6 +10,10 @@ class TestBencoding < Test::Unit::TestCase
|
|
10
10
|
test_load "i17e", 17
|
11
11
|
end
|
12
12
|
|
13
|
+
def test_load_negative_integer
|
14
|
+
test_load "i-17e", -17
|
15
|
+
end
|
16
|
+
|
13
17
|
def test_load_list
|
14
18
|
test_load "l5:helloi17ee", ["hello", 17]
|
15
19
|
end
|
@@ -22,10 +26,36 @@ class TestBencoding < Test::Unit::TestCase
|
|
22
26
|
def test_load_fake
|
23
27
|
str = "d5:key_ai16e5:a_key4:helloe"
|
24
28
|
assert_raise Bencoding::ParseError do
|
25
|
-
out = Bencoding.load(str)
|
29
|
+
out = Bencoding.load!(str)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_load_partial_integer
|
34
|
+
str = "i12"
|
35
|
+
assert_raise Bencoding::ParseError do
|
36
|
+
out = Bencoding.load!(str)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_load_partial_integer_in_list
|
41
|
+
str = "li12i45ee"
|
42
|
+
assert_raise Bencoding::ParseError do
|
43
|
+
out = Bencoding.load!(str)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_load_partial_string
|
48
|
+
str = "5:hel"
|
49
|
+
assert_raise Bencoding::ParseError do
|
50
|
+
out = Bencoding.load!(str)
|
26
51
|
end
|
27
52
|
end
|
28
53
|
|
54
|
+
def test_load_form_uri
|
55
|
+
uri = "http://torrents.thepiratebay.org/4385574/Ubuntu_8.10_(Intrepid_Ibex)_Alpha_5.4385574.TPB.torrent"
|
56
|
+
assert Bencoding.load!(uri)['announce']=='http://tpb.tracker.thepiratebay.org:80/announce'
|
57
|
+
end
|
58
|
+
|
29
59
|
def test_dump_string
|
30
60
|
test_dump "hello", "5:hello"
|
31
61
|
end
|
@@ -34,6 +64,10 @@ class TestBencoding < Test::Unit::TestCase
|
|
34
64
|
test_dump 25, "i25e"
|
35
65
|
end
|
36
66
|
|
67
|
+
def test_dump_negative_integer
|
68
|
+
test_dump -25, "i-25e"
|
69
|
+
end
|
70
|
+
|
37
71
|
def test_dump_float
|
38
72
|
test_dump 25.4, "i25e"
|
39
73
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simonmenke-bencoding
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Simon Menke
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-09-
|
12
|
+
date: 2008-09-13 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|