Skip to content

Commit c343098

Browse files
Merge pull request #579 from sergeyshaykhullin/byte_conversion_support
Byte conversion support
2 parents 069dbb3 + 9b93edb commit c343098

File tree

3 files changed

+103
-102
lines changed

3 files changed

+103
-102
lines changed

projects/client/RabbitMQ.Client/src/client/impl/WireFormatting.cs

Lines changed: 98 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,17 @@ public static decimal AmqpToDecimal(byte scale, uint unsignedMantissa)
5757
throw new SyntaxError("Unrepresentable AMQP decimal table field: " +
5858
"scale=" + scale);
5959
}
60-
return new decimal((int)(unsignedMantissa & 0x7FFFFFFF),
61-
0,
62-
0,
63-
((unsignedMantissa & 0x80000000) == 0) ? false : true,
64-
scale);
60+
61+
return new decimal(
62+
// The low 32 bits of a 96-bit integer
63+
lo: (int)(unsignedMantissa & 0x7FFFFFFF),
64+
// The middle 32 bits of a 96-bit integer.
65+
mid: 0,
66+
// The high 32 bits of a 96-bit integer.
67+
hi: 0,
68+
isNegative: (unsignedMantissa & 0x80000000) != 0,
69+
// A power of 10 ranging from 0 to 28.
70+
scale: scale);
6571
}
6672

6773
public static void DecimalToAmqp(decimal value, out byte scale, out int mantissa)
@@ -91,7 +97,7 @@ public static IList ReadArray(NetworkBinaryReader reader)
9197
{
9298
IList array = new List<object>();
9399
long arrayLength = reader.ReadUInt32();
94-
Stream backingStream = reader.BaseStream;
100+
var backingStream = reader.BaseStream;
95101
long startPosition = backingStream.Position;
96102
while ((backingStream.Position - startPosition) < arrayLength)
97103
{
@@ -129,10 +135,12 @@ public static object ReadFieldValue(NetworkBinaryReader reader)
129135
case 'F':
130136
value = ReadTable(reader);
131137
break;
132-
133138
case 'A':
134139
value = ReadArray(reader);
135140
break;
141+
case 'B':
142+
value = reader.ReadByte();
143+
break;
136144
case 'b':
137145
value = reader.ReadSByte();
138146
break;
@@ -215,7 +223,7 @@ public static IDictionary<string, object> ReadTable(NetworkBinaryReader reader)
215223
IDictionary<string, object> table = new Dictionary<string, object>();
216224
long tableLength = reader.ReadUInt32();
217225

218-
Stream backingStream = reader.BaseStream;
226+
var backingStream = reader.BaseStream;
219227
long startPosition = backingStream.Position;
220228
while ((backingStream.Position - startPosition) < tableLength)
221229
{
@@ -247,7 +255,7 @@ public static void WriteArray(NetworkBinaryWriter writer, IList val)
247255
}
248256
else
249257
{
250-
Stream backingStream = writer.BaseStream;
258+
var backingStream = writer.BaseStream;
251259
long patchPosition = backingStream.Position;
252260
writer.Write((uint)0); // length of table - will be backpatched
253261
foreach (object entry in val)
@@ -264,93 +272,82 @@ public static void WriteArray(NetworkBinaryWriter writer, IList val)
264272

265273
public static void WriteDecimal(NetworkBinaryWriter writer, decimal value)
266274
{
267-
byte scale;
268-
int mantissa;
269-
DecimalToAmqp(value, out scale, out mantissa);
275+
DecimalToAmqp(value, out var scale, out var mantissa);
270276
WriteOctet(writer, scale);
271277
WriteLong(writer, (uint)mantissa);
272278
}
273279

274280
public static void WriteFieldValue(NetworkBinaryWriter writer, object value)
275281
{
276-
if (value == null)
277-
{
278-
WriteOctet(writer, (byte)'V');
279-
}
280-
else if (value is string)
281-
{
282-
WriteOctet(writer, (byte)'S');
283-
WriteLongstr(writer, Encoding.UTF8.GetBytes((string)value));
284-
}
285-
else if (value is byte[])
286-
{
287-
WriteOctet(writer, (byte)'S');
288-
WriteLongstr(writer, (byte[])value);
289-
}
290-
else if (value is int)
291-
{
292-
WriteOctet(writer, (byte)'I');
293-
writer.Write((int)value);
294-
}
295-
else if (value is decimal)
296-
{
297-
WriteOctet(writer, (byte)'D');
298-
WriteDecimal(writer, (decimal)value);
299-
}
300-
else if (value is AmqpTimestamp)
301-
{
302-
WriteOctet(writer, (byte)'T');
303-
WriteTimestamp(writer, (AmqpTimestamp)value);
304-
}
305-
else if (value is IDictionary)
306-
{
307-
WriteOctet(writer, (byte)'F');
308-
WriteTable(writer, (IDictionary)value);
309-
}
310-
else if (value is IList)
311-
{
312-
WriteOctet(writer, (byte)'A');
313-
WriteArray(writer, (IList)value);
314-
}
315-
else if (value is sbyte)
316-
{
317-
WriteOctet(writer, (byte)'b');
318-
writer.Write((sbyte)value);
319-
}
320-
else if (value is double)
321-
{
322-
WriteOctet(writer, (byte)'d');
323-
writer.Write((double)value);
324-
}
325-
else if (value is float)
326-
{
327-
WriteOctet(writer, (byte)'f');
328-
writer.Write((float)value);
329-
}
330-
else if (value is long)
331-
{
332-
WriteOctet(writer, (byte)'l');
333-
writer.Write((long)value);
334-
}
335-
else if (value is short)
336-
{
337-
WriteOctet(writer, (byte)'s');
338-
writer.Write((short)value);
339-
}
340-
else if (value is bool)
282+
switch (value)
341283
{
342-
WriteOctet(writer, (byte)'t');
343-
WriteOctet(writer, (byte)(((bool)value) ? 1 : 0));
344-
}
345-
else if (value is BinaryTableValue)
346-
{
347-
WriteOctet(writer, (byte)'x');
348-
WriteLongstr(writer, ((BinaryTableValue)value).Bytes);
349-
}
350-
else
351-
{
352-
throw new WireFormattingException("Value cannot appear as table value",
353-
value);
284+
case null:
285+
WriteOctet(writer, (byte)'V');
286+
break;
287+
case string val:
288+
WriteOctet(writer, (byte)'S');
289+
WriteLongstr(writer, Encoding.UTF8.GetBytes(val));
290+
break;
291+
case byte[] val:
292+
WriteOctet(writer, (byte)'S');
293+
WriteLongstr(writer, val);
294+
break;
295+
case int val:
296+
WriteOctet(writer, (byte)'I');
297+
writer.Write(val);
298+
break;
299+
case decimal val:
300+
WriteOctet(writer, (byte)'D');
301+
WriteDecimal(writer, val);
302+
break;
303+
case AmqpTimestamp val:
304+
WriteOctet(writer, (byte)'T');
305+
WriteTimestamp(writer, val);
306+
break;
307+
case IDictionary val:
308+
WriteOctet(writer, (byte)'F');
309+
WriteTable(writer, val);
310+
break;
311+
case IList val:
312+
WriteOctet(writer, (byte)'A');
313+
WriteArray(writer, val);
314+
break;
315+
case byte val:
316+
WriteOctet(writer, (byte)'B');
317+
writer.Write(val);
318+
break;
319+
case sbyte val:
320+
WriteOctet(writer, (byte)'b');
321+
writer.Write(val);
322+
break;
323+
case double val:
324+
WriteOctet(writer, (byte)'d');
325+
writer.Write(val);
326+
break;
327+
case float val:
328+
WriteOctet(writer, (byte)'f');
329+
writer.Write(val);
330+
break;
331+
case long val:
332+
WriteOctet(writer, (byte)'l');
333+
writer.Write(val);
334+
break;
335+
case short val:
336+
WriteOctet(writer, (byte)'s');
337+
writer.Write(val);
338+
break;
339+
case bool val:
340+
WriteOctet(writer, (byte)'t');
341+
WriteOctet(writer, (byte)(val ? 1 : 0));
342+
break;
343+
case BinaryTableValue val:
344+
WriteOctet(writer, (byte)'x');
345+
WriteLongstr(writer, val.Bytes);
346+
break;
347+
default:
348+
throw new WireFormattingException(
349+
$"Value of type '{value.GetType().Name}' cannot appear as table value",
350+
value);
354351
}
355352
}
356353

@@ -382,14 +379,16 @@ public static void WriteShort(NetworkBinaryWriter writer, ushort val)
382379

383380
public static void WriteShortstr(NetworkBinaryWriter writer, string val)
384381
{
385-
byte[] bytes = Encoding.UTF8.GetBytes(val);
386-
int len = bytes.Length;
387-
if (len > 255)
382+
var bytes = Encoding.UTF8.GetBytes(val);
383+
var length = bytes.Length;
384+
385+
if (length > 255)
388386
{
389387
throw new WireFormattingException("Short string too long; " +
390-
"UTF-8 encoded length=" + len + ", max=255");
388+
"UTF-8 encoded length=" + length + ", max=255");
391389
}
392-
writer.Write((byte)len);
390+
391+
writer.Write((byte)length);
393392
writer.Write(bytes);
394393
}
395394

@@ -415,15 +414,14 @@ public static void WriteTable(NetworkBinaryWriter writer, IDictionary val)
415414
}
416415
else
417416
{
418-
Stream backingStream = writer.BaseStream;
417+
var backingStream = writer.BaseStream;
419418
long patchPosition = backingStream.Position;
420419
writer.Write((uint)0); // length of table - will be backpatched
421420

422421
foreach (DictionaryEntry entry in val)
423422
{
424423
WriteShortstr(writer, entry.Key.ToString());
425-
object value = entry.Value;
426-
WriteFieldValue(writer, value);
424+
WriteFieldValue(writer, entry.Value);
427425
}
428426

429427
// Now, backpatch the table length.
@@ -457,15 +455,14 @@ public static void WriteTable(NetworkBinaryWriter writer, IDictionary<string, ob
457455
}
458456
else
459457
{
460-
Stream backingStream = writer.BaseStream;
458+
var backingStream = writer.BaseStream;
461459
long patchPosition = backingStream.Position;
462460
writer.Write((uint)0); // length of table - will be backpatched
463461

464-
foreach (KeyValuePair<string, object> entry in val)
462+
foreach (var entry in val)
465463
{
466464
WriteShortstr(writer, entry.Key);
467-
object value = entry.Value;
468-
WriteFieldValue(writer, value);
465+
WriteFieldValue(writer, entry.Value);
469466
}
470467

471468
// Now, backpatch the table length.

projects/client/Unit/src/unit/TestFieldTableFormatting.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,17 +117,19 @@ public void TestQpidJmsTypes()
117117
{
118118
NetworkBinaryWriter w = Writer();
119119
Hashtable t = new Hashtable();
120+
t["B"] = (byte)255;
120121
t["b"] = (sbyte)-128;
121122
t["d"] = (double)123;
122123
t["f"] = (float)123;
123124
t["l"] = (long)123;
124125
t["s"] = (short)123;
125126
t["t"] = true;
126-
byte[] xbytes = new byte[] { 0xaa, 0x55 };
127+
byte[] xbytes = { 0xaa, 0x55 };
127128
t["x"] = new BinaryTableValue(xbytes);
128129
t["V"] = null;
129130
WireFormatting.WriteTable(w, t);
130131
IDictionary nt = (IDictionary)WireFormatting.ReadTable(Reader(Contents(w)));
132+
Assert.AreEqual(typeof(byte), nt["B"].GetType()); Assert.AreEqual((byte)255, nt["B"]);
131133
Assert.AreEqual(typeof(sbyte), nt["b"].GetType()); Assert.AreEqual((sbyte)-128, nt["b"]);
132134
Assert.AreEqual(typeof(double), nt["d"].GetType()); Assert.AreEqual((double)123, nt["d"]);
133135
Assert.AreEqual(typeof(float), nt["f"].GetType()); Assert.AreEqual((float)123, nt["f"]);

projects/client/Unit/src/unit/TestFieldTableFormattingGeneric.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ public void TestQpidJmsTypes()
119119
{
120120
NetworkBinaryWriter w = Writer();
121121
IDictionary<string, object> t = new Dictionary<string, object>();
122+
t["B"] = (byte)255;
122123
t["b"] = (sbyte)-128;
123124
t["d"] = (double)123;
124125
t["f"] = (float)123;
@@ -130,6 +131,7 @@ public void TestQpidJmsTypes()
130131
t["V"] = null;
131132
WireFormatting.WriteTable(w, t);
132133
IDictionary nt = (IDictionary)WireFormatting.ReadTable(Reader(Contents(w)));
134+
Assert.AreEqual(typeof(byte), nt["B"].GetType()); Assert.AreEqual((byte)255, nt["B"]);
133135
Assert.AreEqual(typeof(sbyte), nt["b"].GetType()); Assert.AreEqual((sbyte)-128, nt["b"]);
134136
Assert.AreEqual(typeof(double), nt["d"].GetType()); Assert.AreEqual((double)123, nt["d"]);
135137
Assert.AreEqual(typeof(float), nt["f"].GetType()); Assert.AreEqual((float)123, nt["f"]);

0 commit comments

Comments
 (0)