rencode-ruby 1.0.0

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.
@@ -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