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 +4 -4
- data/.gitignore +1 -0
- data/Rakefile +10 -2
- data/asciipack.gemspec +2 -1
- data/ext/asciipack/extconf.rb +3 -0
- data/ext/asciipack/init.c +23 -0
- data/ext/asciipack/packer.c +448 -0
- data/ext/asciipack/packer.h +40 -0
- data/ext/asciipack/unpacker.c +299 -0
- data/ext/asciipack/unpacker.h +25 -0
- data/lib/asciipack/version.rb +1 -1
- data/lib/asciipack.rb +2 -2
- data/spec/bench.rb +44 -25
- data/spec/format_spec.rb +40 -24
- data/spec/spec_helper.rb +19 -19
- metadata +24 -5
- data/lib/asciipack/packer.rb +0 -219
- data/lib/asciipack/unpacker.rb +0 -201
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 164e298f484a42236cb887376ab27a88d6ea3bbc
|
4
|
+
data.tar.gz: 71363702a9be3a3e840f1abe6e802884eeda00c0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 31b12c722b94d276baf5061e782b041c26225564e0d14fd79e2182ffec089013c62663b20f681e9023ed9e51dd658a95be0065f68f3085730c948296a11ff36e
|
7
|
+
data.tar.gz: 0e16623d5a791f61f1b5cd2a2115759f44ec144d802107b20491c876dfc2e14c7c34cc65a7a6ea03b64581f9b3af9532c57fac6059e4d3b5da34482cb35a2ed1
|
data/.gitignore
CHANGED
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,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
|
+
|