rencode-ruby 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8e4c4b66f1318baa3a826c3b91341e007b045d9d
4
+ data.tar.gz: 41eeecc0d02e829840468a7804c9295a8fa59454
5
+ SHA512:
6
+ metadata.gz: 991793a070c073d1264d86022262743b6ed3e791fb7e4760f32d5f9052a3696aabf8d4c92c62188ff7a3a75c4cbe79cae74c1aa0fc1f14b21fb4f67c251ef25c
7
+ data.tar.gz: baa80ff4cf7dd37f5a5bd70189968fa5fae6dfcf85cea391e34eb3541b7e76e2b32c1c02999505060553077778eb0a3a784776dda5cbc7932ca0347d4cfd01e8
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'turn'
4
+ gem 'shoulda'
5
+ gem 'rake'
6
+
7
+ gemspec
@@ -0,0 +1,39 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ rencode (1.0.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ activesupport (4.0.5)
10
+ i18n (~> 0.6, >= 0.6.9)
11
+ minitest (~> 4.2)
12
+ multi_json (~> 1.3)
13
+ thread_safe (~> 0.1)
14
+ tzinfo (~> 0.3.37)
15
+ ansi (1.4.3)
16
+ i18n (0.6.9)
17
+ minitest (4.7.5)
18
+ multi_json (1.10.0)
19
+ rake (10.3.1)
20
+ shoulda (3.5.0)
21
+ shoulda-context (~> 1.0, >= 1.0.1)
22
+ shoulda-matchers (>= 1.4.1, < 3.0)
23
+ shoulda-context (1.2.1)
24
+ shoulda-matchers (2.6.1)
25
+ activesupport (>= 3.0.0)
26
+ thread_safe (0.3.3)
27
+ turn (0.9.7)
28
+ ansi
29
+ minitest (~> 4)
30
+ tzinfo (0.3.39)
31
+
32
+ PLATFORMS
33
+ ruby
34
+
35
+ DEPENDENCIES
36
+ rake
37
+ rencode!
38
+ shoulda
39
+ turn
@@ -0,0 +1,21 @@
1
+ "Copyright (C) 2014 Mikael Wikman
2
+
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation files
5
+ (the "Software"), to deal in the Software without restriction,
6
+ including without limitation the rights to use, copy, modify, merge,
7
+ publish, distribute, sublicense, and/or sell copies of the Software,
8
+ and to permit persons to whom the Software is furnished to do so,
9
+ subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ The Software is provided "AS IS", without warranty of any kind,
15
+ express or implied, including but not limited to the warranties of
16
+ merchantability, fitness for a particular purpose and
17
+ noninfringement. In no event shall the authors or copyright holders
18
+ be liable for any claim, damages or other liability, whether in an
19
+ action of contract, tort or otherwise, arising from, out of or in
20
+ connection with the Software or the use or other dealings in the
21
+ Software."
@@ -0,0 +1,22 @@
1
+ # REncode -- Web safe object serialization
2
+
3
+ REncode was based on the BitTorrent BEncode module by Petru Paler, et al.
4
+ Licensed by Bram Cohen, 2001-2002, modified by Connelly Barnes 2006-2007.
5
+
6
+ This module for Ruby was written by Mikael Wikman, 2014, and aims to be
7
+ complient with the Connelly Barnes version 1.0.2
8
+
9
+ ## Usage
10
+
11
+ This implementation creates byte arrays, and expects byte arrays as argument. If you have a string, you could simply use str.bytes, or if you want to convert to string do arr.pack("C\*")
12
+
13
+ ```ruby
14
+ require 'rencode'
15
+
16
+ REncode.dump({ 'awesome' => 'It works!' })
17
+ # => [CHR_DICT, '7'.ord, ':'.ord, 'awesome'.bytes, '9'.ord, ':'.ord, 'It works!'.bytes, CHR_TERM].flatten
18
+
19
+ REncode.parse([CHR_INT, '123'.bytes, CHR_TERM].flatten)
20
+ # => 123
21
+
22
+ ```
@@ -0,0 +1,15 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |gem|
4
+ gem.authors = ['Mikael Wikman']
5
+ gem.email = ['mikael@wikman.me']
6
+ gem.description = %q{This implementation aims to be complient with the Connelly Barnes implementation of rencode, version 1.0.2}
7
+ gem.summary = %q{Web safe object serialization}
8
+ gem.files = `git ls-files`.split($\)
9
+ gem.homepage = 'https://github.com/mikaelwikman/rencode'
10
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
11
+ gem.test_files = gem.files.grep(%r{^(test|features)/})
12
+ gem.name = "rencode-ruby"
13
+ gem.require_paths = ["lib"]
14
+ gem.version = '1.0.0'
15
+ end
@@ -0,0 +1,105 @@
1
+ # REncode -- Web safe object serialization
2
+ #
3
+ # REncode was based on the BitTorrent BEncode module by Petru Paler, et al.
4
+ # Licensed by Bram Cohen, 2001-2002, modified by Connelly Barnes 2006-2007.
5
+ #
6
+ #
7
+ # This module for Ruby was written by Mikael Wikman, 2014, and aims to be
8
+ # complient with the Connelly Barnes version 1.0.2
9
+ #
10
+ # "Copyright (C) 2014 Mikael Wikman
11
+ #
12
+ # Permission is hereby granted, free of charge, to any person
13
+ # obtaining a copy of this software and associated documentation files
14
+ # (the "Software"), to deal in the Software without restriction,
15
+ # including without limitation the rights to use, copy, modify, merge,
16
+ # publish, distribute, sublicense, and/or sell copies of the Software,
17
+ # and to permit persons to whom the Software is furnished to do so,
18
+ # subject to the following conditions:
19
+ #
20
+ # The above copyright notice and this permission notice shall be
21
+ # included in all copies or substantial portions of the Software.
22
+ #
23
+ # The Software is provided "AS IS", without warranty of any kind,
24
+ # express or implied, including but not limited to the warranties of
25
+ # merchantability, fitness for a particular purpose and
26
+ # noninfringement. In no event shall the authors or copyright holders
27
+ # be liable for any claim, damages or other liability, whether in an
28
+ # action of contract, tort or otherwise, arising from, out of or in
29
+ # connection with the Software or the use or other dealings in the
30
+ # Software."
31
+ #
32
+
33
+ require 'rencode/decoder'
34
+ require 'rencode/encoder'
35
+
36
+ class REncode
37
+
38
+ def self.parse data
39
+ REncode::Decoder.new(data).parse
40
+ end
41
+
42
+ def self.dump obj
43
+ REncode::Encoder.new.dump(obj)
44
+ end
45
+
46
+ # def self.test
47
+ # f1 = 25.5
48
+ # f2 = 29.3
49
+ # f3 = -0.6
50
+ # L = [
51
+ # [
52
+ # ['a',10**20],
53
+ # [-100000..100000],
54
+ # 'b'*31,
55
+ # 'b'*62,
56
+ # 'b'*64,
57
+ # 2**30,
58
+ # 2**33,
59
+ # 2**62,
60
+ # 2**64,
61
+ # 2**30,
62
+ # 2**33,
63
+ # 2**62,
64
+ # 2**64,
65
+ # false,
66
+ # false,
67
+ # true,
68
+ # -1,
69
+ # 2,
70
+ # 0
71
+ # ],
72
+ # ]
73
+ # test1 = {
74
+ # 'a':15,
75
+ # 'bb':25.5,
76
+ # 'ccc':29.3,
77
+ # '':[ -0.6, [], false, true,'']
78
+ # },
79
+ # raise "Mismatch!" unless parse(dump(test1)) == test1
80
+ # assert loads(dumps(L)) == L
81
+ # d = dict(zip(range(-100000,100000),range(-100000,100000)))
82
+ # d.update({'a':20, 20:40, 40:41, f1:f2, f2:f3, f3:False, False:True, True:False})
83
+ # L = (d, {}, {5:6}, {7:7,True:8}, {9:10, 22:39, 49:50, 44: ''})
84
+ # assert loads(dumps(L)) == L
85
+ # L = ('', 'a'*10, 'a'*100, 'a'*1000, 'a'*10000, 'a'*100000, 'a'*1000000, 'a'*10000000)
86
+ # assert loads(dumps(L)) == L
87
+ # L = tuple([dict(zip(range(n),range(n))) for n in range(100)]) + ('b',)
88
+ # assert loads(dumps(L)) == L
89
+ # L = tuple([dict(zip(range(n),range(-n,0))) for n in range(100)]) + ('b',)
90
+ # assert loads(dumps(L)) == L
91
+ # L = tuple([tuple(range(n)) for n in range(100)]) + ('b',)
92
+ # assert loads(dumps(L)) == L
93
+ # L = tuple(['a'*n for n in range(1000)]) + ('b',)
94
+ # assert loads(dumps(L)) == L
95
+ # L = tuple(['a'*n for n in range(1000)]) + (None,True,None)
96
+ # assert loads(dumps(L)) == L
97
+ # assert loads(dumps(None)) == None
98
+ # assert loads(dumps({None:None})) == {None:None}
99
+ # assert 1e-10<abs(loads(dumps(1.1))-1.1)<1e-6
100
+ # assert 1e-10<abs(loads(dumps(1.1,32))-1.1)<1e-6
101
+ # assert abs(loads(dumps(1.1,64))-1.1)<1e-12
102
+ # assert loads(dumps(u"Hello World!!"))
103
+ # end
104
+
105
+ end
@@ -0,0 +1,47 @@
1
+ module REncodeConstants
2
+ # Default number of bits for serialized floats, either 32 or 64 (also a parameter for dumps()).
3
+ DEFAULT_FLOAT_BITS = 32
4
+
5
+ # Maximum length of integer when written as base 10 string.
6
+ # Ruby has no max integer length
7
+ MAX_INT_LENGTH = 64
8
+
9
+ # The bencode 'typecodes' such as i, d, etc have been extended and
10
+ # relocated on the base-256 character set.
11
+ CHR_LIST = 59
12
+ CHR_DICT = 60
13
+ CHR_INT = 61
14
+ CHR_INT1 = 62
15
+ CHR_INT2 = 63
16
+ CHR_INT4 = 64
17
+ CHR_INT8 = 65
18
+ CHR_FLOAT32 = 66
19
+ CHR_FLOAT64 = 44
20
+ CHR_TRUE = 67
21
+ CHR_FALSE = 68
22
+ CHR_NONE = 69
23
+ CHR_TERM = 127
24
+
25
+ # Dictionaries with length embedded in typecode.
26
+ DICT_FIXED_START = 102
27
+ DICT_FIXED_COUNT = 25
28
+
29
+ # Positive integers with value embedded in typecode.
30
+ INT_POS_FIXED_START = 0
31
+ INT_POS_FIXED_COUNT = 44
32
+
33
+ # Negative integers with value embedded in typecode.
34
+ INT_NEG_FIXED_START = 70
35
+ INT_NEG_FIXED_COUNT = 32
36
+
37
+ # Strings with length embedded in typecode.
38
+ STR_FIXED_START = 128
39
+ STR_FIXED_COUNT = 64
40
+
41
+ # Lists with length embedded in typecode.
42
+ LIST_FIXED_START = STR_FIXED_START+STR_FIXED_COUNT
43
+ LIST_FIXED_COUNT = 64
44
+
45
+ VERSION = '1.0.2'
46
+ ALL = ['dumps', 'loads']
47
+ end
@@ -0,0 +1,162 @@
1
+ require 'rencode/constants'
2
+
3
+ ## a little monkey-patching to add enumerator next-N, where N is a number
4
+ class Enumerator
5
+ def nextn num
6
+ [].tap {|a| num.times {|i| a << send('next') } }
7
+ end
8
+ end
9
+
10
+ class REncode
11
+
12
+ class Decoder
13
+ include REncodeConstants
14
+
15
+ ##
16
+ # Prepare the mapping table
17
+ #
18
+
19
+
20
+ @@mapping_table = Array.new(255)
21
+
22
+ (48..57).each do |i| # '0' to '9'
23
+ @@mapping_table[i] = Proc.new do
24
+ length_str = i.chr
25
+ while (chr=@data.next) != ':'.ord
26
+ length_str << chr.chr
27
+ end
28
+
29
+ if length_str[0] == '0' and length_str.length > 1
30
+ raise "Non-zero string length supplied with initial zero"
31
+ end
32
+
33
+ n = length_str.to_i
34
+ data = @data.nextn(n)
35
+ data.pack('C*')
36
+ end
37
+ end
38
+
39
+ STR_FIXED_COUNT.times do |i|
40
+ @@mapping_table[STR_FIXED_START+i] = Proc.new { @data.nextn(i).pack('C*') } # only ascii for now
41
+ end
42
+
43
+ LIST_FIXED_COUNT.times do |i|
44
+ @@mapping_table[LIST_FIXED_START+i] = Proc.new { Array.new(i) { _parse } }
45
+ end
46
+
47
+ INT_POS_FIXED_COUNT.times do |i|
48
+ @@mapping_table[INT_POS_FIXED_START+i] = Proc.new { i }
49
+ end
50
+
51
+ INT_NEG_FIXED_COUNT.times do |i|
52
+ @@mapping_table[INT_NEG_FIXED_START+i] = Proc.new { -1-i }
53
+ end
54
+
55
+ DICT_FIXED_COUNT.times do |i|
56
+ @@mapping_table[DICT_FIXED_START+i] = Proc.new { {}.tap {|r| i.times {|j| r[_parse] = _parse } } }
57
+ end
58
+
59
+ @@mapping_table[CHR_LIST] = Proc.new do
60
+ r = []
61
+
62
+ while @data.peek != CHR_TERM
63
+ r << _parse
64
+ end
65
+
66
+ @data.next
67
+ r
68
+ end
69
+
70
+ @@mapping_table[CHR_DICT] = Proc.new do
71
+ r = {}
72
+
73
+ while @data.peek != CHR_TERM
74
+ r[_parse] = _parse
75
+ end
76
+
77
+ @data.next
78
+ r
79
+ end
80
+
81
+ @@mapping_table[CHR_INT] = Proc.new do
82
+ num_str = ""
83
+
84
+ while (chr=@data.next) != CHR_TERM
85
+ num_str << chr.chr
86
+ end
87
+
88
+ n = num_str.to_i
89
+
90
+ if num_str[0] == '-'
91
+ if num_str[1] == '0'
92
+ raise "a zero after minus?!"
93
+ end
94
+ elsif num_str[0] == '0' and num_str.length > 1
95
+ raise "A non-zero number started by zero"
96
+ end
97
+
98
+ n
99
+ end
100
+
101
+ @@mapping_table[CHR_INT1] = Proc.new do
102
+ # return (struct.unpack('!b', x[f:f+1])[0], f+1)
103
+ @data.next # python "!b" means 8bit integer, big endian, but what does endianess matter since it's a single byte
104
+ end
105
+
106
+ @@mapping_table[CHR_INT2] = Proc.new do
107
+ # return (struct.unpack('!h', x[f:f+2])[0], f+2)
108
+ @data.nextn(2).pack('C*').unpack('s>')[0]
109
+ end
110
+
111
+ @@mapping_table[CHR_INT4] = Proc.new do
112
+ # return (struct.unpack('!l', x[f:f+4])[0], f+4)
113
+ @data.nextn(4).pack('C*').unpack('l>')[0]
114
+ end
115
+
116
+ @@mapping_table[CHR_INT8] = Proc.new do
117
+ #return (struct.unpack('!q', x[f:f+8])[0], f+8)
118
+ @data.nextn(8).pack('C*').unpack('q>')[0]
119
+ end
120
+
121
+ @@mapping_table[CHR_FLOAT32] = Proc.new do
122
+ #n = struct.unpack('!f', x[f:f+4])[0]
123
+ @data.nextn(4).pack('C*').unpack('g')[0]
124
+ end
125
+
126
+ @@mapping_table[CHR_FLOAT64] = Proc.new do
127
+ #n = struct.unpack('!d', x[f:f+8])[0]
128
+ @data.nextn(8).pack('C*').unpack('G')[0]
129
+ end
130
+
131
+ @@mapping_table[CHR_TRUE] = Proc.new { true}
132
+ @@mapping_table[CHR_FALSE] = Proc.new { false}
133
+ @@mapping_table[CHR_NONE] = Proc.new { nil}
134
+
135
+ #
136
+ # End mapping table
137
+ ##
138
+
139
+ def initialize data, decode_utf8=false
140
+ if data.kind_of?(Array)
141
+ @data = data.each
142
+ elsif data.kind_of?(String)
143
+ @data = data.each_byte
144
+ else
145
+ raise "Bad input argument for data #{data.class}"
146
+ end
147
+ @decode_utf8 = decode_utf8
148
+ end
149
+
150
+ def parse
151
+ _parse
152
+ end
153
+
154
+ private
155
+
156
+ def _parse
157
+ c = @data.next.ord
158
+ instance_eval &@@mapping_table[c]
159
+ end
160
+
161
+ end
162
+ end
@@ -0,0 +1,57 @@
1
+ require 'rencode/constants'
2
+
3
+ class REncode
4
+
5
+ class Encoder
6
+ include REncodeConstants
7
+
8
+ def initialize
9
+ @out = []
10
+ end
11
+
12
+ def dump(obj)
13
+ @out = []
14
+ d(obj)
15
+ @out
16
+ end
17
+
18
+ private
19
+
20
+ # NOTE: Performance-wise, this is a rather lousy implementation. It uses none of the
21
+ # size-optimizations offered by the protocol. Also, doesn't use variable-length numbers,
22
+ # so we're limited to maximum 64bit.
23
+
24
+ def d o
25
+ case o.class.name
26
+ when 'Hash'
27
+ @out << CHR_DICT
28
+ o.each { |k,v| d(k) ; d(v) }
29
+ @out << CHR_TERM
30
+ when 'Fixnum'
31
+ raise "implementation doesn't support such large numbers" if o > 2**31 || o < -1*2**31
32
+ @out << CHR_INT8
33
+ @out.concat [o].pack('q>').bytes
34
+ when 'Float'
35
+ @out << CHR_FLOAT64
36
+ @out.concat [o].pack('G').bytes
37
+ when 'TrueClass'
38
+ @out << CHR_TRUE
39
+ when 'FalseClass'
40
+ @out << CHR_FALSE
41
+ when 'NilClass'
42
+ @out << CHR_NONE
43
+ when 'String'
44
+ bytes = o.bytes
45
+ @out.concat bytes.length.to_s.bytes
46
+ @out << ':'.ord
47
+ @out.concat bytes
48
+ when 'Array'
49
+ @out << CHR_LIST
50
+ o.each { |oo| d(oo) }
51
+ @out << CHR_TERM
52
+ else
53
+ raise "Cannot serialize type #{o.class}"
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,154 @@
1
+ require 'test_helper'
2
+ require 'rencode'
3
+ require 'rencode/constants'
4
+
5
+ class REncodeTest < TestCase
6
+ include REncodeConstants
7
+
8
+ context 'rencode' do
9
+
10
+ setup do
11
+ @it = REncode
12
+ end
13
+
14
+ context 'encode' do
15
+ should 'handle dictionaries' do
16
+ source = { 'a' => 'b' }
17
+ expected = [CHR_DICT, '1'.ord, ':'.ord, 'a'.ord, '1'.ord, ':'.ord, 'b'.ord, CHR_TERM]
18
+
19
+ assert_equal expected, @it.dump(source)
20
+ end
21
+
22
+ should 'handle numbers' do
23
+ assert_equal [CHR_INT8, 0, 0, 0, 0, 0, 0, 0, 0], @it.dump(0)
24
+ assert_equal [CHR_INT8, 0, 0, 0, 0, 0, 0, 0, 1], @it.dump(1)
25
+ assert_equal [CHR_INT8, 255, 255, 255, 255, 255, 255, 255, 255], @it.dump(-1)
26
+ assert_equal [CHR_INT8, 0,0,0,0,0,0,1,0], @it.dump(256)
27
+ @it.dump 2**31
28
+ end
29
+
30
+ should 'fail on too big number' do
31
+ assert_raises RuntimeError do
32
+ @it.dump 2**32
33
+ end
34
+ end
35
+
36
+ should 'handle floats' do
37
+ assert_equal [CHR_FLOAT64, 63,240,0,0,0,0,0,0], @it.dump(1.0)
38
+ end
39
+
40
+ should 'handle boolean' do
41
+ assert_equal [CHR_TRUE], @it.dump(true)
42
+ assert_equal [CHR_FALSE], @it.dump(false)
43
+ end
44
+
45
+ should 'handle nil' do
46
+ assert_equal [CHR_NONE], @it.dump(nil)
47
+ end
48
+
49
+ should 'handle string' do
50
+ assert_equal ['2'.ord, ':'.ord, 'm'.ord, 'e'.ord], @it.dump('me')
51
+ end
52
+
53
+ should 'handle array' do
54
+ assert_equal [CHR_LIST, CHR_TRUE, CHR_TRUE, CHR_TERM], @it.dump([true,true])
55
+ end
56
+
57
+ should 'fail on unrecognized type' do
58
+ assert_raises RuntimeError do
59
+ @it.dump(Object.new)
60
+ end
61
+ end
62
+ end
63
+
64
+ context 'decode' do
65
+ should 'handle dictionaries' do
66
+ source = [CHR_DICT, '1'.ord, ':'.ord, 'a'.ord, '1'.ord, ':'.ord, 'b'.ord, CHR_TERM]
67
+ expected = { 'a' => 'b' }
68
+
69
+ assert_equal expected, @it.parse(source)
70
+ end
71
+
72
+ should 'handle fixed size dictionaries' do
73
+ source = [DICT_FIXED_START+1, '1'.ord, ':'.ord, 'a'.ord, '1'.ord, ':'.ord, 'b'.ord]
74
+ expected = { 'a' => 'b' }
75
+ assert_equal expected, @it.parse(source)
76
+
77
+ assert_equal({}, @it.parse([DICT_FIXED_START+0]))
78
+ end
79
+
80
+ should 'handle int' do
81
+ assert_equal 432678, @it.parse([CHR_INT, '432678'.bytes, CHR_TERM].flatten)
82
+ end
83
+
84
+ should 'handle int1' do
85
+ assert_equal 45, @it.parse([CHR_INT1, 45])
86
+ end
87
+
88
+ should 'handle int2' do
89
+ assert_equal 272, @it.parse([CHR_INT2, 1, 16])
90
+ end
91
+
92
+ should 'handle int4' do
93
+ assert_equal 272, @it.parse([CHR_INT4, 0, 0, 1, 16])
94
+ end
95
+
96
+ should 'handle int8' do
97
+ assert_equal 0, @it.parse([CHR_INT8, 0, 0, 0, 0, 0, 0, 0, 0])
98
+ assert_equal 1, @it.parse([CHR_INT8, 0, 0, 0, 0, 0, 0, 0, 1])
99
+ assert_equal -1, @it.parse([CHR_INT8, 255, 255, 255, 255, 255, 255, 255, 255])
100
+ assert_equal 256, @it.parse([CHR_INT8, 0,0,0,0,0,0,1,0])
101
+ end
102
+
103
+ should 'handle fixed address int' do
104
+ assert_equal 0, @it.parse([INT_POS_FIXED_START+0])
105
+ assert_equal 5, @it.parse([INT_POS_FIXED_START+5])
106
+ assert_equal INT_POS_FIXED_COUNT-1, @it.parse([INT_POS_FIXED_START+INT_POS_FIXED_COUNT-1])
107
+ end
108
+
109
+ should 'handle fixed address negative int' do
110
+ assert_equal -1, @it.parse([INT_NEG_FIXED_START+0])
111
+ assert_equal -7, @it.parse([INT_NEG_FIXED_START+6])
112
+ assert_equal -1-INT_NEG_FIXED_COUNT+1, @it.parse([INT_NEG_FIXED_START+INT_NEG_FIXED_COUNT-1])
113
+ end
114
+
115
+ should 'handle floats' do
116
+ assert_equal 1.0, @it.parse([CHR_FLOAT64, 63,240,0,0,0,0,0,0])
117
+ assert_equal 1.0, @it.parse([CHR_FLOAT32, 63,128,0,0])
118
+ end
119
+
120
+ should 'handle boolean' do
121
+ assert_equal true, @it.parse([CHR_TRUE])
122
+ assert_equal false, @it.parse([CHR_FALSE])
123
+ end
124
+
125
+ should 'handle nil' do
126
+ assert_equal nil, @it.parse([CHR_NONE])
127
+ end
128
+
129
+ should 'handle string' do
130
+ assert_equal 'me', @it.parse(['2'.ord, ':'.ord, 'm'.ord, 'e'.ord])
131
+ end
132
+
133
+ should 'handle fixed-size strings' do
134
+ assert_equal '', @it.parse([STR_FIXED_START+0])
135
+ assert_equal 'a', @it.parse([STR_FIXED_START+1, 'a'.ord])
136
+
137
+ str= 'a'*(STR_FIXED_COUNT-1)
138
+ assert_equal str, @it.parse([STR_FIXED_START+STR_FIXED_COUNT-1].concat(str.bytes))
139
+ end
140
+
141
+ should 'handle array' do
142
+ assert_equal [true, true], @it.parse([CHR_LIST, CHR_TRUE, CHR_TRUE, CHR_TERM])
143
+ end
144
+
145
+ should 'handle fixed-size arrays' do
146
+ assert_equal [], @it.parse([LIST_FIXED_START+0])
147
+ assert_equal [true], @it.parse([LIST_FIXED_START+1, CHR_TRUE])
148
+
149
+ arr = Array.new(LIST_FIXED_COUNT-1, true)
150
+ assert_equal arr, @it.parse([LIST_FIXED_START+LIST_FIXED_COUNT-1].concat(Array.new(LIST_FIXED_COUNT-1, CHR_TRUE)))
151
+ end
152
+ end
153
+ end
154
+ end
@@ -0,0 +1,10 @@
1
+ require 'bundler/setup'
2
+ require 'test/unit'
3
+ require 'turn/autorun'
4
+ require 'shoulda'
5
+
6
+ $LOAD_PATH << 'lib'
7
+
8
+ class TestCase < Test::Unit::TestCase
9
+ end
10
+
metadata ADDED
@@ -0,0 +1,57 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rencode-ruby
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Mikael Wikman
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-05-10 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: This implementation aims to be complient with the Connelly Barnes implementation
14
+ of rencode, version 1.0.2
15
+ email:
16
+ - mikael@wikman.me
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - Gemfile
22
+ - Gemfile.lock
23
+ - LICENSE.txt
24
+ - README.md
25
+ - app.gemspec
26
+ - lib/rencode.rb
27
+ - lib/rencode/constants.rb
28
+ - lib/rencode/decoder.rb
29
+ - lib/rencode/encoder.rb
30
+ - test/rencode_test.rb
31
+ - test/test_helper.rb
32
+ homepage: https://github.com/mikaelwikman/rencode
33
+ licenses: []
34
+ metadata: {}
35
+ post_install_message:
36
+ rdoc_options: []
37
+ require_paths:
38
+ - lib
39
+ required_ruby_version: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ required_rubygems_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ requirements: []
50
+ rubyforge_project:
51
+ rubygems_version: 2.2.2
52
+ signing_key:
53
+ specification_version: 4
54
+ summary: Web safe object serialization
55
+ test_files:
56
+ - test/rencode_test.rb
57
+ - test/test_helper.rb