/// <summary> /// Writes a list value to a buffer. /// </summary> /// <param name="buffer">The buffer to write.</param> /// <param name="value">The list value.</param> /// <param name="smallEncoding">if true, try using small encoding if possible.</param> public static void WriteList(ByteBuffer buffer, IList value, bool smallEncoding) { if (value == null) { AmqpBitConverter.WriteUByte(buffer, FormatCode.Null); } else { // trim tailing nulls int last = value.Count - 1; while (last >= 0 && value[last] == null) { --last; } if (last < 0 && smallEncoding) { AmqpBitConverter.WriteUByte(buffer, FormatCode.List0); } else { int pos = buffer.WritePos; AmqpBitConverter.WriteUByte(buffer, 0); AmqpBitConverter.WriteUInt(buffer, 0); AmqpBitConverter.WriteUInt(buffer, 0); for (int i = 0; i <= last; ++i) { Encoder.WriteObject(buffer, value[i], smallEncoding); } int size = buffer.WritePos - pos - 9; int count = last + 1; if (smallEncoding && size < byte.MaxValue && count <= byte.MaxValue) { buffer.Buffer[pos] = FormatCode.List8; buffer.Buffer[pos + 1] = (byte)(size + 1); buffer.Buffer[pos + 2] = (byte)count; Array.Copy(buffer.Buffer, pos + 9, buffer.Buffer, pos + 3, size); buffer.Shrink(6); } else { buffer.Buffer[pos] = FormatCode.List32; AmqpBitConverter.WriteInt(buffer.Buffer, pos + 1, size + 4); AmqpBitConverter.WriteInt(buffer.Buffer, pos + 5, count); } } } }
/// <summary> /// Writes a map value to a buffer. /// </summary> /// <param name="buffer">The buffer to write.</param> /// <param name="value">The map value.</param> /// <param name="smallEncoding">if true, try using small encoding if possible.</param> public static void WriteMap(ByteBuffer buffer, Map value, bool smallEncoding) { if (value == null) { AmqpBitConverter.WriteUByte(buffer, FormatCode.Null); } else { int pos = buffer.WritePos; AmqpBitConverter.WriteUByte(buffer, 0); AmqpBitConverter.WriteUInt(buffer, 0); AmqpBitConverter.WriteUInt(buffer, 0); foreach (var key in value.Keys) { Encoder.WriteObject(buffer, key); Encoder.WriteObject(buffer, value[key]); } int size = buffer.WritePos - pos - 9; int count = value.Count * 2; if (smallEncoding && size < byte.MaxValue && count <= byte.MaxValue) { buffer.Buffer[pos] = FormatCode.Map8; buffer.Buffer[pos + 1] = (byte)(size + 1); buffer.Buffer[pos + 2] = (byte)count; Array.Copy(buffer.Buffer, pos + 9, buffer.Buffer, pos + 3, size); buffer.Shrink(6); } else { buffer.Buffer[pos] = FormatCode.Map32; AmqpBitConverter.WriteInt(buffer.Buffer, pos + 1, size + 4); AmqpBitConverter.WriteInt(buffer.Buffer, pos + 5, count); } } }
/// <summary> /// Writes an array value to a buffer. /// </summary> /// <param name="buffer">The buffer to write.</param> /// <param name="value">The array value.</param> public static void WriteArray(ByteBuffer buffer, Array value) { if (value == null) { AmqpBitConverter.WriteUByte(buffer, FormatCode.Null); } else { int count = value.Length; Fx.Assert(count > 0, "must have at least 1 element in array"); int pos = buffer.WritePos; AmqpBitConverter.WriteUByte(buffer, 0); AmqpBitConverter.WriteUInt(buffer, 0); AmqpBitConverter.WriteUInt(buffer, 0); for (int i = 0; i < count; ++i) { object item = value.GetValue(i); if (i == 0) { Encoder.WriteObject(buffer, item, false); } else { int lastPos = buffer.WritePos - 1; byte lastByte = buffer.Buffer[lastPos]; buffer.Shrink(1); Encoder.WriteObject(buffer, item, false); buffer.Buffer[lastPos] = lastByte; } } int size = buffer.WritePos - pos - 9; if (size < byte.MaxValue && count <= byte.MaxValue) { buffer.Buffer[pos] = FormatCode.Array8; buffer.Buffer[pos + 1] = (byte)(size + 1); buffer.Buffer[pos + 2] = (byte)count; Array.Copy(buffer.Buffer, pos + 9, buffer.Buffer, pos + 3, size); buffer.Shrink(6); } else { buffer.Buffer[pos] = FormatCode.Array32; AmqpBitConverter.WriteInt(buffer.Buffer, pos + 1, size + 4); AmqpBitConverter.WriteInt(buffer.Buffer, pos + 5, count); } } }