コード例 #1
0
        /// <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);
                }
            }
        }