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.
@@ -0,0 +1,3 @@
1
+ module Hessian2
2
+ class Fault < RuntimeError; end
3
+ end
@@ -0,0 +1,11 @@
1
+ require 'hessian2'
2
+
3
+ module Hessian2
4
+ module Handler
5
+
6
+ def handle(data)
7
+ Hessian2.reply(self.send(*Hessian2.parse_rpc(data)))
8
+ end
9
+
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ module Hessian2
2
+ class HessianClient < Client; end
3
+ end
@@ -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