asciipack 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 12c016c4cbf6dc6932200cd28774219195a6897b
4
- data.tar.gz: db20a4941ad342f86992244148e3fda496f32c5c
3
+ metadata.gz: 164e298f484a42236cb887376ab27a88d6ea3bbc
4
+ data.tar.gz: 71363702a9be3a3e840f1abe6e802884eeda00c0
5
5
  SHA512:
6
- metadata.gz: cd8780bb46e2fa092cd8035efccd1174e6f8c7c659f2d3f2a702694e46f29d5dc78cd555e21678dbdadba2b63f2feef17e51d0ac8726b06f4a036d3758607282
7
- data.tar.gz: f0a6ec0a80d7f49f28e5c08177323779e8c3491f0084d3742e09e596bb7311c59c214252e2957a9f2ccbe7da9063a9d8d71fd221ab207404c340fbc88fcbdd6f
6
+ metadata.gz: 31b12c722b94d276baf5061e782b041c26225564e0d14fd79e2182ffec089013c62663b20f681e9023ed9e51dd658a95be0065f68f3085730c948296a11ff36e
7
+ data.tar.gz: 0e16623d5a791f61f1b5cd2a2115759f44ec144d802107b20491c876dfc2e14c7c34cc65a7a6ea03b64581f9b3af9532c57fac6059e4d3b5da34482cb35a2ed1
data/.gitignore CHANGED
@@ -1,6 +1,7 @@
1
1
  *.gem
2
2
  *.rbc
3
3
  .bundle
4
+ *.bundle
4
5
  .config
5
6
  .yardoc
6
7
  Gemfile.lock
data/Rakefile CHANGED
@@ -1,5 +1,4 @@
1
- require "bundler"
2
- Bundler::GemHelper.install_tasks
1
+ require "bundler/gem_tasks"
3
2
 
4
3
  require 'rspec/core'
5
4
  require 'rspec/core/rake_task'
@@ -9,4 +8,13 @@ RSpec::Core::RakeTask.new(:spec) do |t|
9
8
  t.pattern = "spec/**/*_spec.rb"
10
9
  t.verbose = true
11
10
  end
11
+ task :spec => :compile
12
12
 
13
+ require 'rake/extensiontask'
14
+ spec = eval File.read('asciipack.gemspec')
15
+ Rake::ExtensionTask.new('asciipack', spec) do |ext|
16
+ ext.cross_compile = true
17
+ ext.lib_dir = File.join(*['lib', 'asciipack', ENV['FAT_DIR']].compact)
18
+ end
19
+
20
+ task :default => [:spec]
data/asciipack.gemspec CHANGED
@@ -1,4 +1,3 @@
1
- # encoding: ascii-8bit
2
1
  lib = File.expand_path('../lib', __FILE__)
3
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
3
  require 'asciipack/version'
@@ -17,8 +16,10 @@ Gem::Specification.new do |spec|
17
16
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
17
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
18
  spec.require_paths = ["lib"]
19
+ spec.extensions = ["ext/asciipack/extconf.rb"]
20
20
 
21
21
  spec.add_development_dependency "bundler", "~> 1.3"
22
22
  spec.add_development_dependency "rake"
23
23
  spec.add_development_dependency "rspec", ['~> 2.11']
24
+ spec.add_development_dependency "rake-compiler", ["~> 0.8.3"]
24
25
  end
@@ -0,0 +1,3 @@
1
+ require 'mkmf'
2
+
3
+ create_makefile('asciipack/asciipack')
@@ -0,0 +1,23 @@
1
+ #if defined(_MSC_VER) && _MSC_VER < 1600
2
+ typedef short int8_t;
3
+ typedef unsigned short uint8_t;
4
+ typedef int int16_t;
5
+ typedef unsigned int uint16_t;
6
+ typedef long int32_t;
7
+ typedef unsigned long uint32_t;
8
+ typedef long long int64_t;
9
+ typedef unsigned long long uint64_t;
10
+ #else
11
+ #include <stdint.h>
12
+ #endif
13
+
14
+ #include "packer.h"
15
+ #include "unpacker.h"
16
+
17
+ void
18
+ Init_asciipack(void)
19
+ {
20
+ VALUE mAsciiPack = rb_define_module("AsciiPack");
21
+ AsciiPack_Unpacker_init(mAsciiPack);
22
+ AsciiPack_Packer_init(mAsciiPack);
23
+ }
@@ -0,0 +1,448 @@
1
+ #include <stdio.h>
2
+ #include "packer.h"
3
+
4
+ VALUE cAsciiPack_Packer;
5
+
6
+ static void Packer_write(packer_t* ptr, VALUE obj);
7
+
8
+ static void
9
+ packer_mark(packer_t* ptr)
10
+ {
11
+ }
12
+
13
+ static VALUE
14
+ Packer_alloc(VALUE klass)
15
+ {
16
+ packer_t *ptr = ALLOC(packer_t);
17
+ return Data_Wrap_Struct(klass, packer_mark, -1, ptr);
18
+ }
19
+
20
+ static VALUE
21
+ Packer_initialize(int argc, VALUE *argv, VALUE self)
22
+ {
23
+ PACKER(self, ptr);
24
+
25
+ if (!ptr) {
26
+ rb_raise(rb_eArgError, "unallocated packer");
27
+ }
28
+
29
+ // TODO fix memory control
30
+ ptr->buffer = (char*) malloc(sizeof(char) * MEMSIZE_INIT);
31
+ ptr->ch = ptr->buffer;
32
+ ptr->memsize = MEMSIZE_INIT;
33
+
34
+ return self;
35
+ }
36
+
37
+ static size_t
38
+ Packer_buffer_rest_size (packer_t* ptr)
39
+ {
40
+ return ptr->memsize - (ptr->ch - ptr->buffer);
41
+ }
42
+
43
+ static char*
44
+ Packer_realloc (packer_t* ptr, size_t require)
45
+ {
46
+ size_t newsize = ptr->memsize;
47
+ size_t len = ptr->ch - ptr->buffer;
48
+ size_t require_size = require + len;
49
+ char* mem = NULL;
50
+ char* p;
51
+
52
+ while (newsize < require_size) {
53
+ newsize *= 2;
54
+ }
55
+
56
+ mem = realloc(ptr->buffer, newsize);
57
+ if (mem == NULL) {
58
+ return NULL;
59
+ }
60
+ ptr->buffer = mem;
61
+ ptr->ch = ptr->buffer + len;
62
+ ptr->memsize = newsize;
63
+ return ptr->buffer;
64
+ }
65
+
66
+ static void
67
+ Packer_check (packer_t* ptr, size_t require)
68
+ {
69
+ if (Packer_buffer_rest_size(ptr) < require) {
70
+ if (Packer_realloc(ptr, require) == NULL) {
71
+ // raise!
72
+ }
73
+ }
74
+ }
75
+
76
+ static void
77
+ Packer_write_buffer_1 (packer_t* ptr, char ch)
78
+ {
79
+ *ptr->ch++ = ch;
80
+ }
81
+
82
+ static void
83
+ Packer_write_positive_num_1 (packer_t* ptr, unsigned int word)
84
+ {
85
+ if (word < 10) {
86
+ Packer_write_buffer_1(ptr, word + '0');
87
+ } else {
88
+ Packer_write_buffer_1(ptr, word + 'a' - 10);
89
+ }
90
+ }
91
+
92
+ static void
93
+ Packer_write_uint64 (packer_t* ptr, uint64_t n)
94
+ {
95
+ Packer_write_positive_num_1(ptr, (n & 0xf000000000000000LL) >> 60);
96
+ Packer_write_positive_num_1(ptr, (n & 0x0f00000000000000LL) >> 56);
97
+ Packer_write_positive_num_1(ptr, (n & 0x00f0000000000000LL) >> 52);
98
+ Packer_write_positive_num_1(ptr, (n & 0x000f000000000000LL) >> 48);
99
+ Packer_write_positive_num_1(ptr, (n & 0x0000f00000000000LL) >> 44);
100
+ Packer_write_positive_num_1(ptr, (n & 0x00000f0000000000LL) >> 40);
101
+ Packer_write_positive_num_1(ptr, (n & 0x000000f000000000LL) >> 36);
102
+ Packer_write_positive_num_1(ptr, (n & 0x0000000f00000000LL) >> 32);
103
+ Packer_write_positive_num_1(ptr, (n & 0x00000000f0000000LL) >> 28);
104
+ Packer_write_positive_num_1(ptr, (n & 0x000000000f000000LL) >> 24);
105
+ Packer_write_positive_num_1(ptr, (n & 0x0000000000f00000LL) >> 20);
106
+ Packer_write_positive_num_1(ptr, (n & 0x00000000000f0000LL) >> 16);
107
+ Packer_write_positive_num_1(ptr, (n & 0x000000000000f000LL) >> 12);
108
+ Packer_write_positive_num_1(ptr, (n & 0x0000000000000f00LL) >> 8);
109
+ Packer_write_positive_num_1(ptr, (n & 0x00000000000000f0LL) >> 4);
110
+ Packer_write_positive_num_1(ptr, (n & 0x000000000000000fLL));
111
+ }
112
+
113
+ static void
114
+ Packer_write_ubignum(packer_t* ptr, VALUE ubignum)
115
+ {
116
+ uint64_t n = rb_big2ull(ubignum);
117
+
118
+ Packer_write_buffer_1(ptr, 'j');
119
+ Packer_write_uint64(ptr, n);
120
+ }
121
+
122
+ static void
123
+ Packer_write_positive_num (packer_t* ptr, uint64_t n, unsigned int bytesize)
124
+ {
125
+ if (n == 0) {
126
+ return Packer_write_buffer_1(ptr, '0');
127
+ }
128
+
129
+ switch (bytesize) {
130
+ case 1:
131
+ Packer_write_positive_num_1(ptr, n & 0x0f);
132
+ break;
133
+
134
+ case 2:
135
+ Packer_write_positive_num_1(ptr, (n & 0xf0) >> 4);
136
+ Packer_write_positive_num_1(ptr, n & 0x0f);
137
+ break;
138
+
139
+ case 4:
140
+ Packer_write_positive_num_1(ptr, (n & 0xf000) >> 12);
141
+ Packer_write_positive_num_1(ptr, (n & 0x0f00) >> 8);
142
+ Packer_write_positive_num_1(ptr, (n & 0x00f0) >> 4);
143
+ Packer_write_positive_num_1(ptr, n & 0x000f);
144
+ break;
145
+
146
+ case 8:
147
+ Packer_write_positive_num_1(ptr, (n & 0xf0000000LL) >> 28);
148
+ Packer_write_positive_num_1(ptr, (n & 0x0f000000LL) >> 24);
149
+ Packer_write_positive_num_1(ptr, (n & 0x00f00000LL) >> 20);
150
+ Packer_write_positive_num_1(ptr, (n & 0x000f0000LL) >> 16);
151
+ Packer_write_positive_num_1(ptr, (n & 0x0000f000LL) >> 12);
152
+ Packer_write_positive_num_1(ptr, (n & 0x00000f00LL) >> 8);
153
+ Packer_write_positive_num_1(ptr, (n & 0x000000f0LL) >> 4);
154
+ Packer_write_positive_num_1(ptr, (n & 0x0000000fLL));
155
+ break;
156
+
157
+ case 16:
158
+ Packer_write_uint64(ptr, n);
159
+ break;
160
+ }
161
+ }
162
+
163
+ static void
164
+ Packer_write_bignum(packer_t* ptr, VALUE bignum)
165
+ {
166
+ int64_t v = rb_big2ll(bignum);
167
+ union unegative_int cb;
168
+
169
+ Packer_write_buffer_1(ptr, 'e');
170
+ cb.i64 = v;
171
+ Packer_write_positive_num(ptr, cb.ul, 16);
172
+ }
173
+
174
+ static void
175
+ Packer_bignum (packer_t* ptr, VALUE bignum)
176
+ {
177
+ Packer_check(ptr, 17);
178
+ if (RBIGNUM_POSITIVE_P(bignum)) {
179
+ Packer_write_ubignum(ptr, bignum);
180
+ } else {
181
+ Packer_write_bignum(ptr, bignum);
182
+ }
183
+ }
184
+
185
+ static void
186
+ Packer_fixnum (packer_t* ptr, VALUE fixnum)
187
+ {
188
+ int64_t v = FIX2LONG(fixnum);
189
+ union unegative_int cb;
190
+
191
+ if (v < 0) {
192
+ if (-0x8 <= v) {
193
+ Packer_check(ptr, 2);
194
+ Packer_write_buffer_1(ptr, 'a');
195
+ cb.i4 = v;
196
+ Packer_write_positive_num(ptr, cb.ul, 1);
197
+ } else if (-0x80 <= v) {
198
+ Packer_check(ptr, 3);
199
+ Packer_write_buffer_1(ptr, 'b');
200
+ cb.i8 = v;
201
+ Packer_write_positive_num(ptr, cb.ul, 2);
202
+ } else if (-0x8000L <= v) {
203
+ Packer_check(ptr, 5);
204
+ Packer_write_buffer_1(ptr, 'c');
205
+ cb.i16 = v;
206
+ Packer_write_positive_num(ptr, cb.ul, 4);
207
+ } else if (-0x80000000LL <= v) {
208
+ Packer_check(ptr, 9);
209
+ Packer_write_buffer_1(ptr, 'd');
210
+ cb.i32 = v;
211
+ Packer_write_positive_num(ptr, cb.ul, 8);
212
+ } else {
213
+ Packer_check(ptr, 17);
214
+ Packer_write_buffer_1(ptr, 'e');
215
+ cb.i64 = v;
216
+ Packer_write_positive_num(ptr, cb.ul, 16);
217
+ }
218
+
219
+ } else {
220
+ if (v < 0x10) {
221
+ Packer_check(ptr, 1);
222
+ if (v < 0x0a) {
223
+ Packer_write_buffer_1(ptr, v + '0');
224
+ } else {
225
+ Packer_write_buffer_1(ptr, v + 'A' - 10);
226
+ }
227
+ return;
228
+
229
+ } else if (v < 0x100) {
230
+ Packer_check(ptr, 3);
231
+ Packer_write_buffer_1(ptr, 'g');
232
+ Packer_write_positive_num(ptr, v, 2);
233
+
234
+ } else if (v < 0x10000LL) {
235
+ Packer_check(ptr, 5);
236
+ Packer_write_buffer_1(ptr, 'h');
237
+ Packer_write_positive_num(ptr, v, 4);
238
+
239
+ } else if (v < 0x100000000LL) {
240
+ Packer_check(ptr, 9);
241
+ Packer_write_buffer_1(ptr, 'i');
242
+ Packer_write_positive_num(ptr, v, 8);
243
+
244
+ } else {
245
+ Packer_check(ptr, 17);
246
+ Packer_write_buffer_1(ptr, 'j');
247
+ Packer_write_positive_num(ptr, v, 16);
248
+ }
249
+ }
250
+ }
251
+
252
+ static void
253
+ Packer_float (packer_t* ptr, VALUE floatnum)
254
+ {
255
+ double float64 = rb_num2dbl(floatnum);
256
+ union {
257
+ double d;
258
+ uint64_t u64;
259
+ } converter = {float64};
260
+
261
+ Packer_check(ptr, 9);
262
+ Packer_write_buffer_1(ptr, 'l');
263
+ Packer_write_uint64(ptr, converter.u64);
264
+ }
265
+
266
+ static void
267
+ Packer_str (packer_t* ptr, VALUE string)
268
+ {
269
+ uint32_t len = RSTRING_LEN(string);
270
+ char* p = RSTRING_PTR(string);
271
+ uint8_t n = 0;
272
+
273
+ if (len < 0x10) {
274
+ Packer_check(ptr, 1);
275
+ Packer_write_buffer_1(ptr, 'G' + len);
276
+ } else if (len < 0x100) {
277
+ Packer_check(ptr, 1);
278
+ Packer_write_buffer_1(ptr, 'n');
279
+ Packer_write_positive_num(ptr, len, 2);
280
+ } else if (len < 0x10000) {
281
+ Packer_check(ptr, 1);
282
+ Packer_write_buffer_1(ptr, 'o');
283
+ Packer_write_positive_num(ptr, len, 4);
284
+ } else {
285
+ Packer_check(ptr, 1);
286
+ Packer_write_buffer_1(ptr, 'p');
287
+ Packer_write_positive_num(ptr, len, 8);
288
+ }
289
+
290
+ Packer_check(ptr, len);
291
+ while (len--) {
292
+ Packer_write_buffer_1(ptr, *p++);
293
+ }
294
+ }
295
+
296
+ static void
297
+ Packer_array (packer_t* ptr, VALUE array)
298
+ {
299
+ uint32_t len = RARRAY_LEN(array);
300
+ uint32_t i = 0;
301
+
302
+ if (len < 0x10) {
303
+ Packer_check(ptr, 2);
304
+ Packer_write_buffer_1(ptr, 'v');
305
+ Packer_write_positive_num(ptr, len, 1);
306
+ } else if (len < 0x100) {
307
+ Packer_check(ptr, 3);
308
+ Packer_write_buffer_1(ptr, 'w');
309
+ Packer_write_positive_num(ptr, len, 2);
310
+ } else if (len < 0x10000) {
311
+ Packer_check(ptr, 5);
312
+ Packer_write_buffer_1(ptr, 'x');
313
+ Packer_write_positive_num(ptr, len, 4);
314
+ } else {
315
+ Packer_check(ptr, 9);
316
+ Packer_write_buffer_1(ptr, 'y');
317
+ Packer_write_positive_num(ptr, len, 8);
318
+ }
319
+
320
+ for (i = 0; i < len; i++) {
321
+ VALUE e = rb_ary_entry(array, i);
322
+ Packer_write(ptr, e);
323
+ }
324
+ }
325
+
326
+ static int
327
+ Packer_write_hash_each (VALUE key, VALUE value, VALUE obj)
328
+ {
329
+ packer_t* ptr = (packer_t*) obj;
330
+ Packer_write(ptr, key);
331
+ Packer_write(ptr, value);
332
+ return ST_CONTINUE;
333
+ }
334
+
335
+ static void
336
+ Packer_map (packer_t* ptr, VALUE hash)
337
+ {
338
+ uint32_t len = RHASH_SIZE(hash);
339
+ uint32_t i = 0;
340
+
341
+ if (len < 0x10) {
342
+ Packer_check(ptr, 2);
343
+ Packer_write_buffer_1(ptr, 'r');
344
+ Packer_write_positive_num(ptr, len, 1);
345
+ } else if (len < 0x100) {
346
+ Packer_check(ptr, 3);
347
+ Packer_write_buffer_1(ptr, 's');
348
+ Packer_write_positive_num(ptr, len, 2);
349
+ } else if (len < 0x10000) {
350
+ Packer_check(ptr, 5);
351
+ Packer_write_buffer_1(ptr, 't');
352
+ Packer_write_positive_num(ptr, len, 4);
353
+ } else {
354
+ Packer_check(ptr, 9);
355
+ Packer_write_buffer_1(ptr, 'u');
356
+ Packer_write_positive_num(ptr, len, 8);
357
+ }
358
+
359
+ rb_hash_foreach(hash, Packer_write_hash_each, (VALUE) ptr);
360
+ }
361
+
362
+
363
+ static VALUE
364
+ Packer_pack (VALUE self, VALUE obj)
365
+ {
366
+ PACKER(self, ptr);
367
+
368
+ Packer_write(ptr, obj);
369
+
370
+ *ptr->ch = '\0';
371
+ VALUE str = rb_str_new2(ptr->buffer);
372
+ free(ptr->buffer);
373
+ return str;
374
+ }
375
+
376
+ static void
377
+ Packer_nil (packer_t* ptr)
378
+ {
379
+ Packer_check(ptr, 1);
380
+ Packer_write_buffer_1(ptr, 'W');
381
+ }
382
+
383
+ static void
384
+ Packer_false (packer_t* ptr)
385
+ {
386
+ Packer_check(ptr, 1);
387
+ Packer_write_buffer_1(ptr, 'X');
388
+ }
389
+
390
+ static void
391
+ Packer_true (packer_t* ptr)
392
+ {
393
+ Packer_check(ptr, 1);
394
+ Packer_write_buffer_1(ptr, 'Y');
395
+ }
396
+
397
+ static void
398
+ Packer_write (packer_t* ptr, VALUE obj)
399
+ {
400
+ switch (rb_type(obj)) {
401
+ case T_NIL:
402
+ Packer_nil(ptr);
403
+ break;
404
+ case T_FALSE:
405
+ Packer_false(ptr);
406
+ break;
407
+ case T_TRUE:
408
+ Packer_true(ptr);
409
+ break;
410
+ case T_FIXNUM:
411
+ Packer_fixnum(ptr, obj);
412
+ break;
413
+ case T_BIGNUM:
414
+ Packer_bignum(ptr, obj);
415
+ break;
416
+ case T_FLOAT:
417
+ Packer_float(ptr, obj);
418
+ break;
419
+ case T_STRING:
420
+ Packer_str(ptr, obj);
421
+ break;
422
+ case T_ARRAY:
423
+ Packer_array(ptr, obj);
424
+ break;
425
+ case T_HASH:
426
+ Packer_map(ptr, obj);
427
+ break;
428
+ }
429
+ }
430
+
431
+ static VALUE
432
+ AsciiPack_pack (int argc, VALUE *argv, VALUE self)
433
+ {
434
+ VALUE packer = rb_funcall(cAsciiPack_Packer, rb_intern("new"), 0);
435
+ return rb_funcall(packer, rb_intern("pack"), 1, argv[0]);
436
+ }
437
+
438
+ void
439
+ AsciiPack_Packer_init(VALUE mAsciiPack)
440
+ {
441
+ cAsciiPack_Packer = rb_define_class_under(mAsciiPack, "Packer", rb_cObject);
442
+ rb_define_alloc_func(cAsciiPack_Packer, Packer_alloc);
443
+
444
+ rb_define_method(cAsciiPack_Packer, "initialize", Packer_initialize, -1);
445
+ rb_define_method(cAsciiPack_Packer, "pack", Packer_pack, 1);
446
+
447
+ rb_define_module_function(mAsciiPack, "pack", AsciiPack_pack, -1);
448
+ }
@@ -0,0 +1,40 @@
1
+ /*
2
+ * $Id$
3
+ */
4
+ #ifndef PACKER_H
5
+ # define PACKER_H
6
+
7
+ #include <stdlib.h>
8
+
9
+ struct packer {
10
+ char* buffer;
11
+ char* ch;
12
+ size_t memsize;
13
+ };
14
+ typedef struct packer packer_t;
15
+
16
+ union unegative_int {
17
+ unsigned long ul;
18
+ char i4;
19
+ int8_t i8;
20
+ int16_t i16;
21
+ int32_t i32;
22
+ int64_t i64;
23
+ };
24
+
25
+ #define MEMSIZE_INIT 128
26
+
27
+ #define PACKER(from, name) \
28
+ packer_t* name; \
29
+ Data_Get_Struct(from, packer_t, name); \
30
+ if (name == NULL) { \
31
+ rb_raise(rb_eArgError, "NULL found for " # name " when shouldn't be.'"); \
32
+ }
33
+
34
+ #include "ruby.h"
35
+
36
+ extern VALUE cAsciiPack_Packer;
37
+ void AsciiPack_Packer_init(VALUE mAsciiPack);
38
+
39
+ #endif /* ifndef PACKER_H */
40
+