asciipack 0.2.2 → 0.2.3
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/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
|
[](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:
|