/// <summary>
 /// Writes an enumerable of <see cref="Int32"/> values to the <paramref name="stream"/>.
 /// </summary>
 /// <param name="stream">The extended <see cref="Stream"/> instance.</param>
 /// <param name="values">The values to write.</param>
 /// <param name="converter">The <see cref="ByteConverter"/> to use for converting multibyte data.</param>
 public static void WriteInt32s(this Stream stream, IEnumerable <Int32> values, ByteConverter converter = null)
 {
     Write(stream, values, converter);
 }
 /// <summary>
 /// Writes an enumerable of <see cref="Int32"/> values asynchronously to the <paramref name="stream"/>.
 /// </summary>
 /// <param name="stream">The extended <see cref="Stream"/> instance.</param>
 /// <param name="values">The values to write.</param>
 /// <param name="converter">The <see cref="ByteConverter"/> to use for converting multibyte data.</param>
 /// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
 public static async Task WriteInt32sAsync(this Stream stream, IEnumerable <Int32> values,
                                           ByteConverter converter = null, CancellationToken cancellationToken = default(CancellationToken))
 {
     await WriteAsync(stream, values, converter, cancellationToken);
 }
 /// <summary>
 /// Writes an <see cref="Int32"/> value to the <paramref name="stream"/>.
 /// </summary>
 /// <param name="stream">The extended <see cref="Stream"/> instance.</param>
 /// <param name="value">The value to write.</param>
 /// <param name="converter">The <see cref="ByteConverter"/> to use for converting multibyte data.</param>
 public static void WriteInt32(this Stream stream, Int32 value, ByteConverter converter = null)
 {
     Write(stream, value, converter);
 }
 /// <summary>
 /// Writes an <see cref="Int32"/> value asynchronously to the <paramref name="stream"/>.
 /// </summary>
 /// <param name="stream">The extended <see cref="Stream"/> instance.</param>
 /// <param name="value">The value to write.</param>
 /// <param name="converter">The <see cref="ByteConverter"/> to use for converting multibyte data.</param>
 /// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
 public static async Task WriteInt32Async(this Stream stream, Int32 value, ByteConverter converter = null,
                                          CancellationToken cancellationToken = default(CancellationToken))
 {
     await WriteAsync(stream, value, converter, cancellationToken);
 }
Exemple #5
0
        // ---- Write ----

        /// <summary>
        /// Writes an <see cref="Enum"/> value of type <typeparamref name="T"/> to the <paramref name="stream"/>.
        /// </summary>
        /// <typeparam name="T">The type of the enum.</typeparam>
        /// <param name="stream">The extended <see cref="Stream"/> instance.</param>
        /// <param name="value">The value to write.</param>
        /// <param name="strict"><c>true</c> to raise an <see cref="ArgumentOutOfRangeException"/> if the value is not
        /// defined in the enum type.</param>
        /// <param name="converter">The <see cref="ByteConverter"/> to use for converting multibyte data.</param>
        public static void WriteEnum <T>(this Stream stream, T value, bool strict = false,
                                         ByteConverter converter = null)
            where T : struct, IComparable, IFormattable
        {
            WriteEnum(stream, typeof(T), value, strict, converter);
        }
        // ---- Write ----

        /// <summary>
        /// Writes a <see cref="Decimal"/> value to the <paramref name="stream"/>.
        /// </summary>
        /// <param name="stream">The extended <see cref="Stream"/> instance.</param>
        /// <param name="value">The value to write.</param>
        public static void Write(this Stream stream, Decimal value)
        {
            byte[] buffer = Buffer;
            ByteConverter.GetBytes(value, buffer, 0);
            stream.Write(buffer, 0, sizeof(Decimal));
        }
Exemple #7
0
        // ---- METHODS (PRIVATE) --------------------------------------------------------------------------------------

        private static void WriteEnum(Stream stream, Type enumType, object value, bool strict, ByteConverter converter)
        {
            converter = converter ?? ByteConverter.System;
            Type valueType = Enum.GetUnderlyingType(enumType);

            // Write the enum value.
            byte[] buffer = Buffer;
            if (valueType == typeof(Byte))
            {
                Buffer[0] = (byte)value;
            }
            else if (valueType == typeof(SByte))
            {
                Buffer[0] = (byte)(sbyte)value;
            }
            else if (valueType == typeof(Int16))
            {
                converter.GetBytes((Int16)value, buffer, 0);
            }
            else if (valueType == typeof(Int32))
            {
                converter.GetBytes((Int32)value, buffer, 0);
            }
            else if (valueType == typeof(Int64))
            {
                converter.GetBytes((Int64)value, buffer, 0);
            }
            else if (valueType == typeof(UInt16))
            {
                converter.GetBytes((UInt16)value, buffer, 0);
            }
            else if (valueType == typeof(UInt32))
            {
                converter.GetBytes((UInt32)value, buffer, 0);
            }
            else if (valueType == typeof(UInt64))
            {
                converter.GetBytes((UInt64)value, buffer, 0);
            }
            else
            {
                throw new NotImplementedException($"Unsupported enum type {valueType}.");
            }

            // Check if the value is defined in the enumeration, if requested.
            if (strict)
            {
                EnumTools.IsValid(enumType, value);
            }
            stream.Write(buffer, 0, Marshal.SizeOf(valueType));
        }
 /// <summary>
 /// Returns an array of <see cref="Int32"/> instances read asynchronously from the <paramref name="stream"/>.
 /// </summary>
 /// <param name="stream">The extended <see cref="Stream"/> instance.</param>
 /// <param name="count">The number of values to read.</param>
 /// <param name="converter">The <see cref="ByteConverter"/> to use for converting multibyte data.</param>
 /// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
 /// <returns>The array of values read from the current stream.</returns>
 public static async Task <Int32[]> ReadInt32sAsync(this Stream stream, int count, ByteConverter converter = null,
                                                    CancellationToken cancellationToken = default(CancellationToken))
 {
     converter = converter ?? ByteConverter.System;
     return(await ReadManyAsync(stream, count,
                                () => ReadInt32Async(stream, converter, cancellationToken)));
 }
Exemple #9
0
        private static void WriteMember(Stream stream, object instance, long startOffset, ByteConverter converter,
                                        MemberData member)
        {
            // If possible, reposition the stream according to offset.
            if (stream.CanSeek)
            {
                if (member.Attribute.OffsetOrigin == OffsetOrigin.Begin)
                {
                    stream.Position = startOffset + member.Attribute.Offset;
                }
                else
                {
                    stream.Position += member.Attribute.Offset;
                }
            }
            else
            {
                if (member.Attribute.OffsetOrigin == OffsetOrigin.Begin || member.Attribute.Offset < 0)
                {
                    throw new NotSupportedException("Cannot reposition the stream as it is not seekable.");
                }
                else if (member.Attribute.Offset > 0) // Simulate moving forward by writing bytes.
                {
                    stream.Write(new byte[member.Attribute.Offset]);
                }
            }

            // Get the value to write.
            object value;

            switch (member.MemberInfo)
            {
            case FieldInfo field:
                value = field.GetValue(instance);
                break;

            case PropertyInfo property:
                value = property.GetValue(instance);
                break;

            default:
                throw new InvalidOperationException($"Tried to write an invalid member {member.MemberInfo}.");
            }

            // Write the value and respect settings stored in the member attribute.
            Type elementType = member.Type.GetEnumerableElementType();

            if (elementType == null)
            {
                WriteObject(stream, instance, member.Attribute, member.Type, value, converter);
            }
            else
            {
                foreach (object element in (IEnumerable)value)
                {
                    WriteObject(stream, instance, member.Attribute, elementType, element, converter);
                }
            }
        }
Exemple #10
0
        // ---- METHODS (PUBLIC) ---------------------------------------------------------------------------------------

        // ---- Object ----

        /// <summary>
        /// Writes an object or enumerable of objects to the <paramref name="stream"/>.
        /// </summary>
        /// <param name="stream">The extended <see cref="Stream"/> instance.</param>
        /// <param name="value">The object or enumerable of objects to write.</param>
        /// <param name="converter">The <see cref="ByteConverter"/> to use for converting multibyte data.</param>
        public static void WriteObject(this Stream stream, object value, ByteConverter converter = null)
        => WriteObject(stream, null, BinaryMemberAttribute.Default, value.GetType(), value, converter);
Exemple #11
0
        /// <summary>
        /// Returns an <see cref="Enum"/> instance of the given <paramref name="type"/> read from the
        /// <paramref name="stream"/>.
        /// </summary>
        /// <param name="type">The type of the enum.</param>
        /// <param name="stream">The extended <see cref="Stream"/> instance.</param>
        /// <param name="strict"><c>true</c> to raise an <see cref="ArgumentOutOfRangeException"/> if a value is not
        /// defined in the enum type.</param>
        /// <param name="converter">The <see cref="ByteConverter"/> to use for converting multibyte data.</param>
        /// <returns>The value read from the current stream.</returns>
        public static object ReadEnum(this Stream stream, Type type,
                                      bool strict = false, ByteConverter converter = null)
        {
            converter = converter ?? ByteConverter.System;

            // Read enough bytes to form an enum value.
            Type   valueType = Enum.GetUnderlyingType(type);
            object value;

            if (valueType == typeof(Byte))
            {
                FillBuffer(stream, sizeof(Byte));
                value = Buffer[0];
            }
            else if (valueType == typeof(SByte))
            {
                FillBuffer(stream, sizeof(SByte));
                value = (SByte)Buffer[0];
            }
            else if (valueType == typeof(Int16))
            {
                FillBuffer(stream, sizeof(Int16));
                value = converter.ToInt16(Buffer);
            }
            else if (valueType == typeof(Int32))
            {
                FillBuffer(stream, sizeof(Int32));
                value = converter.ToInt32(Buffer);
            }
            else if (valueType == typeof(Int64))
            {
                FillBuffer(stream, sizeof(Int64));
                value = converter.ToInt64(Buffer);
            }
            else if (valueType == typeof(UInt16))
            {
                FillBuffer(stream, sizeof(UInt16));
                value = converter.ToUInt16(Buffer);
            }
            else if (valueType == typeof(UInt32))
            {
                FillBuffer(stream, sizeof(UInt32));
                value = converter.ToUInt32(Buffer);
            }
            else if (valueType == typeof(UInt64))
            {
                FillBuffer(stream, sizeof(UInt64));
                value = converter.ToUInt64(Buffer);
            }
            else
            {
                throw new NotImplementedException($"Unsupported enum type {valueType}.");
            }

            // Check if the value is defined in the enumeration, if requested.
            if (strict)
            {
                ValidateEnumValue(type, value);
            }
            return(value);
        }
Exemple #12
0
 /// <summary>
 /// Returns an <see cref="Enum"/> instance of type <typeparamref name="T"/> read asynchronously from the
 /// <paramref name="stream"/>.
 /// </summary>
 /// <typeparam name="T">The type of the enum.</typeparam>
 /// <param name="stream">The extended <see cref="Stream"/> instance.</param>
 /// <param name="strict"><c>true</c> to raise an <see cref="ArgumentOutOfRangeException"/> if a value is not
 /// defined in the enum type.</param>
 /// <param name="converter">The <see cref="ByteConverter"/> to use for converting multibyte data.</param>
 /// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
 /// <returns>The value read from the current stream.</returns>
 public static async Task <T> ReadEnumAsync <T>(this Stream stream, bool strict = false,
                                                ByteConverter converter         = null, CancellationToken cancellationToken = default(CancellationToken))
     where T : struct, IComparable, IFormattable
 {
     return((T) await ReadEnumAsync(stream, typeof(T), strict, converter, cancellationToken));
 }
Exemple #13
0
 /// <summary>
 /// Writes an <see cref="Enum"/> value of type <typeparamref name="T"/> asynchronously to the
 /// <paramref name="stream"/>.
 /// </summary>
 /// <typeparam name="T">The type of the enum.</typeparam>
 /// <param name="stream">The extended <see cref="Stream"/> instance.</param>
 /// <param name="value">The value to write.</param>
 /// <param name="strict"><c>true</c> to raise an <see cref="ArgumentOutOfRangeException"/> if the value is not
 /// defined in the enum type.</param>
 /// <param name="converter">The <see cref="ByteConverter"/> to use for converting multibyte data.</param>
 /// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
 public static async Task WriteEnumAsync <T>(this Stream stream, T value, bool strict = false,
                                             ByteConverter converter = null, CancellationToken cancellationToken = default(CancellationToken))
     where T : struct, IComparable, IFormattable
 {
     await WriteEnumAsync(stream, typeof(T), value, strict, converter, cancellationToken);
 }
        // ---- METHODS (PUBLIC) ---------------------------------------------------------------------------------------

        // ---- Read ----

        /// <summary>
        /// Returns an <see cref="Int32"/> instance read from the <paramref name="stream"/>.
        /// </summary>
        /// <param name="stream">The extended <see cref="Stream"/> instance.</param>
        /// <param name="converter">The <see cref="ByteConverter"/> to use for converting multibyte data.</param>
        /// <returns>The value read from the current stream.</returns>
        public static Int32 ReadInt32(this Stream stream, ByteConverter converter = null)
        {
            FillBuffer(stream, sizeof(Int32));
            return((converter ?? ByteConverter.System).ToInt32(Buffer));
        }
Exemple #15
0
        private static void WriteObject(Stream stream, object instance, BinaryMemberAttribute attribute, Type type,
                                        object value, ByteConverter converter)
        {
            converter = converter ?? ByteConverter.System;

            if (attribute.Converter == null)
            {
                if (value == null)
                {
                    return;
                }
                else if (type == typeof(String))
                {
                    stream.Write((String)value, attribute.StringFormat, converter: converter);
                }
                else if (type.TryGetEnumerableElementType(out Type elementType))
                {
                    foreach (object element in (IEnumerable)value)
                    {
                        WriteObject(stream, null, BinaryMemberAttribute.Default, elementType, element, converter);
                    }
                }
                else if (type == typeof(Boolean))
                {
                    stream.Write((Boolean)value, attribute.BooleanFormat, converter);
                }
                else if (type == typeof(Byte))
                {
                    stream.Write((Byte)value);
                }
                else if (type == typeof(DateTime))
                {
                    stream.Write((DateTime)value, attribute.DateTimeFormat, converter);
                }
                else if (type == typeof(Decimal))
                {
                    stream.Write((Decimal)value);
                }
                else if (type == typeof(Double))
                {
                    stream.Write((Double)value, converter);
                }
                else if (type == typeof(Int16))
                {
                    stream.Write((Int16)value, converter);
                }
                else if (type == typeof(Int32))
                {
                    stream.Write((Int32)value, converter);
                }
                else if (type == typeof(Int64))
                {
                    stream.Write((Int64)value, converter);
                }
                else if (type == typeof(SByte))
                {
                    stream.Write((SByte)value);
                }
                else if (type == typeof(Single))
                {
                    stream.Write((Single)value, converter);
                }
                else if (type == typeof(UInt16))
                {
                    stream.Write((UInt16)value, converter);
                }
                else if (type == typeof(UInt32))
                {
                    stream.Write((UInt32)value, converter);
                }
                else if (type == typeof(UInt64))
                {
                    stream.Write((UInt64)value, converter);
                }
                else if (type.IsEnum)
                {
                    WriteEnum(stream, type, value, attribute.Strict, converter);
                }
                else
                {
                    if (stream.CanSeek)
                    {
                        WriteCustomObject(stream, type, value, stream.Position, converter);
                    }
                    else
                    {
                        WriteCustomObject(stream, type, value, -1, converter);
                    }
                }
            }
            else
            {
                // Let a binary converter do all the work.
                IBinaryConverter binaryConverter = BinaryConverterCache.GetConverter(attribute.Converter);
                binaryConverter.Write(stream, instance, attribute, value, converter);
            }
        }
 /// <summary>
 /// Returns an array of <see cref="Int32"/> instances read from the <paramref name="stream"/>.
 /// </summary>
 /// <param name="stream">The extended <see cref="Stream"/> instance.</param>
 /// <param name="count">The number of values to read.</param>
 /// <param name="converter">The <see cref="ByteConverter"/> to use for converting multibyte data.</param>
 /// <returns>The array of values read from the current stream.</returns>
 public static Int32[] ReadInt32s(this Stream stream, int count, ByteConverter converter = null)
 {
     converter = converter ?? ByteConverter.System;
     return(ReadMany(stream, count,
                     () => ReadInt32(stream, converter)));
 }
        // ---- METHODS (PUBLIC) ---------------------------------------------------------------------------------------

        // ---- Read ----

        /// <summary>
        /// Returns a <see cref="Decimal"/> instance read from the <paramref name="stream"/>.
        /// </summary>
        /// <param name="stream">The extended <see cref="Stream"/> instance.</param>
        /// <returns>The value read from the current stream.</returns>
        public static Decimal ReadDecimal(this Stream stream)
        {
            FillBuffer(stream, sizeof(Decimal));
            return(ByteConverter.ToDecimal(Buffer));
        }
        // ---- Write ----

        /// <summary>
        /// Writes an <see cref="Int32"/> value to the <paramref name="stream"/>.
        /// </summary>
        /// <param name="stream">The extended <see cref="Stream"/> instance.</param>
        /// <param name="value">The value to write.</param>
        /// <param name="converter">The <see cref="ByteConverter"/> to use for converting multibyte data.</param>
        public static void Write(this Stream stream, Int32 value, ByteConverter converter = null)
        {
            byte[] buffer = Buffer;
            (converter ?? ByteConverter.System).GetBytes(value, buffer, 0);
            stream.Write(buffer, 0, sizeof(Int32));
        }
Exemple #19
0
        // ---- METHODS (PUBLIC) ---------------------------------------------------------------------------------------

        // ---- Read ----

        /// <summary>
        /// Returns an <see cref="Enum"/> instance of type <typeparamref name="T"/> read from the
        /// <paramref name="stream"/>.
        /// </summary>
        /// <typeparam name="T">The type of the enum.</typeparam>
        /// <param name="stream">The extended <see cref="Stream"/> instance.</param>
        /// <param name="strict"><c>true</c> to raise an <see cref="ArgumentOutOfRangeException"/> if a value is not
        /// defined in the enum type.</param>
        /// <param name="converter">The <see cref="ByteConverter"/> to use for converting multibyte data.</param>
        /// <returns>The value read from the current stream.</returns>
        public static T ReadEnum <T>(this Stream stream, bool strict = false, ByteConverter converter = null)
            where T : struct, IComparable, IFormattable
        {
            return((T)ReadEnum(stream, typeof(T), strict, converter));
        }