bert 1.1.2-java

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,72 @@
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{bert}
8
+ s.version = "1.1.2"
9
+ s.platform = %q{java}
10
+
11
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
+ s.authors = ["Tom Preston-Werner"]
13
+ s.date = %q{2010-04-03}
14
+ s.description = %q{BERT Serializiation for Ruby}
15
+ s.email = %q{tom@mojombo.com}
16
+ s.extra_rdoc_files = [
17
+ "LICENSE",
18
+ "README.md"
19
+ ]
20
+ s.files = [
21
+ ".document",
22
+ ".gitignore",
23
+ "History.txt",
24
+ "LICENSE",
25
+ "README.md",
26
+ "Rakefile",
27
+ "VERSION",
28
+ "bench/bench.rb",
29
+ "bench/decode_bench.rb",
30
+ "bench/encode_bench.rb",
31
+ "bench/results.txt",
32
+ "bert.gemspec",
33
+ "ext/bert/c/decode.c",
34
+ "ext/bert/c/extconf.rb",
35
+ "lib/bert.rb",
36
+ "lib/bert/bert.rb",
37
+ "lib/bert/decode.rb",
38
+ "lib/bert/decoder.rb",
39
+ "lib/bert/encode.rb",
40
+ "lib/bert/encoder.rb",
41
+ "lib/bert/types.rb",
42
+ "test/bert_test.rb",
43
+ "test/decoder_test.rb",
44
+ "test/encoder_test.rb",
45
+ "test/test_helper.rb"
46
+ ]
47
+ s.homepage = %q{http://github.com/mojombo/bert}
48
+ s.rdoc_options = ["--charset=UTF-8"]
49
+ s.require_paths = ["lib"]
50
+ s.rubygems_version = %q{1.3.5}
51
+ s.summary = %q{BERT Serializiation for Ruby}
52
+ s.test_files = [
53
+ "test/bert_test.rb",
54
+ "test/decoder_test.rb",
55
+ "test/encoder_test.rb",
56
+ "test/test_helper.rb"
57
+ ]
58
+
59
+ if s.respond_to? :specification_version then
60
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
61
+ s.specification_version = 3
62
+
63
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
64
+ s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
65
+ else
66
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
67
+ end
68
+ else
69
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
70
+ end
71
+ end
72
+
@@ -0,0 +1,438 @@
1
+ #include "ruby.h"
2
+ #include <string.h>
3
+
4
+ #define ERL_VERSION 131
5
+ #define ERL_SMALL_INT 97
6
+ #define ERL_INT 98
7
+ #define ERL_SMALL_BIGNUM 110
8
+ #define ERL_LARGE_BIGNUM 111
9
+ #define ERL_FLOAT 99
10
+ #define ERL_ATOM 100
11
+ #define ERL_SMALL_TUPLE 104
12
+ #define ERL_LARGE_TUPLE 105
13
+ #define ERL_NIL 106
14
+ #define ERL_STRING 107
15
+ #define ERL_LIST 108
16
+ #define ERL_BIN 109
17
+
18
+ static VALUE mBERT;
19
+ static VALUE cDecode;
20
+ static VALUE cTuple;
21
+ void Init_decode();
22
+
23
+ VALUE method_decode(VALUE klass, VALUE rString);
24
+
25
+ VALUE read_any_raw(unsigned char **pData);
26
+
27
+ // printers
28
+
29
+ void p(VALUE val) {
30
+ rb_funcall(rb_mKernel, rb_intern("p"), 1, val);
31
+ }
32
+
33
+ // checkers
34
+
35
+ void check_int(int num) {
36
+ char buf[17];
37
+ sprintf(buf, "%u", num);
38
+ rb_raise(rb_eStandardError, buf);
39
+ }
40
+
41
+ void check_str(char *str) {
42
+ rb_raise(rb_eStandardError, str);
43
+ }
44
+
45
+ // string peekers/readers
46
+
47
+ unsigned int peek_1(unsigned char **pData) {
48
+ return (unsigned int) **pData;
49
+ }
50
+
51
+ unsigned int peek_2(unsigned char **pData) {
52
+ return (unsigned int) ((**pData << 8) + *(*pData + 1));
53
+ }
54
+
55
+ unsigned int peek_4(unsigned char **pData) {
56
+ return (unsigned int) ((**pData << 24) + (*(*pData + 1) << 16) + (*(*pData + 2) << 8) + *(*pData + 3));
57
+ }
58
+
59
+ unsigned int read_1(unsigned char **pData) {
60
+ unsigned int val = peek_1(pData);
61
+ *pData += 1;
62
+ return val;
63
+ }
64
+
65
+ unsigned int read_2(unsigned char **pData) {
66
+ unsigned int val = peek_2(pData);
67
+ *pData += 2;
68
+ return val;
69
+ }
70
+
71
+ unsigned int read_4(unsigned char **pData) {
72
+ unsigned int val = peek_4(pData);
73
+ *pData += 4;
74
+ return val;
75
+ }
76
+
77
+ // tuples
78
+
79
+ VALUE read_tuple(unsigned char **pData, unsigned int arity);
80
+
81
+ VALUE read_dict_pair(unsigned char **pData) {
82
+ if(read_1(pData) != ERL_SMALL_TUPLE) {
83
+ rb_raise(rb_eStandardError, "Invalid dict pair, not a small tuple");
84
+ }
85
+
86
+ int arity = read_1(pData);
87
+
88
+ if(arity != 2) {
89
+ rb_raise(rb_eStandardError, "Invalid dict pair, not a 2-tuple");
90
+ }
91
+
92
+ return read_tuple(pData, arity);
93
+ }
94
+
95
+ VALUE read_dict(unsigned char **pData) {
96
+ int type = read_1(pData);
97
+ if(!(type == ERL_LIST || type == ERL_NIL)) {
98
+ rb_raise(rb_eStandardError, "Invalid dict spec, not an erlang list");
99
+ }
100
+
101
+ unsigned int length = 0;
102
+ if(type == ERL_LIST) {
103
+ length = read_4(pData);
104
+ }
105
+
106
+ VALUE cHash = rb_const_get(rb_cObject, rb_intern("Hash"));
107
+ VALUE hash = rb_funcall(cHash, rb_intern("new"), 0);
108
+
109
+ int i;
110
+ for(i = 0; i < length; ++i) {
111
+ VALUE pair = read_dict_pair(pData);
112
+ VALUE first = rb_ary_entry(pair, 0);
113
+ VALUE last = rb_ary_entry(pair, 1);
114
+ rb_funcall(hash, rb_intern("store"), 2, first, last);
115
+ }
116
+
117
+ if(type == ERL_LIST) {
118
+ read_1(pData);
119
+ }
120
+
121
+ return hash;
122
+ }
123
+
124
+ VALUE read_complex_type(unsigned char **pData, int arity) {
125
+ VALUE type = read_any_raw(pData);
126
+ ID id = SYM2ID(type);
127
+ if(id == rb_intern("nil")) {
128
+ return Qnil;
129
+ } else if(id == rb_intern("true")) {
130
+ return Qtrue;
131
+ } else if(id == rb_intern("false")) {
132
+ return Qfalse;
133
+ } else if(id == rb_intern("time")) {
134
+ VALUE megasecs = read_any_raw(pData);
135
+ VALUE msecs = rb_funcall(megasecs, rb_intern("*"), 1, INT2NUM(1000000));
136
+ VALUE secs = read_any_raw(pData);
137
+ VALUE microsecs = read_any_raw(pData);
138
+ VALUE stamp = rb_funcall(msecs, rb_intern("+"), 1, secs);
139
+ return rb_funcall(rb_cTime, rb_intern("at"), 2, stamp, microsecs);
140
+ } else if(id == rb_intern("regex")) {
141
+ VALUE source = read_any_raw(pData);
142
+ VALUE opts = read_any_raw(pData);
143
+ int flags = 0;
144
+ if(rb_ary_includes(opts, ID2SYM(rb_intern("caseless"))))
145
+ flags = flags | 1;
146
+ if(rb_ary_includes(opts, ID2SYM(rb_intern("extended"))))
147
+ flags = flags | 2;
148
+ if(rb_ary_includes(opts, ID2SYM(rb_intern("multiline"))))
149
+ flags = flags | 4;
150
+ return rb_funcall(rb_cRegexp, rb_intern("new"), 2, source, INT2NUM(flags));
151
+ } else if(id == rb_intern("dict")) {
152
+ return read_dict(pData);
153
+ } else {
154
+ return Qnil;
155
+ }
156
+ }
157
+
158
+ VALUE read_tuple(unsigned char **pData, unsigned int arity) {
159
+ if(arity > 0) {
160
+ VALUE tag = read_any_raw(pData);
161
+ if(SYM2ID(tag) == rb_intern("bert")) {
162
+ return read_complex_type(pData, arity);
163
+ } else {
164
+ VALUE tuple = rb_funcall(cTuple, rb_intern("new"), 1, INT2NUM(arity));
165
+ rb_ary_store(tuple, 0, tag);
166
+ int i;
167
+ for(i = 1; i < arity; ++i) {
168
+ rb_ary_store(tuple, i, read_any_raw(pData));
169
+ }
170
+ return tuple;
171
+ }
172
+ } else {
173
+ return rb_funcall(cTuple, rb_intern("new"), 0);
174
+ }
175
+ }
176
+
177
+ VALUE read_small_tuple(unsigned char **pData) {
178
+ if(read_1(pData) != ERL_SMALL_TUPLE) {
179
+ rb_raise(rb_eStandardError, "Invalid Type, not a small tuple");
180
+ }
181
+
182
+ int arity = read_1(pData);
183
+ return read_tuple(pData, arity);
184
+ }
185
+
186
+ VALUE read_large_tuple(unsigned char **pData) {
187
+ if(read_1(pData) != ERL_LARGE_TUPLE) {
188
+ rb_raise(rb_eStandardError, "Invalid Type, not a large tuple");
189
+ }
190
+
191
+ unsigned int arity = read_4(pData);
192
+ return read_tuple(pData, arity);
193
+ }
194
+
195
+ // lists
196
+
197
+ VALUE read_list(unsigned char **pData) {
198
+ if(read_1(pData) != ERL_LIST) {
199
+ rb_raise(rb_eStandardError, "Invalid Type, not an erlang list");
200
+ }
201
+
202
+ unsigned int size = read_4(pData);
203
+
204
+ VALUE array = rb_ary_new2(size);
205
+
206
+ int i;
207
+ for(i = 0; i < size; ++i) {
208
+ rb_ary_store(array, i, read_any_raw(pData));
209
+ }
210
+
211
+ read_1(pData);
212
+
213
+ return array;
214
+ }
215
+
216
+ // primitives
217
+
218
+ void read_string_raw(unsigned char *dest, unsigned char **pData, unsigned int length) {
219
+ memcpy((char *) dest, (char *) *pData, length);
220
+ *(dest + length) = (unsigned char) 0;
221
+ *pData += length;
222
+ }
223
+
224
+ VALUE read_bin(unsigned char **pData) {
225
+ if(read_1(pData) != ERL_BIN) {
226
+ rb_raise(rb_eStandardError, "Invalid Type, not an erlang binary");
227
+ }
228
+
229
+ unsigned int length = read_4(pData);
230
+
231
+ VALUE rStr = rb_str_new((char *) *pData, length);
232
+ *pData += length;
233
+
234
+ return rStr;
235
+ }
236
+
237
+ VALUE read_string(unsigned char **pData) {
238
+ if(read_1(pData) != ERL_STRING) {
239
+ rb_raise(rb_eStandardError, "Invalid Type, not an erlang string");
240
+ }
241
+
242
+ int length = read_2(pData);
243
+ VALUE array = rb_ary_new2(length);
244
+
245
+ int i = 0;
246
+ for(i; i < length; ++i) {
247
+ rb_ary_store(array, i, INT2NUM(**pData));
248
+ *pData += 1;
249
+ }
250
+
251
+ return array;
252
+ }
253
+
254
+ VALUE read_atom(unsigned char **pData) {
255
+ if(read_1(pData) != ERL_ATOM) {
256
+ rb_raise(rb_eStandardError, "Invalid Type, not an atom");
257
+ }
258
+
259
+ int length = read_2(pData);
260
+
261
+ unsigned char buf[length + 1];
262
+ read_string_raw(buf, pData, length);
263
+
264
+ return ID2SYM(rb_intern((char *) buf));
265
+ }
266
+
267
+ VALUE read_small_int(unsigned char **pData) {
268
+ if(read_1(pData) != ERL_SMALL_INT) {
269
+ rb_raise(rb_eStandardError, "Invalid Type, not a small int");
270
+ }
271
+
272
+ int value = read_1(pData);
273
+
274
+ return INT2FIX(value);
275
+ }
276
+
277
+ VALUE read_int(unsigned char **pData) {
278
+ if(read_1(pData) != ERL_INT) {
279
+ rb_raise(rb_eStandardError, "Invalid Type, not an int");
280
+ }
281
+
282
+ long long value = read_4(pData);
283
+
284
+ long long negative = ((value >> 31) & 0x1 == 1);
285
+
286
+ if(negative) {
287
+ value = (value - ((long long) 1 << 32));
288
+ }
289
+
290
+ return INT2FIX(value);
291
+ }
292
+
293
+ VALUE read_small_bignum(unsigned char **pData) {
294
+ if(read_1(pData) != ERL_SMALL_BIGNUM) {
295
+ rb_raise(rb_eStandardError, "Invalid Type, not a small bignum");
296
+ }
297
+
298
+ unsigned int size = read_1(pData);
299
+ unsigned int sign = read_1(pData);
300
+
301
+ VALUE num = INT2NUM(0);
302
+ VALUE tmp;
303
+
304
+ unsigned char buf[size + 1];
305
+ read_string_raw(buf, pData, size);
306
+
307
+ int i;
308
+ for(i = 0; i < size; ++i) {
309
+ tmp = INT2FIX(*(buf + i));
310
+ tmp = rb_funcall(tmp, rb_intern("<<"), 1, INT2NUM(i * 8));
311
+ num = rb_funcall(num, rb_intern("+"), 1, tmp);
312
+ }
313
+
314
+ if(sign) {
315
+ num = rb_funcall(num, rb_intern("*"), 1, INT2NUM(-1));
316
+ }
317
+
318
+ return num;
319
+ }
320
+
321
+ VALUE read_large_bignum(unsigned char **pData) {
322
+ if(read_1(pData) != ERL_LARGE_BIGNUM) {
323
+ rb_raise(rb_eStandardError, "Invalid Type, not a small bignum");
324
+ }
325
+
326
+ unsigned int size = read_4(pData);
327
+ unsigned int sign = read_1(pData);
328
+
329
+ VALUE num = INT2NUM(0);
330
+ VALUE tmp;
331
+
332
+ unsigned char buf[size + 1];
333
+ read_string_raw(buf, pData, size);
334
+
335
+ int i;
336
+ for(i = 0; i < size; ++i) {
337
+ tmp = INT2FIX(*(buf + i));
338
+ tmp = rb_funcall(tmp, rb_intern("<<"), 1, INT2NUM(i * 8));
339
+
340
+ num = rb_funcall(num, rb_intern("+"), 1, tmp);
341
+ }
342
+
343
+ if(sign) {
344
+ num = rb_funcall(num, rb_intern("*"), 1, INT2NUM(-1));
345
+ }
346
+
347
+ return num;
348
+ }
349
+
350
+ VALUE read_float(unsigned char **pData) {
351
+ if(read_1(pData) != ERL_FLOAT) {
352
+ rb_raise(rb_eStandardError, "Invalid Type, not a float");
353
+ }
354
+
355
+ unsigned char buf[32];
356
+ read_string_raw(buf, pData, 31);
357
+
358
+ VALUE rString = rb_str_new2((char *) buf);
359
+
360
+ return rb_funcall(rString, rb_intern("to_f"), 0);
361
+ }
362
+
363
+ VALUE read_nil(unsigned char **pData) {
364
+ if(read_1(pData) != ERL_NIL) {
365
+ rb_raise(rb_eStandardError, "Invalid Type, not a nil list");
366
+ }
367
+
368
+ return rb_ary_new2(0);
369
+ }
370
+
371
+ // read_any_raw
372
+
373
+ VALUE read_any_raw(unsigned char **pData) {
374
+ switch(peek_1(pData)) {
375
+ case ERL_SMALL_INT:
376
+ return read_small_int(pData);
377
+ break;
378
+ case ERL_INT:
379
+ return read_int(pData);
380
+ break;
381
+ case ERL_FLOAT:
382
+ return read_float(pData);
383
+ break;
384
+ case ERL_ATOM:
385
+ return read_atom(pData);
386
+ break;
387
+ case ERL_SMALL_TUPLE:
388
+ return read_small_tuple(pData);
389
+ break;
390
+ case ERL_LARGE_TUPLE:
391
+ return read_large_tuple(pData);
392
+ break;
393
+ case ERL_NIL:
394
+ return read_nil(pData);
395
+ break;
396
+ case ERL_STRING:
397
+ return read_string(pData);
398
+ break;
399
+ case ERL_LIST:
400
+ return read_list(pData);
401
+ break;
402
+ case ERL_BIN:
403
+ return read_bin(pData);
404
+ break;
405
+ case ERL_SMALL_BIGNUM:
406
+ return read_small_bignum(pData);
407
+ break;
408
+ case ERL_LARGE_BIGNUM:
409
+ return read_large_bignum(pData);
410
+ break;
411
+ }
412
+ return Qnil;
413
+ }
414
+
415
+ VALUE method_decode(VALUE klass, VALUE rString) {
416
+ unsigned char *data = (unsigned char *) StringValuePtr(rString);
417
+
418
+ unsigned char **pData = &data;
419
+
420
+ // check protocol version
421
+ if(read_1(pData) != ERL_VERSION) {
422
+ rb_raise(rb_eStandardError, "Bad Magic");
423
+ }
424
+
425
+ return read_any_raw(pData);
426
+ }
427
+
428
+ VALUE method_impl(VALUE klass) {
429
+ return rb_str_new("C", 1);
430
+ }
431
+
432
+ void Init_decode() {
433
+ mBERT = rb_const_get(rb_cObject, rb_intern("BERT"));
434
+ cDecode = rb_define_class_under(mBERT, "Decode", rb_cObject);
435
+ cTuple = rb_const_get(mBERT, rb_intern("Tuple"));
436
+ rb_define_singleton_method(cDecode, "decode", method_decode, 1);
437
+ rb_define_singleton_method(cDecode, "impl", method_impl, 0);
438
+ }