libsl 0.0.2
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.
- data/.gitignore +1 -0
- data/README.md +50 -0
- data/Rakefile +54 -0
- data/VERSION +1 -0
- data/lib/_packets.rb +10346 -0
- data/lib/agent.rb +119 -0
- data/lib/client.rb +57 -0
- data/lib/dsl.rb +54 -0
- data/lib/events.rb +59 -0
- data/lib/libsl.rb +14 -0
- data/lib/network.rb +305 -0
- data/lib/packet.rb +279 -0
- data/lib/types.rb +490 -0
- data/libsl.gemspec +30 -0
- data/test/tc_packet.rb +99 -0
- data/test/tc_types.rb +342 -0
- data/test/ts_all.rb +2 -0
- metadata +101 -0
data/lib/types.rb
ADDED
@@ -0,0 +1,490 @@
|
|
1
|
+
|
2
|
+
module LibSL
|
3
|
+
class LLPacketNumber
|
4
|
+
def self.decode(data)
|
5
|
+
data = data.unpack('C1a*')
|
6
|
+
num = data.shift()
|
7
|
+
unless num < 0xff then
|
8
|
+
data = data[0].unpack('C1a*')
|
9
|
+
num = (num << 8) + data.shift()
|
10
|
+
end
|
11
|
+
unless num < 0xffff then
|
12
|
+
data = data[0].unpack('C2a*')
|
13
|
+
num = (num << 16) + (data.shift() << 8) + data.shift()
|
14
|
+
end
|
15
|
+
if [*data].length > 0 then
|
16
|
+
data = data[0]
|
17
|
+
else
|
18
|
+
data = nil
|
19
|
+
end
|
20
|
+
return self.new(num), data
|
21
|
+
end
|
22
|
+
|
23
|
+
def encode()
|
24
|
+
case @frequency
|
25
|
+
when :high then data = [@number].pack('C')
|
26
|
+
when :medium then data = [@number].pack('n')
|
27
|
+
else data = [@number].pack('N')
|
28
|
+
end
|
29
|
+
return data
|
30
|
+
end
|
31
|
+
|
32
|
+
attr_accessor :number, :frequency
|
33
|
+
def initialize(number)
|
34
|
+
@number = number
|
35
|
+
if @number < 0xff then
|
36
|
+
@frequency = :high
|
37
|
+
elsif @number < 0xffff then
|
38
|
+
@frequency = :medium
|
39
|
+
elsif @number < 0xfffffffa then
|
40
|
+
@frequency = :low
|
41
|
+
else
|
42
|
+
@frequency = :fixed
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class LLSequenceNumber
|
48
|
+
def self.decode(data)
|
49
|
+
data = data.unpack('N1a*')
|
50
|
+
return self.new(data[0]), data[1]
|
51
|
+
end
|
52
|
+
|
53
|
+
def encode()
|
54
|
+
[@number].pack('N')
|
55
|
+
end
|
56
|
+
|
57
|
+
attr_accessor :number
|
58
|
+
def initialize(num)
|
59
|
+
@number = num
|
60
|
+
end
|
61
|
+
|
62
|
+
def inc()
|
63
|
+
@number += 1
|
64
|
+
@number
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
class LLNull
|
69
|
+
def self.decode(data)
|
70
|
+
return self.new, data
|
71
|
+
end
|
72
|
+
|
73
|
+
def encode()
|
74
|
+
""
|
75
|
+
end
|
76
|
+
|
77
|
+
def initialize(val)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
class LLFixed
|
82
|
+
def self.decode(data, len)
|
83
|
+
data = data.unpack("a#{len}a*")
|
84
|
+
return self.new(data[0]), data[1]
|
85
|
+
end
|
86
|
+
|
87
|
+
def encode()
|
88
|
+
@data
|
89
|
+
end
|
90
|
+
|
91
|
+
attr_accessor :data
|
92
|
+
def initialize(data)
|
93
|
+
@data = data
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
class LLVariable1
|
98
|
+
def self.decode(data)
|
99
|
+
data = data.unpack('C1a*')
|
100
|
+
data = data[1].unpack("a#{data[0]}a*")
|
101
|
+
return self.new(data[0]), data[1]
|
102
|
+
end
|
103
|
+
|
104
|
+
def encode()
|
105
|
+
[@data.length, @data].pack('C1a*')
|
106
|
+
end
|
107
|
+
|
108
|
+
attr_accessor :data
|
109
|
+
def initialize(data)
|
110
|
+
@data = data
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
class LLVariable2 < LLVariable1
|
115
|
+
def self.decode(data)
|
116
|
+
data = data.unpack('n1a*')
|
117
|
+
data = data[1].unpack("a#{data[0]}a*")
|
118
|
+
return self.new(data[0]), data[1]
|
119
|
+
end
|
120
|
+
|
121
|
+
def encode()
|
122
|
+
[@data.length, @data].pack('n1a*')
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
class LLNumber
|
127
|
+
def self.decode(data, pattern, klass)
|
128
|
+
data = data.unpack(pattern)
|
129
|
+
return klass.new(data[0]), data[1]
|
130
|
+
end
|
131
|
+
|
132
|
+
def self.endianness()
|
133
|
+
little = "78563412"
|
134
|
+
big = "12345678"
|
135
|
+
case "%8x" % ([0x12345678].pack('l').unpack('N')[0])
|
136
|
+
when little then :little
|
137
|
+
when big then :big
|
138
|
+
else :other
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def encode(pattern)
|
143
|
+
[@value].pack(pattern)
|
144
|
+
end
|
145
|
+
|
146
|
+
attr_accessor :value
|
147
|
+
def initialize(value)
|
148
|
+
@value = value
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
class LLU8 < LLNumber
|
153
|
+
def self.decode(data)
|
154
|
+
LLNumber.decode(data, 'C1a*', LLU8)
|
155
|
+
end
|
156
|
+
|
157
|
+
def encode()
|
158
|
+
raise ArgumentError, "Value out of range: #{@value}" if @value < 0 or @value > 0xff
|
159
|
+
super('C')
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
class LLU16 < LLNumber
|
164
|
+
def self.decode(data)
|
165
|
+
LLNumber.decode(data, 'v1a*', LLU16)
|
166
|
+
end
|
167
|
+
|
168
|
+
def encode()
|
169
|
+
raise ArgumentError, "Value out of range: #{@value}" if @value < 0 or @value > 0xffff
|
170
|
+
super('v1')
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
class LLU32 < LLNumber
|
175
|
+
def self.decode(data)
|
176
|
+
LLNumber.decode(data, 'V1a*', LLU32)
|
177
|
+
end
|
178
|
+
|
179
|
+
def encode()
|
180
|
+
raise ArgumentError, "Value out of range: #{@value}" if @value < 0 or @value > 0xffffffff
|
181
|
+
super('V1')
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
class LLU64 < LLNumber
|
186
|
+
def self.decode(data)
|
187
|
+
u64, data = LLNumber.decode(data, 'Q1a*', LLU64)
|
188
|
+
if self.endianness == :big
|
189
|
+
# Convert to little endian
|
190
|
+
u64.value = u64.value >> 56 |
|
191
|
+
(u64.value & 0xff000000000000) >> 40 |
|
192
|
+
(u64.value & 0xff0000000000) >> 24 |
|
193
|
+
(u64.value & 0xff00000000) >> 8 |
|
194
|
+
(u64.value & 0xff000000) << 8 |
|
195
|
+
(u64.value & 0xff0000) << 24 |
|
196
|
+
(u64.value & 0xff00) << 40 |
|
197
|
+
(u64.value & 0xff) << 56
|
198
|
+
end
|
199
|
+
return u64, data
|
200
|
+
end
|
201
|
+
|
202
|
+
def encode()
|
203
|
+
raise ArgumentError, "Value out of range: #{@value}" if @value < 0 or @value > 0xffffffffffffffff
|
204
|
+
ms = @value >> 32
|
205
|
+
ls = @value - (ms << 32)
|
206
|
+
[ls, ms].pack('V2')
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
class LLS8 < LLNumber
|
211
|
+
def self.decode(data)
|
212
|
+
LLNumber.decode(data, 'c1a*', LLS8)
|
213
|
+
end
|
214
|
+
|
215
|
+
def encode()
|
216
|
+
raise ArgumentError, "Value out of range: #{@value}" if @value < -0x80 or @value > 0x7f
|
217
|
+
super('c1')
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
class LLS16 < LLNumber
|
222
|
+
def self.decode(data)
|
223
|
+
s16, data = LLNumber.decode(data, 's1a*', LLS16)
|
224
|
+
if self.endianness == :big
|
225
|
+
# Convert to little endian
|
226
|
+
ms = s16.value >> 8
|
227
|
+
ls = s16 - (ms << 8)
|
228
|
+
s16.value = (ls << 8) + ms
|
229
|
+
end
|
230
|
+
return s16, data
|
231
|
+
end
|
232
|
+
|
233
|
+
def encode()
|
234
|
+
raise ArgumentError, "Value out of range: #{@value}" if @value < -0x8000 or @value > 0x7fff
|
235
|
+
data = super('s')
|
236
|
+
if LLNumber::endianness == :big
|
237
|
+
data = data.unpack('C2').reverse.pack('C2')
|
238
|
+
end
|
239
|
+
return data
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
class LLS32 < LLNumber
|
244
|
+
def self.decode(data)
|
245
|
+
s32, data = LLNumber.decode(data, 'l1a*', LLS32)
|
246
|
+
if self.endianness == :big
|
247
|
+
# Convert to little endian
|
248
|
+
s32.value = s32.value >> 24 |
|
249
|
+
(s32.value & 0xff0000) >> 8 |
|
250
|
+
(s32.value & 0xff00) << 8 |
|
251
|
+
(s32.value & 0xff) << 24
|
252
|
+
end
|
253
|
+
return s32, data
|
254
|
+
end
|
255
|
+
|
256
|
+
def encode()
|
257
|
+
raise ArgumentError, "Value out of range: #{@value}" if @value < -0x80000000 or @value > 0x7fffffff
|
258
|
+
data = super('l')
|
259
|
+
if LLNumber::endianness == :big
|
260
|
+
data = data.unpack('C4').reverse.pack('C4')
|
261
|
+
end
|
262
|
+
return data
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
class LLS64 < LLNumber
|
267
|
+
def self.decode(data)
|
268
|
+
s64, data = LLNumber.decode(data, 'q1a*', LLS64)
|
269
|
+
if self.endianness == :big
|
270
|
+
# Convert to little endian
|
271
|
+
s64.value = s64.value >> 56 |
|
272
|
+
(s64.value & 0xff000000000000) >> 40 |
|
273
|
+
(s64.value & 0xff0000000000) >> 24 |
|
274
|
+
(s64.value & 0xff00000000) >> 8 |
|
275
|
+
(s64.value & 0xff000000) << 8 |
|
276
|
+
(s64.value & 0xff0000) << 24 |
|
277
|
+
(s64.value & 0xff00) << 40 |
|
278
|
+
(s64.value & 0xff) << 56
|
279
|
+
end
|
280
|
+
return s64, data
|
281
|
+
end
|
282
|
+
|
283
|
+
def encode()
|
284
|
+
raise ArgumentError, "Value out of range: #{@value}" if @value < -0x8000000000000000 or @value > 0x7fffffffffffffff
|
285
|
+
data = super('q')
|
286
|
+
if LLNumber::endianness == :big
|
287
|
+
data = data.unpack('C8').reverse.pack('C8')
|
288
|
+
end
|
289
|
+
return data
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
class LLF32 < LLNumber
|
294
|
+
def self.decode(data)
|
295
|
+
data = data.unpack('ea*')
|
296
|
+
return self.new(data[0]), data[1]
|
297
|
+
end
|
298
|
+
|
299
|
+
def encode()
|
300
|
+
[@value].pack('e')
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
class LLF64 < LLNumber
|
305
|
+
def self.decode(data)
|
306
|
+
data = data.unpack('Ea*')
|
307
|
+
return self.new(data[0]), data[1]
|
308
|
+
end
|
309
|
+
|
310
|
+
def encode()
|
311
|
+
[@value].pack('E')
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
class LLVector3
|
316
|
+
def self.decode(data)
|
317
|
+
data = data.unpack('e3a*')
|
318
|
+
return self.new(data[0], data[1], data[2]), data[3]
|
319
|
+
end
|
320
|
+
|
321
|
+
def encode()
|
322
|
+
[@x, @y, @z].pack('e3')
|
323
|
+
end
|
324
|
+
|
325
|
+
attr_accessor :x, :y, :z
|
326
|
+
def initialize(x, y, z)
|
327
|
+
@x, @y, @z = x, y, z
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
class LLVector3d < LLVector3
|
332
|
+
def self.decode(data)
|
333
|
+
data = data.unpack('E3a*')
|
334
|
+
return self.new(data[0], data[1], data[2]), data[3]
|
335
|
+
end
|
336
|
+
|
337
|
+
def encode()
|
338
|
+
[@x, @y, @z].pack('E3')
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
class LLVector4
|
343
|
+
def self.decode(data)
|
344
|
+
data = data.unpack('e4a*')
|
345
|
+
return self.new(data[0], data[1], data[2], data[3]), data[4]
|
346
|
+
end
|
347
|
+
|
348
|
+
def encode()
|
349
|
+
[@a, @b, @c, @d].pack('e4')
|
350
|
+
end
|
351
|
+
|
352
|
+
attr_accessor :a, :b, :c, :d
|
353
|
+
def initialize(a, b, c, d)
|
354
|
+
@a, @b, @c, @d = a, b, c, d
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
class LLQuaternion
|
359
|
+
def self.decode(data)
|
360
|
+
data = data.unpack 'e3a*'
|
361
|
+
return self.new(data[0], data[1], data[2]), data[3]
|
362
|
+
end
|
363
|
+
|
364
|
+
def encode()
|
365
|
+
[@x, @y, @z].pack 'e3'
|
366
|
+
end
|
367
|
+
|
368
|
+
attr_accessor :x, :y, :z, :w
|
369
|
+
def initialize(x, y, z, w=nil)
|
370
|
+
@x, @y, @z = x, y, z
|
371
|
+
if w.nil? then
|
372
|
+
sum = 1 - @x**2 - @y**2 - @z**2
|
373
|
+
@w = if sum > 0 then Math.sqrt sum else 0 end
|
374
|
+
else
|
375
|
+
@w = w
|
376
|
+
end
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
380
|
+
class LLUUID
|
381
|
+
attr_reader :uuid
|
382
|
+
|
383
|
+
def self.decode(data)
|
384
|
+
data = data.unpack 'a16a*'
|
385
|
+
return self.new(data[0]), data[1]
|
386
|
+
end
|
387
|
+
|
388
|
+
def self.null()
|
389
|
+
return self.new("00000000-0000-0000-0000-000000000000")
|
390
|
+
end
|
391
|
+
|
392
|
+
def encode()
|
393
|
+
to_bytes
|
394
|
+
end
|
395
|
+
|
396
|
+
def initialize(uuid=nil)
|
397
|
+
if uuid.nil?
|
398
|
+
# Generate a random UUID
|
399
|
+
uuid = [
|
400
|
+
rand(0x100000000),
|
401
|
+
rand(0x100000000),
|
402
|
+
rand(0x100000000),
|
403
|
+
rand(0x100000000),
|
404
|
+
].pack "N4"
|
405
|
+
uuid[6] &= 0b00001111
|
406
|
+
uuid[6] |= 48
|
407
|
+
uuid[8] &= 0b00111111
|
408
|
+
uuid[8] |= 0b10000000
|
409
|
+
end
|
410
|
+
|
411
|
+
raise "Invalid uuid format" unless uuid.is_a? String
|
412
|
+
@uuid = if uuid.length == 36 and uuid.count("-") == 4 then
|
413
|
+
# String representation (Guid)
|
414
|
+
uuid.delete("-").scan(/../).map{|s| s.to_i(16)}
|
415
|
+
else
|
416
|
+
# Unpack from binary string
|
417
|
+
uuid.unpack('C16')
|
418
|
+
end
|
419
|
+
end
|
420
|
+
|
421
|
+
def to_s()
|
422
|
+
sprintf('%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x', *(@uuid)).upcase
|
423
|
+
end
|
424
|
+
|
425
|
+
def to_bytes()
|
426
|
+
@uuid.pack('C16')
|
427
|
+
end
|
428
|
+
end
|
429
|
+
|
430
|
+
class LLBool
|
431
|
+
def self.decode(data)
|
432
|
+
data = data.unpack('C1a*')
|
433
|
+
return self.new(data[0] == 1), data[1]
|
434
|
+
end
|
435
|
+
|
436
|
+
def encode()
|
437
|
+
[@value ? 1 : 0].pack('C')
|
438
|
+
end
|
439
|
+
|
440
|
+
def eql?(val)
|
441
|
+
@value == val
|
442
|
+
end
|
443
|
+
|
444
|
+
def ==(val)
|
445
|
+
@value == val
|
446
|
+
end
|
447
|
+
|
448
|
+
attr_accessor :value
|
449
|
+
def initialize(value)
|
450
|
+
@value = value
|
451
|
+
end
|
452
|
+
end
|
453
|
+
|
454
|
+
class LLIPAddress
|
455
|
+
def self.decode(data)
|
456
|
+
data = data.unpack('C4a*')
|
457
|
+
return self.new(sprintf("%d.%d.%d.%d", data[0], data[1], data[2], data[3])), data[4]
|
458
|
+
end
|
459
|
+
|
460
|
+
def encode()
|
461
|
+
@ip.scan(/[0-9]+/).map {|s| s.to_i}.pack('C4')
|
462
|
+
end
|
463
|
+
|
464
|
+
attr_accessor :ip
|
465
|
+
def initialize(ip)
|
466
|
+
raise ArgumentError, "ip must be a string (e.g. 1.2.3.4)" unless ip.is_a? String
|
467
|
+
@ip = ip
|
468
|
+
end
|
469
|
+
|
470
|
+
def to_s()
|
471
|
+
@ip.to_s
|
472
|
+
end
|
473
|
+
end
|
474
|
+
|
475
|
+
class LLIPPort
|
476
|
+
def self.decode(data)
|
477
|
+
data = data.unpack('n1a*')
|
478
|
+
return self.new(data[0]), data[1]
|
479
|
+
end
|
480
|
+
|
481
|
+
def encode()
|
482
|
+
[@port].pack('n1')
|
483
|
+
end
|
484
|
+
|
485
|
+
attr_accessor :port
|
486
|
+
def initialize(port)
|
487
|
+
@port = port
|
488
|
+
end
|
489
|
+
end
|
490
|
+
end
|
data/libsl.gemspec
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
|
2
|
+
Gem::Specification.new do |s|
|
3
|
+
s.name = "libsl"
|
4
|
+
s.version = File.read('VERSION')
|
5
|
+
s.platform = Gem::Platform::RUBY
|
6
|
+
s.authors = ["Lukas Botsch"]
|
7
|
+
s.email = ["lukas.botsch@gmail.com"]
|
8
|
+
s.homepage = "http://github.com/lbotsch/libsl-ruby"
|
9
|
+
s.summary = "Library for building SecondLife client applications"
|
10
|
+
s.description = "Build SecondLife clients using a simple DSL"
|
11
|
+
s.rubyforge_project = s.name
|
12
|
+
|
13
|
+
s.required_rubygems_version = ">= 1.3.6"
|
14
|
+
|
15
|
+
# If you have runtime dependencies, add them here
|
16
|
+
s.add_runtime_dependency "eventmachine", ">= 0.12.10"
|
17
|
+
|
18
|
+
# If you have development dependencies, add them here
|
19
|
+
# s.add_development_dependency "another", "= 0.9"
|
20
|
+
|
21
|
+
# The list of files to be contained in the gem
|
22
|
+
s.files = `git ls-files`.split("\n").delete_if{|f| f =~ /^(example|scripts|\.)\//}
|
23
|
+
# s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
|
24
|
+
# s.extensions = `git ls-files ext/extconf.rb`.split("\n")
|
25
|
+
|
26
|
+
s.require_path = 'lib'
|
27
|
+
|
28
|
+
# For C extensions
|
29
|
+
# s.extensions = "ext/extconf.rb"
|
30
|
+
end
|
data/test/tc_packet.rb
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
%w{types packet}.each{|f|
|
3
|
+
require File.join File.dirname(__FILE__), "..", "lib", f
|
4
|
+
}
|
5
|
+
|
6
|
+
module LibSL
|
7
|
+
class StubPacket < Packet
|
8
|
+
def self.packet_id()
|
9
|
+
1
|
10
|
+
end
|
11
|
+
|
12
|
+
def build_structure()
|
13
|
+
@blocks = [
|
14
|
+
[:SomeBlock, Block.new([
|
15
|
+
[:Data, :LLU8]
|
16
|
+
])],
|
17
|
+
[:FixedCollection, FixedBlockCollection.new(2, [
|
18
|
+
[:Data, :LLU8]
|
19
|
+
])],
|
20
|
+
[:VariableCollection, VariableBlockCollection.new([
|
21
|
+
[:Data, :LLU8]
|
22
|
+
])]
|
23
|
+
]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
MESSAGE_MAP = {1 => StubPacket}
|
28
|
+
|
29
|
+
class TestPacket < Test::Unit::TestCase
|
30
|
+
def test_decode()
|
31
|
+
packet = Packet.decode(
|
32
|
+
"\x40" + # Flags
|
33
|
+
"\x00\x00\x00\x01" + # Sequence Number
|
34
|
+
"\x00" + # Extra header length
|
35
|
+
"\x01" + # Message Number
|
36
|
+
"\xff" + # SomeBlock
|
37
|
+
"\xff\xff" + # FixedCollection
|
38
|
+
"\x02\xff\xff") # VariableCollection
|
39
|
+
assert_equal(StubPacket, packet.class)
|
40
|
+
assert_equal(true, packet.reliable_flag)
|
41
|
+
assert_equal(0xff, packet.SomeBlock.Data.value)
|
42
|
+
assert_equal(0xff, packet.FixedCollection[0].Data.value)
|
43
|
+
assert_equal(0xff, packet.FixedCollection[1].Data.value)
|
44
|
+
assert_equal(0xff, packet.VariableCollection[0].Data.value)
|
45
|
+
assert_equal(0xff, packet.VariableCollection[1].Data.value)
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_zero_decode()
|
49
|
+
packet = Packet.decode(
|
50
|
+
"\x80" + # Flags zero_coded
|
51
|
+
"\x00\x00\x00\x01" + # Sequence Number
|
52
|
+
"\x00" + # Extra header length
|
53
|
+
"\x01" + # Message Number
|
54
|
+
"\x00\x01" + # SomeBlock
|
55
|
+
"\x00\x02" + # FixedCollection
|
56
|
+
"\x02\x00\x02") # VariableCollection
|
57
|
+
assert_equal(StubPacket, packet.class)
|
58
|
+
assert_equal(true, packet.zero_coded_flag)
|
59
|
+
assert_equal(0x00, packet.SomeBlock.Data.value)
|
60
|
+
assert_equal(0x00, packet.FixedCollection[0].Data.value)
|
61
|
+
assert_equal(0x00, packet.FixedCollection[1].Data.value)
|
62
|
+
assert_equal(0x00, packet.VariableCollection[0].Data.value)
|
63
|
+
assert_equal(0x00, packet.VariableCollection[1].Data.value)
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_encode()
|
67
|
+
packet = StubPacket.new
|
68
|
+
packet.reliable_flag = true
|
69
|
+
packet.sequence_number = 1
|
70
|
+
packet.SomeBlock.Data = LLU8.new(0xff)
|
71
|
+
packet.FixedCollection[0].Data = LLU8.new(0xff)
|
72
|
+
packet.FixedCollection[1].Data = LLU8.new(0xff)
|
73
|
+
packet.VariableCollection.add.Data = LLU8.new(0xff)
|
74
|
+
packet.VariableCollection.add.Data = LLU8.new(0xff)
|
75
|
+
|
76
|
+
data = packet.encode
|
77
|
+
assert_equal("\x40\x00\x00\x00\x01\x00\x01\xff\xff\xff\x02\xff\xff", data)
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_new()
|
81
|
+
packet = StubPacket.new({
|
82
|
+
:SomeBlock => { :Data => LLU8.new(0xff) },
|
83
|
+
:FixedCollection => [
|
84
|
+
{ :Data => LLU8.new(0xff) },
|
85
|
+
{ :Data => LLU8.new(0xff) }
|
86
|
+
],
|
87
|
+
:VariableCollection => [
|
88
|
+
{ :Data => LLU8.new(0xff) },
|
89
|
+
{ :Data => LLU8.new(0xff) }
|
90
|
+
]
|
91
|
+
})
|
92
|
+
assert_equal(0xff, packet.SomeBlock.Data.value)
|
93
|
+
assert_equal(0xff, packet.FixedCollection[0].Data.value)
|
94
|
+
assert_equal(0xff, packet.FixedCollection[1].Data.value)
|
95
|
+
assert_equal(0xff, packet.VariableCollection[0].Data.value)
|
96
|
+
assert_equal(0xff, packet.VariableCollection[1].Data.value)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|