em_hessian2 2.0.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 +7 -0
- data/.gitignore +8 -0
- data/Gemfile +4 -0
- data/README.md +186 -0
- data/Rakefile +1 -0
- data/hessian2.gemspec +28 -0
- data/lib/hessian2.rb +14 -0
- data/lib/hessian2/class_wrapper.rb +8 -0
- data/lib/hessian2/client.rb +73 -0
- data/lib/hessian2/constants.rb +164 -0
- data/lib/hessian2/fault.rb +3 -0
- data/lib/hessian2/handler.rb +11 -0
- data/lib/hessian2/hessian_client.rb +3 -0
- data/lib/hessian2/parser.rb +555 -0
- data/lib/hessian2/struct_wrapper.rb +8 -0
- data/lib/hessian2/type_wrapper.rb +24 -0
- data/lib/hessian2/version.rb +3 -0
- data/lib/hessian2/writer.rb +543 -0
- data/test/Lighthouse.jpg +0 -0
- data/test/another_monkey.rb +7 -0
- data/test/app.rb +23 -0
- data/test/config.ru +2 -0
- data/test/create_monkeys.rb +4 -0
- data/test/defs.pb.rb +25 -0
- data/test/defs.proto +7 -0
- data/test/establish_connection.rb +7 -0
- data/test/get.rb +275 -0
- data/test/monkey.rb +5 -0
- data/test/monkey_service.rb +769 -0
- data/test/seeds.rb +14 -0
- data/test/set.rb +195 -0
- data/test/src/HessianTest.java +20 -0
- data/test/src/example/IMonkeyService.java +283 -0
- data/test/src/example/Monkey.java +31 -0
- data/test/src/example/MonkeyService.java +1125 -0
- data/test/test_class_wrapper.rb +75 -0
- data/test/test_exception.rb +21 -0
- data/test/test_struct_wrapper.rb +93 -0
- data/test/test_type_wrapper.rb +75 -0
- data/test/test_wait_taka.rb +8 -0
- data/test/vs_object_array2struct.rb +50 -0
- data/test/vs_redis_memcached_mysql2.rb +182 -0
- metadata +152 -0
@@ -0,0 +1,555 @@
|
|
1
|
+
require 'hessian2/constants'
|
2
|
+
require 'hessian2/fault'
|
3
|
+
|
4
|
+
module Hessian2
|
5
|
+
module Parser
|
6
|
+
include Constants
|
7
|
+
|
8
|
+
def parse_rpc(data)
|
9
|
+
bytes = data.each_byte
|
10
|
+
bc = bytes.next
|
11
|
+
if bc == 0x48 # skip hessian version
|
12
|
+
2.times{ bytes.next }
|
13
|
+
bc = bytes.next
|
14
|
+
end
|
15
|
+
|
16
|
+
case bc
|
17
|
+
when 0x43 # rpc call ('C')
|
18
|
+
method = parse_string(bytes)
|
19
|
+
refs, cdefs = [], []
|
20
|
+
args = [].tap do |arr|
|
21
|
+
parse_int(bytes).times{ arr << parse_bytes(bytes, nil, refs, cdefs) }
|
22
|
+
end
|
23
|
+
[ method, *args ]
|
24
|
+
when 0x46 # fault ('F')
|
25
|
+
fault = parse_bytes(bytes)
|
26
|
+
code, message = fault['code'], fault['message']
|
27
|
+
raise Fault.new, code == 'RuntimeError' ? message : "#{code} - #{message}"
|
28
|
+
when 0x52 # rpc result ('R')
|
29
|
+
parse_bytes(bytes)
|
30
|
+
else
|
31
|
+
raise data
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def parse(data, klass = nil)
|
36
|
+
parse_bytes(data.each_byte, klass)
|
37
|
+
end
|
38
|
+
|
39
|
+
def parse_bytes(bytes, klass = nil, refs = [], cdefs = [])
|
40
|
+
bc = bytes.next
|
41
|
+
case bc
|
42
|
+
when 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
43
|
+
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
44
|
+
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
45
|
+
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
|
46
|
+
# 0x00 - 0x1f utf-8 string length 0-31
|
47
|
+
read_string_direct(bytes, bc)
|
48
|
+
when 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
|
49
|
+
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f
|
50
|
+
# 0x20 - 0x2f binary data length 0-15
|
51
|
+
read_binary_direct(bytes, bc)
|
52
|
+
when 0x30, 0x31, 0x32, 0x33
|
53
|
+
# 0x30 - 0x33 utf-8 string length 0-1023
|
54
|
+
read_string_short(bytes, bc)
|
55
|
+
when 0x34, 0x35, 0x36, 0x37
|
56
|
+
# 0x34 - 0x37 binary data length 0-1023
|
57
|
+
read_binary_short(bytes, bc)
|
58
|
+
when 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f
|
59
|
+
# 0x38 - 0x3f three-octet compact long (-x40000 to x3ffff)
|
60
|
+
read_long_short_zero(bytes, bc)
|
61
|
+
when 0x41 # 8-bit binary data non-final chunk ('A')
|
62
|
+
read_binary_chunk(bytes)
|
63
|
+
when 0x42 # 8-bit binary data final chunk ('B')
|
64
|
+
read_binary(bytes)
|
65
|
+
when 0x43 # object type definition ('C')
|
66
|
+
name = parse_string(bytes)
|
67
|
+
fields = []
|
68
|
+
|
69
|
+
parse_int(bytes).times do
|
70
|
+
fields << parse_string(bytes)
|
71
|
+
end
|
72
|
+
cdefs << Struct.new(*fields.map{|f| f.to_sym})
|
73
|
+
|
74
|
+
parse_bytes(bytes, klass, refs, cdefs)
|
75
|
+
when 0x44 # 64-bit IEEE encoded double ('D')
|
76
|
+
read_double(bytes)
|
77
|
+
when 0x46 # boolean false ('F')
|
78
|
+
false
|
79
|
+
when 0x48 # untyped map ('H')
|
80
|
+
val = {}
|
81
|
+
refs << val # store a value reference first
|
82
|
+
while bytes.peek != BC_END
|
83
|
+
val[parse_bytes(bytes, klass, refs, cdefs)] = parse_bytes(bytes, klass, refs, cdefs)
|
84
|
+
end
|
85
|
+
|
86
|
+
bytes.next
|
87
|
+
val
|
88
|
+
when 0x49 # 32-bit signed integer ('I')
|
89
|
+
read_int(bytes)
|
90
|
+
when 0x4a # 64-bit UTC millisecond date
|
91
|
+
read_date(bytes)
|
92
|
+
when 0x4b # 32-bit UTC minute date
|
93
|
+
read_date_minute(bytes)
|
94
|
+
when 0x4c # 64-bit signed long integer ('L')
|
95
|
+
read_long(bytes)
|
96
|
+
when 0x4d # map with type ('M')
|
97
|
+
parse_type(bytes) # skip type
|
98
|
+
val = {}
|
99
|
+
refs << val
|
100
|
+
while bytes.peek != BC_END
|
101
|
+
val[parse_bytes(bytes, klass, refs, cdefs)] = parse_bytes(bytes, klass, refs, cdefs)
|
102
|
+
end
|
103
|
+
|
104
|
+
bytes.next
|
105
|
+
val
|
106
|
+
when 0x4e # null ('N')
|
107
|
+
nil
|
108
|
+
when 0x4f # object instance ('O')
|
109
|
+
cdef = cdefs[parse_int(bytes)]
|
110
|
+
val = cdef.new
|
111
|
+
refs << val # store a value reference first
|
112
|
+
val.members.each do |sym|
|
113
|
+
val[sym] = parse_bytes(bytes, klass, refs, cdefs)
|
114
|
+
end
|
115
|
+
|
116
|
+
val
|
117
|
+
when 0x51 # reference to map/list/object - integer ('Q')
|
118
|
+
refs[parse_int(bytes)]
|
119
|
+
when 0x52 # utf-8 string non-final chunk ('R')
|
120
|
+
read_string_chunk(bytes)
|
121
|
+
when 0x53 # utf-8 string final chunk ('S')
|
122
|
+
read_string(bytes)
|
123
|
+
when 0x54 # boolean true ('T')
|
124
|
+
true
|
125
|
+
when 0x55 # variable-length list/vector ('U')
|
126
|
+
parse_type(bytes)
|
127
|
+
if klass && !klass.is_a?(Array) # parse to struct
|
128
|
+
arr = []
|
129
|
+
while bytes.peek != BC_END
|
130
|
+
arr << parse_bytes(bytes, nil, refs, cdefs)
|
131
|
+
end
|
132
|
+
|
133
|
+
val = klass.new(*arr)
|
134
|
+
refs << val
|
135
|
+
else
|
136
|
+
klass = klass ? klass.first : nil
|
137
|
+
val = []
|
138
|
+
refs << val # store a value reference first
|
139
|
+
while bytes.peek != BC_END
|
140
|
+
val << parse_bytes(bytes, klass, refs, cdefs)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
bytes.next
|
145
|
+
val
|
146
|
+
when 0x56 # fixed-length list/vector ('V')
|
147
|
+
parse_type(bytes)
|
148
|
+
if klass && !klass.is_a?(Array) # parse to struct
|
149
|
+
arr = []
|
150
|
+
parse_int(bytes).times do
|
151
|
+
arr << parse_bytes(bytes, nil, refs, cdefs)
|
152
|
+
end
|
153
|
+
|
154
|
+
val = klass.new(*arr)
|
155
|
+
refs << val
|
156
|
+
else
|
157
|
+
klass = klass ? klass.first : nil
|
158
|
+
val = []
|
159
|
+
refs << val # store a value reference
|
160
|
+
parse_int(bytes).times do
|
161
|
+
val << parse_bytes(bytes, klass, refs, cdefs)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
val
|
166
|
+
when 0x57 # variable-length untyped list/vector ('W')
|
167
|
+
if klass && !klass.is_a?(Array) # parse to struct
|
168
|
+
arr = []
|
169
|
+
while bytes.peek != BC_END
|
170
|
+
arr << parse_bytes(bytes, nil, refs, cdefs)
|
171
|
+
end
|
172
|
+
|
173
|
+
val = klass.new(*arr)
|
174
|
+
refs << val
|
175
|
+
else
|
176
|
+
klass = klass ? klass.first : nil
|
177
|
+
val = []
|
178
|
+
refs << val # store a value reference first
|
179
|
+
while bytes.peek != BC_END
|
180
|
+
val << parse_bytes(bytes, klass, refs, cdefs)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
bytes.next
|
185
|
+
val
|
186
|
+
when 0x58 # fixed-length untyped list/vector ('X')
|
187
|
+
if klass && !klass.is_a?(Array) # parse to struct
|
188
|
+
arr = []
|
189
|
+
parse_int(bytes).times do
|
190
|
+
arr << parse_bytes(bytes, nil, refs, cdefs)
|
191
|
+
end
|
192
|
+
|
193
|
+
val = klass.new(*arr)
|
194
|
+
refs << val
|
195
|
+
else
|
196
|
+
klass = klass ? klass.first : nil
|
197
|
+
val = []
|
198
|
+
refs << val # store a value reference first
|
199
|
+
parse_int(bytes).times do
|
200
|
+
val << parse_bytes(bytes, klass, refs, cdefs)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
val
|
205
|
+
when 0x59 # long encoded as 32-bit int ('Y')
|
206
|
+
read_int(bytes)
|
207
|
+
when 0x5b # double 0.0
|
208
|
+
0
|
209
|
+
when 0x5c # double 1.0
|
210
|
+
1
|
211
|
+
when 0x5d # double represented as byte (-128.0 to 127.0)
|
212
|
+
read_double_direct(bytes)
|
213
|
+
when 0x5e # double represented as short (-32768.0 to 32767.0)
|
214
|
+
read_double_short(bytes)
|
215
|
+
when 0x5f # double represented as float
|
216
|
+
read_double_mill(bytes)
|
217
|
+
when 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
|
218
|
+
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f
|
219
|
+
# 0x60 - 0x6f object with direct type
|
220
|
+
cdef = cdefs[bc - BC_OBJECT_DIRECT]
|
221
|
+
val = cdef.new
|
222
|
+
refs << val # store a value reference first
|
223
|
+
val.members.each do |sym|
|
224
|
+
val[sym] = parse_bytes(bytes, klass, refs, cdefs)
|
225
|
+
end
|
226
|
+
|
227
|
+
val
|
228
|
+
when 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77
|
229
|
+
# 0x70 - 0x77 fixed list with direct length
|
230
|
+
parse_type(bytes)
|
231
|
+
if klass && !klass.is_a?(Array) # parse to struct
|
232
|
+
arr = []
|
233
|
+
(bc - BC_LIST_DIRECT).times do
|
234
|
+
arr << parse_bytes(bytes, nil, refs, cdefs)
|
235
|
+
end
|
236
|
+
|
237
|
+
val = klass.new(*arr)
|
238
|
+
refs << val
|
239
|
+
else
|
240
|
+
klass = klass ? klass.first : nil
|
241
|
+
val = []
|
242
|
+
refs << val # store a value reference first
|
243
|
+
(bc - BC_LIST_DIRECT).times do
|
244
|
+
val << parse_bytes(bytes, klass, refs, cdefs)
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
val
|
249
|
+
when 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f
|
250
|
+
# 0x78 - 0x7f fixed untyped list with direct length
|
251
|
+
if klass && !klass.is_a?(Array) # parse to struct
|
252
|
+
arr = []
|
253
|
+
(bc - BC_LIST_DIRECT_UNTYPED).times do
|
254
|
+
arr << parse_bytes(bytes, nil, refs, cdefs)
|
255
|
+
end
|
256
|
+
|
257
|
+
val = klass.new(*arr)
|
258
|
+
refs << val
|
259
|
+
else
|
260
|
+
klass = klass ? klass.first : nil
|
261
|
+
val = []
|
262
|
+
refs << val # store a value reference first
|
263
|
+
(bc - BC_LIST_DIRECT_UNTYPED).times do
|
264
|
+
val << parse_bytes(bytes, klass, refs, cdefs)
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
val
|
269
|
+
when 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
|
270
|
+
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
|
271
|
+
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
|
272
|
+
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
|
273
|
+
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
|
274
|
+
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
|
275
|
+
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
|
276
|
+
0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf
|
277
|
+
# 0x80 - 0xbf one-octet compact int (-x10 to x2f, x90 is 0)
|
278
|
+
read_int_zero(bc)
|
279
|
+
when 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
|
280
|
+
0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf
|
281
|
+
# 0xc0 - 0xcf two-octet compact int (-x800 to x7ff)
|
282
|
+
read_int_byte_zero(bytes, bc)
|
283
|
+
when 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7
|
284
|
+
# 0xd0 - 0xd7 three-octet compact int (-x40000 to x3ffff)
|
285
|
+
read_int_short_zero(bytes, bc)
|
286
|
+
when 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
|
287
|
+
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
|
288
|
+
0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef
|
289
|
+
# 0xd8 - 0xef one-octet compact long (-x8 to xf, xe0 is 0)
|
290
|
+
read_long_zero(bc)
|
291
|
+
when 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
|
292
|
+
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
|
293
|
+
# 0xf0 - 0xff two-octet compact long (-x800 to x7ff, xf8 is 0)
|
294
|
+
read_long_byte_zero(bytes, bc)
|
295
|
+
else
|
296
|
+
raise sprintf("Invalid type: %#x", bc)
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
def parse_utf8_char(bytes)
|
301
|
+
bc = bytes.next
|
302
|
+
if bc < 0x80 # 0xxxxxxx
|
303
|
+
bc
|
304
|
+
elsif bc & 0xe0 == 0xc0 # 110xxxxx 10xxxxxx
|
305
|
+
((bc & 0x1f) << 6) + (bytes.next & 0x3f)
|
306
|
+
elsif bc & 0xf0 == 0xe0 # 1110xxxx 10xxxxxx 10xxxxxx
|
307
|
+
((bc & 0x0f) << 12) + ((bytes.next & 0x3f) << 6) + (bytes.next & 0x3f)
|
308
|
+
else
|
309
|
+
raise sprintf("bad utf-8 encoding at %#x", bc)
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
def parse_binary(bytes)
|
314
|
+
bc = bytes.next
|
315
|
+
case bc
|
316
|
+
when 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
|
317
|
+
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f
|
318
|
+
read_binary_direct(bytes, bc)
|
319
|
+
when 0x34, 0x35, 0x36, 0x37
|
320
|
+
read_binary_short(bytes, bc)
|
321
|
+
when 0x41
|
322
|
+
read_binary_chunk(bytes)
|
323
|
+
when 0x42
|
324
|
+
read_binary(bytes)
|
325
|
+
else
|
326
|
+
raise sprintf("%#x is not a binary", bc)
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
def parse_int(bytes)
|
331
|
+
bc = bytes.next
|
332
|
+
case bc
|
333
|
+
when 0x49
|
334
|
+
read_int(bytes)
|
335
|
+
when 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
|
336
|
+
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
|
337
|
+
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
|
338
|
+
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
|
339
|
+
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
|
340
|
+
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
|
341
|
+
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
|
342
|
+
0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf
|
343
|
+
read_int_zero(bc)
|
344
|
+
when 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
|
345
|
+
0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf
|
346
|
+
read_int_byte_zero(bytes, bc)
|
347
|
+
when 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7
|
348
|
+
read_int_short_zero(bytes, bc)
|
349
|
+
else
|
350
|
+
raise sprintf("%#x is not a int", bc)
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
354
|
+
def parse_string(bytes)
|
355
|
+
bc = bytes.next
|
356
|
+
case bc
|
357
|
+
when 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
358
|
+
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
359
|
+
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
360
|
+
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
|
361
|
+
read_string_direct(bytes, bc)
|
362
|
+
when 0x30, 0x31, 0x32, 0x33
|
363
|
+
read_string_short(bytes, bc)
|
364
|
+
when 0x52
|
365
|
+
read_string_chunk(bytes)
|
366
|
+
when 0x53
|
367
|
+
read_string(bytes)
|
368
|
+
else
|
369
|
+
raise sprintf("%#x is not a string", bc)
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
373
|
+
def parse_type(bytes)
|
374
|
+
bc = bytes.next
|
375
|
+
case bc
|
376
|
+
when 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
377
|
+
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
378
|
+
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
379
|
+
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
|
380
|
+
read_string_direct(bytes, bc)
|
381
|
+
when 0x30, 0x31, 0x32, 0x33
|
382
|
+
read_string_short(bytes, bc)
|
383
|
+
when 0x49
|
384
|
+
read_int(bytes)
|
385
|
+
when 0x52
|
386
|
+
read_string_chunk(bytes)
|
387
|
+
when 0x53
|
388
|
+
read_string(bytes)
|
389
|
+
when 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
|
390
|
+
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
|
391
|
+
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
|
392
|
+
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
|
393
|
+
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
|
394
|
+
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
|
395
|
+
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
|
396
|
+
0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf
|
397
|
+
read_int_zero(bc)
|
398
|
+
when 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
|
399
|
+
0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf
|
400
|
+
read_int_byte_zero(bytes, bc)
|
401
|
+
when 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7
|
402
|
+
read_int_short_zero(bytes, bc)
|
403
|
+
else
|
404
|
+
raise sprintf("%#x is not a type", bc)
|
405
|
+
end
|
406
|
+
end
|
407
|
+
|
408
|
+
private
|
409
|
+
|
410
|
+
def read_binary_direct(bytes, bc)
|
411
|
+
read_binary_string(bytes, bc - BC_BINARY_DIRECT)
|
412
|
+
end
|
413
|
+
|
414
|
+
def read_binary_short(bytes, bc)
|
415
|
+
read_binary_string(bytes, ((bc - BC_BINARY_SHORT) << 8) + bytes.next)
|
416
|
+
end
|
417
|
+
|
418
|
+
def read_binary_chunk(bytes)
|
419
|
+
chunks = []
|
420
|
+
chunks << read_binary(bytes)
|
421
|
+
while(bytes.peek == BC_BINARY_CHUNK)
|
422
|
+
bytes.next
|
423
|
+
chunks << read_binary(bytes)
|
424
|
+
end
|
425
|
+
|
426
|
+
chunks << parse_binary(bytes)
|
427
|
+
chunks.join
|
428
|
+
end
|
429
|
+
|
430
|
+
def read_binary(bytes)
|
431
|
+
read_binary_string(bytes, (bytes.next << 8) + bytes.next)
|
432
|
+
end
|
433
|
+
|
434
|
+
def read_binary_string(bytes, len)
|
435
|
+
[].tap do |arr|
|
436
|
+
len.times{ arr << bytes.next }
|
437
|
+
end.pack('C*')
|
438
|
+
end
|
439
|
+
|
440
|
+
def read_date(bytes)
|
441
|
+
val = read_long(bytes)
|
442
|
+
Time.at(val / 1000, val % 1000 * 1000)
|
443
|
+
end
|
444
|
+
|
445
|
+
def read_date_minute(bytes)
|
446
|
+
val = (bytes.next << 24) + (bytes.next << 16) + (bytes.next << 8) + bytes.next
|
447
|
+
Time.at(val * 60)
|
448
|
+
end
|
449
|
+
|
450
|
+
def read_double(bytes)
|
451
|
+
b64, b56, b48, b40, b32, b24, b16, b8 = bytes.next, bytes.next, bytes.next, bytes.next, bytes.next, bytes.next, bytes.next, bytes.next
|
452
|
+
bits = (b64 << 56) + (b56 << 48) + (b48 << 40) + (b40 << 32) + (b32 << 24) + (b24 << 16) + (b16 << 8) + b8
|
453
|
+
return Float::INFINITY if bits == 0x7_ff0_000_000_000_000
|
454
|
+
return -Float::INFINITY if bits == 0xf_ff0_000_000_000_000
|
455
|
+
return Float::NAN if (bits >= 0x7_ff0_000_000_000_001 && bits <= 0x7_fff_fff_fff_fff_fff) or (bits >= 0xf_ff0_000_000_000_001 && bits <= 0xf_fff_fff_fff_fff_fff)
|
456
|
+
s = b64 < 0x80 ? 1 : -1
|
457
|
+
e = (bits >> 52) & 0x7ff
|
458
|
+
m = (e == 0) ? (bits & 0xf_fff_fff_fff_fff) << 1 : (bits & 0xf_fff_fff_fff_fff) | 0x10_000_000_000_000
|
459
|
+
s * m * 2**(e - 1075)
|
460
|
+
end
|
461
|
+
|
462
|
+
def read_double_direct(bytes)
|
463
|
+
bc = bytes.next
|
464
|
+
bc < 0x80 ? bc : -(0xff - bc + 1)
|
465
|
+
end
|
466
|
+
|
467
|
+
def read_double_short(bytes)
|
468
|
+
b16, b8 = bytes.next, bytes.next
|
469
|
+
if b16 < 0x80
|
470
|
+
(b16 << 8) + b8
|
471
|
+
else
|
472
|
+
-(((0xff - b16) << 8) + 0xff - b8 + 1)
|
473
|
+
end
|
474
|
+
end
|
475
|
+
|
476
|
+
def read_double_mill(bytes)
|
477
|
+
0.001 * read_int(bytes)
|
478
|
+
end
|
479
|
+
|
480
|
+
def read_int(bytes)
|
481
|
+
b32, b24, b16, b8 = bytes.next, bytes.next, bytes.next, bytes.next
|
482
|
+
if b32 < 0x80
|
483
|
+
(b32 << 24) + (b24 << 16) + (b16 << 8) + b8
|
484
|
+
else
|
485
|
+
-(((0xff - b32) << 24) + ((0xff - b24) << 16) + ((0xff - b16) << 8) + 0xff - b8 + 1)
|
486
|
+
end
|
487
|
+
end
|
488
|
+
|
489
|
+
def read_int_zero(bc)
|
490
|
+
bc - BC_INT_ZERO
|
491
|
+
end
|
492
|
+
|
493
|
+
def read_int_byte_zero(bytes, bc)
|
494
|
+
((bc - BC_INT_BYTE_ZERO) << 8) + bytes.next
|
495
|
+
end
|
496
|
+
|
497
|
+
def read_int_short_zero(bytes, bc)
|
498
|
+
((bc - BC_INT_SHORT_ZERO) << 16) + (bytes.next << 8) + bytes.next
|
499
|
+
end
|
500
|
+
|
501
|
+
def read_long(bytes)
|
502
|
+
b64, b56, b48, b40, b32, b24, b16, b8 = bytes.next, bytes.next, bytes.next, bytes.next, bytes.next, bytes.next, bytes.next, bytes.next
|
503
|
+
if b64 < 0x80
|
504
|
+
(b64 << 56) + (b56 << 48) + (b48 << 40) + (b40 << 32) \
|
505
|
+
+ (b32 << 24) + (b24 << 16) + (b16 << 8) + b8
|
506
|
+
else
|
507
|
+
-(((0xff - b64) << 56) + ((0xff - b56) << 48) + ((0xff - b48) << 40) + ((0xff - b40) << 32) \
|
508
|
+
+ ((0xff - b32) << 24) + ((0xff - b24) << 16) + ((0xff - b16) << 8) + 0xff - b8 + 1)
|
509
|
+
end
|
510
|
+
end
|
511
|
+
|
512
|
+
def read_long_zero(bc)
|
513
|
+
bc - BC_LONG_ZERO
|
514
|
+
end
|
515
|
+
|
516
|
+
def read_long_byte_zero(bytes, bc)
|
517
|
+
((bc - BC_LONG_BYTE_ZERO) << 8) + bytes.next
|
518
|
+
end
|
519
|
+
|
520
|
+
def read_long_short_zero(bytes, bc)
|
521
|
+
((bc - BC_LONG_SHORT_ZERO) << 16) + (bytes.next << 8) + bytes.next
|
522
|
+
end
|
523
|
+
|
524
|
+
def read_string_direct(bytes, bc)
|
525
|
+
read_utf8_string(bytes, bc - BC_STRING_DIRECT)
|
526
|
+
end
|
527
|
+
|
528
|
+
def read_string_short(bytes, bc)
|
529
|
+
read_utf8_string(bytes, ((bc - BC_STRING_SHORT) << 8) + bytes.next)
|
530
|
+
end
|
531
|
+
|
532
|
+
def read_string_chunk(bytes)
|
533
|
+
chunks = []
|
534
|
+
chunks << read_string(bytes)
|
535
|
+
while(bytes.peek == BC_STRING_CHUNK)
|
536
|
+
bytes.next
|
537
|
+
chunks << read_string(bytes)
|
538
|
+
end
|
539
|
+
|
540
|
+
chunks << parse_string(bytes)
|
541
|
+
chunks.join
|
542
|
+
end
|
543
|
+
|
544
|
+
def read_string(bytes)
|
545
|
+
read_utf8_string(bytes, (bytes.next << 8) + bytes.next)
|
546
|
+
end
|
547
|
+
|
548
|
+
def read_utf8_string(bytes, len)
|
549
|
+
[].tap do |chars|
|
550
|
+
len.times{ chars << parse_utf8_char(bytes) }
|
551
|
+
end.pack('U*')
|
552
|
+
end
|
553
|
+
|
554
|
+
end
|
555
|
+
end
|