rcstorable 0.2.3 → 0.2.4
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/ext/rcstorable.bundle +0 -0
- data/ext/rcstorable.c +68 -89
- data/ext/rcstorable.o +0 -0
- data/spec/store.pl +0 -2
- metadata +1 -1
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.4
|
data/ext/rcstorable.bundle
CHANGED
Binary file
|
data/ext/rcstorable.c
CHANGED
@@ -1,19 +1,22 @@
|
|
1
1
|
#include <stdbool.h>
|
2
2
|
#include <stdio.h>
|
3
3
|
#include <string.h>
|
4
|
+
#include <stdint.h>
|
4
5
|
|
5
6
|
#include "ruby.h"
|
6
7
|
|
8
|
+
typedef unsigned char uchar;
|
9
|
+
|
7
10
|
VALUE thaw(VALUE, VALUE);
|
8
11
|
static VALUE read_object();
|
9
12
|
static VALUE read_boolean();
|
10
|
-
static
|
11
|
-
static
|
12
|
-
static void read_n_hash_pairs(VALUE,
|
13
|
-
static void read_n_array_entries(VALUE,
|
13
|
+
static uint32_t read_32_bit_integer();
|
14
|
+
static uint32_t read_compact_size();
|
15
|
+
static void read_n_hash_pairs(VALUE, uint32_t);
|
16
|
+
static void read_n_array_entries(VALUE, uint32_t);
|
14
17
|
static VALUE read_string(bool);
|
15
18
|
static void read_magic_numbers();
|
16
|
-
static void check_pointer(
|
19
|
+
static void check_pointer(uchar*);
|
17
20
|
|
18
21
|
enum perl_types
|
19
22
|
{
|
@@ -23,13 +26,14 @@ enum perl_types
|
|
23
26
|
PT_VECTOR = 4,
|
24
27
|
PT_UNDEF = 5,
|
25
28
|
PT_BOOLEAN = 8,
|
29
|
+
PT_INT32 = 9,
|
26
30
|
PT_STRING = 10,
|
27
31
|
PT_STRING_ALT = 23
|
28
32
|
};
|
29
33
|
|
30
34
|
// Used globally. Raptors. I know.
|
31
|
-
static
|
32
|
-
static
|
35
|
+
static uchar *serialized;
|
36
|
+
static uchar *serialized_end;
|
33
37
|
|
34
38
|
/*
|
35
39
|
* Given a perl Storable frozen blob, decode it into a ruby data structure.
|
@@ -38,7 +42,7 @@ VALUE
|
|
38
42
|
thaw(VALUE self, VALUE str)
|
39
43
|
{
|
40
44
|
Check_Type(str, T_STRING);
|
41
|
-
extern
|
45
|
+
extern uchar *serialized, *serialized_end;
|
42
46
|
|
43
47
|
serialized = RSTRING_PTR(str);
|
44
48
|
serialized_end = serialized + RSTRING_LEN(str);
|
@@ -53,9 +57,9 @@ thaw(VALUE self, VALUE str)
|
|
53
57
|
* We'll check pretty much everything we do against the pre-computed end-of-string.
|
54
58
|
*/
|
55
59
|
static void
|
56
|
-
check_pointer(
|
60
|
+
check_pointer(uchar *ptr)
|
57
61
|
{
|
58
|
-
extern
|
62
|
+
extern uchar *serialized_end;
|
59
63
|
if (ptr > serialized_end) {
|
60
64
|
rb_raise(rb_eRangeError, "malformed data");
|
61
65
|
}
|
@@ -68,10 +72,9 @@ check_pointer(unsigned char *ptr)
|
|
68
72
|
static void
|
69
73
|
read_magic_numbers()
|
70
74
|
{
|
71
|
-
extern
|
75
|
+
extern uchar *serialized;
|
72
76
|
check_pointer(serialized+1);
|
73
|
-
serialized
|
74
|
-
serialized++;
|
77
|
+
serialized += 2;
|
75
78
|
}
|
76
79
|
|
77
80
|
/*
|
@@ -81,24 +84,39 @@ read_magic_numbers()
|
|
81
84
|
static VALUE
|
82
85
|
read_object()
|
83
86
|
{
|
84
|
-
extern
|
87
|
+
extern uchar *serialized;
|
85
88
|
check_pointer(serialized);
|
86
|
-
|
87
|
-
|
89
|
+
uint32_t type = *serialized++;
|
90
|
+
uint32_t size = 0;
|
88
91
|
|
89
|
-
VALUE object;
|
92
|
+
VALUE object = Qnil;
|
90
93
|
|
91
94
|
switch(type) {
|
95
|
+
case PT_UNDEF:
|
96
|
+
object = Qnil;
|
97
|
+
break;
|
92
98
|
case PT_HASH:
|
93
99
|
object = rb_hash_new();
|
100
|
+
size = read_32_bit_integer();
|
94
101
|
read_n_hash_pairs(object, size);
|
95
102
|
break;
|
103
|
+
case PT_INT32:
|
104
|
+
object = read_32_bit_integer();
|
105
|
+
break;
|
96
106
|
case PT_ARRAY:
|
97
107
|
object = rb_ary_new();
|
108
|
+
size = read_32_bit_integer();
|
98
109
|
read_n_array_entries(object, size);
|
99
110
|
break;
|
100
|
-
case
|
101
|
-
object =
|
111
|
+
case PT_BOOLEAN:
|
112
|
+
object = read_boolean();
|
113
|
+
break;
|
114
|
+
case PT_STRING:
|
115
|
+
case PT_STRING_ALT:
|
116
|
+
object = read_string(false);
|
117
|
+
break;
|
118
|
+
case PT_VECTOR:
|
119
|
+
object = read_object(); // This is a marker we can just ignore...
|
102
120
|
break;
|
103
121
|
}
|
104
122
|
|
@@ -111,45 +129,18 @@ read_object()
|
|
111
129
|
* Now we need to read in n items, and add them to the hash.
|
112
130
|
*/
|
113
131
|
static void
|
114
|
-
read_n_hash_pairs(VALUE hash,
|
132
|
+
read_n_hash_pairs(VALUE hash, uint32_t num)
|
115
133
|
{
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
if (num == 0) {
|
120
|
-
return;
|
121
|
-
}
|
122
|
-
|
123
|
-
int type = *serialized++;
|
124
|
-
VALUE temp;
|
125
|
-
VALUE str;
|
126
|
-
|
127
|
-
switch(type) {
|
128
|
-
case PT_UNDEF:
|
129
|
-
rb_hash_aset(hash, read_string(true), Qnil);
|
130
|
-
break;
|
131
|
-
case PT_VECTOR:
|
132
|
-
temp = read_object();
|
133
|
-
str = read_string(true);
|
134
|
-
rb_hash_aset(hash, str, temp);
|
135
|
-
break;
|
136
|
-
case PT_BOOLEAN:
|
137
|
-
temp = read_boolean();
|
138
|
-
rb_hash_aset(hash, read_string(true), temp);
|
139
|
-
break;
|
140
|
-
case PT_STRING:
|
141
|
-
case PT_STRING_ALT:
|
142
|
-
temp = read_string(false);
|
143
|
-
rb_hash_aset(hash, read_string(true), temp);
|
144
|
-
break;
|
145
|
-
}
|
146
|
-
|
134
|
+
if (num == 0) { return; }
|
135
|
+
VALUE temp = read_object();
|
136
|
+
rb_hash_aset(hash, read_string(true), temp);
|
147
137
|
read_n_hash_pairs(hash, num-1);
|
148
138
|
}
|
149
139
|
|
150
140
|
static VALUE
|
151
141
|
read_boolean()
|
152
142
|
{
|
143
|
+
extern uchar *serialized;
|
153
144
|
check_pointer(serialized);
|
154
145
|
return (*serialized++ == 128) ? Qfalse : Qtrue;
|
155
146
|
}
|
@@ -159,26 +150,10 @@ read_boolean()
|
|
159
150
|
* Now we need to read in n items, and add them to the array.
|
160
151
|
*/
|
161
152
|
static void
|
162
|
-
read_n_array_entries(VALUE array,
|
153
|
+
read_n_array_entries(VALUE array, uint32_t num)
|
163
154
|
{
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
if (num == 0) {
|
168
|
-
return;
|
169
|
-
}
|
170
|
-
|
171
|
-
VALUE item = Qnil;
|
172
|
-
int type = *serialized++;
|
173
|
-
|
174
|
-
switch(type) {
|
175
|
-
case PT_HASH_KEY:
|
176
|
-
item = read_string(true);
|
177
|
-
break;
|
178
|
-
}
|
179
|
-
|
180
|
-
rb_ary_push(array, item);
|
181
|
-
|
155
|
+
if (num == 0) { return; }
|
156
|
+
rb_ary_push(array, read_object());
|
182
157
|
read_n_array_entries(array, num-1);
|
183
158
|
}
|
184
159
|
|
@@ -191,13 +166,14 @@ read_n_array_entries(VALUE array, int num)
|
|
191
166
|
static VALUE
|
192
167
|
read_string(bool extended_size)
|
193
168
|
{
|
194
|
-
extern
|
169
|
+
extern uchar *serialized;
|
195
170
|
check_pointer(serialized);
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
171
|
+
|
172
|
+
uint32_t size = extended_size ? read_32_bit_integer() : read_compact_size();
|
173
|
+
|
174
|
+
uint32_t actual_size = 0;
|
175
|
+
uint32_t rem;
|
176
|
+
uchar *tp = serialized;
|
201
177
|
|
202
178
|
if (size == 319) { // apparently Storable uses \000\000\001\077 to mean "read until n<7"
|
203
179
|
while (*tp++ >= 7) {
|
@@ -208,8 +184,8 @@ read_string(bool extended_size)
|
|
208
184
|
}
|
209
185
|
rem = size;
|
210
186
|
|
211
|
-
|
212
|
-
|
187
|
+
uchar *np = ALLOCA_N(char, size+1);
|
188
|
+
uchar *cnp = np;
|
213
189
|
|
214
190
|
check_pointer(serialized+rem-1);
|
215
191
|
while (rem > 0) {
|
@@ -226,17 +202,20 @@ read_string(bool extended_size)
|
|
226
202
|
* Extended sizes are given as [w,x,y,z], where the size is 256*y + z.
|
227
203
|
* This should really be read as a uint_32t, I guess.
|
228
204
|
*/
|
229
|
-
static
|
230
|
-
|
205
|
+
static uint32_t
|
206
|
+
read_32_bit_integer()
|
231
207
|
{
|
232
|
-
extern
|
233
|
-
|
208
|
+
extern uchar *serialized;
|
209
|
+
|
210
|
+
uint32_t size = 0;
|
211
|
+
|
234
212
|
check_pointer(serialized+3);
|
235
|
-
|
236
|
-
|
237
|
-
serialized
|
238
|
-
size +=
|
239
|
-
size += *serialized
|
213
|
+
|
214
|
+
// I don't want to deal with byte-order. This is just easier.
|
215
|
+
size += (*serialized++)*16777216;
|
216
|
+
size += (*serialized++)*65536;
|
217
|
+
size += (*serialized++)*256;
|
218
|
+
size += (*serialized++);
|
240
219
|
|
241
220
|
return size;
|
242
221
|
}
|
@@ -244,10 +223,10 @@ read_extended_size()
|
|
244
223
|
/*
|
245
224
|
* Just one byte.
|
246
225
|
*/
|
247
|
-
static
|
226
|
+
static uint32_t
|
248
227
|
read_compact_size() {
|
228
|
+
extern uchar *serialized;
|
249
229
|
check_pointer(serialized);
|
250
|
-
extern unsigned char *serialized;
|
251
230
|
return *serialized++;
|
252
231
|
}
|
253
232
|
|
data/ext/rcstorable.o
CHANGED
Binary file
|
data/spec/store.pl
CHANGED