/// <summary> /// Begins an array node of the given length. /// </summary> /// <param name="length">The length of the array to come.</param> public override void BeginArrayNode(long length) { this.Stream.WriteByte((byte)BinaryEntryType.StartOfArray); ProperBitConverter.GetBytes(this.buffer, 0, length); this.Stream.Write(this.buffer, 0, 8); this.PushArray(); }
/// <summary> /// Writes a primitive array to the stream. /// </summary> /// <typeparam name="T">The element type of the primitive array. Valid element types can be determined using <see cref="FormatterUtilities.IsPrimitiveArrayType(Type)" />.</typeparam> /// <param name="array">The primitive array to write.</param> /// <exception cref="System.ArgumentException">Type + typeof(T).Name + is not a valid primitive array type.</exception> public override void WritePrimitiveArray <T>(T[] array) { if (FormatterUtilities.IsPrimitiveArrayType(typeof(T)) == false) { throw new ArgumentException("Type " + typeof(T).Name + " is not a valid primitive array type."); } int bytesPerElement = PrimitiveSizes[typeof(T)]; int byteCount = array.Length * bytesPerElement; // Write entry flag this.Stream.WriteByte((byte)BinaryEntryType.PrimitiveArray); // Write array length ProperBitConverter.GetBytes(this.buffer, 0, array.Length); this.Stream.Write(this.buffer, 0, 4); // Write size of an element in bytes ProperBitConverter.GetBytes(this.buffer, 0, bytesPerElement); this.Stream.Write(this.buffer, 0, 4); // Write the actual array content if (typeof(T) == typeof(byte)) { // We can include a special case for byte arrays, as there's no need to copy that to a buffer var byteArray = (byte[])(object)array; this.Stream.Write(byteArray, 0, byteCount); } else { // Otherwise we copy to a buffer in order to write the entire array into the stream with one call using (var tempBuffer = Buffer <byte> .Claim(byteCount)) { if (BitConverter.IsLittleEndian) { // We always store in little endian, so we can do a direct memory mapping, which is a lot faster UnsafeUtilities.MemoryCopy(array, tempBuffer.Array, byteCount, 0, 0); } else { // We have to convert each individual element to bytes, since the byte order has to be reversed Action <byte[], int, T> toBytes = (Action <byte[], int, T>)PrimitiveGetBytesMethods[typeof(T)]; var b = tempBuffer.Array; for (int i = 0; i < array.Length; i++) { toBytes(b, i * bytesPerElement, array[i]); } } this.Stream.Write(tempBuffer.Array, 0, byteCount); } } }
/// <summary> /// Writes an <see cref="ushort" /> value to the stream. /// </summary> /// <param name="name">The name of the value. If this is null, no name will be written.</param> /// <param name="value">The value to write.</param> public override void WriteUInt16(string name, ushort value) { if (name != null) { this.Stream.WriteByte((byte)BinaryEntryType.NamedUShort); this.WriteStringValue(name); } else { this.Stream.WriteByte((byte)BinaryEntryType.UnnamedUShort); } ProperBitConverter.GetBytes(this.buffer, 0, value); this.Stream.Write(this.buffer, 0, 2); }
/// <summary> /// Writes a <see cref="float" /> value to the stream. /// </summary> /// <param name="name">The name of the value. If this is null, no name will be written.</param> /// <param name="value">The value to write.</param> public override void WriteSingle(string name, float value) { if (name != null) { this.Stream.WriteByte((byte)BinaryEntryType.NamedFloat); this.WriteStringValue(name); } else { this.Stream.WriteByte((byte)BinaryEntryType.UnnamedFloat); } ProperBitConverter.GetBytes(this.buffer, 0, value); this.Stream.Write(this.buffer, 0, 4); }
/// <summary> /// Writes an internal reference to the stream. /// </summary> /// <param name="name">The name of the value. If this is null, no name will be written.</param> /// <param name="id">The value to write.</param> public override void WriteInternalReference(string name, int id) { if (name != null) { this.Stream.WriteByte((byte)BinaryEntryType.NamedInternalReference); this.WriteStringValue(name); } else { this.Stream.WriteByte((byte)BinaryEntryType.UnnamedInternalReference); } ProperBitConverter.GetBytes(this.buffer, 0, id); this.Stream.Write(this.buffer, 0, 4); }
/// <summary> /// Writes a <see cref="long" /> value to the stream. /// </summary> /// <param name="name">The name of the value. If this is null, no name will be written.</param> /// <param name="value">The value to write.</param> public override void WriteInt64(string name, long value) { if (name != null) { this.Stream.WriteByte((byte)BinaryEntryType.NamedLong); this.WriteStringValue(name); } else { this.Stream.WriteByte((byte)BinaryEntryType.UnnamedLong); } ProperBitConverter.GetBytes(this.buffer, 0, value); this.Stream.Write(this.buffer, 0, 8); }
/// <summary> /// Writes a <see cref="Guid" /> value to the stream. /// </summary> /// <param name="name">The name of the value. If this is null, no name will be written.</param> /// <param name="value">The value to write.</param> public override void WriteGuid(string name, Guid value) { if (name != null) { this.Stream.WriteByte((byte)BinaryEntryType.NamedGuid); this.WriteStringValue(name); } else { this.Stream.WriteByte((byte)BinaryEntryType.UnnamedGuid); } ProperBitConverter.GetBytes(this.buffer, 0, value); this.Stream.Write(this.buffer, 0, 16); }
private void WriteStringValue(string value) { bool twoByteString = this.StringRequires16BitSupport(value); if (twoByteString) { this.Stream.WriteByte(1); // Write 16 bit flag ProperBitConverter.GetBytes(this.buffer, 0, value.Length); this.Stream.Write(this.buffer, 0, 4); using (var tempBuffer = Buffer <byte> .Claim(value.Length * 2)) { var array = tempBuffer.Array; UnsafeUtilities.StringToBytes(array, value, true); this.Stream.Write(array, 0, value.Length * 2); } } else { this.Stream.WriteByte(0); // Write 8 bit flag ProperBitConverter.GetBytes(this.buffer, 0, value.Length); this.Stream.Write(this.buffer, 0, 4); using (var tempBuffer = Buffer <byte> .Claim(value.Length)) { var array = tempBuffer.Array; for (int i = 0; i < value.Length; i++) { array[i] = (byte)value[i]; } this.Stream.Write(array, 0, value.Length); } } }
private void WriteIntValue(int value) { ProperBitConverter.GetBytes(this.buffer, 0, value); this.Stream.Write(this.buffer, 0, 4); }