@@ -128,7 +128,7 @@ public static decimal ReadDecimal(NetworkBinaryReader reader)
128
128
///<remarks>
129
129
/// Supports the AMQP 0-8/0-9 standard entry types S, I, D, T
130
130
/// and F, as well as the QPid-0-8 specific b, d, f, l, s, t,
131
- /// x and V types.
131
+ /// x and V types and the AMQP 0-9-1 A type .
132
132
///</remarks>
133
133
public static IDictionary ReadTable ( NetworkBinaryReader reader )
134
134
{
@@ -140,10 +140,36 @@ public static IDictionary ReadTable(NetworkBinaryReader reader)
140
140
while ( ( backingStream . Position - startPosition ) < tableLength )
141
141
{
142
142
string key = ReadShortstr ( reader ) ;
143
- object value = null ;
143
+ object value = ReadFieldValue ( reader ) ;
144
+
145
+ if ( ! table . ContainsKey ( key ) )
146
+ {
147
+ table [ key ] = value ;
148
+ }
149
+ }
144
150
145
- byte discriminator = reader . ReadByte ( ) ;
146
- switch ( ( char ) discriminator )
151
+ return table ;
152
+ }
153
+
154
+ public static IList ReadArray ( NetworkBinaryReader reader )
155
+ {
156
+ IList array = new ArrayList ( ) ;
157
+ long arrayLength = reader . ReadUInt32 ( ) ;
158
+ Stream backingStream = reader . BaseStream ;
159
+ long startPosition = backingStream . Position ;
160
+ while ( ( backingStream . Position - startPosition ) < arrayLength )
161
+ {
162
+ object value = ReadFieldValue ( reader ) ;
163
+ array . Add ( value ) ;
164
+ }
165
+ return array ;
166
+ }
167
+
168
+ public static object ReadFieldValue ( NetworkBinaryReader reader )
169
+ {
170
+ object value = null ;
171
+ byte discriminator = reader . ReadByte ( ) ;
172
+ switch ( ( char ) discriminator )
147
173
{
148
174
case 'S' :
149
175
value = ReadLongstr ( reader ) ;
@@ -161,6 +187,9 @@ public static IDictionary ReadTable(NetworkBinaryReader reader)
161
187
value = ReadTable ( reader ) ;
162
188
break ;
163
189
190
+ case 'A' :
191
+ value = ReadArray ( reader ) ;
192
+ break ;
164
193
case 'b' :
165
194
value = ReadOctet ( reader ) ;
166
195
break ;
@@ -190,16 +219,9 @@ public static IDictionary ReadTable(NetworkBinaryReader reader)
190
219
throw new SyntaxError ( "Unrecognised type in table: " +
191
220
( char ) discriminator ) ;
192
221
}
193
-
194
- if ( ! table . ContainsKey ( key ) )
195
- {
196
- table [ key ] = value ;
197
- }
198
- }
199
-
200
- return table ;
222
+ return value ;
201
223
}
202
-
224
+
203
225
public static AmqpTimestamp ReadTimestamp ( NetworkBinaryReader reader )
204
226
{
205
227
ulong stamp = ReadLonglong ( reader ) ;
@@ -290,7 +312,7 @@ public static void WriteDecimal(NetworkBinaryWriter writer, decimal value)
290
312
///<para>
291
313
/// Supports the AMQP 0-8/0-9 standard entry types S, I, D, T
292
314
/// and F, as well as the QPid-0-8 specific b, d, f, l, s, t
293
- /// x and V types.
315
+ /// x and V types and the AMQP 0-9-1 A type .
294
316
///</para>
295
317
///</remarks>
296
318
public static void WriteTable ( NetworkBinaryWriter writer , IDictionary val )
@@ -309,81 +331,7 @@ public static void WriteTable(NetworkBinaryWriter writer, IDictionary val)
309
331
{
310
332
WriteShortstr ( writer , ( string ) entry . Key ) ;
311
333
object value = entry . Value ;
312
-
313
- if ( value == null )
314
- {
315
- WriteOctet ( writer , ( byte ) 'V' ) ;
316
- }
317
- else if ( value is string )
318
- {
319
- WriteOctet ( writer , ( byte ) 'S' ) ;
320
- WriteLongstr ( writer , Encoding . UTF8 . GetBytes ( ( string ) value ) ) ;
321
- }
322
- else if ( value is byte [ ] )
323
- {
324
- WriteOctet ( writer , ( byte ) 'S' ) ;
325
- WriteLongstr ( writer , ( byte [ ] ) value ) ;
326
- }
327
- else if ( value is int )
328
- {
329
- WriteOctet ( writer , ( byte ) 'I' ) ;
330
- writer . Write ( ( int ) value ) ;
331
- }
332
- else if ( value is decimal )
333
- {
334
- WriteOctet ( writer , ( byte ) 'D' ) ;
335
- WriteDecimal ( writer , ( decimal ) value ) ;
336
- }
337
- else if ( value is AmqpTimestamp )
338
- {
339
- WriteOctet ( writer , ( byte ) 'T' ) ;
340
- WriteTimestamp ( writer , ( AmqpTimestamp ) value ) ;
341
- }
342
- else if ( value is IDictionary )
343
- {
344
- WriteOctet ( writer , ( byte ) 'F' ) ;
345
- WriteTable ( writer , ( IDictionary ) value ) ;
346
- }
347
- else if ( value is byte )
348
- {
349
- WriteOctet ( writer , ( byte ) 'b' ) ;
350
- WriteOctet ( writer , ( byte ) value ) ;
351
- }
352
- else if ( value is double )
353
- {
354
- WriteOctet ( writer , ( byte ) 'd' ) ;
355
- writer . Write ( ( double ) value ) ;
356
- }
357
- else if ( value is float )
358
- {
359
- WriteOctet ( writer , ( byte ) 'f' ) ;
360
- writer . Write ( ( float ) value ) ;
361
- }
362
- else if ( value is long )
363
- {
364
- WriteOctet ( writer , ( byte ) 'l' ) ;
365
- writer . Write ( ( long ) value ) ;
366
- }
367
- else if ( value is short )
368
- {
369
- WriteOctet ( writer , ( byte ) 's' ) ;
370
- writer . Write ( ( short ) value ) ;
371
- }
372
- else if ( value is bool )
373
- {
374
- WriteOctet ( writer , ( byte ) 't' ) ;
375
- WriteOctet ( writer , ( byte ) ( ( ( bool ) value ) ? 1 : 0 ) ) ;
376
- }
377
- else if ( value is BinaryTableValue )
378
- {
379
- WriteOctet ( writer , ( byte ) 'x' ) ;
380
- WriteLongstr ( writer , ( ( BinaryTableValue ) value ) . Bytes ) ;
381
- }
382
- else
383
- {
384
- throw new WireFormattingException ( "Value cannot appear as table value" ,
385
- value ) ;
386
- }
334
+ WriteFieldValue ( writer , value ) ;
387
335
}
388
336
389
337
// Now, backpatch the table length.
@@ -395,6 +343,112 @@ public static void WriteTable(NetworkBinaryWriter writer, IDictionary val)
395
343
}
396
344
}
397
345
346
+ public static void WriteArray ( NetworkBinaryWriter writer , IList val )
347
+ {
348
+ if ( val == null )
349
+ {
350
+ writer . Write ( ( uint ) 0 ) ;
351
+ }
352
+ else
353
+ {
354
+ Stream backingStream = writer . BaseStream ;
355
+ long patchPosition = backingStream . Position ;
356
+ writer . Write ( ( uint ) 0 ) ; // length of table - will be backpatched
357
+ foreach ( object entry in val )
358
+ {
359
+ WriteFieldValue ( writer , entry ) ;
360
+ }
361
+ long savedPosition = backingStream . Position ;
362
+ long tableLength = savedPosition - patchPosition - 4 ; // offset for length word
363
+ backingStream . Seek ( patchPosition , SeekOrigin . Begin ) ;
364
+ writer . Write ( ( uint ) tableLength ) ;
365
+ backingStream . Seek ( savedPosition , SeekOrigin . Begin ) ;
366
+ }
367
+ }
368
+
369
+ public static void WriteFieldValue ( NetworkBinaryWriter writer , object value )
370
+ {
371
+ if ( value == null )
372
+ {
373
+ WriteOctet ( writer , ( byte ) 'V' ) ;
374
+ }
375
+ else if ( value is string )
376
+ {
377
+ WriteOctet ( writer , ( byte ) 'S' ) ;
378
+ WriteLongstr ( writer , Encoding . UTF8 . GetBytes ( ( string ) value ) ) ;
379
+ }
380
+ else if ( value is byte [ ] )
381
+ {
382
+ WriteOctet ( writer , ( byte ) 'S' ) ;
383
+ WriteLongstr ( writer , ( byte [ ] ) value ) ;
384
+ }
385
+ else if ( value is int )
386
+ {
387
+ WriteOctet ( writer , ( byte ) 'I' ) ;
388
+ writer . Write ( ( int ) value ) ;
389
+ }
390
+ else if ( value is decimal )
391
+ {
392
+ WriteOctet ( writer , ( byte ) 'D' ) ;
393
+ WriteDecimal ( writer , ( decimal ) value ) ;
394
+ }
395
+ else if ( value is AmqpTimestamp )
396
+ {
397
+ WriteOctet ( writer , ( byte ) 'T' ) ;
398
+ WriteTimestamp ( writer , ( AmqpTimestamp ) value ) ;
399
+ }
400
+ else if ( value is IDictionary )
401
+ {
402
+ WriteOctet ( writer , ( byte ) 'F' ) ;
403
+ WriteTable ( writer , ( IDictionary ) value ) ;
404
+ }
405
+ else if ( value is IList )
406
+ {
407
+ WriteOctet ( writer , ( byte ) 'A' ) ;
408
+ WriteArray ( writer , ( IList ) value ) ;
409
+ }
410
+ else if ( value is byte )
411
+ {
412
+ WriteOctet ( writer , ( byte ) 'b' ) ;
413
+ WriteOctet ( writer , ( byte ) value ) ;
414
+ }
415
+ else if ( value is double )
416
+ {
417
+ WriteOctet ( writer , ( byte ) 'd' ) ;
418
+ writer . Write ( ( double ) value ) ;
419
+ }
420
+ else if ( value is float )
421
+ {
422
+ WriteOctet ( writer , ( byte ) 'f' ) ;
423
+ writer . Write ( ( float ) value ) ;
424
+ }
425
+ else if ( value is long )
426
+ {
427
+ WriteOctet ( writer , ( byte ) 'l' ) ;
428
+ writer . Write ( ( long ) value ) ;
429
+ }
430
+ else if ( value is short )
431
+ {
432
+ WriteOctet ( writer , ( byte ) 's' ) ;
433
+ writer . Write ( ( short ) value ) ;
434
+ }
435
+ else if ( value is bool )
436
+ {
437
+ WriteOctet ( writer , ( byte ) 't' ) ;
438
+ WriteOctet ( writer , ( byte ) ( ( ( bool ) value ) ? 1 : 0 ) ) ;
439
+ }
440
+ else if ( value is BinaryTableValue )
441
+ {
442
+ WriteOctet ( writer , ( byte ) 'x' ) ;
443
+ WriteLongstr ( writer , ( ( BinaryTableValue ) value ) . Bytes ) ;
444
+ }
445
+ else
446
+ {
447
+ throw new WireFormattingException ( "Value cannot appear as table value" ,
448
+ value ) ;
449
+ }
450
+ }
451
+
398
452
public static void WriteTimestamp ( NetworkBinaryWriter writer , AmqpTimestamp val )
399
453
{
400
454
// 0-9 is afaict silent on the signedness of the timestamp.
0 commit comments