asciipack 0.1.3 → 0.2.0
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.
- 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
|