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/.document +5 -0
- data/.gitignore +25 -0
- data/LICENSE +20 -0
- data/README.rdoc +26 -0
- data/Rakefile +53 -0
- data/TODO +13 -0
- data/VERSION +1 -0
- data/ext/java_bin/ext/extconf.rb +26 -0
- data/ext/java_bin/ext/parser.c +372 -0
- data/ext/java_bin/ext/parser.h +134 -0
- data/fixtures/javabin.dat +0 -0
- data/fixtures/json.dat +55 -0
- data/fixtures/ruby.dat +55 -0
- data/java_bin.gemspec +67 -0
- data/lib/java_bin/ext/.keep +0 -0
- data/lib/java_bin/ext.rb +9 -0
- data/lib/java_bin/pure/parser.rb +219 -0
- data/lib/java_bin/pure.rb +8 -0
- data/lib/java_bin/version.rb +10 -0
- data/lib/java_bin.rb +17 -0
- data/test/helper.rb +10 -0
- data/test/test_java_bin_parser.rb +240 -0
- data/test/xxx_performance.rb +106 -0
- metadata +82 -0
data/.document
ADDED
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 kennyj
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
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 BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
= java_bin
|
2
|
+
|
3
|
+
This is a Solr JavaBin format implementation for Ruby.
|
4
|
+
|
5
|
+
== Note on Patches/Pull Requests
|
6
|
+
|
7
|
+
* Fork the project.
|
8
|
+
* Make your feature addition or bug fix.
|
9
|
+
* Add tests for it. This is important so I don't break it in a
|
10
|
+
future version unintentionally.
|
11
|
+
* Commit, do not mess with rakefile, version, or history.
|
12
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
13
|
+
* Send me a pull request. Bonus points for topic branches.
|
14
|
+
|
15
|
+
=== References
|
16
|
+
|
17
|
+
* http://wiki.apache.org/solr/javabin
|
18
|
+
* http://svn.apache.org/viewvc/lucene/solr/trunk/src/common/org/apache/solr/common/util/JavaBinCodec.java?view=markup
|
19
|
+
|
20
|
+
=== Author
|
21
|
+
|
22
|
+
Toshinori Kajihara <mailto:kennyj@gmail.com>
|
23
|
+
|
24
|
+
== Copyright
|
25
|
+
|
26
|
+
Copyright (c) 2010 kennyj. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "java_bin"
|
8
|
+
gem.summary = %Q{Solr JavaBin format implementation for Ruby.}
|
9
|
+
gem.description = %Q{Solr JavaBin format implementation for Ruby.}
|
10
|
+
gem.email = "kennyj@gmail.com"
|
11
|
+
gem.homepage = "http://github.com/kennyj/java_bin"
|
12
|
+
gem.authors = ["kennyj"]
|
13
|
+
gem.require_paths = ["lib", "ext"]
|
14
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
15
|
+
end
|
16
|
+
Jeweler::GemcutterTasks.new
|
17
|
+
rescue LoadError
|
18
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
19
|
+
end
|
20
|
+
|
21
|
+
require 'rake/testtask'
|
22
|
+
Rake::TestTask.new(:test) do |test|
|
23
|
+
test.libs << 'lib' << 'test'
|
24
|
+
test.pattern = 'test/**/test_*.rb'
|
25
|
+
test.verbose = true
|
26
|
+
end
|
27
|
+
|
28
|
+
begin
|
29
|
+
require 'rcov/rcovtask'
|
30
|
+
Rcov::RcovTask.new do |test|
|
31
|
+
test.libs << 'test'
|
32
|
+
test.pattern = 'test/**/test_*.rb'
|
33
|
+
test.verbose = true
|
34
|
+
end
|
35
|
+
rescue LoadError
|
36
|
+
task :rcov do
|
37
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
task :test => :check_dependencies
|
42
|
+
|
43
|
+
task :default => :test
|
44
|
+
|
45
|
+
require 'rake/rdoctask'
|
46
|
+
Rake::RDocTask.new do |rdoc|
|
47
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
48
|
+
|
49
|
+
rdoc.rdoc_dir = 'rdoc'
|
50
|
+
rdoc.title = "java_bin #{version}"
|
51
|
+
rdoc.rdoc_files.include('README*')
|
52
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
53
|
+
end
|
data/TODO
ADDED
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# vim:fileencoding=utf-8
|
2
|
+
require 'mkmf'
|
3
|
+
require 'rbconfig'
|
4
|
+
|
5
|
+
unless $CFLAGS.gsub!(/ -O[\dsz]?/, ' -O3')
|
6
|
+
$CFLAGS << ' -O3'
|
7
|
+
end
|
8
|
+
if CONFIG['CC'] =~ /gcc/
|
9
|
+
$CFLAGS << ' -Wall'
|
10
|
+
#unless $CFLAGS.gsub!(/ -O[\dsz]?/, ' -O0 -ggdb')
|
11
|
+
# $CFLAGS << ' -O0 -ggdb'
|
12
|
+
#end
|
13
|
+
end
|
14
|
+
|
15
|
+
if RUBY_VERSION >= '1.9'
|
16
|
+
$CFLAGS << ' -DRUBY_19'
|
17
|
+
end
|
18
|
+
|
19
|
+
have_header("endian.h")
|
20
|
+
have_header("byteswap.h")
|
21
|
+
have_header("sys/types.h")
|
22
|
+
|
23
|
+
have_header("ruby.h")
|
24
|
+
have_header("ruby/encoding.h")
|
25
|
+
|
26
|
+
create_makefile("parser")
|
@@ -0,0 +1,372 @@
|
|
1
|
+
/* utf-8 */
|
2
|
+
#include "parser.h"
|
3
|
+
|
4
|
+
/*
|
5
|
+
* variables
|
6
|
+
*/
|
7
|
+
static VALUE rb_mJavaBin;
|
8
|
+
static VALUE rb_mExt;
|
9
|
+
static VALUE rb_cParser;
|
10
|
+
|
11
|
+
static ID i_At; // Time#at用
|
12
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
13
|
+
static rb_encoding* rb_encUtf8;
|
14
|
+
#endif
|
15
|
+
|
16
|
+
/*
|
17
|
+
* javabinフォーマット読み込み関数群
|
18
|
+
*/
|
19
|
+
|
20
|
+
static int32_t JavaBinParser_read_v_int(JAVA_BIN_PARSER* ptr) {
|
21
|
+
unsigned char byte;
|
22
|
+
int32_t result;
|
23
|
+
int shift;
|
24
|
+
byte = _getbyte(ptr);
|
25
|
+
result = byte & 0x7f;
|
26
|
+
for(shift = 7; (byte & 0x80) != 0; shift += 7) {
|
27
|
+
byte = _getbyte(ptr);
|
28
|
+
result |= (((int32_t)(byte & 0x7f)) << shift);
|
29
|
+
}
|
30
|
+
return result;
|
31
|
+
}
|
32
|
+
|
33
|
+
static int64_t JavaBinParser_read_v_long(JAVA_BIN_PARSER* ptr) {
|
34
|
+
unsigned char byte;
|
35
|
+
int64_t result;
|
36
|
+
int shift;
|
37
|
+
byte = _getbyte(ptr);
|
38
|
+
result = byte & 0x7f;
|
39
|
+
for(shift = 7; (byte & 0x80) != 0; shift += 7) {
|
40
|
+
byte = _getbyte(ptr);
|
41
|
+
result |= (((int64_t)(byte & 0x7f)) << shift);
|
42
|
+
}
|
43
|
+
return result;
|
44
|
+
}
|
45
|
+
|
46
|
+
static int JavaBinParser_read_size(JAVA_BIN_PARSER* ptr) {
|
47
|
+
int size;
|
48
|
+
size = (ptr->tag_byte & 0x1f);
|
49
|
+
if (size == 0x1f) {
|
50
|
+
size += JavaBinParser_read_v_int(ptr);
|
51
|
+
}
|
52
|
+
return size;
|
53
|
+
}
|
54
|
+
|
55
|
+
static VALUE JavaBinParser_read_small_int(JAVA_BIN_PARSER* ptr) {
|
56
|
+
int32_t result;
|
57
|
+
result = ptr->tag_byte & 0x0f;
|
58
|
+
if ((ptr->tag_byte & 0x10) != 0) {
|
59
|
+
result = ((JavaBinParser_read_v_int(ptr) << 4) | result);
|
60
|
+
}
|
61
|
+
return INT2NUM(result);
|
62
|
+
}
|
63
|
+
|
64
|
+
static VALUE JavaBinParser_read_small_long(JAVA_BIN_PARSER* ptr) {
|
65
|
+
int64_t result;
|
66
|
+
result = ptr->tag_byte & 0x0f;
|
67
|
+
if ((ptr->tag_byte & 0x10) != 0) {
|
68
|
+
result = ((JavaBinParser_read_v_long(ptr) << 4) | result);
|
69
|
+
}
|
70
|
+
return LL2NUM(result);
|
71
|
+
}
|
72
|
+
|
73
|
+
static VALUE JavaBinParser_read_string(JAVA_BIN_PARSER* ptr) {
|
74
|
+
int size;
|
75
|
+
int i;
|
76
|
+
|
77
|
+
unsigned char b;
|
78
|
+
|
79
|
+
size = JavaBinParser_read_size(ptr);
|
80
|
+
ptr->last_string_offset = ptr->current;
|
81
|
+
for (i = 0; i < size; i++) {
|
82
|
+
/* HINT. read utf-8 char */
|
83
|
+
b = _getbyte(ptr);
|
84
|
+
if ((b & 0x80) == 0) {
|
85
|
+
} else if ((b & 0xE0) == 0xC0) {
|
86
|
+
_skipbytes(ptr, 1);
|
87
|
+
} else {
|
88
|
+
_skipbytes(ptr, 2);
|
89
|
+
} /* TODO 4byte以上のケース? */
|
90
|
+
}
|
91
|
+
ptr->last_string_len = ptr->current - ptr->last_string_offset;
|
92
|
+
return _utf8_string((const char*) &ptr->data[ptr->last_string_offset], ptr->last_string_len);
|
93
|
+
}
|
94
|
+
|
95
|
+
static VALUE JavaBinParser_read_byte(JAVA_BIN_PARSER* ptr) {
|
96
|
+
int8_t c;
|
97
|
+
c = _readnumeric(ptr, c);
|
98
|
+
return INT2NUM(*((int8_t*)&c));
|
99
|
+
}
|
100
|
+
|
101
|
+
static VALUE JavaBinParser_read_short(JAVA_BIN_PARSER* ptr) {
|
102
|
+
u_int16_t c;
|
103
|
+
c = _readnumeric(ptr, c);
|
104
|
+
c = _swap_16(c);
|
105
|
+
return INT2NUM(*((int16_t*)&c));
|
106
|
+
}
|
107
|
+
|
108
|
+
static VALUE JavaBinParser_read_int(JAVA_BIN_PARSER* ptr) {
|
109
|
+
u_int32_t c;
|
110
|
+
c = _readnumeric(ptr, c);
|
111
|
+
c = _swap_32(c);
|
112
|
+
return INT2NUM(*((int32_t*)&c));
|
113
|
+
}
|
114
|
+
|
115
|
+
static VALUE JavaBinParser_read_long(JAVA_BIN_PARSER* ptr) {
|
116
|
+
u_int64_t c;
|
117
|
+
c = _readnumeric(ptr, c);
|
118
|
+
c = _swap_64(c);
|
119
|
+
return LL2NUM(*((int64_t*)&c));
|
120
|
+
}
|
121
|
+
|
122
|
+
static VALUE JavaBinParser_read_date(JAVA_BIN_PARSER* ptr) {
|
123
|
+
u_int64_t c;
|
124
|
+
c = _readnumeric(ptr, c);
|
125
|
+
c = _swap_64(c);
|
126
|
+
return rb_funcall(rb_cTime, i_At, 1, ULL2NUM(*((int64_t*)&c) / 1000));
|
127
|
+
}
|
128
|
+
|
129
|
+
static VALUE JavaBinParser_read_float(JAVA_BIN_PARSER* ptr) {
|
130
|
+
u_int32_t c;
|
131
|
+
c = _readnumeric(ptr, c);
|
132
|
+
c = _swap_32(c);
|
133
|
+
return rb_float_new((double)*((float*)&c));
|
134
|
+
}
|
135
|
+
|
136
|
+
static VALUE JavaBinParser_read_double(JAVA_BIN_PARSER* ptr) {
|
137
|
+
u_int64_t c;
|
138
|
+
c = _readnumeric(ptr, c);
|
139
|
+
c = _swap_64(c);
|
140
|
+
return rb_float_new(*((double*)&c));
|
141
|
+
}
|
142
|
+
|
143
|
+
static VALUE JavaBinParser_read_val(JAVA_BIN_PARSER* ptr) {
|
144
|
+
int size;
|
145
|
+
int i;
|
146
|
+
VALUE key;
|
147
|
+
VALUE value;
|
148
|
+
VALUE array;
|
149
|
+
VALUE hash;
|
150
|
+
|
151
|
+
ptr->tag_byte = _getbyte(ptr);
|
152
|
+
switch (ptr->tag_byte >> 5) { /* unsignedなので論理シフト */
|
153
|
+
case SHIFTED_STR:
|
154
|
+
return JavaBinParser_read_string(ptr);
|
155
|
+
case SHIFTED_ARR:
|
156
|
+
size = JavaBinParser_read_size(ptr);
|
157
|
+
array = rb_ary_new();
|
158
|
+
for (i = 0; i < size; i++) {
|
159
|
+
value = JavaBinParser_read_val(ptr);
|
160
|
+
rb_ary_push(array, value);
|
161
|
+
}
|
162
|
+
return array;
|
163
|
+
case SHIFTED_EXTERN_STRING:
|
164
|
+
size = JavaBinParser_read_size(ptr);
|
165
|
+
if(size == 0) {
|
166
|
+
/* rubyの文字列 */
|
167
|
+
value = JavaBinParser_read_val(ptr);
|
168
|
+
|
169
|
+
/* 参照文字列としてcの文字列を保持 */
|
170
|
+
ptr->cache[ptr->cache_index].offset = ptr->last_string_offset;
|
171
|
+
ptr->cache[ptr->cache_index].len = ptr->last_string_len;
|
172
|
+
ptr->cache_index ++;
|
173
|
+
/* 参照文字列用のcacheを拡張する */
|
174
|
+
if (ptr->cache_size <= ptr->cache_index) {
|
175
|
+
JavaBinParser_extend_cache(ptr);
|
176
|
+
}
|
177
|
+
return value;
|
178
|
+
} else {
|
179
|
+
return _utf8_string((const char*)&ptr->data[ptr->cache[size - 1].offset], ptr->cache[size - 1].len);
|
180
|
+
}
|
181
|
+
case SHIFTED_ORDERED_MAP:
|
182
|
+
case SHIFTED_NAMED_LST:
|
183
|
+
size = JavaBinParser_read_size(ptr);
|
184
|
+
hash = rb_hash_new();
|
185
|
+
for (i = 0; i < size; i++) {
|
186
|
+
key = JavaBinParser_read_val(ptr);
|
187
|
+
value = JavaBinParser_read_val(ptr);
|
188
|
+
rb_hash_aset(hash, key, value);
|
189
|
+
}
|
190
|
+
return hash;
|
191
|
+
case SHIFTED_SINT:
|
192
|
+
return JavaBinParser_read_small_int(ptr);
|
193
|
+
case SHIFTED_SLONG:
|
194
|
+
return JavaBinParser_read_small_long(ptr);
|
195
|
+
}
|
196
|
+
|
197
|
+
switch(ptr->tag_byte) {
|
198
|
+
case BYTE:
|
199
|
+
return JavaBinParser_read_byte(ptr);
|
200
|
+
case SHORT:
|
201
|
+
return JavaBinParser_read_short(ptr);
|
202
|
+
case DOUBLE:
|
203
|
+
return JavaBinParser_read_double(ptr);
|
204
|
+
case INT:
|
205
|
+
return JavaBinParser_read_int(ptr);
|
206
|
+
case LONG:
|
207
|
+
return JavaBinParser_read_long(ptr);
|
208
|
+
case FLOAT:
|
209
|
+
return JavaBinParser_read_float(ptr);
|
210
|
+
case DATE:
|
211
|
+
return JavaBinParser_read_date(ptr);
|
212
|
+
case BYTEARR:
|
213
|
+
size = JavaBinParser_read_v_int(ptr);
|
214
|
+
array = rb_ary_new();
|
215
|
+
for (i = 0; i < size; i++) {
|
216
|
+
rb_ary_push(array, INT2FIX(_getbyte(ptr)));
|
217
|
+
}
|
218
|
+
return array;
|
219
|
+
case NULL_MARK:
|
220
|
+
return Qnil;
|
221
|
+
case BOOL_TRUE:
|
222
|
+
return Qtrue;
|
223
|
+
case BOOL_FALSE:
|
224
|
+
return Qfalse;
|
225
|
+
case MAP:
|
226
|
+
size = JavaBinParser_read_v_int(ptr);
|
227
|
+
hash = rb_hash_new();
|
228
|
+
for (i = 0; i < size; i++) {
|
229
|
+
key = JavaBinParser_read_val(ptr);
|
230
|
+
value = JavaBinParser_read_val(ptr);
|
231
|
+
rb_hash_aset(hash, key, value);
|
232
|
+
}
|
233
|
+
return hash;
|
234
|
+
case ITERATOR:
|
235
|
+
array = rb_ary_new();
|
236
|
+
while (1) {
|
237
|
+
value = JavaBinParser_read_val(ptr);
|
238
|
+
if (value == END_OBJ) {
|
239
|
+
break;
|
240
|
+
}
|
241
|
+
rb_ary_push(array, value);
|
242
|
+
}
|
243
|
+
return array;
|
244
|
+
case END:
|
245
|
+
return END_OBJ;
|
246
|
+
case SOLRDOC:
|
247
|
+
return JavaBinParser_read_val(ptr);
|
248
|
+
case SOLRDOCLST:
|
249
|
+
hash = rb_hash_new();
|
250
|
+
value = JavaBinParser_read_val(ptr);
|
251
|
+
rb_hash_aset(hash, rb_str_new2("numFound"), rb_ary_entry(value, 0));
|
252
|
+
rb_hash_aset(hash, rb_str_new2("start"), rb_ary_entry(value, 1));
|
253
|
+
rb_hash_aset(hash, rb_str_new2("maxScore"), rb_ary_entry(value, 2));
|
254
|
+
rb_hash_aset(hash, rb_str_new2("docs"), JavaBinParser_read_val(ptr));
|
255
|
+
return hash;
|
256
|
+
default:
|
257
|
+
rb_raise(rb_eRuntimeError, "JavaBinParser_read_val - unknown tag type");
|
258
|
+
}
|
259
|
+
}
|
260
|
+
|
261
|
+
static void JavaBinParser_free(JAVA_BIN_PARSER* ptr) {
|
262
|
+
if (ptr) {
|
263
|
+
// free(ptr->data);
|
264
|
+
free(ptr->cache);
|
265
|
+
free(ptr);
|
266
|
+
}
|
267
|
+
}
|
268
|
+
|
269
|
+
static VALUE JavaBinParser_alloc(VALUE klass) {
|
270
|
+
return Data_Wrap_Struct(klass, 0, JavaBinParser_free, NULL);
|
271
|
+
}
|
272
|
+
|
273
|
+
static void JavaBinParser_extend_cache(JAVA_BIN_PARSER* ptr) {
|
274
|
+
_EXTERN_STRING_INFO* newP;
|
275
|
+
int next_size;
|
276
|
+
if (ptr->cache == NULL) {
|
277
|
+
next_size = 64;
|
278
|
+
} else {
|
279
|
+
next_size = ptr->cache_size * 2;
|
280
|
+
}
|
281
|
+
|
282
|
+
newP = (_EXTERN_STRING_INFO*) malloc(next_size * sizeof(_EXTERN_STRING_INFO));
|
283
|
+
if (!newP) {
|
284
|
+
rb_raise(rb_eRuntimeError, "JavaBinParser_extend_cache - allocate error");
|
285
|
+
}
|
286
|
+
|
287
|
+
if (ptr->cache) {
|
288
|
+
memcpy(newP, ptr->cache, sizeof(_EXTERN_STRING_INFO) * ptr->cache_size);
|
289
|
+
}
|
290
|
+
ptr->cache = newP;
|
291
|
+
ptr->cache_size = next_size;
|
292
|
+
}
|
293
|
+
|
294
|
+
/*
|
295
|
+
* rubyメソッド
|
296
|
+
*/
|
297
|
+
static VALUE rb_cParser_parse(VALUE self, VALUE data) {
|
298
|
+
JAVA_BIN_PARSER* ptr;
|
299
|
+
char* ptrData;
|
300
|
+
int dataLen;
|
301
|
+
|
302
|
+
Data_Get_Struct(self, JAVA_BIN_PARSER, ptr);
|
303
|
+
|
304
|
+
/* 引数処理 */
|
305
|
+
SafeStringValue(data);
|
306
|
+
ptrData = RSTRING_PTR(data);
|
307
|
+
dataLen = RSTRING_LEN(data);
|
308
|
+
|
309
|
+
/* 引数チェック */
|
310
|
+
if (ptrData == NULL || dataLen == 0) {
|
311
|
+
rb_raise(rb_eRuntimeError, "rb_cParser_parse - data is empty.");
|
312
|
+
}
|
313
|
+
|
314
|
+
// ptr->data = (unsigned char*) malloc(dataLen);
|
315
|
+
// if (!ptr->data) {
|
316
|
+
// rb_raise(rb_eRuntimeError, "rb_cParser_parse - allocate error");
|
317
|
+
// }
|
318
|
+
// memcpy(ptr->data, ptrData, dataLen);
|
319
|
+
ptr->data = (unsigned char*)ptrData;
|
320
|
+
ptr->data_len = dataLen;
|
321
|
+
|
322
|
+
/* version check */
|
323
|
+
if (ptr->data[0] != 0x01) {
|
324
|
+
rb_raise(rb_eRuntimeError, "rb_cParser_parse - not supported version");
|
325
|
+
}
|
326
|
+
|
327
|
+
ptr->current = 1; /* VERSIONをとばした */
|
328
|
+
ptr->tag_byte = 0;
|
329
|
+
|
330
|
+
/* 参照文字列の準備 */
|
331
|
+
ptr->cache = NULL;
|
332
|
+
ptr->cache_index = 0;
|
333
|
+
JavaBinParser_extend_cache(ptr);
|
334
|
+
|
335
|
+
return JavaBinParser_read_val(ptr);
|
336
|
+
}
|
337
|
+
|
338
|
+
static VALUE rb_cParser_initialize(VALUE self) {
|
339
|
+
JAVA_BIN_PARSER* ptr;
|
340
|
+
|
341
|
+
/* データの初期化 */
|
342
|
+
ptr = (JAVA_BIN_PARSER*) malloc(sizeof(JAVA_BIN_PARSER));
|
343
|
+
if (!ptr) {
|
344
|
+
rb_raise(rb_eRuntimeError, "rb_cParser_initialize - allocate error");
|
345
|
+
}
|
346
|
+
DATA_PTR(self) = ptr;
|
347
|
+
|
348
|
+
return self;
|
349
|
+
}
|
350
|
+
|
351
|
+
/*
|
352
|
+
* エントリーポイント
|
353
|
+
*/
|
354
|
+
void Init_parser(void) {
|
355
|
+
i_At = rb_intern("at");
|
356
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
357
|
+
rb_encUtf8 = rb_utf8_encoding();
|
358
|
+
#endif
|
359
|
+
|
360
|
+
/* クラス定義 */
|
361
|
+
rb_mJavaBin = rb_define_module("JavaBin");
|
362
|
+
rb_mExt = rb_define_module_under(rb_mJavaBin, "Ext");
|
363
|
+
rb_cParser = rb_define_class_under(rb_mExt, "Parser", rb_cObject);
|
364
|
+
|
365
|
+
/* メモリーアロケーター設定 */
|
366
|
+
rb_define_alloc_func(rb_cParser, JavaBinParser_alloc);
|
367
|
+
/* コンストラクタ */
|
368
|
+
rb_define_method(rb_cParser, "initialize", rb_cParser_initialize, 0);
|
369
|
+
/* parseメソッド*/
|
370
|
+
rb_define_method(rb_cParser, "parse", rb_cParser_parse, 1);
|
371
|
+
}
|
372
|
+
|
@@ -0,0 +1,134 @@
|
|
1
|
+
/* utf-8 */
|
2
|
+
#ifndef _PARSER_H_
|
3
|
+
#define _PARSER_H_
|
4
|
+
|
5
|
+
#include "ruby.h"
|
6
|
+
|
7
|
+
#if HAVE_ENDIAN_H
|
8
|
+
#include <endian.h>
|
9
|
+
#endif /* HAVE_ENDIAN_H */
|
10
|
+
|
11
|
+
#if HAVE_BYTESWAP_H
|
12
|
+
#include <byteswap.h>
|
13
|
+
#endif /* HAVE_BYTESWAP_H */
|
14
|
+
|
15
|
+
#if HAVE_SYS_TYPES_H
|
16
|
+
#include <sys/types.h>
|
17
|
+
#endif /* HAVE_SYS_TYPES_H */
|
18
|
+
|
19
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
20
|
+
#include <ruby/encoding.h>
|
21
|
+
#endif /* HAVE_RUBY_ENCODING_H */
|
22
|
+
|
23
|
+
/*
|
24
|
+
* javabin constants
|
25
|
+
*/
|
26
|
+
#define NULL_MARK 0
|
27
|
+
#define BOOL_TRUE 1
|
28
|
+
#define BOOL_FALSE 2
|
29
|
+
#define BYTE 3
|
30
|
+
#define SHORT 4
|
31
|
+
#define DOUBLE 5
|
32
|
+
#define INT 6
|
33
|
+
#define LONG 7
|
34
|
+
#define FLOAT 8
|
35
|
+
#define DATE 9
|
36
|
+
#define MAP 10
|
37
|
+
#define SOLRDOC 11
|
38
|
+
#define SOLRDOCLST 12
|
39
|
+
#define BYTEARR 13
|
40
|
+
#define ITERATOR 14
|
41
|
+
#define END 15
|
42
|
+
/*#define TAG_AND_LEN (1U << 5)*/
|
43
|
+
#define STR (1U << 5)
|
44
|
+
#define SINT (2U << 5)
|
45
|
+
#define SLONG (3U << 5)
|
46
|
+
#define ARR (4U << 5)
|
47
|
+
#define ORDERED_MAP (5U << 5)
|
48
|
+
#define NAMED_LST (6U << 5)
|
49
|
+
#define EXTERN_STRING (7U << 5)
|
50
|
+
|
51
|
+
/* HINT. 終端判定用オブジェクト */
|
52
|
+
#define END_OBJ ((int) NULL)
|
53
|
+
|
54
|
+
/* HINT. 先に計算しておく(unsignedなので論理シフト) */
|
55
|
+
#define SHIFTED_STR (STR >> 5)
|
56
|
+
#define SHIFTED_ARR (ARR >> 5)
|
57
|
+
#define SHIFTED_EXTERN_STRING (EXTERN_STRING >> 5)
|
58
|
+
#define SHIFTED_ORDERED_MAP (ORDERED_MAP >> 5)
|
59
|
+
#define SHIFTED_NAMED_LST (NAMED_LST >> 5)
|
60
|
+
#define SHIFTED_SINT (SINT >> 5)
|
61
|
+
#define SHIFTED_SLONG (SLONG >> 5)
|
62
|
+
|
63
|
+
/*
|
64
|
+
* 参照文字列情報保持用
|
65
|
+
*/
|
66
|
+
typedef struct _extern_string_info {
|
67
|
+
int offset;
|
68
|
+
int len;
|
69
|
+
} _EXTERN_STRING_INFO;
|
70
|
+
|
71
|
+
/*
|
72
|
+
* 読込処理データ保持構造体
|
73
|
+
*/
|
74
|
+
typedef struct java_bin_reader {
|
75
|
+
unsigned char* data;
|
76
|
+
int data_len;
|
77
|
+
int current;
|
78
|
+
unsigned char tag_byte;
|
79
|
+
|
80
|
+
/* 外部文字列用 */
|
81
|
+
_EXTERN_STRING_INFO* cache;
|
82
|
+
int cache_size;
|
83
|
+
int cache_index;
|
84
|
+
int last_string_offset;
|
85
|
+
int last_string_len;
|
86
|
+
|
87
|
+
} JAVA_BIN_PARSER;
|
88
|
+
|
89
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
90
|
+
#define _utf8_string(str, len) (rb_enc_str_new(str, len, rb_encUtf8))
|
91
|
+
#else
|
92
|
+
#define _utf8_string(str, len) (rb_str_new(str, len))
|
93
|
+
#endif
|
94
|
+
|
95
|
+
#define _getbyte(ptr) (ptr->data[ptr->current++])
|
96
|
+
#define _skipbytes(ptr, x) ((ptr->current) += (x))
|
97
|
+
#define _readnumeric(ptr, c) \
|
98
|
+
({ u_int8_t* p; \
|
99
|
+
p = (void*)&c; \
|
100
|
+
memcpy(p, &ptr->data[ptr->current], sizeof(c)); \
|
101
|
+
_skipbytes(ptr, sizeof(c)); c; \
|
102
|
+
})
|
103
|
+
|
104
|
+
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
105
|
+
#define _swap_16(o) bswap_16(o)
|
106
|
+
#define _swap_32(o) bswap_32(o)
|
107
|
+
#define _swap_64(o) bswap_64(o)
|
108
|
+
#else
|
109
|
+
#define _swap_16(o) (o)
|
110
|
+
#define _swap_32(o) (o)
|
111
|
+
#define _swap_64(o) (o)
|
112
|
+
#endif
|
113
|
+
|
114
|
+
static int32_t JavaBinParser_read_v_int(JAVA_BIN_PARSER* ptr);
|
115
|
+
static int64_t JavaBinParser_read_v_long(JAVA_BIN_PARSER* ptr);
|
116
|
+
static int JavaBinParser_read_size(JAVA_BIN_PARSER* ptr);
|
117
|
+
static VALUE JavaBinParser_read_small_int(JAVA_BIN_PARSER* ptr);
|
118
|
+
static VALUE JavaBinParser_read_small_long(JAVA_BIN_PARSER* ptr);
|
119
|
+
static VALUE JavaBinParser_read_string(JAVA_BIN_PARSER* ptr);
|
120
|
+
static VALUE JavaBinParser_read_byte(JAVA_BIN_PARSER* ptr);
|
121
|
+
static VALUE JavaBinParser_read_short(JAVA_BIN_PARSER* ptr);
|
122
|
+
static VALUE JavaBinParser_read_int(JAVA_BIN_PARSER* ptr);
|
123
|
+
static VALUE JavaBinParser_read_long(JAVA_BIN_PARSER* ptr);
|
124
|
+
static VALUE JavaBinParser_read_date(JAVA_BIN_PARSER* ptr);
|
125
|
+
static VALUE JavaBinParser_read_float(JAVA_BIN_PARSER* ptr);
|
126
|
+
static VALUE JavaBinParser_read_double(JAVA_BIN_PARSER* ptr);
|
127
|
+
static VALUE JavaBinParser_read_val(JAVA_BIN_PARSER* ptr);
|
128
|
+
static void JavaBinParser_free(JAVA_BIN_PARSER* ptr);
|
129
|
+
static VALUE JavaBinParser_alloc(VALUE klass);
|
130
|
+
static void JavaBinParser_extend_cache(JAVA_BIN_PARSER* ptr);
|
131
|
+
static VALUE rb_cParser_parse(VALUE self, VALUE data);
|
132
|
+
static VALUE rb_cParser_initialize(VALUE self);
|
133
|
+
|
134
|
+
#endif /* _PARSER_H_ */
|
Binary file
|