asciipack 0.2.2 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +4 -0
- data/ext/asciipack/packer.c +335 -135
- data/ext/asciipack/packer.h +37 -3
- data/ext/asciipack/unpacker.c +64 -14
- data/lib/asciipack/version.rb +1 -1
- data/spec/bench.rb +12 -17
- data/spec/exception_spec.rb +9 -0
- data/spec/format_spec.rb +15 -1
- data/spec/mem_spec.rb +20 -8
- data/spec/packer_spec.rb +24 -0
- data/spec/unpacker_spec.rb +18 -0
- metadata +20 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d1459faeca6230153b447a21394155ed54cee71f
|
4
|
+
data.tar.gz: 04fe8fa21164a3fc518dc6f18d4f817bd1abc446
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: db669a6873f4df13b32a65319a147c897828a25444a51e7bf95320ec815245fc3560cbe9767146d303c1c3ffc442d7a0421e3fc29856b31c3f3a101366d4ceee
|
7
|
+
data.tar.gz: 9a0b27bdcfbd0aa0c1cccbf6dcb3aa85c7bc6eecec3958fc5a90eaea6bacc289e7a5fdb2ad37e920317ad91e75f81e44fe4c5b7e3c5322324018c6b4443517aa
|
data/README.md
CHANGED
@@ -2,6 +2,10 @@
|
|
2
2
|
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/asciipack.png)](http://badge.fury.io/rb/asciipack)
|
4
4
|
|
5
|
+
AsciiPack is an object serialization inspired by MessagePack.
|
6
|
+
|
7
|
+
AsciiPack is use easy by Web. because all serialize object is only writed by ascii strings.
|
8
|
+
|
5
9
|
## Synopsis
|
6
10
|
|
7
11
|
```ruby
|
data/ext/asciipack/packer.c
CHANGED
@@ -1,24 +1,54 @@
|
|
1
|
-
#include <stdio.h>
|
2
1
|
#include "packer.h"
|
3
2
|
|
4
3
|
VALUE cAsciiPack_Packer;
|
5
4
|
|
6
|
-
static void
|
5
|
+
static void Packer_write_value(packer_t* ptr, VALUE obj);
|
7
6
|
|
8
7
|
static void
|
9
|
-
|
8
|
+
Packer_mark (packer_t* ptr)
|
10
9
|
{
|
11
10
|
}
|
12
11
|
|
12
|
+
static void
|
13
|
+
Packer_free (packer_t* ptr)
|
14
|
+
{
|
15
|
+
tag_t* b = ptr->start;
|
16
|
+
tag_t* next;
|
17
|
+
|
18
|
+
while (b != NULL) {
|
19
|
+
next = b->next;
|
20
|
+
free(b);
|
21
|
+
b = next;
|
22
|
+
}
|
23
|
+
free(ptr->mem);
|
24
|
+
}
|
25
|
+
|
13
26
|
static VALUE
|
14
|
-
Packer_alloc(VALUE klass)
|
27
|
+
Packer_alloc (VALUE klass)
|
15
28
|
{
|
16
29
|
packer_t *ptr = ALLOC(packer_t);
|
17
|
-
return Data_Wrap_Struct(klass,
|
30
|
+
return Data_Wrap_Struct(klass, Packer_mark, Packer_free, ptr);
|
31
|
+
}
|
32
|
+
|
33
|
+
static void
|
34
|
+
Packer_init (packer_t* ptr)
|
35
|
+
{
|
36
|
+
tag_t* tag = (tag_t*) malloc(sizeof(tag_t));
|
37
|
+
char* mem = (char*) malloc(sizeof(char) * MEMSIZE_INIT);
|
38
|
+
|
39
|
+
ptr->mem = mem;
|
40
|
+
ptr->mem_end = mem;
|
41
|
+
ptr->memsize = MEMSIZE_INIT;
|
42
|
+
ptr->start = tag;
|
43
|
+
ptr->tag = ptr->start;
|
44
|
+
ptr->tag->begin = mem;
|
45
|
+
ptr->tag->end = mem;
|
46
|
+
ptr->tag->is_reference = 0;
|
47
|
+
ptr->tag->next = NULL;
|
18
48
|
}
|
19
49
|
|
20
50
|
static VALUE
|
21
|
-
Packer_initialize(int argc, VALUE *argv, VALUE self)
|
51
|
+
Packer_initialize (int argc, VALUE *argv, VALUE self)
|
22
52
|
{
|
23
53
|
PACKER(self, ptr);
|
24
54
|
|
@@ -26,63 +56,133 @@ Packer_initialize(int argc, VALUE *argv, VALUE self)
|
|
26
56
|
rb_raise(rb_eArgError, "unallocated packer");
|
27
57
|
}
|
28
58
|
|
29
|
-
|
30
|
-
ptr->buffer = (char*) malloc(sizeof(char) * MEMSIZE_INIT);
|
31
|
-
ptr->ch = ptr->buffer;
|
32
|
-
ptr->memsize = MEMSIZE_INIT;
|
33
|
-
|
59
|
+
Packer_init(ptr);
|
34
60
|
return self;
|
35
61
|
}
|
36
62
|
|
37
63
|
static size_t
|
38
|
-
|
64
|
+
Packer_tag_writed_size (packer_t* ptr)
|
65
|
+
{
|
66
|
+
return ptr->tag->end - ptr->mem;
|
67
|
+
}
|
68
|
+
|
69
|
+
static size_t
|
70
|
+
Packer_tag_rest_size (packer_t* ptr)
|
39
71
|
{
|
40
|
-
return ptr->memsize - (ptr
|
72
|
+
return ptr->memsize - Packer_tag_writed_size(ptr);
|
41
73
|
}
|
42
74
|
|
43
75
|
static char*
|
44
76
|
Packer_realloc (packer_t* ptr, size_t require)
|
45
77
|
{
|
46
78
|
size_t newsize = ptr->memsize;
|
47
|
-
size_t len = ptr
|
79
|
+
size_t len = Packer_tag_writed_size(ptr);
|
48
80
|
size_t require_size = require + len;
|
81
|
+
char* mem;
|
82
|
+
tag_t* b = ptr->start;
|
49
83
|
|
50
84
|
while (newsize < require_size) {
|
51
85
|
newsize *= 2;
|
52
86
|
}
|
53
87
|
|
54
|
-
|
55
|
-
ptr->
|
88
|
+
mem = (char*) realloc(ptr->mem, sizeof(char) * newsize);
|
89
|
+
ptr->mem = mem;
|
56
90
|
ptr->memsize = newsize;
|
57
|
-
|
91
|
+
if (mem == NULL) {
|
92
|
+
return NULL;
|
93
|
+
}
|
94
|
+
|
95
|
+
while (1) {
|
96
|
+
if (!b->is_reference) {
|
97
|
+
len = b->end - b->begin;
|
98
|
+
b->begin = mem;
|
99
|
+
b->end = mem + len;
|
100
|
+
ptr->mem_end = b->end;
|
101
|
+
mem += len;
|
102
|
+
}
|
103
|
+
if (b->next == NULL) {
|
104
|
+
return ptr->mem;
|
105
|
+
}
|
106
|
+
b = b->next;
|
107
|
+
}
|
58
108
|
}
|
59
109
|
|
60
110
|
static void
|
61
111
|
Packer_check (packer_t* ptr, size_t require)
|
62
112
|
{
|
63
|
-
if (
|
113
|
+
if (ptr->tag->is_reference) {
|
114
|
+
tag_t* tag_mem = (tag_t*) malloc(sizeof(tag_t));
|
115
|
+
|
116
|
+
ptr->tag->next = tag_mem;
|
117
|
+
|
118
|
+
tag_mem->begin = ptr->mem_end;
|
119
|
+
tag_mem->end = ptr->mem_end;
|
120
|
+
tag_mem->next = NULL;
|
121
|
+
tag_mem->is_reference = 0;
|
122
|
+
ptr->tag = tag_mem;
|
123
|
+
}
|
124
|
+
if (Packer_tag_rest_size(ptr) < require) {
|
64
125
|
if (Packer_realloc(ptr, require) == NULL) {
|
65
|
-
|
126
|
+
rb_raise(rb_eNoMemError, "Packer can not realloc.");
|
66
127
|
}
|
67
128
|
}
|
68
129
|
}
|
69
130
|
|
70
131
|
static void
|
71
|
-
|
132
|
+
Packer_write_tag_1 (packer_t* ptr, char ch)
|
133
|
+
{
|
134
|
+
*ptr->tag->end++ = ch;
|
135
|
+
}
|
136
|
+
|
137
|
+
static void
|
138
|
+
Packer_write_tag_cpy (packer_t* ptr, VALUE string)
|
72
139
|
{
|
73
|
-
*
|
140
|
+
const char* p = RSTRING_PTR(string);
|
141
|
+
uint32_t len = RSTRING_LEN(string);
|
142
|
+
|
143
|
+
memcpy(ptr->tag->end, p, len);
|
144
|
+
ptr->tag->end += len;
|
74
145
|
}
|
75
146
|
|
76
147
|
static void
|
77
148
|
Packer_write_positive_num_1 (packer_t* ptr, unsigned int word)
|
78
149
|
{
|
79
150
|
if (word < 10) {
|
80
|
-
|
151
|
+
Packer_write_tag_1(ptr, word + '0');
|
81
152
|
} else {
|
82
|
-
|
153
|
+
Packer_write_tag_1(ptr, word + 'a' - 10);
|
83
154
|
}
|
84
155
|
}
|
85
156
|
|
157
|
+
static void
|
158
|
+
Packer_write_uint8 (packer_t* ptr, uint8_t n)
|
159
|
+
{
|
160
|
+
Packer_write_positive_num_1(ptr, (n & 0xf0) >> 4);
|
161
|
+
Packer_write_positive_num_1(ptr, n & 0x0f);
|
162
|
+
}
|
163
|
+
|
164
|
+
static void
|
165
|
+
Packer_write_uint16 (packer_t* ptr, uint16_t n)
|
166
|
+
{
|
167
|
+
Packer_write_positive_num_1(ptr, (n & 0xf000) >> 12);
|
168
|
+
Packer_write_positive_num_1(ptr, (n & 0x0f00) >> 8);
|
169
|
+
Packer_write_positive_num_1(ptr, (n & 0x00f0) >> 4);
|
170
|
+
Packer_write_positive_num_1(ptr, n & 0x000f);
|
171
|
+
}
|
172
|
+
|
173
|
+
static void
|
174
|
+
Packer_write_uint32 (packer_t* ptr, uint32_t n)
|
175
|
+
{
|
176
|
+
Packer_write_positive_num_1(ptr, (n & 0xf0000000LL) >> 28);
|
177
|
+
Packer_write_positive_num_1(ptr, (n & 0x0f000000LL) >> 24);
|
178
|
+
Packer_write_positive_num_1(ptr, (n & 0x00f00000LL) >> 20);
|
179
|
+
Packer_write_positive_num_1(ptr, (n & 0x000f0000LL) >> 16);
|
180
|
+
Packer_write_positive_num_1(ptr, (n & 0x0000f000LL) >> 12);
|
181
|
+
Packer_write_positive_num_1(ptr, (n & 0x00000f00LL) >> 8);
|
182
|
+
Packer_write_positive_num_1(ptr, (n & 0x000000f0LL) >> 4);
|
183
|
+
Packer_write_positive_num_1(ptr, (n & 0x0000000fLL));
|
184
|
+
}
|
185
|
+
|
86
186
|
static void
|
87
187
|
Packer_write_uint64 (packer_t* ptr, uint64_t n)
|
88
188
|
{
|
@@ -109,60 +209,19 @@ Packer_write_ubignum(packer_t* ptr, VALUE ubignum)
|
|
109
209
|
{
|
110
210
|
uint64_t n = rb_big2ull(ubignum);
|
111
211
|
|
112
|
-
|
212
|
+
Packer_write_tag_1(ptr, 'j');
|
113
213
|
Packer_write_uint64(ptr, n);
|
114
214
|
}
|
115
215
|
|
116
|
-
static void
|
117
|
-
Packer_write_positive_num (packer_t* ptr, uint64_t n, unsigned int bytesize)
|
118
|
-
{
|
119
|
-
if (n == 0) {
|
120
|
-
return Packer_write_buffer_1(ptr, '0');
|
121
|
-
}
|
122
|
-
|
123
|
-
switch (bytesize) {
|
124
|
-
case 1:
|
125
|
-
Packer_write_positive_num_1(ptr, n & 0x0f);
|
126
|
-
break;
|
127
|
-
|
128
|
-
case 2:
|
129
|
-
Packer_write_positive_num_1(ptr, (n & 0xf0) >> 4);
|
130
|
-
Packer_write_positive_num_1(ptr, n & 0x0f);
|
131
|
-
break;
|
132
|
-
|
133
|
-
case 4:
|
134
|
-
Packer_write_positive_num_1(ptr, (n & 0xf000) >> 12);
|
135
|
-
Packer_write_positive_num_1(ptr, (n & 0x0f00) >> 8);
|
136
|
-
Packer_write_positive_num_1(ptr, (n & 0x00f0) >> 4);
|
137
|
-
Packer_write_positive_num_1(ptr, n & 0x000f);
|
138
|
-
break;
|
139
|
-
|
140
|
-
case 8:
|
141
|
-
Packer_write_positive_num_1(ptr, (n & 0xf0000000LL) >> 28);
|
142
|
-
Packer_write_positive_num_1(ptr, (n & 0x0f000000LL) >> 24);
|
143
|
-
Packer_write_positive_num_1(ptr, (n & 0x00f00000LL) >> 20);
|
144
|
-
Packer_write_positive_num_1(ptr, (n & 0x000f0000LL) >> 16);
|
145
|
-
Packer_write_positive_num_1(ptr, (n & 0x0000f000LL) >> 12);
|
146
|
-
Packer_write_positive_num_1(ptr, (n & 0x00000f00LL) >> 8);
|
147
|
-
Packer_write_positive_num_1(ptr, (n & 0x000000f0LL) >> 4);
|
148
|
-
Packer_write_positive_num_1(ptr, (n & 0x0000000fLL));
|
149
|
-
break;
|
150
|
-
|
151
|
-
case 16:
|
152
|
-
Packer_write_uint64(ptr, n);
|
153
|
-
break;
|
154
|
-
}
|
155
|
-
}
|
156
|
-
|
157
216
|
static void
|
158
217
|
Packer_write_bignum(packer_t* ptr, VALUE bignum)
|
159
218
|
{
|
160
219
|
int64_t v = rb_big2ll(bignum);
|
161
220
|
union unegative_int cb;
|
162
221
|
|
163
|
-
|
222
|
+
Packer_write_tag_1(ptr, 'e');
|
164
223
|
cb.i64 = v;
|
165
|
-
|
224
|
+
Packer_write_uint64(ptr, cb.ul);
|
166
225
|
}
|
167
226
|
|
168
227
|
static void
|
@@ -185,60 +244,60 @@ Packer_fixnum (packer_t* ptr, VALUE fixnum)
|
|
185
244
|
if (v < 0) {
|
186
245
|
if (-0x8 <= v) {
|
187
246
|
Packer_check(ptr, 2);
|
188
|
-
|
247
|
+
Packer_write_tag_1(ptr, 'a');
|
189
248
|
cb.i4 = v;
|
190
|
-
|
249
|
+
Packer_write_positive_num_1(ptr, cb.ul & 0x0f);
|
191
250
|
} else if (-0x80 <= v) {
|
192
251
|
Packer_check(ptr, 3);
|
193
|
-
|
252
|
+
Packer_write_tag_1(ptr, 'b');
|
194
253
|
cb.i8 = v;
|
195
|
-
|
254
|
+
Packer_write_uint8(ptr, cb.ul);
|
196
255
|
} else if (-0x8000L <= v) {
|
197
256
|
Packer_check(ptr, 5);
|
198
|
-
|
257
|
+
Packer_write_tag_1(ptr, 'c');
|
199
258
|
cb.i16 = v;
|
200
|
-
|
259
|
+
Packer_write_uint16(ptr, cb.ul);
|
201
260
|
} else if (-0x80000000LL <= v) {
|
202
261
|
Packer_check(ptr, 9);
|
203
|
-
|
262
|
+
Packer_write_tag_1(ptr, 'd');
|
204
263
|
cb.i32 = v;
|
205
|
-
|
264
|
+
Packer_write_uint32(ptr, cb.ul);
|
206
265
|
} else {
|
207
266
|
Packer_check(ptr, 17);
|
208
|
-
|
267
|
+
Packer_write_tag_1(ptr, 'e');
|
209
268
|
cb.i64 = v;
|
210
|
-
|
269
|
+
Packer_write_uint64(ptr, cb.ul);
|
211
270
|
}
|
212
271
|
|
213
272
|
} else {
|
214
273
|
if (v < 0x10) {
|
215
274
|
Packer_check(ptr, 1);
|
216
275
|
if (v < 0x0a) {
|
217
|
-
|
276
|
+
Packer_write_tag_1(ptr, v + '0');
|
218
277
|
} else {
|
219
|
-
|
278
|
+
Packer_write_tag_1(ptr, v + 'A' - 10);
|
220
279
|
}
|
221
280
|
return;
|
222
281
|
|
223
282
|
} else if (v < 0x100) {
|
224
283
|
Packer_check(ptr, 3);
|
225
|
-
|
226
|
-
|
284
|
+
Packer_write_tag_1(ptr, 'g');
|
285
|
+
Packer_write_uint8(ptr, v);
|
227
286
|
|
228
287
|
} else if (v < 0x10000LL) {
|
229
288
|
Packer_check(ptr, 5);
|
230
|
-
|
231
|
-
|
289
|
+
Packer_write_tag_1(ptr, 'h');
|
290
|
+
Packer_write_uint16(ptr, v);
|
232
291
|
|
233
292
|
} else if (v < 0x100000000LL) {
|
234
293
|
Packer_check(ptr, 9);
|
235
|
-
|
236
|
-
|
294
|
+
Packer_write_tag_1(ptr, 'i');
|
295
|
+
Packer_write_uint32(ptr, v);
|
237
296
|
|
238
297
|
} else {
|
239
298
|
Packer_check(ptr, 17);
|
240
|
-
|
241
|
-
|
299
|
+
Packer_write_tag_1(ptr, 'j');
|
300
|
+
Packer_write_uint64(ptr, v);
|
242
301
|
}
|
243
302
|
}
|
244
303
|
}
|
@@ -253,36 +312,77 @@ Packer_float (packer_t* ptr, VALUE floatnum)
|
|
253
312
|
} converter = {float64};
|
254
313
|
|
255
314
|
Packer_check(ptr, 17);
|
256
|
-
|
315
|
+
Packer_write_tag_1(ptr, 'l');
|
257
316
|
Packer_write_uint64(ptr, converter.u64);
|
258
317
|
}
|
259
318
|
|
260
319
|
static void
|
261
|
-
|
320
|
+
Packer_write_string_header (packer_t* ptr, uint32_t len)
|
262
321
|
{
|
263
|
-
uint32_t len = RSTRING_LEN(string);
|
264
|
-
char* p = RSTRING_PTR(string);
|
265
|
-
|
266
322
|
if (len < 0x10) {
|
267
323
|
Packer_check(ptr, 1);
|
268
|
-
|
324
|
+
Packer_write_tag_1(ptr, 'G' + len);
|
269
325
|
} else if (len < 0x100) {
|
270
326
|
Packer_check(ptr, 3);
|
271
|
-
|
272
|
-
|
327
|
+
Packer_write_tag_1(ptr, 'n');
|
328
|
+
Packer_write_uint8(ptr, len);
|
273
329
|
} else if (len < 0x10000) {
|
274
330
|
Packer_check(ptr, 5);
|
275
|
-
|
276
|
-
|
331
|
+
Packer_write_tag_1(ptr, 'o');
|
332
|
+
Packer_write_uint16(ptr, len);
|
277
333
|
} else {
|
278
334
|
Packer_check(ptr, 9);
|
279
|
-
|
280
|
-
|
335
|
+
Packer_write_tag_1(ptr, 'p');
|
336
|
+
Packer_write_uint32(ptr, len);
|
281
337
|
}
|
338
|
+
}
|
339
|
+
|
340
|
+
static void
|
341
|
+
Packer_write_string_reference (packer_t* ptr, VALUE string)
|
342
|
+
{
|
343
|
+
VALUE dup = rb_str_dup(string);
|
344
|
+
char* p = RSTRING_PTR(dup);
|
345
|
+
uint32_t len = RSTRING_LEN(dup);
|
346
|
+
tag_t* tag_reference = (tag_t*) malloc(sizeof(tag_t));
|
347
|
+
|
348
|
+
if (!ptr->tag->is_reference) {
|
349
|
+
ptr->mem_end = ptr->tag->end;
|
350
|
+
}
|
351
|
+
|
352
|
+
tag_reference->begin = p;
|
353
|
+
tag_reference->end = p + len;
|
354
|
+
tag_reference->next = NULL;
|
355
|
+
tag_reference->is_reference = 1;
|
356
|
+
ptr->tag->next = tag_reference;
|
357
|
+
ptr->tag = tag_reference;
|
358
|
+
}
|
359
|
+
|
360
|
+
static void
|
361
|
+
Packer_str (packer_t* ptr, VALUE string)
|
362
|
+
{
|
363
|
+
uint32_t len = RSTRING_LEN(string);
|
364
|
+
|
365
|
+
Packer_write_string_header(ptr, len);
|
366
|
+
|
367
|
+
if (len < 131072L) {
|
368
|
+
Packer_check(ptr, len);
|
369
|
+
Packer_write_tag_cpy(ptr, string);
|
370
|
+
} else {
|
371
|
+
Packer_write_string_reference(ptr, string);
|
372
|
+
}
|
373
|
+
}
|
374
|
+
|
375
|
+
static void
|
376
|
+
Packer_symbol (packer_t* ptr, VALUE symbol)
|
377
|
+
{
|
378
|
+
const char* p = rb_id2name(SYM2ID(symbol));
|
379
|
+
uint32_t len = strlen(p);
|
380
|
+
|
381
|
+
Packer_write_string_header(ptr, len);
|
282
382
|
|
283
383
|
Packer_check(ptr, len);
|
284
384
|
while (len--) {
|
285
|
-
|
385
|
+
Packer_write_tag_1(ptr, *p++);
|
286
386
|
}
|
287
387
|
}
|
288
388
|
|
@@ -294,25 +394,25 @@ Packer_array (packer_t* ptr, VALUE array)
|
|
294
394
|
|
295
395
|
if (len < 0x10) {
|
296
396
|
Packer_check(ptr, 2);
|
297
|
-
|
298
|
-
|
397
|
+
Packer_write_tag_1(ptr, 'v');
|
398
|
+
Packer_write_positive_num_1(ptr, len);
|
299
399
|
} else if (len < 0x100) {
|
300
400
|
Packer_check(ptr, 3);
|
301
|
-
|
302
|
-
|
401
|
+
Packer_write_tag_1(ptr, 'w');
|
402
|
+
Packer_write_uint8(ptr, len);
|
303
403
|
} else if (len < 0x10000) {
|
304
404
|
Packer_check(ptr, 5);
|
305
|
-
|
306
|
-
|
405
|
+
Packer_write_tag_1(ptr, 'x');
|
406
|
+
Packer_write_uint16(ptr, len);
|
307
407
|
} else {
|
308
408
|
Packer_check(ptr, 9);
|
309
|
-
|
310
|
-
|
409
|
+
Packer_write_tag_1(ptr, 'y');
|
410
|
+
Packer_write_uint32(ptr, len);
|
311
411
|
}
|
312
412
|
|
313
413
|
for (i = 0; i < len; i++) {
|
314
414
|
VALUE e = rb_ary_entry(array, i);
|
315
|
-
|
415
|
+
Packer_write_value(ptr, e);
|
316
416
|
}
|
317
417
|
}
|
318
418
|
|
@@ -320,8 +420,8 @@ static int
|
|
320
420
|
Packer_write_hash_each (VALUE key, VALUE value, VALUE obj)
|
321
421
|
{
|
322
422
|
packer_t* ptr = (packer_t*) obj;
|
323
|
-
|
324
|
-
|
423
|
+
Packer_write_value(ptr, key);
|
424
|
+
Packer_write_value(ptr, value);
|
325
425
|
return ST_CONTINUE;
|
326
426
|
}
|
327
427
|
|
@@ -332,64 +432,120 @@ Packer_map (packer_t* ptr, VALUE hash)
|
|
332
432
|
|
333
433
|
if (len < 0x10) {
|
334
434
|
Packer_check(ptr, 2);
|
335
|
-
|
336
|
-
|
435
|
+
Packer_write_tag_1(ptr, 'r');
|
436
|
+
Packer_write_positive_num_1(ptr, len);
|
337
437
|
} else if (len < 0x100) {
|
338
438
|
Packer_check(ptr, 3);
|
339
|
-
|
340
|
-
|
439
|
+
Packer_write_tag_1(ptr, 's');
|
440
|
+
Packer_write_uint8(ptr, len);
|
341
441
|
} else if (len < 0x10000) {
|
342
442
|
Packer_check(ptr, 5);
|
343
|
-
|
344
|
-
|
443
|
+
Packer_write_tag_1(ptr, 't');
|
444
|
+
Packer_write_uint16(ptr, len);
|
345
445
|
} else {
|
346
446
|
Packer_check(ptr, 9);
|
347
|
-
|
348
|
-
|
447
|
+
Packer_write_tag_1(ptr, 'u');
|
448
|
+
Packer_write_uint32(ptr, len);
|
349
449
|
}
|
350
450
|
|
351
451
|
rb_hash_foreach(hash, Packer_write_hash_each, (VALUE) ptr);
|
352
452
|
}
|
353
453
|
|
354
|
-
|
355
454
|
static VALUE
|
356
|
-
|
455
|
+
Packer_write_to_s (packer_t* ptr)
|
357
456
|
{
|
358
|
-
|
457
|
+
uint64_t length = ptr->start->end - ptr->mem;
|
458
|
+
uint64_t total_length = length;
|
459
|
+
tag_t* b = ptr->start->next;
|
460
|
+
char* p = NULL;
|
461
|
+
VALUE string;
|
462
|
+
|
463
|
+
while (b != NULL) {
|
464
|
+
total_length += b->end - b->begin;
|
465
|
+
b = b->next;
|
466
|
+
}
|
359
467
|
|
468
|
+
string = rb_str_new(NULL, total_length);
|
469
|
+
p = RSTRING_PTR(string);
|
470
|
+
memcpy(p, ptr->mem, length);
|
471
|
+
p += length;
|
472
|
+
|
473
|
+
b = ptr->start->next;
|
474
|
+
if (b == NULL) {
|
475
|
+
return string;
|
476
|
+
}
|
477
|
+
while (1) {
|
478
|
+
length = b->end - b->begin;
|
479
|
+
memcpy(p, b->begin, length);
|
480
|
+
if (b->next == NULL) {
|
481
|
+
return string;
|
482
|
+
}
|
483
|
+
p += length;
|
484
|
+
b = b->next;
|
485
|
+
}
|
486
|
+
}
|
487
|
+
|
488
|
+
static VALUE
|
489
|
+
Packer_to_s (VALUE self)
|
490
|
+
{
|
360
491
|
PACKER(self, ptr);
|
492
|
+
return Packer_write_to_s(ptr);
|
493
|
+
}
|
361
494
|
|
362
|
-
|
495
|
+
static void
|
496
|
+
Packer_write_clear (packer_t* ptr)
|
497
|
+
{
|
498
|
+
tag_t* b;
|
499
|
+
tag_t* next;
|
500
|
+
|
501
|
+
*ptr->mem = '\0';
|
502
|
+
ptr->mem_end = ptr->mem;
|
503
|
+
|
504
|
+
if (ptr->start->next != NULL) {
|
505
|
+
b = ptr->start->next;
|
506
|
+
while (b != NULL) {
|
507
|
+
next = b->next;
|
508
|
+
free(b);
|
509
|
+
b = next;
|
510
|
+
}
|
511
|
+
}
|
512
|
+
ptr->start->begin = ptr->mem;
|
513
|
+
ptr->start->end = ptr->mem;
|
514
|
+
ptr->start->next = NULL;
|
515
|
+
ptr->tag = ptr->start;
|
516
|
+
}
|
363
517
|
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
518
|
+
static VALUE
|
519
|
+
Packer_clear (VALUE self)
|
520
|
+
{
|
521
|
+
PACKER(self, ptr);
|
522
|
+
Packer_write_clear(ptr);
|
523
|
+
return Qnil;
|
368
524
|
}
|
369
525
|
|
370
526
|
static void
|
371
527
|
Packer_nil (packer_t* ptr)
|
372
528
|
{
|
373
529
|
Packer_check(ptr, 1);
|
374
|
-
|
530
|
+
Packer_write_tag_1(ptr, 'W');
|
375
531
|
}
|
376
532
|
|
377
533
|
static void
|
378
534
|
Packer_false (packer_t* ptr)
|
379
535
|
{
|
380
536
|
Packer_check(ptr, 1);
|
381
|
-
|
537
|
+
Packer_write_tag_1(ptr, 'X');
|
382
538
|
}
|
383
539
|
|
384
540
|
static void
|
385
541
|
Packer_true (packer_t* ptr)
|
386
542
|
{
|
387
543
|
Packer_check(ptr, 1);
|
388
|
-
|
544
|
+
Packer_write_tag_1(ptr, 'Y');
|
389
545
|
}
|
390
546
|
|
391
547
|
static void
|
392
|
-
|
548
|
+
Packer_write_value (packer_t* ptr, VALUE obj)
|
393
549
|
{
|
394
550
|
switch (rb_type(obj)) {
|
395
551
|
case T_NIL:
|
@@ -410,6 +566,9 @@ Packer_write (packer_t* ptr, VALUE obj)
|
|
410
566
|
case T_FLOAT:
|
411
567
|
Packer_float(ptr, obj);
|
412
568
|
break;
|
569
|
+
case T_SYMBOL:
|
570
|
+
Packer_symbol(ptr, obj);
|
571
|
+
break;
|
413
572
|
case T_STRING:
|
414
573
|
Packer_str(ptr, obj);
|
415
574
|
break;
|
@@ -423,10 +582,37 @@ Packer_write (packer_t* ptr, VALUE obj)
|
|
423
582
|
}
|
424
583
|
|
425
584
|
static VALUE
|
426
|
-
|
585
|
+
Packer_write (VALUE self, VALUE obj)
|
427
586
|
{
|
428
|
-
|
429
|
-
|
587
|
+
PACKER(self, ptr);
|
588
|
+
Packer_write_value(ptr, obj);
|
589
|
+
return self;
|
590
|
+
}
|
591
|
+
|
592
|
+
static VALUE
|
593
|
+
AsciiPack_pack (int argc, VALUE* argv)
|
594
|
+
{
|
595
|
+
VALUE str;
|
596
|
+
VALUE v = *argv;
|
597
|
+
VALUE self = Packer_alloc(cAsciiPack_Packer);
|
598
|
+
|
599
|
+
PACKER(self, ptr);
|
600
|
+
if (!ptr) {
|
601
|
+
rb_raise(rb_eArgError, "unallocated packer");
|
602
|
+
}
|
603
|
+
Packer_init(ptr);
|
604
|
+
|
605
|
+
Packer_write_value(ptr, v);
|
606
|
+
|
607
|
+
str = Packer_write_to_s(ptr);
|
608
|
+
|
609
|
+
Packer_write_clear(ptr);
|
610
|
+
return str;
|
611
|
+
}
|
612
|
+
|
613
|
+
static VALUE AsciiPack_to_asciipack (int argc, VALUE* argv, VALUE self)
|
614
|
+
{
|
615
|
+
return AsciiPack_pack(1, &self);
|
430
616
|
}
|
431
617
|
|
432
618
|
void
|
@@ -436,7 +622,21 @@ AsciiPack_Packer_init(VALUE mAsciiPack)
|
|
436
622
|
rb_define_alloc_func(cAsciiPack_Packer, Packer_alloc);
|
437
623
|
|
438
624
|
rb_define_method(cAsciiPack_Packer, "initialize", Packer_initialize, -1);
|
439
|
-
rb_define_method(cAsciiPack_Packer, "
|
625
|
+
rb_define_method(cAsciiPack_Packer, "write", Packer_write, 1);
|
626
|
+
rb_define_alias(cAsciiPack_Packer, "pack", "write");
|
627
|
+
rb_define_method(cAsciiPack_Packer, "to_s", Packer_to_s, 0);
|
628
|
+
rb_define_method(cAsciiPack_Packer, "clear", Packer_clear, 0);
|
440
629
|
|
441
630
|
rb_define_module_function(mAsciiPack, "pack", AsciiPack_pack, -1);
|
631
|
+
|
632
|
+
rb_define_method(rb_cFixnum, "to_asciipack", AsciiPack_to_asciipack, -1);
|
633
|
+
rb_define_method(rb_cBignum, "to_asciipack", AsciiPack_to_asciipack, -1);
|
634
|
+
rb_define_method(rb_cFloat, "to_asciipack", AsciiPack_to_asciipack, -1);
|
635
|
+
rb_define_method(rb_cString, "to_asciipack", AsciiPack_to_asciipack, -1);
|
636
|
+
rb_define_method(rb_cSymbol, "to_asciipack", AsciiPack_to_asciipack, -1);
|
637
|
+
rb_define_method(rb_cHash, "to_asciipack", AsciiPack_to_asciipack, -1);
|
638
|
+
rb_define_method(rb_cArray, "to_asciipack", AsciiPack_to_asciipack, -1);
|
639
|
+
rb_define_method(rb_cNilClass, "to_asciipack", AsciiPack_to_asciipack, -1);
|
640
|
+
rb_define_method(rb_cFalseClass, "to_asciipack", AsciiPack_to_asciipack, -1);
|
641
|
+
rb_define_method(rb_cTrueClass, "to_asciipack", AsciiPack_to_asciipack, -1);
|
442
642
|
}
|
data/ext/asciipack/packer.h
CHANGED
@@ -6,9 +6,43 @@
|
|
6
6
|
|
7
7
|
#include <stdlib.h>
|
8
8
|
|
9
|
+
/*
|
10
|
+
* packer:
|
11
|
+
* | - memsize - |
|
12
|
+
* +-----------------------+
|
13
|
+
* | || | |
|
14
|
+
* +-----------------------+
|
15
|
+
* ^mem ^(tag) ^mem_end
|
16
|
+
*
|
17
|
+
* main write strings memory.
|
18
|
+
* realloc when will write over size string.
|
19
|
+
* if will write too large stiring,
|
20
|
+
* it is skip and continue write from mem_end.
|
21
|
+
*
|
22
|
+
*
|
23
|
+
* tag:
|
24
|
+
* +--------------------------+
|
25
|
+
* | tag(too large string) |
|
26
|
+
* +--------------------------+ ...
|
27
|
+
* ^begin ^end
|
28
|
+
*
|
29
|
+
* too large string tag to use Copy-on-Write.
|
30
|
+
* tag->next look packer or an another tag.
|
31
|
+
*/
|
32
|
+
|
33
|
+
struct tag {
|
34
|
+
char* begin;
|
35
|
+
char* end;
|
36
|
+
unsigned int is_reference:1;
|
37
|
+
struct tag* next;
|
38
|
+
};
|
39
|
+
typedef struct tag tag_t;
|
40
|
+
|
9
41
|
struct packer {
|
10
|
-
char*
|
11
|
-
char*
|
42
|
+
char* mem;
|
43
|
+
char* mem_end;
|
44
|
+
tag_t* tag;
|
45
|
+
tag_t* start;
|
12
46
|
size_t memsize;
|
13
47
|
};
|
14
48
|
typedef struct packer packer_t;
|
@@ -22,7 +56,7 @@ union unegative_int {
|
|
22
56
|
int64_t i64;
|
23
57
|
};
|
24
58
|
|
25
|
-
#define MEMSIZE_INIT 128
|
59
|
+
#define MEMSIZE_INIT (1024*128)
|
26
60
|
|
27
61
|
#define PACKER(from, name) \
|
28
62
|
packer_t* name; \
|
data/ext/asciipack/unpacker.c
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
VALUE cAsciiPack_Unpacker;
|
4
4
|
|
5
|
-
static VALUE
|
5
|
+
static VALUE Unpacker_buffer_read(unpacker_t* ptr);
|
6
6
|
|
7
7
|
static void
|
8
8
|
unpacker_mark(unpacker_t* ptr)
|
@@ -25,8 +25,8 @@ Unpacker_init(VALUE self, VALUE obj, int argc, VALUE *argv, VALUE size)
|
|
25
25
|
rb_raise(rb_eArgError, "unallocated unpacker");
|
26
26
|
}
|
27
27
|
|
28
|
-
ptr->buffer =
|
29
|
-
ptr->ch =
|
28
|
+
ptr->buffer = NULL;
|
29
|
+
ptr->ch = NULL;
|
30
30
|
|
31
31
|
return self;
|
32
32
|
}
|
@@ -100,8 +100,8 @@ Unpacker_str (unpacker_t* ptr, size_t len)
|
|
100
100
|
char* head = ptr->ch;
|
101
101
|
|
102
102
|
VALUE str = rb_str_new(head, len);
|
103
|
-
rb_funcall(str, rb_intern("force_encoding"), 1, rb_str_new2("utf-8"));
|
104
103
|
ptr->ch += len;
|
104
|
+
rb_funcall(str, rb_intern("force_encoding"), 1, rb_str_new2("utf-8"));
|
105
105
|
return str;
|
106
106
|
}
|
107
107
|
|
@@ -111,8 +111,8 @@ Unpacker_map (unpacker_t* ptr, size_t len)
|
|
111
111
|
VALUE map = rb_hash_new();
|
112
112
|
VALUE key, value;
|
113
113
|
while (len--) {
|
114
|
-
key =
|
115
|
-
value =
|
114
|
+
key = Unpacker_buffer_read(ptr);
|
115
|
+
value = Unpacker_buffer_read(ptr);
|
116
116
|
rb_hash_aset(map, key, value);
|
117
117
|
}
|
118
118
|
return map;
|
@@ -123,13 +123,13 @@ Unpacker_array (unpacker_t* ptr, size_t len)
|
|
123
123
|
{
|
124
124
|
VALUE array = rb_ary_new2(len);
|
125
125
|
while (len--) {
|
126
|
-
rb_ary_push(array,
|
126
|
+
rb_ary_push(array, Unpacker_buffer_read(ptr));
|
127
127
|
}
|
128
128
|
return array;
|
129
129
|
}
|
130
130
|
|
131
131
|
static VALUE
|
132
|
-
|
132
|
+
Unpacker_buffer_read (unpacker_t* ptr)
|
133
133
|
{
|
134
134
|
uint64_t num;
|
135
135
|
|
@@ -270,17 +270,64 @@ Unpacker_read (unpacker_t* ptr)
|
|
270
270
|
}
|
271
271
|
|
272
272
|
static VALUE
|
273
|
-
|
273
|
+
Unpacker_read (VALUE self)
|
274
|
+
{
|
275
|
+
UNPACKER(self, ptr);
|
276
|
+
|
277
|
+
return Unpacker_buffer_read(ptr);
|
278
|
+
}
|
279
|
+
|
280
|
+
static void
|
281
|
+
Unpacker_buffer_feed (unpacker_t* ptr, VALUE obj)
|
282
|
+
{
|
283
|
+
if (rb_type(obj) != T_STRING) {
|
284
|
+
rb_raise(rb_eArgError, "can not unpack object");
|
285
|
+
}
|
286
|
+
|
287
|
+
char* p = RSTRING_PTR(obj);
|
288
|
+
|
289
|
+
ptr->buffer = p;
|
290
|
+
ptr->ch = p;
|
291
|
+
}
|
292
|
+
|
293
|
+
static VALUE
|
294
|
+
Unpacker_feed (VALUE self, VALUE obj)
|
295
|
+
{
|
296
|
+
UNPACKER(self, ptr);
|
297
|
+
|
298
|
+
Unpacker_buffer_feed(ptr, obj);
|
299
|
+
|
300
|
+
return self;
|
301
|
+
}
|
302
|
+
|
303
|
+
static void
|
304
|
+
Unpacker_buffer_clear (unpacker_t* ptr)
|
305
|
+
{
|
306
|
+
ptr->buffer = NULL;
|
307
|
+
ptr->ch = NULL;
|
308
|
+
}
|
309
|
+
|
310
|
+
static VALUE
|
311
|
+
Unpacker_clear (VALUE self)
|
274
312
|
{
|
275
313
|
UNPACKER(self, ptr);
|
276
|
-
|
314
|
+
|
315
|
+
Unpacker_buffer_clear(ptr);
|
316
|
+
|
317
|
+
return self;
|
277
318
|
}
|
278
319
|
|
279
320
|
static VALUE
|
280
|
-
AsciiPack_unpack (int argc, VALUE *argv
|
321
|
+
AsciiPack_unpack (int argc, VALUE *argv)
|
281
322
|
{
|
282
|
-
VALUE
|
283
|
-
|
323
|
+
VALUE v = argv[0];
|
324
|
+
VALUE self = Unpacker_alloc(cAsciiPack_Unpacker);
|
325
|
+
|
326
|
+
UNPACKER(self, ptr);
|
327
|
+
|
328
|
+
Unpacker_buffer_feed(ptr, v);
|
329
|
+
|
330
|
+
return Unpacker_buffer_read(ptr);
|
284
331
|
}
|
285
332
|
|
286
333
|
void
|
@@ -291,7 +338,10 @@ AsciiPack_Unpacker_init(VALUE mAsciiPack)
|
|
291
338
|
rb_define_alloc_func(cAsciiPack_Unpacker, Unpacker_alloc);
|
292
339
|
|
293
340
|
rb_define_method(cAsciiPack_Unpacker, "initialize", Unpacker_initialize, -1);
|
294
|
-
rb_define_method(cAsciiPack_Unpacker, "
|
341
|
+
rb_define_method(cAsciiPack_Unpacker, "feed", Unpacker_feed, 1);
|
342
|
+
rb_define_method(cAsciiPack_Unpacker, "read", Unpacker_read, 0);
|
343
|
+
rb_define_alias(cAsciiPack_Unpacker, "<<", "feed");
|
344
|
+
rb_define_method(cAsciiPack_Unpacker, "clear", Unpacker_clear, 0);
|
295
345
|
|
296
346
|
rb_define_module_function(mAsciiPack, "unpack", AsciiPack_unpack, -1);
|
297
347
|
}
|
data/lib/asciipack/version.rb
CHANGED
data/spec/bench.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
#! /usr/bin/env ruby
|
2
2
|
|
3
3
|
lib = File.expand_path('../../lib', __FILE__)
|
4
|
+
here = File.dirname(File.expand_path(__FILE__))
|
4
5
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
6
|
|
6
7
|
require 'asciipack'
|
@@ -8,11 +9,11 @@ require 'json'
|
|
8
9
|
require 'msgpack'
|
9
10
|
|
10
11
|
def count
|
11
|
-
|
12
|
+
1
|
12
13
|
end
|
13
14
|
|
14
15
|
def reports (obj)
|
15
|
-
obj =
|
16
|
+
obj =[obj] * 1
|
16
17
|
json = obj.to_json
|
17
18
|
ap = AsciiPack.pack obj
|
18
19
|
ms = Marshal.dump obj
|
@@ -39,31 +40,25 @@ def json_asciipack(name, obj)
|
|
39
40
|
count.times {
|
40
41
|
func.call
|
41
42
|
}
|
42
|
-
results << "%.
|
43
|
+
results << "%.6f" % ((Time.now - t) * 1000)
|
43
44
|
}
|
44
45
|
puts results.join("|") + "|"
|
45
46
|
end
|
46
47
|
|
47
48
|
puts("|object|" + reports(0).keys.join("|") + "|")
|
48
|
-
puts("|---|" + reports(0).keys.map{"
|
49
|
+
puts("|---|" + reports(0).keys.map{"---:"}.join("|") + "|")
|
49
50
|
|
50
51
|
map16 = {}
|
51
|
-
|
52
|
+
0x10000.times {|i| map16[i.to_s] = 0 }
|
52
53
|
|
53
54
|
tt = Time.now
|
54
55
|
{
|
55
|
-
"
|
56
|
-
"
|
57
|
-
"
|
58
|
-
"
|
59
|
-
"
|
60
|
-
"
|
61
|
-
"str 32" => 'a' * 0x10000,
|
62
|
-
"map 4" => {},
|
63
|
-
"map 16" => map16,
|
64
|
-
"array 4" => [],
|
65
|
-
"array 16" => Array.new(0x100,0),
|
66
|
-
"nil" => nil,
|
56
|
+
"float 64" => [1.0/3.0] * 100,
|
57
|
+
"str (1KB)" => ['a' * 1024],
|
58
|
+
"str (1MB)" => ['a' * 1024*1024],
|
59
|
+
"str (100MB)" => ['a' * 100*1024*1024],
|
60
|
+
"map 32" => map16,
|
61
|
+
"array 32" => Array.new(0x10000,0),
|
67
62
|
}.each { |key, value|
|
68
63
|
json_asciipack key, value
|
69
64
|
}
|
data/spec/format_spec.rb
CHANGED
@@ -12,6 +12,7 @@ describe AsciiPack do
|
|
12
12
|
it "int 4" do
|
13
13
|
format -1, T.int4, 2
|
14
14
|
format -8, T.int4, 2
|
15
|
+
expect(-1.to_asciipack).to eq(T.int4 + 'f')
|
15
16
|
end
|
16
17
|
|
17
18
|
it "int 8" do
|
@@ -39,6 +40,7 @@ describe AsciiPack do
|
|
39
40
|
format 0x1, T.positive_fixint_1, 1
|
40
41
|
format 0xe, T.positive_fixint_E, 1
|
41
42
|
format 0xf, T.positive_fixint_F, 1
|
43
|
+
expect(0.to_asciipack).to eq(T.positive_fixint_0)
|
42
44
|
end
|
43
45
|
|
44
46
|
it "uint 8" do
|
@@ -59,6 +61,7 @@ describe AsciiPack do
|
|
59
61
|
it "uint 64" do
|
60
62
|
format 0x100000000, T.uint64, 17
|
61
63
|
format 0xffffffffffffffff, T.uint64, 17
|
64
|
+
expect(0xffffffffffffffff.to_asciipack).to eq(T.uint64 + 'ffffffffffffffff')
|
62
65
|
end
|
63
66
|
|
64
67
|
it "float 64" do
|
@@ -70,11 +73,12 @@ describe AsciiPack do
|
|
70
73
|
check_each_other(1.0, T.float64 + '3ff0000000000000')
|
71
74
|
check_each_other(1.0000000000000002, T.float64 + '3ff0000000000001')
|
72
75
|
check_each_other(1.0000000000000004, T.float64 + '3ff0000000000002')
|
73
|
-
check_each_other(1/3.0, T.float64 + '3fd5555555555555')
|
76
|
+
check_each_other(1.0/3.0, T.float64 + '3fd5555555555555')
|
74
77
|
expect(AsciiPack.pack(Float::NAN)).to eq(T.float64 + '7ff8000000000000')
|
75
78
|
expect(AsciiPack.unpack(T.float64 + '7ff8000000000000').nan?).to be true
|
76
79
|
check_each_other(1 / 0.0, T.float64 + '7ff0000000000000')
|
77
80
|
check_each_other(-1 / 0.0, T.float64 + 'fff0000000000000')
|
81
|
+
expect(1.0.to_asciipack).to eq(T.float64 + '3ff0000000000000')
|
78
82
|
end
|
79
83
|
|
80
84
|
it "fixstr" do
|
@@ -84,6 +88,7 @@ describe AsciiPack do
|
|
84
88
|
format "漢字", T.fixstr_6, 7
|
85
89
|
format " " * 0xe, T.fixstr_E, 15
|
86
90
|
format " " * 0xf, T.fixstr_F, 16
|
91
|
+
expect("".to_asciipack).to eq(T.fixstr_0)
|
87
92
|
end
|
88
93
|
|
89
94
|
it "str 8" do
|
@@ -102,9 +107,14 @@ describe AsciiPack do
|
|
102
107
|
# format "a" * 0xffffffff, T.str32, 9 + 0xffffffff
|
103
108
|
end
|
104
109
|
|
110
|
+
it "symbol is converted to str" do
|
111
|
+
expect(:sym.to_asciipack).to eq(T.fixstr_3 + 'sym')
|
112
|
+
end
|
113
|
+
|
105
114
|
it "map 4" do
|
106
115
|
format_map 0, T.map4
|
107
116
|
format_map 0xf, T.map4
|
117
|
+
expect({}.to_asciipack).to eq(T.map4 + '0')
|
108
118
|
end
|
109
119
|
|
110
120
|
it "map 8" do
|
@@ -126,6 +136,7 @@ describe AsciiPack do
|
|
126
136
|
it "array 4" do
|
127
137
|
format_array 0, T.array4
|
128
138
|
format_array 0xf, T.array4
|
139
|
+
expect([].to_asciipack).to eq(T.array4 + '0')
|
129
140
|
end
|
130
141
|
|
131
142
|
it "array 8" do
|
@@ -154,14 +165,17 @@ describe AsciiPack do
|
|
154
165
|
|
155
166
|
it "nil" do
|
156
167
|
format nil, T.nil, 1
|
168
|
+
expect(nil.to_asciipack).to eq(T.nil)
|
157
169
|
end
|
158
170
|
|
159
171
|
it "false" do
|
160
172
|
format false, T.false, 1
|
173
|
+
expect(false.to_asciipack).to eq(T.false)
|
161
174
|
end
|
162
175
|
|
163
176
|
it "true" do
|
164
177
|
format true, T.true, 1
|
178
|
+
expect(true.to_asciipack).to eq(T.true)
|
165
179
|
end
|
166
180
|
end
|
167
181
|
|
data/spec/mem_spec.rb
CHANGED
@@ -2,14 +2,26 @@
|
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
5
|
+
describe "AsciiPack:memory" do
|
6
|
+
it "packer:num" do
|
7
|
+
check([1,1.1,-1.1,1.0/3.0,0xffffffffffffffff,-0x8000000000000000,0,Float::INFINITY] * 3)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "packer:str" do
|
11
|
+
check(["a"*100*1024*1024,"b"*1024*1024,"c"*1024] * 3)
|
12
|
+
end
|
13
|
+
|
14
|
+
def check (obj)
|
15
|
+
packer = AsciiPack::Packer.new
|
16
|
+
obj.each {|i|
|
17
|
+
packer.write i
|
18
|
+
GC.start
|
19
|
+
expect(AsciiPack.unpack(packer.to_s)).to eq(i)
|
20
|
+
GC.start
|
21
|
+
packer.clear
|
22
|
+
expect(packer.to_s).to eq("")
|
23
|
+
}
|
24
|
+
expect(AsciiPack.unpack(obj.to_asciipack)).to eq(obj)
|
13
25
|
end
|
14
26
|
end
|
15
27
|
|
data/spec/packer_spec.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe AsciiPack::Packer do
|
4
|
+
let :packer do
|
5
|
+
AsciiPack::Packer.new
|
6
|
+
end
|
7
|
+
|
8
|
+
it "pack:to_s:clear" do
|
9
|
+
packer.write nil
|
10
|
+
expect(packer.to_s).to eq(T.nil)
|
11
|
+
|
12
|
+
packer.write 0
|
13
|
+
expect(packer.to_s).to eq(T.nil + T.positive_fixint_0)
|
14
|
+
|
15
|
+
packer.write "a"
|
16
|
+
expect(packer.to_s).to eq(T.nil + T.positive_fixint_0 + T.fixstr_1 + "a")
|
17
|
+
|
18
|
+
packer.clear
|
19
|
+
expect(packer.to_s).to eq("")
|
20
|
+
|
21
|
+
packer.write nil
|
22
|
+
expect(packer.to_s).to eq(T.nil)
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe AsciiPack::Unpacker do
|
4
|
+
let :unpacker do
|
5
|
+
AsciiPack::Unpacker.new
|
6
|
+
end
|
7
|
+
|
8
|
+
it "read:to_s:clear" do
|
9
|
+
unpacker.feed "W"
|
10
|
+
expect(unpacker.read).to eq(nil)
|
11
|
+
|
12
|
+
unpacker.feed "X"
|
13
|
+
expect(unpacker.read).to eq(false)
|
14
|
+
|
15
|
+
unpacker.feed "Y"
|
16
|
+
expect(unpacker.read).to eq(true)
|
17
|
+
end
|
18
|
+
end
|
metadata
CHANGED
@@ -1,69 +1,69 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: asciipack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ksss
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-11-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '1.3'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.3'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - ~>
|
45
|
+
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '2.11'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - ~>
|
52
|
+
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '2.11'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rake-compiler
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - ~>
|
59
|
+
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: 0.8.3
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - ~>
|
66
|
+
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: 0.8.3
|
69
69
|
description: AsciiPack is an object serialization inspired by MessagePack.
|
@@ -73,7 +73,7 @@ extensions:
|
|
73
73
|
- ext/asciipack/extconf.rb
|
74
74
|
extra_rdoc_files: []
|
75
75
|
files:
|
76
|
-
- .gitignore
|
76
|
+
- ".gitignore"
|
77
77
|
- Gemfile
|
78
78
|
- LICENSE.txt
|
79
79
|
- README.md
|
@@ -88,9 +88,12 @@ files:
|
|
88
88
|
- lib/asciipack.rb
|
89
89
|
- lib/asciipack/version.rb
|
90
90
|
- spec/bench.rb
|
91
|
+
- spec/exception_spec.rb
|
91
92
|
- spec/format_spec.rb
|
92
93
|
- spec/mem_spec.rb
|
94
|
+
- spec/packer_spec.rb
|
93
95
|
- spec/spec_helper.rb
|
96
|
+
- spec/unpacker_spec.rb
|
94
97
|
homepage: http://ksss.github.io/AsciiPack
|
95
98
|
licenses:
|
96
99
|
- MIT
|
@@ -101,23 +104,26 @@ require_paths:
|
|
101
104
|
- lib
|
102
105
|
required_ruby_version: !ruby/object:Gem::Requirement
|
103
106
|
requirements:
|
104
|
-
- -
|
107
|
+
- - ">="
|
105
108
|
- !ruby/object:Gem::Version
|
106
109
|
version: '0'
|
107
110
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
108
111
|
requirements:
|
109
|
-
- -
|
112
|
+
- - ">="
|
110
113
|
- !ruby/object:Gem::Version
|
111
114
|
version: '0'
|
112
115
|
requirements: []
|
113
116
|
rubyforge_project:
|
114
|
-
rubygems_version: 2.
|
117
|
+
rubygems_version: 2.2.0
|
115
118
|
signing_key:
|
116
119
|
specification_version: 4
|
117
120
|
summary: AsciiPack is an object serialization inspired by MessagePack.
|
118
121
|
test_files:
|
119
122
|
- spec/bench.rb
|
123
|
+
- spec/exception_spec.rb
|
120
124
|
- spec/format_spec.rb
|
121
125
|
- spec/mem_spec.rb
|
126
|
+
- spec/packer_spec.rb
|
122
127
|
- spec/spec_helper.rb
|
128
|
+
- spec/unpacker_spec.rb
|
123
129
|
has_rdoc:
|