rcstorable 0.2.3 → 0.2.4

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.
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