asciipack 0.1.3 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/Rakefile +10 -2
- data/asciipack.gemspec +2 -1
- data/ext/asciipack/extconf.rb +3 -0
- data/ext/asciipack/init.c +23 -0
- data/ext/asciipack/packer.c +448 -0
- data/ext/asciipack/packer.h +40 -0
- data/ext/asciipack/unpacker.c +299 -0
- data/ext/asciipack/unpacker.h +25 -0
- data/lib/asciipack/version.rb +1 -1
- data/lib/asciipack.rb +2 -2
- data/spec/bench.rb +44 -25
- data/spec/format_spec.rb +40 -24
- data/spec/spec_helper.rb +19 -19
- metadata +24 -5
- data/lib/asciipack/packer.rb +0 -219
- data/lib/asciipack/unpacker.rb +0 -201
data/lib/asciipack/packer.rb
DELETED
@@ -1,219 +0,0 @@
|
|
1
|
-
module AsciiPack
|
2
|
-
class Packer
|
3
|
-
class << self
|
4
|
-
def pack (obj)
|
5
|
-
case
|
6
|
-
when obj.kind_of?(Hash)
|
7
|
-
map(obj);
|
8
|
-
when obj.kind_of?(Array)
|
9
|
-
array(obj);
|
10
|
-
when obj.kind_of?(Numeric)
|
11
|
-
if obj.kind_of?(Integer)
|
12
|
-
if 0 <= obj
|
13
|
-
if obj < 0x10
|
14
|
-
positive_fixint obj
|
15
|
-
elsif obj < 0x100
|
16
|
-
uint8 obj
|
17
|
-
elsif obj < 0x10000
|
18
|
-
uint16 obj
|
19
|
-
elsif obj < 0x100000000
|
20
|
-
uint32 obj
|
21
|
-
elsif obj < 0x10000000000000000
|
22
|
-
uint64 obj
|
23
|
-
end
|
24
|
-
else
|
25
|
-
if -0x8 <= obj
|
26
|
-
int4 obj
|
27
|
-
elsif -0x80 <= obj
|
28
|
-
int8 obj
|
29
|
-
elsif -0x8000 <= obj
|
30
|
-
int16 obj
|
31
|
-
elsif -0x80000000 <= obj
|
32
|
-
int32 obj
|
33
|
-
elsif -0x8000000000000000 <= obj
|
34
|
-
int64 obj
|
35
|
-
else
|
36
|
-
raise "pack size limit over"
|
37
|
-
end
|
38
|
-
end
|
39
|
-
else
|
40
|
-
float64 obj
|
41
|
-
end
|
42
|
-
when obj.kind_of?(String)
|
43
|
-
case obj.length
|
44
|
-
when 0...0x10
|
45
|
-
fixstr obj
|
46
|
-
when 0x10...0x100
|
47
|
-
str8 obj
|
48
|
-
when 0x100...0x10000
|
49
|
-
str16 obj
|
50
|
-
when 0x10000...0x100000000
|
51
|
-
str32 obj
|
52
|
-
else
|
53
|
-
raise "pack size limit over"
|
54
|
-
end
|
55
|
-
when obj.nil?
|
56
|
-
"W"
|
57
|
-
when obj == false
|
58
|
-
"X"
|
59
|
-
when obj == true
|
60
|
-
"Y"
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
private
|
65
|
-
|
66
|
-
def int4 (obj)
|
67
|
-
"a" + ((obj & 0xf).to_s(16))
|
68
|
-
end
|
69
|
-
|
70
|
-
def int8 (obj)
|
71
|
-
"b" + ((obj & 0xff).to_s(16))
|
72
|
-
end
|
73
|
-
|
74
|
-
def int16 (obj)
|
75
|
-
"c" + ((obj & 0xffff).to_s(16))
|
76
|
-
end
|
77
|
-
|
78
|
-
def int16 (obj)
|
79
|
-
"c" + ((obj & 0xffff).to_s(16))
|
80
|
-
end
|
81
|
-
|
82
|
-
def int32 (obj)
|
83
|
-
"d" + ((obj & 0xffffffff).to_s(16))
|
84
|
-
end
|
85
|
-
|
86
|
-
def int64 (obj)
|
87
|
-
"e" + ((obj & 0xffffffffffffffff).to_s(16))
|
88
|
-
end
|
89
|
-
|
90
|
-
def positive_fixint (obj)
|
91
|
-
obj.to_s(16).upcase
|
92
|
-
end
|
93
|
-
|
94
|
-
def uint8 (obj)
|
95
|
-
format_uint("g", 2, obj)
|
96
|
-
end
|
97
|
-
|
98
|
-
def uint16 (obj)
|
99
|
-
format_uint("h", 4, obj)
|
100
|
-
end
|
101
|
-
|
102
|
-
def uint32 (obj)
|
103
|
-
format_uint("i", 8, obj)
|
104
|
-
end
|
105
|
-
|
106
|
-
def uint64 (obj)
|
107
|
-
format_uint("j", 16, obj)
|
108
|
-
end
|
109
|
-
|
110
|
-
def float64 (obj)
|
111
|
-
unless obj.finite?
|
112
|
-
case obj.infinite?
|
113
|
-
when 1; return "l" + '7ff0000000000000' # +∞
|
114
|
-
when -1; return "l" + 'fff0000000000000' # -∞
|
115
|
-
else; return "l" + '7fffffffffffffff' # NAN
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
sign = obj < 0
|
120
|
-
obj *= -1 if sign
|
121
|
-
exp = ((Math.log(obj) / Math.log(2, Math::E)) + 1023).to_i
|
122
|
-
frac = obj * (2**(52 + 1023 - exp))
|
123
|
-
low = frac.to_i & 0xffffffff
|
124
|
-
exp |= 0x800 if sign
|
125
|
-
high = ((frac / 0x100000000).to_i & 0xfffff) | (exp << 20)
|
126
|
-
|
127
|
-
"l" + to_s16([
|
128
|
-
(high >> 24) & 0xff, (high >> 16) & 0xff,
|
129
|
-
(high >> 8) & 0xff, (high) & 0xff,
|
130
|
-
(low >> 24) & 0xff, (low >> 16) & 0xff,
|
131
|
-
(low >> 8) & 0xff, (low) & 0xff
|
132
|
-
])
|
133
|
-
end
|
134
|
-
|
135
|
-
def fixstr (obj)
|
136
|
-
(obj.length + 71).chr + obj
|
137
|
-
end
|
138
|
-
|
139
|
-
def str8 (obj)
|
140
|
-
format_str "n", 2, obj
|
141
|
-
end
|
142
|
-
|
143
|
-
def str16 (obj)
|
144
|
-
format_str "o", 4, obj
|
145
|
-
end
|
146
|
-
|
147
|
-
def str32 (obj)
|
148
|
-
format_str "p", 8, obj
|
149
|
-
end
|
150
|
-
|
151
|
-
def map (obj)
|
152
|
-
keys = [];
|
153
|
-
obj.each { |key, value|
|
154
|
-
keys.push(pack(key) + pack(value))
|
155
|
-
}
|
156
|
-
if keys.length < 0x10
|
157
|
-
f = ["r", 1]
|
158
|
-
elsif keys.length < 0x100
|
159
|
-
f = ["s", 2]
|
160
|
-
elsif keys.length < 0x10000
|
161
|
-
f = ["t", 4]
|
162
|
-
elsif keys.length < 0x100000000
|
163
|
-
f = ["u", 8]
|
164
|
-
else
|
165
|
-
raise "pack size limit over"
|
166
|
-
end
|
167
|
-
format_uint(f[0], f[1], keys.length) + keys.join('');
|
168
|
-
end
|
169
|
-
|
170
|
-
def array (obj)
|
171
|
-
keys = [];
|
172
|
-
obj.each { |value|
|
173
|
-
keys.push(pack(value));
|
174
|
-
}
|
175
|
-
if keys.length < 0x10
|
176
|
-
f = ["v", 1]
|
177
|
-
elsif keys.length < 0x100
|
178
|
-
f = ["w", 2]
|
179
|
-
elsif keys.length < 0x10000
|
180
|
-
f = ["x", 4]
|
181
|
-
elsif keys.length < 0x100000000
|
182
|
-
f = ["y", 8]
|
183
|
-
else
|
184
|
-
raise "pack size limit over"
|
185
|
-
end
|
186
|
-
format_uint(f[0], f[1], keys.length) + keys.join('');
|
187
|
-
end
|
188
|
-
|
189
|
-
def format_uint (type, length, num)
|
190
|
-
hex = num.to_s(16);
|
191
|
-
len = length - hex.length;
|
192
|
-
zero = '0' * len;
|
193
|
-
type + zero + hex;
|
194
|
-
end
|
195
|
-
|
196
|
-
def format_str (type, length, str)
|
197
|
-
hex = str.length.to_s(16);
|
198
|
-
len = length - hex.length;
|
199
|
-
zero = '0' * len;
|
200
|
-
type + zero + hex + str;
|
201
|
-
end
|
202
|
-
|
203
|
-
def to_s16 (a)
|
204
|
-
a.map { |i|
|
205
|
-
hex = i.to_s(16)
|
206
|
-
len = hex.length
|
207
|
-
i = 2 - len
|
208
|
-
('0' * i) + hex
|
209
|
-
}.join('')
|
210
|
-
end
|
211
|
-
end
|
212
|
-
end
|
213
|
-
|
214
|
-
class << self
|
215
|
-
def pack (obj)
|
216
|
-
Packer.pack obj
|
217
|
-
end
|
218
|
-
end
|
219
|
-
end
|
data/lib/asciipack/unpacker.rb
DELETED
@@ -1,201 +0,0 @@
|
|
1
|
-
module AsciiPack
|
2
|
-
class Unpacker
|
3
|
-
@@fixmap = {
|
4
|
-
"0" => 0x0,
|
5
|
-
"1" => 0x1,
|
6
|
-
"2" => 0x2,
|
7
|
-
"3" => 0x3,
|
8
|
-
"4" => 0x4,
|
9
|
-
"5" => 0x5,
|
10
|
-
"6" => 0x6,
|
11
|
-
"7" => 0x7,
|
12
|
-
"8" => 0x8,
|
13
|
-
"9" => 0x9,
|
14
|
-
"A" => 0xa,
|
15
|
-
"B" => 0xb,
|
16
|
-
"C" => 0xc,
|
17
|
-
"D" => 0xd,
|
18
|
-
"E" => 0xe,
|
19
|
-
"F" => 0xf,
|
20
|
-
"W" => nil,
|
21
|
-
"X" => false,
|
22
|
-
"Y" => true,
|
23
|
-
}.freeze
|
24
|
-
|
25
|
-
def initialize (ap)
|
26
|
-
@ap = ap
|
27
|
-
@at = 0
|
28
|
-
@ch = @ap[0]
|
29
|
-
end
|
30
|
-
|
31
|
-
def unpack
|
32
|
-
move
|
33
|
-
|
34
|
-
if @@fixmap.key?(@ch)
|
35
|
-
return @@fixmap[@ch]
|
36
|
-
end
|
37
|
-
|
38
|
-
case @ch
|
39
|
-
when "a"; int4
|
40
|
-
when "b"; int8
|
41
|
-
when "c"; int16
|
42
|
-
when "d"; int32
|
43
|
-
when "e"; int64
|
44
|
-
when "g"; uint8
|
45
|
-
when "h"; uint16
|
46
|
-
when "i"; uint32
|
47
|
-
when "j"; uint64
|
48
|
-
when "l"; float64
|
49
|
-
when "n"; str8
|
50
|
-
when "o"; str16
|
51
|
-
when "p"; str32
|
52
|
-
when "r"; map4
|
53
|
-
when "s"; map8
|
54
|
-
when "t"; map16
|
55
|
-
when "u"; map32
|
56
|
-
when "v"; array4
|
57
|
-
when "w"; array8
|
58
|
-
when "x"; array16
|
59
|
-
when "y"; array32
|
60
|
-
when /[G-V]/; fixstr
|
61
|
-
else raise "undefined type " + @ch.to_s
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
private
|
66
|
-
|
67
|
-
def move
|
68
|
-
@ch = @ap[@at]
|
69
|
-
@at += 1
|
70
|
-
@ch
|
71
|
-
end
|
72
|
-
|
73
|
-
def cut (len)
|
74
|
-
ret = @ap[@at...(@at + len)]
|
75
|
-
@at += len
|
76
|
-
@ch = @ap[@at]
|
77
|
-
ret
|
78
|
-
end
|
79
|
-
|
80
|
-
def int4
|
81
|
-
move
|
82
|
-
i = @ch.to_i(16)
|
83
|
-
(@ch[0].to_i(16) < 0x8) ? i : i - 0x10;
|
84
|
-
end
|
85
|
-
|
86
|
-
def int8
|
87
|
-
c = cut(2)
|
88
|
-
i = c.to_i(16)
|
89
|
-
(c[0].to_i(16) < 0x8) ? i : i - 0x100;
|
90
|
-
end
|
91
|
-
|
92
|
-
def int16
|
93
|
-
c = cut(4)
|
94
|
-
i = c.to_i(16)
|
95
|
-
(c[0].to_i(16) < 0x8) ? i : i - 0x10000;
|
96
|
-
end
|
97
|
-
|
98
|
-
def int32
|
99
|
-
c = cut(8)
|
100
|
-
i = c.to_i(16)
|
101
|
-
(c[0].to_i(16) < 0x8) ? i : i - 0x100000000;
|
102
|
-
end
|
103
|
-
|
104
|
-
def int64
|
105
|
-
c = cut(16)
|
106
|
-
i = c.to_i(16)
|
107
|
-
(c[0].to_i(16) < 0x8) ? i : i - 0x10000000000000000;
|
108
|
-
end
|
109
|
-
|
110
|
-
def uint8
|
111
|
-
cut(2).to_i(16)
|
112
|
-
end
|
113
|
-
|
114
|
-
def uint16
|
115
|
-
cut(4).to_i(16)
|
116
|
-
end
|
117
|
-
|
118
|
-
def uint32
|
119
|
-
cut(8).to_i(16)
|
120
|
-
end
|
121
|
-
|
122
|
-
def uint64
|
123
|
-
cut(16).to_i(16)
|
124
|
-
end
|
125
|
-
|
126
|
-
def float64
|
127
|
-
# IEEE 752 format
|
128
|
-
hex = cut(3)
|
129
|
-
num = hex.to_i(16)
|
130
|
-
sign = num & 0x800
|
131
|
-
exp = (num & 0x7ff) - 1023
|
132
|
-
frac = ('1' + cut(13)).to_i(16)
|
133
|
-
|
134
|
-
if hex == '7ff' && frac != 0
|
135
|
-
return Float.NAN
|
136
|
-
elsif hex == '7ff' && frac == 0
|
137
|
-
return Float.INFINITY
|
138
|
-
elsif hex == 'fff' && frac == 0
|
139
|
-
return -1 / 0.0
|
140
|
-
end
|
141
|
-
|
142
|
-
((sign == 0 ? 1 : -1) * frac * (2**(exp - 52))).to_f
|
143
|
-
end
|
144
|
-
|
145
|
-
def map (length)
|
146
|
-
len = cut(length).to_i(16)
|
147
|
-
hash = {}
|
148
|
-
len.times {
|
149
|
-
key = unpack
|
150
|
-
hash[key] = unpack
|
151
|
-
}
|
152
|
-
hash
|
153
|
-
end
|
154
|
-
|
155
|
-
def map4; map(1) end
|
156
|
-
def map8; map(2) end
|
157
|
-
def map16; map(4) end
|
158
|
-
def map32; map(8) end
|
159
|
-
|
160
|
-
def array (length)
|
161
|
-
len = cut(length).to_i(16)
|
162
|
-
array = []
|
163
|
-
len.times {
|
164
|
-
array << unpack
|
165
|
-
}
|
166
|
-
array
|
167
|
-
end
|
168
|
-
|
169
|
-
def array4; array(1) end
|
170
|
-
def array8; array(2) end
|
171
|
-
def array16; array(4) end
|
172
|
-
def array32; array(8) end
|
173
|
-
|
174
|
-
def fixstr
|
175
|
-
len = @ch.ord - 71 # 71 = "G".ord
|
176
|
-
cut(len)
|
177
|
-
end
|
178
|
-
|
179
|
-
def str8
|
180
|
-
len = cut(2).to_i(16)
|
181
|
-
cut(len)
|
182
|
-
end
|
183
|
-
|
184
|
-
def str16
|
185
|
-
len = cut(4).to_i(16)
|
186
|
-
cut(len)
|
187
|
-
end
|
188
|
-
|
189
|
-
def str32
|
190
|
-
len = cut(8).to_i(16)
|
191
|
-
cut(len)
|
192
|
-
end
|
193
|
-
end
|
194
|
-
|
195
|
-
class << self
|
196
|
-
def unpack (obj)
|
197
|
-
unpacker = Unpacker.new obj
|
198
|
-
unpacker.unpack
|
199
|
-
end
|
200
|
-
end
|
201
|
-
end
|