asciipack 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -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