rcstorable 0.3.4 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/ext/rcstorable.c +27 -23
- data/spec/rcstorable_spec.rb +18 -6
- data/spec/store.pl +3 -2
- metadata +2 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.4.0
|
data/ext/rcstorable.c
CHANGED
@@ -9,7 +9,7 @@ typedef unsigned char uchar;
|
|
9
9
|
|
10
10
|
VALUE thaw(VALUE, VALUE);
|
11
11
|
static VALUE read_object();
|
12
|
-
static VALUE
|
12
|
+
static VALUE read_number();
|
13
13
|
static uint32_t read_32_bit_integer();
|
14
14
|
static uint32_t read_compact_size();
|
15
15
|
static void read_n_hash_pairs(VALUE, uint32_t);
|
@@ -18,23 +18,23 @@ static VALUE read_string(bool);
|
|
18
18
|
static void read_magic_numbers();
|
19
19
|
static inline void check_pointer(uchar*);
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
21
|
+
/* Perl Storable encodes values with an associated type.
|
22
|
+
* There are probably more types than are enumerated here,
|
23
|
+
* but I've yet to encounter them. */
|
24
24
|
|
25
25
|
enum perl_types {
|
26
|
-
|
27
|
-
PT_ARRAY
|
28
|
-
PT_HASH
|
29
|
-
PT_VECTOR
|
30
|
-
PT_UNDEF
|
31
|
-
|
32
|
-
PT_INT32
|
33
|
-
PT_STRING
|
34
|
-
PT_STRING_ALT
|
26
|
+
PT_LONG_STRING = 1,
|
27
|
+
PT_ARRAY = 2,
|
28
|
+
PT_HASH = 3,
|
29
|
+
PT_VECTOR = 4,
|
30
|
+
PT_UNDEF = 5,
|
31
|
+
PT_NUMBER = 8,
|
32
|
+
PT_INT32 = 9,
|
33
|
+
PT_STRING = 10,
|
34
|
+
PT_STRING_ALT = 23
|
35
35
|
};
|
36
36
|
|
37
|
-
|
37
|
+
/* Used globally. Raptors. I know. */
|
38
38
|
static uchar *serialized;
|
39
39
|
static uchar *serialized_end;
|
40
40
|
|
@@ -46,7 +46,7 @@ static uchar *error_message = "malformed data";
|
|
46
46
|
VALUE
|
47
47
|
thaw(VALUE self, VALUE str)
|
48
48
|
{
|
49
|
-
if (str == Qnil) return Qnil;
|
49
|
+
if (str == Qnil) return Qnil; /* Do something logical with nil. */
|
50
50
|
|
51
51
|
Check_Type(str, T_STRING);
|
52
52
|
extern uchar *serialized, *serialized_end;
|
@@ -115,18 +115,18 @@ read_object()
|
|
115
115
|
size = read_32_bit_integer();
|
116
116
|
read_n_array_entries(object, size);
|
117
117
|
break;
|
118
|
-
case
|
119
|
-
object =
|
118
|
+
case PT_NUMBER:
|
119
|
+
object = read_number();
|
120
120
|
break;
|
121
121
|
case PT_STRING:
|
122
122
|
case PT_STRING_ALT:
|
123
123
|
object = read_string(false);
|
124
124
|
break;
|
125
|
-
case
|
125
|
+
case PT_LONG_STRING:
|
126
126
|
object = read_string(true);
|
127
127
|
break;
|
128
128
|
case PT_VECTOR:
|
129
|
-
object = read_object();
|
129
|
+
object = read_object(); /* This is a marker we can just ignore... */
|
130
130
|
break;
|
131
131
|
}
|
132
132
|
|
@@ -147,12 +147,16 @@ read_n_hash_pairs(VALUE hash, uint32_t num)
|
|
147
147
|
read_n_hash_pairs(hash, num-1);
|
148
148
|
}
|
149
149
|
|
150
|
+
/*
|
151
|
+
* Numbers below |128| are encoded as a sort of signed byte.
|
152
|
+
* High bit 0 implies negative, high bit 1 implies positive.
|
153
|
+
*/
|
150
154
|
static VALUE
|
151
|
-
|
155
|
+
read_number()
|
152
156
|
{
|
153
157
|
extern uchar *serialized;
|
154
158
|
check_pointer(serialized);
|
155
|
-
return (*serialized++
|
159
|
+
return INT2FIX((signed char)(*serialized++ ^ 0x80));
|
156
160
|
}
|
157
161
|
|
158
162
|
/*
|
@@ -187,7 +191,7 @@ read_string(bool extended_size)
|
|
187
191
|
uint32_t actual_size = 0;
|
188
192
|
uchar *tp = serialized;
|
189
193
|
|
190
|
-
if (size == 319) {
|
194
|
+
if (size == 319) { /* apparently Storable uses \000\000\001\077 to mean "read until n<7" */
|
191
195
|
while (*tp++ >= 7) {
|
192
196
|
check_pointer(tp);
|
193
197
|
actual_size++;
|
@@ -218,7 +222,7 @@ read_32_bit_integer()
|
|
218
222
|
|
219
223
|
check_pointer(serialized+3);
|
220
224
|
|
221
|
-
|
225
|
+
/* I don't want to deal with byte-order. This is just easier. */
|
222
226
|
size += (*serialized++)*16777216;
|
223
227
|
size += (*serialized++)*65536;
|
224
228
|
size += (*serialized++)*256;
|
data/spec/rcstorable_spec.rb
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
require 'rcstorable'
|
2
2
|
|
3
3
|
describe RCStorable do
|
4
|
-
|
5
|
-
|
6
|
-
it "should correctly decode format A" do
|
4
|
+
|
5
|
+
it "should understand Format 1286" do
|
7
6
|
store = "\005\006\003\000\000\000\005\005\000\000\000\aAaaaaaa\004\003\000\000\000\017\n\fasdjfsadfjfd\000\000\000\tdkjfjaksj\n\00560565\000\000\000\nksdjfksjdf\n\020aksjgjeijpqiwjff\000\000\000\020ksdjfkasjfkjefjj\n\022ewjfklqjkzxjfnvnds\000\000\000\ajfjwjwj\n\nlsakdvnnff\000\000\000\004qpwo\n\002jf\000\000\000\005qwojf\n\bzxemffew\000\000\000\005owjff\n\004zjxf\000\000\000\016jzxmfnfkneoqjf\n\003jas\000\000\000\aowfjjwf\n\003jfw\000\000\000\rjadsnzxfkjfej\n\005oqwfj\000\000\000\bqpwofjff\n\004owjf\000\000\000\njzxnfnqwwf\n\000\000\000\000\nqpwofjfjww\n\000\000\000\000\vpdofjfejqwj\n\002jf\000\000\000\vpwqofjwjqfj\000\000\000\apojsfww\005\000\000\000\005posjf\004\002\000\000\000\001\001\000\000\001?sdlkfjewigjepofjqwpfjsdalkfjqepogjgpojqwfpowejfqpowfjlksdjdslkgjsdflgjerhgi;oerhjgoiprejwgioperjgkl;djglsdk;fgjsdlkf;gjal;gfjerigjergkjarigojaegkl;sdfnga;lksfjwi;eogjieryjkw;ljfa;sdlgkhjaglkajwegf;lkajgaweklfhajklghawejklghawejkhawelurhaewtluiawehtawlkjehfasjkldfnasjklfhsadfjklashfluiewhwlquthqluitqwyeoiuthwefjklasdhfkjlasdfnbasjlkdfhqweuiltqytoeqwieutyqoeto9845yhsjdaghfajkewntewakjlhtawkerhweuirhaweruhewiurahwefljkshdafjhadkf\n\000\000\000\003oje\005\000\000\000\016lsdkfjlkfjqwtr"
|
8
7
|
|
9
8
|
expected = {"Aaaaaaa"=>nil, "lsdkfjlkfjqwtr"=>nil, "posjf"=>nil, "oje"=>["sdlkfjewigjepofjqwpfjsdalkfjqepogjgpojqwfpowejfqpowfjlksdjdslkgjsdflgjerhgi;oerhjgoiprejwgioperjgkl;djglsdk;fgjsdlkf;gjal;gfjerigjergkjarigojaegkl;sdfnga;lksfjwi;eogjieryjkw;ljfa;sdlgkhjaglkajwegf;lkajgaweklfhajklghawejklghawejkhawelurhaewtluiawehtawlkjehfasjkldfnasjklfhsadfjklashfluiewhwlquthqluitqwyeoiuthwefjklasdhfkjlasdfnbasjlkdfhqweuiltqytoeqwieutyqoeto9845yhsjdaghfajkewntewakjlhtawkerhweuirhaweruhewiurahwefljkshdafjhadkf\n"], "pojsfww"=>{"jfjwjwj"=>"ewjfklqjkzxjfnvnds", "qpwo"=>"lsakdvnnff", "ksdjfksjdf"=>"60565", "pdofjfejqwj"=>"", "owfjjwf"=>"jas", "owjff"=>"zxemffew", "jzxnfnqwwf"=>"owjf", "qpwofjff"=>"oqwfj", "jadsnzxfkjfej"=>"jfw", "ksdjfkasjfkjefjj"=>"aksjgjeijpqiwjff", "pwqofjwjqfj"=>"jf", "dkjfjaksj"=>"asdjfsadfjfd", "qpwofjfjww"=>"", "jzxmfnfkneoqjf"=>"zjxf", "qwojf"=>"jf"}}
|
@@ -11,7 +10,7 @@ describe RCStorable do
|
|
11
10
|
RCStorable.thaw(store).should == expected
|
12
11
|
end
|
13
12
|
|
14
|
-
it "
|
13
|
+
it "Should understand Format 1287" do
|
15
14
|
store = "\005\a\003\000\000\000\004\004\003\000\000\000\002\n\004blah\000\000\000\001p\001\000\000\002>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.\000\000\000\001q\000\000\000\001c\n\00229\000\000\000\017longer_key_name\n\020A longish string\000\000\000\001a\n\00235\000\000\000\001b"
|
16
15
|
|
17
16
|
expected = {
|
@@ -27,7 +26,7 @@ describe RCStorable do
|
|
27
26
|
RCStorable.thaw(store).should == expected
|
28
27
|
end
|
29
28
|
|
30
|
-
it "
|
29
|
+
it "should handle Format 1287 arrays" do
|
31
30
|
store = "\005\a\003\000\000\000\001\004\002\000\000\000\003\n\004asdf\n\004zxcv\n\004qwer\000\000\000\001b"
|
32
31
|
|
33
32
|
expected = {"b" => ["asdf", "zxcv", "qwer"]}
|
@@ -35,11 +34,24 @@ describe RCStorable do
|
|
35
34
|
RCStorable.thaw(store).should == expected
|
36
35
|
end
|
37
36
|
|
38
|
-
it "empty hash" do
|
37
|
+
it "should handle an empty hash" do
|
39
38
|
store = "\005\a\003\000\000\000\001\004\003\000\000\000\000\000\000\000\001a"
|
40
39
|
|
41
40
|
expected = {"a" => {}}
|
42
41
|
RCStorable.thaw(store).should == expected
|
43
42
|
end
|
43
|
+
|
44
|
+
it "should understand numbers" do
|
45
|
+
store = "\005\a\003\000\000\000\003\bX\000\000\000\001a\b\200\000\000\000\001b\b\373\000\000\000\001c"
|
46
|
+
expected = {"a" => -40, "b" => 0, "c" => 123}
|
47
|
+
|
48
|
+
RCStorable.thaw(store).should == expected
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should understand nil" do
|
52
|
+
store = "\005\a\003\000\000\000\001\005\000\000\000\001a"
|
53
|
+
expected = {"a" => nil}
|
54
|
+
RCStorable.thaw(store).should == expected
|
55
|
+
end
|
44
56
|
|
45
57
|
end
|
data/spec/store.pl
CHANGED
@@ -1,11 +1,12 @@
|
|
1
|
-
use strict;
|
1
|
+
#use strict;
|
2
2
|
use warnings;
|
3
3
|
|
4
4
|
use Storable;
|
5
5
|
use Data::Dumper;
|
6
6
|
|
7
7
|
my %blah = (
|
8
|
-
"a" =>
|
8
|
+
"a" => 123,
|
9
|
+
"b" => -40
|
9
10
|
);
|
10
11
|
|
11
12
|
#my $x = "004\a\b12345678\004\b\b\b\003\004\000\000\000\004\003\002\000\000\000\n\004blah\001\000\000\000p\001>\002\000\000Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.\001\000\000\000q\001\000\000\000c\n\00229\017\000\000\000longer_key_name\n\020A longish string\001\000\000\000a\n\00235\001\000\000\000b";
|