asciipack 0.1.3 → 0.2.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.
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
+