1383 lines · 68.5 KB · C#
RawDownload
//******************************************************************************************************//  EndianOrderTest.cs - Gbtc////  Copyright © 2010, Grid Protection Alliance.  All Rights Reserved.////  Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See//  the NOTICE file distributed with this work for additional information regarding copyright ownership.//  The GPA licenses this file to you under the MIT License (MIT), the "License"; you may//  not use this file except in compliance with the License. You may obtain a copy of the License at:////      http://www.opensource.org/licenses/MIT////  Unless agreed to in writing, the subject software distributed under the License is distributed on an//  "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the//  License for the specific language governing permissions and limitations.////  Code Modification History://  ----------------------------------------------------------------------------------------------------//  02/13/2014 - J. Ritchie Carroll//       Generated original version of source code.////****************************************************************************************************** // Uncomment only for hard coded testing of BigEndian architecture code//#define ForceBigEndianTesting using System;using System.Collections.Generic;using System.Diagnostics.CodeAnalysis;using Microsoft.VisualStudio.TestTools.UnitTesting; namespace GSF.Core.Tests{    [TestClass]    public class EndianOrderTest    {        #region [ Byte Swap/Copy Only Endian Order Testing Classes ]         // These classes represent a brute-force approach to Endian order handling        // that are used as a base-line for testing other optimized approaches         /// <summary>        /// Represents a big-endian byte order interoperability class.        /// </summary>        private class BigEndianOrderTester : EndianOrderTester        {            #region [ Constructors ]             /// <summary>            /// Constructs a new instance of the <see cref="BigEndianOrderTester"/> class.            /// </summary>            public BigEndianOrderTester()                : base(Endianness.BigEndian)            {            }             #endregion             #region [ Static ]             private static BigEndianOrderTester s_endianOrder;             /// <summary>            /// Returns the default instance of the <see cref="BigEndianOrderTester"/> class.            /// </summary>            public static BigEndianOrderTester Default            {                get                {                    if ((object)s_endianOrder == null)                        s_endianOrder = new BigEndianOrderTester();                     return s_endianOrder;                }            }             #endregion        }         /// <summary>        /// Represents a little-endian byte order interoperability class.        /// </summary>        private class LittleEndianOrderTester : EndianOrderTester        {            #region [ Constructors ]             /// <summary>            /// Constructs a new instance of the <see cref="LittleEndianOrderTester"/> class.            /// </summary>            public LittleEndianOrderTester()                : base(Endianness.LittleEndian)            {            }             #endregion             #region [ Static ]             private static LittleEndianOrderTester s_endianOrder;             /// <summary>            /// Returns the default instance of the <see cref="LittleEndianOrderTester"/> class.            /// </summary>            public static LittleEndianOrderTester Default            {                get                {                    if ((object)s_endianOrder == null)                        s_endianOrder = new LittleEndianOrderTester();                     return s_endianOrder;                }            }             #endregion        }         /// <summary>        /// Represents a native-endian byte order interoperability class.        /// </summary>        private class NativeEndianOrderTester : EndianOrderTester        {            #region [ Constructors ]             /// <summary>            /// Constructs a new instance of the <see cref="NativeEndianOrderTester"/> class.            /// </summary>            public NativeEndianOrderTester()                : base(BitConverter.IsLittleEndian ? Endianness.LittleEndian : Endianness.BigEndian)            {            }             #endregion             #region [ Static ]             private static NativeEndianOrderTester s_endianOrder;             /// <summary>            /// Returns the default instance of the <see cref="NativeEndianOrderTester"/> class.            /// </summary>            public static NativeEndianOrderTester Default            {                get                {                    if ((object)s_endianOrder == null)                        s_endianOrder = new NativeEndianOrderTester();                     return s_endianOrder;                }            }             #endregion        }         /// <summary>        /// Represents an endian byte order interoperability class.        /// </summary>        /// <remarks>        /// Intel systems use little-endian byte order, other systems, such as Unix, use big-endian byte ordering.        /// Little-endian ordering means bits are ordered such that the bit whose in-memory representation is right-most is the most-significant-bit in a byte.        /// Big-endian ordering means bits are ordered such that the bit whose in-memory representation is left-most is the most-significant-bit in a byte.        /// </remarks>        private class EndianOrderTester        {            #region [ Members ]             // Delegates            private delegate void CopyBufferFunction(byte[] sourceBuffer, int sourceIndex, byte[] destinationBuffer, int destinationIndex, int length);            private delegate byte[] CoerceByteOrderFunction(byte[] buffer);             // Fields            private readonly Endianness m_targetEndianness;            private readonly CopyBufferFunction m_copyBuffer;            private readonly CoerceByteOrderFunction m_coerceByteOrder;             #endregion             #region [ Constructors ]             /// <summary>            /// Constructs a new instance of the <see cref="EndianOrderTester"/> class.            /// </summary>            /// <param name="targetEndianness">Endianness parameter.</param>            protected EndianOrderTester(Endianness targetEndianness)            {                m_targetEndianness = targetEndianness;                 // We perform this logic only once for speed in conversions - we can do this because neither                // the target nor the OS endian order will change during the lifecycle of this class...                if (targetEndianness == Endianness.BigEndian)                {#if ForceBigEndianTesting                    if (!BitConverter.IsLittleEndian) // <- Hard coded test for alternate architecture#else                    if (BitConverter.IsLittleEndian)#endif                    {                        // If OS is little endian and we want big endian, we swap the bytes                        m_copyBuffer = SwapCopy;                        m_coerceByteOrder = ReverseBuffer;                    }                    else                    {                        // If OS is big endian and we want big endian, we just copy the bytes                        m_copyBuffer = BlockCopy;                        m_coerceByteOrder = PassThroughBuffer;                    }                }                else                {#if ForceBigEndianTesting                    if (!BitConverter.IsLittleEndian) // <- Hard coded test for alternate architecture#else                    if (BitConverter.IsLittleEndian)#endif                    {                        // If OS is little endian and we want little endian, we just copy the bytes                        m_copyBuffer = BlockCopy;                        m_coerceByteOrder = PassThroughBuffer;                    }                    else                    {                        // If OS is big endian and we want little endian, we swap the bytes                        m_copyBuffer = SwapCopy;                        m_coerceByteOrder = ReverseBuffer;                    }                }            }             #endregion             #region [ Properties ]             /// <summary>            /// Returns the target endian-order of this <see cref="EndianOrderTester"/> representation.            /// </summary>            public Endianness TargetEndianness            {                get                {                    return m_targetEndianness;                }            }             #endregion             #region [ Methods ]             private void BlockCopy(byte[] sourceBuffer, int sourceIndex, byte[] destinationBuffer, int destinationIndex, int length)            {                Buffer.BlockCopy(sourceBuffer, sourceIndex, destinationBuffer, destinationIndex, length);            }             // This function behaves just like Array.Copy but takes a little-endian source array and copies it in big-endian order,            // or if the source array is big-endian it will copy it in little-endian order            private void SwapCopy(byte[] sourceBuffer, int sourceIndex, byte[] destinationBuffer, int destinationIndex, int length)            {                int offset = destinationIndex + length - 1;                 for (int x = sourceIndex; x <= sourceIndex + length - 1; x++)                {                    destinationBuffer[offset - (x - sourceIndex)] = sourceBuffer[x];                }            }             private byte[] PassThroughBuffer(byte[] buffer)            {                return buffer;            }             private byte[] ReverseBuffer(byte[] buffer)            {                Array.Reverse(buffer);                return buffer;            }             /// <summary>            /// Returns a <see cref="Boolean"/> value converted from one byte at a specified position in a byte array.            /// </summary>            /// <param name="value">An array of bytes.</param>            /// <param name="startIndex">The starting position within value.</param>            /// <returns>true if the byte at startIndex in value is nonzero; otherwise, false.</returns>            /// <exception cref="ArgumentNullException">value is null.</exception>            /// <exception cref="ArgumentOutOfRangeException">startIndex is less than zero or greater than the length of value minus 1.</exception>            [SuppressMessage("Microsoft.Performance", "CA1822")]            public bool ToBoolean(byte[] value, int startIndex)            {                return BitConverter.ToBoolean(value, startIndex);            }             /// <summary>            /// Returns a Unicode character converted from two bytes, accounting for target endian-order, at a specified position in a byte array.            /// </summary>            /// <param name="value">An array of bytes (i.e., buffer containing binary image of value).</param>            /// <param name="startIndex">The starting position within value.</param>            /// <returns>A character formed by two bytes beginning at startIndex.</returns>            /// <exception cref="ArgumentNullException">value is null.</exception>            /// <exception cref="ArgumentOutOfRangeException">startIndex is less than zero or greater than the length of value minus 1.</exception>            public char ToChar(byte[] value, int startIndex)            {                byte[] buffer = new byte[2];                 m_copyBuffer(value, startIndex, buffer, 0, 2);                 return BitConverter.ToChar(buffer, 0);            }             /// <summary>            /// Returns a double-precision floating point number converted from eight bytes, accounting for target endian-order, at a specified position in a byte array.            /// </summary>            /// <param name="value">An array of bytes (i.e., buffer containing binary image of value).</param>            /// <param name="startIndex">The starting position within value.</param>            /// <returns>A double-precision floating point number formed by eight bytes beginning at startIndex.</returns>            /// <exception cref="ArgumentNullException">value is null.</exception>            /// <exception cref="ArgumentOutOfRangeException">startIndex is less than zero or greater than the length of value minus 1.</exception>            public double ToDouble(byte[] value, int startIndex)            {                byte[] buffer = new byte[8];                 m_copyBuffer(value, startIndex, buffer, 0, 8);                 return BitConverter.ToDouble(buffer, 0);            }             /// <summary>            /// Returns a 16-bit signed integer converted from two bytes, accounting for target endian-order, at a specified position in a byte array.            /// </summary>            /// <param name="value">An array of bytes (i.e., buffer containing binary image of value).</param>            /// <param name="startIndex">The starting position within value.</param>            /// <returns>A 16-bit signed integer formed by two bytes beginning at startIndex.</returns>            /// <exception cref="ArgumentNullException">value is null.</exception>            /// <exception cref="ArgumentOutOfRangeException">startIndex is less than zero or greater than the length of value minus 1.</exception>            public short ToInt16(byte[] value, int startIndex)            {                byte[] buffer = new byte[2];                 m_copyBuffer(value, startIndex, buffer, 0, 2);                 return BitConverter.ToInt16(buffer, 0);            }             /// <summary>            /// Returns a 24-bit signed integer converted from three bytes, accounting for target endian-order, at a specified position in a byte array.            /// </summary>            /// <param name="value">An array of bytes (i.e., buffer containing binary image of value).</param>            /// <param name="startIndex">The starting position within value.</param>            /// <returns>A 24-bit signed integer formed by three bytes beginning at startIndex.</returns>            /// <exception cref="ArgumentNullException">value is null.</exception>            /// <exception cref="ArgumentOutOfRangeException">startIndex is less than zero or greater than the length of value minus 1.</exception>            public Int24 ToInt24(byte[] value, int startIndex)            {                byte[] buffer = new byte[3];                 m_copyBuffer(value, startIndex, buffer, 0, 3);                 return Int24.GetValue(buffer, 0);            }             /// <summary>            /// Returns a 32-bit signed integer converted from four bytes, accounting for target endian-order, at a specified position in a byte array.            /// </summary>            /// <param name="value">An array of bytes (i.e., buffer containing binary image of value).</param>            /// <param name="startIndex">The starting position within value.</param>            /// <returns>A 32-bit signed integer formed by four bytes beginning at startIndex.</returns>            /// <exception cref="ArgumentNullException">value is null.</exception>            /// <exception cref="ArgumentOutOfRangeException">startIndex is less than zero or greater than the length of value minus 1.</exception>            public int ToInt32(byte[] value, int startIndex)            {                byte[] buffer = new byte[4];                 m_copyBuffer(value, startIndex, buffer, 0, 4);                 return BitConverter.ToInt32(buffer, 0);            }             /// <summary>            /// Returns a 64-bit signed integer converted from eight bytes, accounting for target endian-order, at a specified position in a byte array.            /// </summary>            /// <param name="value">An array of bytes (i.e., buffer containing binary image of value).</param>            /// <param name="startIndex">The starting position within value.</param>            /// <returns>A 64-bit signed integer formed by eight bytes beginning at startIndex.</returns>            /// <exception cref="ArgumentNullException">value is null.</exception>            /// <exception cref="ArgumentOutOfRangeException">startIndex is less than zero or greater than the length of value minus 1.</exception>            public long ToInt64(byte[] value, int startIndex)            {                byte[] buffer = new byte[8];                 m_copyBuffer(value, startIndex, buffer, 0, 8);                 return BitConverter.ToInt64(buffer, 0);            }             /// <summary>            /// Returns a single-precision floating point number converted from four bytes, accounting for target endian-order, at a specified position in a byte array.            /// </summary>            /// <param name="value">An array of bytes (i.e., buffer containing binary image of value).</param>            /// <param name="startIndex">The starting position within value.</param>            /// <returns>A single-precision floating point number formed by four bytes beginning at startIndex.</returns>            /// <exception cref="ArgumentNullException">value is null.</exception>            /// <exception cref="ArgumentOutOfRangeException">startIndex is less than zero or greater than the length of value minus 1.</exception>            public float ToSingle(byte[] value, int startIndex)            {                byte[] buffer = new byte[4];                 m_copyBuffer(value, startIndex, buffer, 0, 4);                 return BitConverter.ToSingle(buffer, 0);            }             /// <summary>            /// Returns a 16-bit unsigned integer converted from two bytes, accounting for target endian-order, at a specified position in a byte array.            /// </summary>            /// <param name="value">An array of bytes (i.e., buffer containing binary image of value).</param>            /// <param name="startIndex">The starting position within value.</param>            /// <returns>A 16-bit unsigned integer formed by two bytes beginning at startIndex.</returns>            /// <exception cref="ArgumentNullException">value is null.</exception>            /// <exception cref="ArgumentOutOfRangeException">startIndex is less than zero or greater than the length of value minus 1.</exception>            public ushort ToUInt16(byte[] value, int startIndex)            {                byte[] buffer = new byte[2];                 m_copyBuffer(value, startIndex, buffer, 0, 2);                 return BitConverter.ToUInt16(buffer, 0);            }             /// <summary>            /// Returns a 24-bit unsigned integer converted from three bytes, accounting for target endian-order, at a specified position in a byte array.            /// </summary>            /// <param name="value">An array of bytes (i.e., buffer containing binary image of value).</param>            /// <param name="startIndex">The starting position within value.</param>            /// <returns>A 24-bit unsigned integer formed by three bytes beginning at startIndex.</returns>            /// <exception cref="ArgumentNullException">value is null.</exception>            /// <exception cref="ArgumentOutOfRangeException">startIndex is less than zero or greater than the length of value minus 1.</exception>            public UInt24 ToUInt24(byte[] value, int startIndex)            {                byte[] buffer = new byte[3];                 m_copyBuffer(value, startIndex, buffer, 0, 3);                 return UInt24.GetValue(buffer, 0);            }             /// <summary>            /// Returns a 32-bit unsigned integer converted from four bytes, accounting for target endian-order, at a specified position in a byte array.            /// </summary>            /// <param name="value">An array of bytes (i.e., buffer containing binary image of value).</param>            /// <param name="startIndex">The starting position within value.</param>            /// <returns>A 32-bit unsigned integer formed by four bytes beginning at startIndex.</returns>            /// <exception cref="ArgumentNullException">value is null.</exception>            /// <exception cref="ArgumentOutOfRangeException">startIndex is less than zero or greater than the length of value minus 1.</exception>            public uint ToUInt32(byte[] value, int startIndex)            {                byte[] buffer = new byte[4];                 m_copyBuffer(value, startIndex, buffer, 0, 4);                 return BitConverter.ToUInt32(buffer, 0);            }             /// <summary>            /// Returns a 64-bit unsigned integer converted from eight bytes, accounting for target endian-order, at a specified position in a byte array.            /// </summary>            /// <param name="value">An array of bytes (i.e., buffer containing binary image of value).</param>            /// <param name="startIndex">The starting position within value.</param>            /// <returns>A 64-bit unsigned integer formed by eight bytes beginning at startIndex.</returns>            /// <exception cref="ArgumentNullException">value is null.</exception>            /// <exception cref="ArgumentOutOfRangeException">startIndex is less than zero or greater than the length of value minus 1.</exception>            public ulong ToUInt64(byte[] value, int startIndex)            {                byte[] buffer = new byte[8];                 m_copyBuffer(value, startIndex, buffer, 0, 8);                 return BitConverter.ToUInt64(buffer, 0);            }             /// <summary>            /// Returns the specified value as an array of bytes in the target endian-order.            /// </summary>            /// <param name="value">The value to convert.</param>            /// <returns>An array of bytes with length 1.</returns>            /// <typeparam name="T">Native value type to get bytes for.</typeparam>            /// <exception cref="ArgumentException"><paramref name="value"/> type is not primitive.</exception>            /// <exception cref="InvalidOperationException">Cannot get bytes for <paramref name="value"/> type.</exception>            public byte[] GetBytes<T>(T value) where T : struct, IConvertible            {                if (!typeof(T).IsPrimitive)                    throw new ArgumentException("Value type is not primitive", "value");                 IConvertible nativeValue = (IConvertible)value;                 switch (nativeValue.GetTypeCode())                {                    case TypeCode.Char:                        return GetBytes(nativeValue.ToChar(null));                    case TypeCode.Boolean:                        return GetBytes(nativeValue.ToBoolean(null));                    case TypeCode.Int16:

Lines 1–500 of 1383.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t