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 CHANGED
@@ -1 +1 @@
1
- 0.2.3
1
+ 0.2.4
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 int read_extended_size();
11
- static int read_compact_size();
12
- static void read_n_hash_pairs(VALUE, int);
13
- static void read_n_array_entries(VALUE, int);
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(unsigned char*);
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 unsigned char *serialized;
32
- static unsigned char *serialized_end;
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 unsigned char *serialized, *serialized_end;
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(unsigned char *ptr)
60
+ check_pointer(uchar *ptr)
57
61
  {
58
- extern unsigned char *serialized_end;
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 unsigned char *serialized;
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 unsigned char *serialized;
87
+ extern uchar *serialized;
85
88
  check_pointer(serialized);
86
- int type = *serialized++;
87
- int size = read_extended_size();
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 PT_UNDEF:
101
- object = Qnil;
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, int num)
132
+ read_n_hash_pairs(VALUE hash, uint32_t num)
115
133
  {
116
- extern unsigned char *serialized;
117
- check_pointer(serialized);
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, int num)
153
+ read_n_array_entries(VALUE array, uint32_t num)
163
154
  {
164
- extern unsigned char *serialized;
165
- check_pointer(serialized);
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 unsigned char *serialized;
169
+ extern uchar *serialized;
195
170
  check_pointer(serialized);
196
-
197
- int size = extended_size ? read_extended_size() : read_compact_size();
198
- int actual_size = 0;
199
- int rem;
200
- char *tp = serialized;
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
- char *np = malloc(size * sizeof(char) + 1);
212
- char *cnp = np;
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 int
230
- read_extended_size()
205
+ static uint32_t
206
+ read_32_bit_integer()
231
207
  {
232
- extern unsigned char *serialized;
233
- int size = 0;
208
+ extern uchar *serialized;
209
+
210
+ uint32_t size = 0;
211
+
234
212
  check_pointer(serialized+3);
235
-
236
- serialized++;
237
- serialized++;
238
- size += 256*(*serialized++);
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 int
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
@@ -5,7 +5,5 @@ use warnings;
5
5
  use Storable;
6
6
  use Data::Dumper;
7
7
 
8
-
9
-
10
8
  print Dumper(Storable::thaw($x));
11
9
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rcstorable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Burke Libbey