java_bin 0.1.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.
data/fixtures/json.dat ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "responseHeader":{
3
+ "status":0,
4
+ "QTime":0,
5
+ "params":{
6
+ "explainOther":"",
7
+ "fl":"*,score",
8
+ "indent":"on",
9
+ "start":"0",
10
+ "q":"software",
11
+ "hl.fl":"",
12
+ "qt":"standard",
13
+ "wt":"json",
14
+ "fq":"",
15
+ "version":"2.2",
16
+ "rows":"10"}},
17
+ "response":{"numFound":2,"start":0,"maxScore":0.6288448,"docs":[
18
+ {
19
+ "id":"UTF8TEST",
20
+ "name":"Test with some UTF-8 encoded characters",
21
+ "manu":"Apache Software Foundation",
22
+ "price":0.0,
23
+ "inStock":true,
24
+ "cat":[
25
+ "software",
26
+ "search"],
27
+ "features":[
28
+ "No accents here",
29
+ "This is an e acute: é",
30
+ "eaiou with circumflexes: êâîôû",
31
+ "eaiou with umlauts: ëäïöü",
32
+ "tag with escaped chars: <nicetag/>",
33
+ "escaped ampersand: Bonnie & Clyde"],
34
+ "score":0.6288448},
35
+ {
36
+ "id":"SOLR1000",
37
+ "name":"Solr, the Enterprise Search Server",
38
+ "manu":"Apache Software Foundation",
39
+ "price":0.0,
40
+ "popularity":10,
41
+ "inStock":true,
42
+ "incubationdate_dt":"2006-01-17T00:00:00Z",
43
+ "cat":[
44
+ "software",
45
+ "search"],
46
+ "features":[
47
+ "Advanced Full-Text Search Capabilities using Lucene",
48
+ "Optimized for High Volume Web Traffic",
49
+ "Standards Based Open Interfaces - XML and HTTP",
50
+ "Comprehensive HTML Administration Interfaces",
51
+ "Scalability - Efficient Replication to other Solr Search Servers",
52
+ "Flexible and Adaptable with XML configuration and Schema",
53
+ "Good unicode support: héllo (hello with an accent over the e)"],
54
+ "score":0.50307584}]
55
+ }}
data/fixtures/ruby.dat ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ 'responseHeader'=>{
3
+ 'status'=>0,
4
+ 'QTime'=>0,
5
+ 'params'=>{
6
+ 'explainOther'=>'',
7
+ 'fl'=>'*,score',
8
+ 'indent'=>'on',
9
+ 'start'=>'0',
10
+ 'q'=>'software',
11
+ 'hl.fl'=>'',
12
+ 'qt'=>'standard',
13
+ 'wt'=>'ruby',
14
+ 'fq'=>'',
15
+ 'version'=>'2.2',
16
+ 'rows'=>'10'}},
17
+ 'response'=>{'numFound'=>2,'start'=>0,'maxScore'=>0.6288448,'docs'=>[
18
+ {
19
+ 'id'=>'UTF8TEST',
20
+ 'name'=>'Test with some UTF-8 encoded characters',
21
+ 'manu'=>'Apache Software Foundation',
22
+ 'price'=>0.0,
23
+ 'inStock'=>true,
24
+ 'cat'=>[
25
+ 'software',
26
+ 'search'],
27
+ 'features'=>[
28
+ 'No accents here',
29
+ 'This is an e acute: é',
30
+ 'eaiou with circumflexes: êâîôû',
31
+ 'eaiou with umlauts: ëäïöü',
32
+ 'tag with escaped chars: <nicetag/>',
33
+ 'escaped ampersand: Bonnie & Clyde'],
34
+ 'score'=>0.6288448},
35
+ {
36
+ 'id'=>'SOLR1000',
37
+ 'name'=>'Solr, the Enterprise Search Server',
38
+ 'manu'=>'Apache Software Foundation',
39
+ 'price'=>0.0,
40
+ 'popularity'=>10,
41
+ 'inStock'=>true,
42
+ 'incubationdate_dt'=>'2006-01-17T00:00:00Z',
43
+ 'cat'=>[
44
+ 'software',
45
+ 'search'],
46
+ 'features'=>[
47
+ 'Advanced Full-Text Search Capabilities using Lucene',
48
+ 'Optimized for High Volume Web Traffic',
49
+ 'Standards Based Open Interfaces - XML and HTTP',
50
+ 'Comprehensive HTML Administration Interfaces',
51
+ 'Scalability - Efficient Replication to other Solr Search Servers',
52
+ 'Flexible and Adaptable with XML configuration and Schema',
53
+ 'Good unicode support: héllo (hello with an accent over the e)'],
54
+ 'score'=>0.50307584}]
55
+ }}
data/java_bin.gemspec ADDED
@@ -0,0 +1,67 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{java_bin}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["kennyj"]
12
+ s.date = %q{2010-01-11}
13
+ s.description = %q{Solr JavaBin format implementation for Ruby.}
14
+ s.email = %q{kennyj@gmail.com}
15
+ s.extensions = ["ext/java_bin/ext/extconf.rb"]
16
+ s.extra_rdoc_files = [
17
+ "LICENSE",
18
+ "README.rdoc",
19
+ "TODO"
20
+ ]
21
+ s.files = [
22
+ ".document",
23
+ ".gitignore",
24
+ "LICENSE",
25
+ "README.rdoc",
26
+ "Rakefile",
27
+ "TODO",
28
+ "VERSION",
29
+ "ext/java_bin/ext/extconf.rb",
30
+ "ext/java_bin/ext/parser.c",
31
+ "ext/java_bin/ext/parser.h",
32
+ "fixtures/javabin.dat",
33
+ "fixtures/json.dat",
34
+ "fixtures/ruby.dat",
35
+ "java_bin.gemspec",
36
+ "lib/java_bin.rb",
37
+ "lib/java_bin/ext.rb",
38
+ "lib/java_bin/ext/.keep",
39
+ "lib/java_bin/pure.rb",
40
+ "lib/java_bin/pure/parser.rb",
41
+ "lib/java_bin/version.rb",
42
+ "test/helper.rb",
43
+ "test/test_java_bin_parser.rb",
44
+ "test/xxx_performance.rb"
45
+ ]
46
+ s.homepage = %q{http://github.com/kennyj/java_bin}
47
+ s.rdoc_options = ["--charset=UTF-8"]
48
+ s.require_paths = ["lib", "ext"]
49
+ s.rubygems_version = %q{1.3.5}
50
+ s.summary = %q{Solr JavaBin format implementation for Ruby.}
51
+ s.test_files = [
52
+ "test/xxx_performance.rb",
53
+ "test/test_java_bin_parser.rb",
54
+ "test/helper.rb"
55
+ ]
56
+
57
+ if s.respond_to? :specification_version then
58
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
59
+ s.specification_version = 3
60
+
61
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
62
+ else
63
+ end
64
+ else
65
+ end
66
+ end
67
+
File without changes
@@ -0,0 +1,9 @@
1
+ # vim:fileencoding=utf-8
2
+ module JavaBin
3
+ module Ext
4
+ require 'java_bin/ext/parser'
5
+ #require 'parser'
6
+ $DEBUG and warn "Using c extension for JavaBin."
7
+ ::JavaBin.parser = ::JavaBin::Ext::Parser
8
+ end
9
+ end
@@ -0,0 +1,219 @@
1
+ # vim:fileencoding=utf-8
2
+ module JavaBin
3
+ module Pure
4
+ NULL = 0
5
+ BOOL_TRUE = 1
6
+ BOOL_FALSE = 2
7
+ BYTE = 3
8
+ SHORT = 4
9
+ DOUBLE = 5
10
+ INT = 6
11
+ LONG = 7
12
+ FLOAT = 8
13
+ DATE = 9
14
+ MAP = 10
15
+ SOLRDOC = 11
16
+ SOLRDOCLST = 12
17
+ BYTEARR = 13
18
+ ITERATOR = 14
19
+ TERM = 15 #END = 15
20
+
21
+ #TAG_AND_LEN = (1 << 5)
22
+ STR = (1 << 5)
23
+ SINT = (2 << 5)
24
+ SLONG = (3 << 5)
25
+ ARR = (4 << 5)
26
+ ORDERED_MAP = (5 << 5)
27
+ NAMED_LST = (6 << 5)
28
+ EXTERN_STRING = (7 << 5)
29
+
30
+ # TODO 論理シフト
31
+ SHIFTED_STR = STR >> 5
32
+ SHIFTED_ARR = ARR >> 5
33
+ SHIFTED_EXTERN_STRING = EXTERN_STRING >> 5
34
+ SHIFTED_ORDERED_MAP = ORDERED_MAP >> 5
35
+ SHIFTED_NAMED_LST = NAMED_LST >> 5
36
+ SHIFTED_SINT = SINT >> 5
37
+ SHIFTED_SLONG = SLONG >> 5
38
+
39
+ VERSION = 1
40
+ TERM_OBJ = :term_obj
41
+
42
+ class Parser
43
+
44
+ attr_reader :tag_byte, :input, :current
45
+
46
+ def initialize
47
+ end
48
+
49
+ def parse(input)
50
+ array = input.bytes.to_a
51
+ check_version(array[0])
52
+ @input = array
53
+ @current = 1 # HINT VERSIONをとばす
54
+ @tag_byte = nil
55
+ read_val
56
+ end
57
+
58
+ private
59
+ def check_version(byte)
60
+ return true if VERSION == byte
61
+ raise "unsupported version #{byte}"
62
+ end
63
+
64
+ def getbyte
65
+ ret = @input[@current]
66
+ @current += 1
67
+ ret
68
+ end
69
+
70
+ def getbytes(size)
71
+ ret = @input[@current...(@current + size)]
72
+ @current += size
73
+ ret
74
+ end
75
+
76
+ def read_val
77
+ @tag_byte = getbyte
78
+ case (@tag_byte >> 5) # TODO 論理シフト
79
+ when SHIFTED_STR
80
+ return read_chars
81
+ when SHIFTED_ARR
82
+ size = read_size
83
+ array = Array.new(size)
84
+ size.times { |i| array[i] = read_val }
85
+ return array
86
+ when SHIFTED_EXTERN_STRING
87
+ size = read_size
88
+ if size == 0
89
+ str = read_val
90
+ @exts ||= []
91
+ @exts << str
92
+ return str
93
+ else
94
+ return @exts[size - 1].dup
95
+ end
96
+ when SHIFTED_ORDERED_MAP, SHIFTED_NAMED_LST
97
+ size = read_size
98
+ hash = {}
99
+ size.times do
100
+ k = read_val
101
+ v = read_val
102
+ hash[k] = v
103
+ end
104
+ return hash
105
+ when SHIFTED_SINT
106
+ return read_small_int
107
+ when SHIFTED_SLONG
108
+ return read_small_int
109
+ end
110
+
111
+ case @tag_byte
112
+ when NULL
113
+ return nil
114
+ when BOOL_TRUE
115
+ return true
116
+ when BOOL_FALSE
117
+ return false
118
+ when BYTE
119
+ return getbytes(1).pack("C*").unpack("c")[0]
120
+ when SHORT
121
+ return getbytes(2).reverse.pack("C*").unpack("s")[0]
122
+ when DOUBLE
123
+ return getbytes(8).pack("C*").unpack("G")[0]
124
+ when INT
125
+ return getbytes(4).reverse.pack("C*").unpack("i")[0]
126
+ when LONG
127
+ return getbytes(8).reverse.pack("C*").unpack("q")[0]
128
+ when FLOAT
129
+ return getbytes(4).pack("C*").unpack("g")[0]
130
+ when DATE
131
+ x = getbytes(8).reverse.pack("C*").unpack("q")[0]
132
+ return Time.at(x/1000)
133
+ when MAP
134
+ size = read_v_int
135
+ hash = {}
136
+ size.times do
137
+ k = read_val
138
+ v = read_val
139
+ hash[k] = v
140
+ end
141
+ return hash
142
+ when BYTEARR
143
+ size = read_v_int
144
+ return getbytes(size)
145
+ when ITERATOR
146
+ array = []
147
+ while true
148
+ i = read_val
149
+ break if i == TERM_OBJ
150
+ array << i
151
+ end
152
+ return array
153
+ when TERM
154
+ return TERM_OBJ
155
+ when SOLRDOC
156
+ return read_val
157
+ when SOLRDOCLST
158
+ result = {}
159
+ list = read_val
160
+ result['numFound'] = list[0]
161
+ result['start'] = list[1]
162
+ result['maxScore'] = list[2]
163
+ result['docs'] = read_val
164
+ return result
165
+ end
166
+ end
167
+
168
+ def read_v_int
169
+ byte = getbyte
170
+ result = byte & 0x7f
171
+ shift = 7
172
+ while (byte & 0x80) != 0
173
+ byte = getbyte
174
+ result |= ((byte & 0x7f) << shift)
175
+ shift += 7
176
+ end
177
+ result
178
+ end
179
+
180
+ def read_size
181
+ size = (@tag_byte & 0x1f)
182
+ size += read_v_int if (size == 0x1f)
183
+ size
184
+ end
185
+
186
+ def read_small_int
187
+ result = @tag_byte & 0x0F
188
+ result = ((read_v_int << 4) | result) if ((@tag_byte & 0x10) != 0)
189
+ result
190
+ end
191
+
192
+ def read_chars
193
+ size = read_size
194
+ str = ''
195
+ size.times {
196
+ # HINT. read utf-8 char
197
+ b = getbyte
198
+ if ((b & 0x80) == 0)
199
+ str << b
200
+ elsif ((b & 0xE0) == 0xC0)
201
+ #str << (((b & 0x1F) << 6) | (getbyte & 0x3F))
202
+ str << b
203
+ str << getbyte
204
+ else
205
+ #str << (((b & 0x0F) << 12) | ((getbyte & 0x3F) << 6) | (getbyte & 0x3F))
206
+ str << b
207
+ str << getbyte
208
+ str << getbyte
209
+ end
210
+ }
211
+ str.force_encoding('utf-8') if str.respond_to? :force_encoding
212
+ str
213
+ end
214
+
215
+ end
216
+
217
+ end
218
+ end
219
+
@@ -0,0 +1,8 @@
1
+ # vim:fileencoding=utf-8
2
+ module JavaBin
3
+ module Pure
4
+ require 'java_bin/pure/parser'
5
+ $DEBUG and warn "Using pure for JavaBin."
6
+ ::JavaBin.parser = ::JavaBin::Pure::Parser
7
+ end
8
+ end
@@ -0,0 +1,10 @@
1
+ # vim:fileencoding=utf-8
2
+ module JavaBin
3
+ # JavaBin version
4
+ VERSION = '0.1.0'
5
+ VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc:
6
+ VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
7
+ VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
8
+ VERSION_BUILD = VERSION_ARRAY[2] # :nodoc:
9
+ end
10
+
data/lib/java_bin.rb ADDED
@@ -0,0 +1,17 @@
1
+ # vim:fileencoding=utf-8
2
+ module JavaBin
3
+ def self.parser=(value)
4
+ @parser = value
5
+ end
6
+ def self.parser
7
+ @parser
8
+ end
9
+
10
+ require 'java_bin/version'
11
+ begin
12
+ require 'java_bin/ext'
13
+ rescue LoadError => e
14
+ require 'java_bin/pure'
15
+ end
16
+
17
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,10 @@
1
+ # vim:fileencoding=utf-8
2
+ require 'rubygems'
3
+ require 'test/unit'
4
+
5
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
6
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
7
+ require 'java_bin'
8
+
9
+ class Test::Unit::TestCase
10
+ end
@@ -0,0 +1,240 @@
1
+ # vim:fileencoding=utf-8
2
+ require 'helper'
3
+
4
+ case ENV['JavaBin']
5
+ when 'pure'
6
+ then
7
+ require 'java_bin/pure'
8
+ else
9
+ require 'java_bin/ext'
10
+ end
11
+
12
+ class TestJavaBin < Test::Unit::TestCase
13
+
14
+ private
15
+ def write_v_int(i, output)
16
+ while ((i & ~0x7F) != 0)
17
+ output.putc(((i & 0x7f) | 0x80))
18
+ # i >>>= 7
19
+ i = (i >> 7) # TODO 論理シフト
20
+ end
21
+ output.putc(i)
22
+ end
23
+
24
+ def write_tag(tag, size, output)
25
+ if ((tag & 0xe0) != 0)
26
+ if (size < 0x1f)
27
+ output.putc(tag | size)
28
+ else
29
+ output.putc(tag | 0x1f)
30
+ write_v_int(size - 0x1f, output)
31
+ end
32
+ else
33
+ output.putc(tag)
34
+ write_v_int(size, output)
35
+ end
36
+ end
37
+
38
+ def elapsed_time(name, t, &block)
39
+ GC.start
40
+ s = Time.now
41
+ t.times {
42
+ block.call
43
+ }
44
+ e = Time.now
45
+ puts "#{name}#{t} times. elapsed time #{e - s}"
46
+ (e - s)
47
+ end
48
+
49
+ public
50
+ def setup
51
+ @parser = JavaBin.parser.new
52
+ end
53
+
54
+ def test_valid_version
55
+ assert @parser.parse([1, 1].pack("C*"))
56
+ end
57
+ def test_invalid_version
58
+ assert_raise(RuntimeError) { @parser.parse([2].pack("C*")) }
59
+ end
60
+
61
+ def test_javabin_dat
62
+ result = @parser.parse(open("fixtures/javabin.dat", "r:utf-8").read)
63
+ assert result['response']['docs'][0]['features'].include?('eaiou with umlauts: ëäïöü')
64
+ assert_equal result['response']['docs'][1]['incubationdate_dt'], Time.local(2006, 1, 17, 9, 0, 0)
65
+ assert_equal result['response']['docs'][1]['score'], 0.5030758380889893
66
+ end
67
+
68
+ TIMES = 5000
69
+ def test_javabin_parse_and_ruby_eval
70
+ jb = open("fixtures/javabin.dat", "r:utf-8").read
71
+ r = open("fixtures/ruby.dat", "r:utf-8").read
72
+ puts ""
73
+ r_et = elapsed_time("ruby eval parse. ", TIMES) { eval(r) }
74
+ jb_et = elapsed_time("javabin parse. ", TIMES) { @parser.parse(jb) }
75
+ assert (jb_et * 3) < r_et if @parser.is_a? JavaBin::Ext::Parser
76
+ end
77
+
78
+ def test_null
79
+ assert_nil @parser.parse([1, 0].pack("C*"))
80
+ end
81
+
82
+ def test_true
83
+ assert @parser.parse([1, 1].pack("C*"))
84
+ end
85
+
86
+ def test_false
87
+ assert !@parser.parse([1, 2].pack("C*"))
88
+ end
89
+
90
+ def test_byte
91
+ assert_equal 1, @parser.parse([1, 3, 0x01].pack("C*"))
92
+ assert_equal 127, @parser.parse([1, 3, 0x7f].pack("C*"))
93
+ assert_equal -1, @parser.parse([1, 3, 0xff].pack("C*"))
94
+ assert_equal -2, @parser.parse([1, 3, 0xfe].pack("C*"))
95
+ end
96
+
97
+ def test_short
98
+ assert_equal 1, @parser.parse([1, 4, 0x00, 0x01].pack("C*"))
99
+ assert_equal 32767, @parser.parse([1, 4, 0x7f, 0xff].pack("C*"))
100
+ assert_equal -1, @parser.parse([1, 4, 0xff, 0xff].pack("C*"))
101
+ assert_equal -2, @parser.parse([1, 4, 0xff, 0xfe].pack("C*"))
102
+ end
103
+
104
+ def test_double
105
+ assert_equal -1.0, @parser.parse([1, 5, -1.0].pack("C2G"))
106
+ end
107
+
108
+ def test_int
109
+ assert_equal 1, @parser.parse([1, 6, 0x00, 0x00, 0x00, 0x01].pack("C*"))
110
+ assert_equal 2147483647, @parser.parse([1, 6, 0x7f, 0xff, 0xff, 0xff].pack("C*"))
111
+ assert_equal -1, @parser.parse([1, 6, 0xff, 0xff, 0xff, 0xff].pack("C*"))
112
+ assert_equal -2, @parser.parse([1, 6, 0xff, 0xff, 0xff, 0xfe].pack("C*"))
113
+ end
114
+
115
+ def test_long
116
+ assert_equal 1, @parser.parse([1, 7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01].pack("C*"))
117
+ assert_equal 9223372036854775807 , @parser.parse([1, 7, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff].pack("C*"))
118
+ assert_equal -1, @parser.parse([1, 7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff].pack("C*"))
119
+ assert_equal -2, @parser.parse([1, 7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe].pack("C*"))
120
+ end
121
+
122
+ def test_float
123
+ assert_equal -1.0, @parser.parse([1, 8, -1.0].pack("C2g"))
124
+ end
125
+
126
+ def test_date
127
+ t = Time.now
128
+ x = (t.to_f * 1000).to_i
129
+ x = [x].pack("q").unpack("C*").reverse # TODO endian次第なので修正必要
130
+ assert_equal t.to_i, @parser.parse(([1, 9] + x).pack("C*")).to_i
131
+ end
132
+
133
+ def test_map
134
+ assert_equal({0 => 0, 1 => 1}, @parser.parse([1, 10, 2, 3, 0, 3, 0, 3, 1, 3, 1].pack("C*")))
135
+ end
136
+
137
+ def test_solrdoc
138
+ arr = [1, 11] + [(5 << 5) | 2] + [(1 << 5) | 1] + "a".unpack("C*") + [3, 8] + [(1 << 5) | 1] + "b".unpack("C*") + [3, 9]
139
+ assert_equal({"a" => 8, "b" => 9}, @parser.parse(arr.pack("C*")))
140
+ end
141
+
142
+ def test_solrdoclst
143
+ arr = [1, 12] + [(4 << 5) | 3, 3, 3, 3, 4, 3, 5] + [(4 << 5) | 0]
144
+ assert_equal({'numFound' => 3, 'start' => 4, 'maxScore' => 5, 'docs' => []}, @parser.parse(arr.pack("C*")))
145
+ end
146
+
147
+ def test_bytearr
148
+ array = [0, 1, 0xff]
149
+ assert_equal array, @parser.parse([1, 13, array.size, *array].pack("C*"))
150
+ end
151
+
152
+ def test_large_bytearr
153
+ array = [0,1,255] * 100
154
+ sio = StringIO.new
155
+ sio.putc 1 #VERSION
156
+ sio.putc 13 #JavaBin::BYTEARR
157
+ write_v_int(array.size, sio)
158
+ array.each { |e| sio.putc e }
159
+ sio.pos = 0
160
+ assert_equal array, @parser.parse(sio.read)
161
+ end
162
+
163
+ def test_iterator
164
+ assert_equal([0, 127, nil, true], @parser.parse([1, 14, 3, 0, 3, 127, 0, 1,15].pack("C*")))
165
+ end
166
+
167
+ # def test_term
168
+ # end
169
+
170
+ def test_string
171
+ assert_equal "あい", @parser.parse(([1, (1 << 5) | 2] + "あい".unpack("C*")).pack("C*"))
172
+ end
173
+
174
+ def test_long_string
175
+ str = "0123456789" * 100
176
+ sio = StringIO.new
177
+ sio.putc 1 #VERSION
178
+ write_tag(1 << 5, str.size, sio)
179
+ str.each_byte { |e| sio.putc e }
180
+ sio.pos = 0
181
+ assert_equal str, @parser.parse(sio.read)
182
+ end
183
+
184
+ def test_sint
185
+ assert_equal 8, @parser.parse([1, (2 << 5) | 8].pack("C*"))
186
+ # flunk("not implemented yet.")
187
+ end
188
+
189
+ def test_slong
190
+ assert_equal 8, @parser.parse([1, (3 << 5) | 8].pack("C*"))
191
+ # flunk("not implemented yet.")
192
+ end
193
+
194
+ def test_arr
195
+ assert_equal [3, 4], @parser.parse([1, (4 << 5) | 2, 3, 3, 3, 4].pack("C*"))
196
+ end
197
+
198
+ def test_large_arr
199
+ array = [0, 1, 2, 3, 4] * 100
200
+ sio = StringIO.new
201
+ sio.putc 1 #VERSION
202
+ write_tag(4 << 5, array.size, sio)
203
+ array.each { |e| sio.putc 3; sio.putc e }
204
+ sio.pos = 0
205
+ assert_equal array, @parser.parse(sio.read)
206
+ end
207
+
208
+ def test_ordered_map
209
+ arr = [1, (5 << 5) | 2] + [(1 << 5) | 1] + "a".unpack("C*") + [3, 8] + [(1 << 5) | 1] + "b".unpack("C*") + [3, 9]
210
+ assert_equal({"a" => 8, "b" => 9}, @parser.parse(arr.pack("C*")))
211
+ end
212
+
213
+ # def test_named_lst
214
+ # end
215
+
216
+ def test_extern_string
217
+ arr = [1, (5 << 5) | 2] +
218
+ [(1 << 5) | 1] + "a".unpack("C*") +
219
+ [(7 << 5) | 0] + [(1 << 5) | 3] + "あいa".unpack("C*") +
220
+ [(1 << 5) | 1] + "b".unpack("C*") +
221
+ [(7 << 5) | 1]
222
+ assert_equal({"a" => "あいa", "b" => "あいa"}, @parser.parse(arr.pack("C*")))
223
+ end
224
+
225
+ LARGE_SIZE = 1000
226
+ def test_long_large_amount_extern_string
227
+ sio = StringIO.new
228
+ sio.putc 1 #VERSION
229
+ write_tag(4 << 5, LARGE_SIZE, sio)
230
+ LARGE_SIZE.times { |i|
231
+ sio.putc((7 << 5) | 0)
232
+ sio.putc((1 << 5) | 1)
233
+ sio.putc("a")
234
+ write_tag((7 << 5), i, sio)
235
+ }
236
+ sio.pos = 0
237
+ assert_equal ['a'] * LARGE_SIZE, @parser.parse(sio.read)
238
+ end
239
+
240
+ end