/*
 * Copyright 2014 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

using System;
using System.Linq;
using System.Runtime.InteropServices;

namespace Google.FlatBuffers.Test
{
    [FlatBuffersTestClass]
    public class ByteBufferTests
    {

        [FlatBuffersTestMethod]
        public void ByteBuffer_Length_MatchesBufferLength()
        {
            var buffer = new byte[1000];
            var uut = new ByteBuffer(buffer);
            Assert.AreEqual(buffer.Length, uut.Length);
        }

        [FlatBuffersTestMethod]
        public void ByteBuffer_PutBytePopulatesBufferAtZeroOffset()
        {
            var buffer = new byte[1];
            var uut = new ByteBuffer(buffer);
            uut.PutByte(0, (byte)99);

            Assert.AreEqual((byte)99, buffer[0]);
        }

#if !BYTEBUFFER_NO_BOUNDS_CHECK
        [FlatBuffersTestMethod]
        public void ByteBuffer_PutByteCannotPutAtOffsetPastLength()
        {
            var uut = new ByteBuffer(1);
            Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutByte(1, 99));
        }
#endif

        [FlatBuffersTestMethod]
        public void ByteBuffer_PutShortPopulatesBufferCorrectly()
        {
            var buffer = new byte[2];
            var uut = new ByteBuffer(buffer);
            uut.PutShort(0, (short)1);

            // Ensure Endianness was written correctly
            Assert.AreEqual((byte)1, buffer[0]);
            Assert.AreEqual((byte)0, buffer[1]);
        }

#if !BYTEBUFFER_NO_BOUNDS_CHECK
        [FlatBuffersTestMethod]
        public void ByteBuffer_PutShortCannotPutAtOffsetPastLength()
        {
            var uut = new ByteBuffer(2);
            Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutShort(2, 99));
        }
#endif

#if !BYTEBUFFER_NO_BOUNDS_CHECK
        [FlatBuffersTestMethod]
        public void ByteBuffer_PutShortChecksLength()
        {
            var uut = new ByteBuffer(1);
            Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutShort(0, 99));
        }

        [FlatBuffersTestMethod]
        public void ByteBuffer_PutShortChecksLengthAndOffset()
        {
            var uut = new ByteBuffer(2);
            Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutShort(1, 99));
        }
#endif

        [FlatBuffersTestMethod]
        public void ByteBuffer_PutIntPopulatesBufferCorrectly()
        {
            var buffer = new byte[4];
            var uut = new ByteBuffer(buffer);
            uut.PutInt(0, 0x0A0B0C0D);

            // Ensure Endianness was written correctly
            Assert.AreEqual(0x0D, buffer[0]);
            Assert.AreEqual(0x0C, buffer[1]);
            Assert.AreEqual(0x0B, buffer[2]);
            Assert.AreEqual(0x0A, buffer[3]);
        }

#if !BYTEBUFFER_NO_BOUNDS_CHECK
        [FlatBuffersTestMethod]
        public void ByteBuffer_PutIntCannotPutAtOffsetPastLength()
        {
            var uut = new ByteBuffer(4);
            Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutInt(2, 0x0A0B0C0D));
        }

        [FlatBuffersTestMethod]
        public void ByteBuffer_PutIntChecksLength()
        {
            var uut = new ByteBuffer(1);
            Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutInt(0, 0x0A0B0C0D));
        }

        [FlatBuffersTestMethod]
        public void ByteBuffer_PutIntChecksLengthAndOffset()
        {
            var uut = new ByteBuffer(4);
            Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutInt(2, 0x0A0B0C0D));
        }
#endif

        [FlatBuffersTestMethod]
        public void ByteBuffer_PutLongPopulatesBufferCorrectly()
        {
            var buffer = new byte[8];
            var uut = new ByteBuffer(buffer);
            uut.PutLong(0, 0x010203040A0B0C0D);

            // Ensure Endianness was written correctly
            Assert.AreEqual(0x0D, buffer[0]);
            Assert.AreEqual(0x0C, buffer[1]);
            Assert.AreEqual(0x0B, buffer[2]);
            Assert.AreEqual(0x0A, buffer[3]);
            Assert.AreEqual(0x04, buffer[4]);
            Assert.AreEqual(0x03, buffer[5]);
            Assert.AreEqual(0x02, buffer[6]);
            Assert.AreEqual(0x01, buffer[7]);
        }

#if !BYTEBUFFER_NO_BOUNDS_CHECK
        [FlatBuffersTestMethod]
        public void ByteBuffer_PutLongCannotPutAtOffsetPastLength()
        {
            var uut = new ByteBuffer(8);
            Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutLong(2, 0x010203040A0B0C0D));
        }

        [FlatBuffersTestMethod]
        public void ByteBuffer_PutLongChecksLength()
        {
            var uut = new ByteBuffer(1);
            Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutLong(0, 0x010203040A0B0C0D));
        }

        [FlatBuffersTestMethod]
        public void ByteBuffer_PutLongChecksLengthAndOffset()
        {
            var uut = new ByteBuffer(8);
            Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutLong(2, 0x010203040A0B0C0D));
        }
#endif

        [FlatBuffersTestMethod]
        public void ByteBuffer_GetByteReturnsCorrectData()
        {
            var buffer = new byte[1];
            buffer[0] = 99;
            var uut = new ByteBuffer(buffer);
            Assert.AreEqual((byte)99, uut.Get(0));
        }

#if !BYTEBUFFER_NO_BOUNDS_CHECK
        [FlatBuffersTestMethod]
        public void ByteBuffer_GetByteChecksOffset()
        {
            var uut = new ByteBuffer(1);
            Assert.Throws<ArgumentOutOfRangeException>(() => uut.Get(1));
        }
#endif

        [FlatBuffersTestMethod]
        public void ByteBuffer_GetShortReturnsCorrectData()
        {
            var buffer = new byte[2];
            buffer[0] = 1;
            buffer[1] = 0;
            var uut = new ByteBuffer(buffer);
            Assert.AreEqual(1, uut.GetShort(0));
        }

#if !BYTEBUFFER_NO_BOUNDS_CHECK
        [FlatBuffersTestMethod]
        public void ByteBuffer_GetShortChecksOffset()
        {
            var uut = new ByteBuffer(2);
            Assert.Throws<ArgumentOutOfRangeException>(() => uut.GetShort(2));
        }

        [FlatBuffersTestMethod]
        public void ByteBuffer_GetShortChecksLength()
        {
            var uut = new ByteBuffer(2);
            Assert.Throws<ArgumentOutOfRangeException>(() => uut.GetShort(1));
        }
#endif

        [FlatBuffersTestMethod]
        public void ByteBuffer_GetIntReturnsCorrectData()
        {
            var buffer = new byte[4];
            buffer[0] = 0x0D;
            buffer[1] = 0x0C;
            buffer[2] = 0x0B;
            buffer[3] = 0x0A;
            var uut = new ByteBuffer(buffer);
            Assert.AreEqual(0x0A0B0C0D, uut.GetInt(0));
        }

#if !BYTEBUFFER_NO_BOUNDS_CHECK
        [FlatBuffersTestMethod]
        public void ByteBuffer_GetIntChecksOffset()
        {
            var uut = new ByteBuffer(4);
            Assert.Throws<ArgumentOutOfRangeException>(() => uut.GetInt(4));
        }

        [FlatBuffersTestMethod]
        public void ByteBuffer_GetIntChecksLength()
        {
            var uut = new ByteBuffer(2);
            Assert.Throws<ArgumentOutOfRangeException>(() => uut.GetInt(0));
        }
#endif

        [FlatBuffersTestMethod]
        public void ByteBuffer_GetLongReturnsCorrectData()
        {
            var buffer = new byte[8];
            buffer[0] = 0x0D;
            buffer[1] = 0x0C;
            buffer[2] = 0x0B;
            buffer[3] = 0x0A;
            buffer[4] = 0x04;
            buffer[5] = 0x03;
            buffer[6] = 0x02;
            buffer[7] = 0x01;
            var uut = new ByteBuffer(buffer);
            Assert.AreEqual(0x010203040A0B0C0D, uut.GetLong(0));
        }

#if !BYTEBUFFER_NO_BOUNDS_CHECK
        [FlatBuffersTestMethod]
        public void ByteBuffer_GetLongChecksOffset()
        {
            var uut = new ByteBuffer(8);
            Assert.Throws<ArgumentOutOfRangeException>(() => uut.GetLong(8));
        }

        [FlatBuffersTestMethod]
        public void ByteBuffer_GetLongChecksLength()
        {
            var uut = new ByteBuffer(7);
            Assert.Throws<ArgumentOutOfRangeException>(() => uut.GetLong(0));
        }
#endif

        [FlatBuffersTestMethod]
        public void ByteBuffer_ReverseBytesUshort()
        {
            const ushort original = (ushort)0x1234U;
            var reverse = ByteBuffer.ReverseBytes(original);
            Assert.AreEqual(0x3412U, reverse);

            var rereverse = ByteBuffer.ReverseBytes(reverse);
            Assert.AreEqual(original, rereverse);
        }

        [FlatBuffersTestMethod]
        public void ByteBuffer_ReverseBytesUint()
        {
            const uint original = 0x12345678;
            var reverse = ByteBuffer.ReverseBytes(original);
            Assert.AreEqual(0x78563412U, reverse);

            var rereverse = ByteBuffer.ReverseBytes(reverse);
            Assert.AreEqual(original, rereverse);
        }

        [FlatBuffersTestMethod]
        public void ByteBuffer_ReverseBytesUlong()
        {
            const ulong original = 0x1234567890ABCDEFUL;
            var reverse = ByteBuffer.ReverseBytes(original);
            Assert.AreEqual(0xEFCDAB9078563412UL, reverse);

            var rereverse = ByteBuffer.ReverseBytes(reverse);
            Assert.AreEqual(original, rereverse);
        }

        [FlatBuffersTestMethod]
        public void ByteBuffer_ToFullArray_MatchesBuffer()
        {
            var buffer = new byte[4];
            buffer[0] = 0x0D;
            buffer[1] = 0x0C;
            buffer[2] = 0x0B;
            buffer[3] = 0x0A;
            var uut = new ByteBuffer(buffer);
            Assert.ArrayEqual(buffer, uut.ToFullArray());
        }

        [FlatBuffersTestMethod]
        public void ByteBuffer_ToSizedArray_MatchesBuffer()
        {
            var buffer = new byte[4];
            buffer[0] = 0x0D;
            buffer[1] = 0x0C;
            buffer[2] = 0x0B;
            buffer[3] = 0x0A;
            var uut = new ByteBuffer(buffer);
            Assert.ArrayEqual(buffer, uut.ToFullArray());
        }

        [FlatBuffersTestMethod]
        public void ByteBuffer_Duplicate_MatchesBuffer()
        {
            var buffer = new byte[4];
            buffer[0] = 0x0D;
            buffer[1] = 0x0C;
            buffer[2] = 0x0B;
            buffer[3] = 0x0A;
            var uut = new ByteBuffer(buffer);
            Assert.AreEqual(0x0A0B0C0D, uut.GetInt(0));

            // Advance by two bytes
            uut.Position = 2; uut = uut.Duplicate();
            Assert.AreEqual(0x0A0B, uut.GetShort(2));

            // Advance by one more byte
            uut.Position = 1; uut = uut.Duplicate();
            Assert.AreEqual(0x0A, uut.Get(3));
        }

        [FlatBuffersTestMethod]
        public void ByteBuffer_To_Array_Float()
        {
            const int len = 9;

            // Construct the data array
            var fData = new float[len];
            fData[0] = 1.0079F;
            fData[1] = 4.0026F;
            fData[2] = 6.941F;
            fData[3] = 9.0122F;
            fData[4] = 10.811F;
            fData[5] = 12.0107F;
            fData[6] = 14.0067F;
            fData[7] = 15.9994F;
            fData[8] = 18.9984F;

            var sizeInBytes = ByteBuffer.ConvertTsToBytes<float>(fData.Length);

            // Tranfer it to a byte array
            var buffer = new byte[sizeInBytes];
            Buffer.BlockCopy(fData, 0, buffer, 0, buffer.Length);

            // Create the Byte Buffer from byte array
            var uut = new ByteBuffer(buffer);

            // Get the full array back out and ensure they are equivalent
            var bbArray = uut.ToArray<float>(0, sizeInBytes);
            Assert.ArrayEqual(fData, bbArray);

            // Get a portion of the full array back out and ensure the
            // subrange agrees
            var posInFloats = 4;
            var lenInFloats = Math.Min(fData.Length - posInFloats - 1, 4);
            var bbArray2 = uut.ToArray<float>(ByteBuffer.ConvertTsToBytes<float>(posInFloats), ByteBuffer.ConvertTsToBytes<float>(lenInFloats));
            Assert.ArrayEqual(fData.Skip(posInFloats).Take(bbArray2.Length).ToArray(), bbArray2);

            // Get a sub portion of the full array back out and ensure the
            // subrange agrees
            posInFloats = 6;
            lenInFloats = Math.Min(fData.Length - posInFloats - 1, 1);
            var bbArray3 = uut.ToArray<float>(ByteBuffer.ConvertTsToBytes<float>(posInFloats), ByteBuffer.ConvertTsToBytes<float>(lenInFloats));
            Assert.ArrayEqual(fData.Skip(posInFloats).Take(bbArray3.Length).ToArray(), bbArray3);
        }

        public void ByteBuffer_Put_Array_Helper<T>(T[] data, int typeSize)
            where T : struct
        {
            // Create the Byte Buffer
            var uut = new ByteBuffer(1024);

            // Put the data into the buffer and make sure the offset is
            // calculated correctly
            int nOffset = uut.Put(1024, data);
            Assert.AreEqual(1024 - typeSize * data.Length, nOffset);

            // Get the full array back out and ensure they are equivalent
            var bbArray = uut.ToArray<T>(nOffset, ByteBuffer.ConvertTsToBytes<T>(data.Length));
            Assert.ArrayEqual(data, bbArray);
        }

        public void ByteBuffer_Put_ArraySegment_Helper<T>(ArraySegment<T> data, int typeSize)
            where T : struct
        {
            // Create the Byte Buffer
            var uut = new ByteBuffer(1024);

            // Put the data into the buffer and make sure the offset is
            // calculated correctly
            int nOffset = uut.Put(1024, data);
            Assert.AreEqual(1024 - typeSize * data.Count, nOffset);
      
            // Get the full array back out and ensure they are equivalent
            var bbArray = uut.ToArray<T>(nOffset, ByteBuffer.ConvertTsToBytes<T>(data.Count));
            Assert.ArrayEqual(data, bbArray);
        }
    
        public unsafe void ByteBuffer_Put_IntPtr_Helper<T>(T[] data, int typeSize)
            where T : struct
        {
            GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned);
            try
            {
                var dataPtr = handle.AddrOfPinnedObject();
                var sizeInBytes = data.Length * typeSize;

                // Create the Byte Buffer
                var uut = new ByteBuffer(1024);

                // Put the data into the buffer and make sure the offset is
                // calculated correctly
                int nOffset = uut.Put<T>(1024, dataPtr, sizeInBytes);
                Assert.AreEqual(1024 - sizeInBytes, nOffset);

                // Get the full array back out and ensure they are equivalent
                var bbArray = uut.ToArray<T>(nOffset, ByteBuffer.ConvertTsToBytes<T>(data.Length));
                Assert.ArrayEqual(data, bbArray);
            }
            finally
            {
                handle.Free();
            }
        }

        public void ByteBuffer_Put_ArrayTypes_Helper<T>(T[] data, int typeSize)
            where T : struct
        {
            ByteBuffer_Put_Array_Helper(data, typeSize);

            var arraySegment = CreateArraySegment(data);
            ByteBuffer_Put_ArraySegment_Helper(arraySegment, typeSize);

            ByteBuffer_Put_IntPtr_Helper(data, typeSize);
        }

        [FlatBuffersTestMethod]
        public void ByteBuffer_Put_Array_Float()
        {
            const int len = 9;

            // Construct the data array
            var data = new float[len];
            data[0] = 1.0079F;
            data[1] = 4.0026F;
            data[2] = 6.941F;
            data[3] = 9.0122F;
            data[4] = 10.811F;
            data[5] = 12.0107F;
            data[6] = 14.0067F;
            data[7] = 15.9994F;
            data[8] = 18.9984F;

            ByteBuffer_Put_ArrayTypes_Helper(data, sizeof(float));
        }

        [FlatBuffersTestMethod]
        public void ByteBuffer_Put_Array_Double()
        {
            const int len = 9;

            // Construct the data array
            var data = new double[len];
            data[0] = 1.0079;
            data[1] = 4.0026;
            data[2] = 6.941;
            data[3] = 9.0122;
            data[4] = 10.811;
            data[5] = 12.0107;
            data[6] = 14.0067;
            data[7] = 15.9994;
            data[8] = 18.9984;

            ByteBuffer_Put_ArrayTypes_Helper(data, sizeof(double));
        }

        [FlatBuffersTestMethod]
        public void ByteBuffer_Put_Array_Int()
        {
            const int len = 9;

            // Construct the data array
            var data = new int[len];
            data[0] = 1;
            data[1] = 4;
            data[2] = 6;
            data[3] = 9;
            data[4] = 10;
            data[5] = 12;
            data[6] = 14;
            data[7] = 15;
            data[8] = 18;

            ByteBuffer_Put_ArrayTypes_Helper(data, sizeof(int));
        }


        [FlatBuffersTestMethod]
        public void ByteBuffer_Put_Array_UInt()
        {
            const int len = 9;

            // Construct the data array
            var data = new uint[len];
            data[0] = 1;
            data[1] = 4;
            data[2] = 6;
            data[3] = 9;
            data[4] = 10;
            data[5] = 12;
            data[6] = 14;
            data[7] = 15;
            data[8] = 18;

            ByteBuffer_Put_ArrayTypes_Helper(data, sizeof(uint));
        }

        [FlatBuffersTestMethod]
        public void ByteBuffer_Put_Array_Bool()
        {
            const int len = 9;

            // Construct the data array
            var data = new bool[len];
            data[0] = true;
            data[1] = true;
            data[2] = false;
            data[3] = true;
            data[4] = false;
            data[5] = true;
            data[6] = true;
            data[7] = true;
            data[8] = false;

            ByteBuffer_Put_ArrayTypes_Helper(data, sizeof(bool));
        }

        [FlatBuffersTestMethod]
        public void ByteBuffer_Put_Array_Long()
        {
            const int len = 9;

            // Construct the data array
            var data = new long[len];
            data[0] = 1;
            data[1] = 4;
            data[2] = 6;
            data[3] = 9;
            data[4] = 10;
            data[5] = 12;
            data[6] = 14;
            data[7] = 15;
            data[8] = 18;

            ByteBuffer_Put_ArrayTypes_Helper(data, sizeof(long));
        }

        [FlatBuffersTestMethod]
        public void ByteBuffer_Put_Array_Byte()
        {
            const int len = 9;

            // Construct the data array
            var data = new byte[len];
            data[0] = 1;
            data[1] = 4;
            data[2] = 6;
            data[3] = 9;
            data[4] = 10;
            data[5] = 12;
            data[6] = 14;
            data[7] = 15;
            data[8] = 18;

            ByteBuffer_Put_ArrayTypes_Helper(data, sizeof(byte));
        }

        [FlatBuffersTestMethod]
        public void ByteBuffer_Put_Array_SByte()
        {
            const int len = 9;

            // Construct the data array
            var data = new sbyte[len];
            data[0] = 1;
            data[1] = 4;
            data[2] = 6;
            data[3] = 9;
            data[4] = 10;
            data[5] = 12;
            data[6] = 14;
            data[7] = 15;
            data[8] = 18;

            ByteBuffer_Put_ArrayTypes_Helper(data, sizeof(sbyte));
        }

        private static ArraySegment<T> CreateArraySegment<T>(T[] data)
            where T : struct
        {
            const int arraySegmentPadding = 7;
            var newData = new T[data.Length + 2 * arraySegmentPadding];
            Array.Copy(data, 0, newData, arraySegmentPadding, data.Length);
            return new ArraySegment<T>(newData, arraySegmentPadding, data.Length);
        }

        [FlatBuffersTestMethod]
        public void ByteBuffer_Put_Array_Null_Throws()
        {
            // Create the Byte Buffer
            var uut = new ByteBuffer(1024);

            // create a null array and try to put it into the buffer
            float[] data = null;
            Assert.Throws<ArgumentNullException>(() => uut.Put(1024, data));

            ArraySegment<float> dataArraySegment = default(ArraySegment<float>);
            Assert.Throws<ArgumentNullException>(() => uut.Put(1024, dataArraySegment));

            IntPtr dataPtr = IntPtr.Zero;
            int dataPtrLength = 100;
            Assert.Throws<ArgumentNullException>(() => uut.Put<float>(1024, dataPtr, dataPtrLength));
        }

        [FlatBuffersTestMethod]
        public unsafe void ByteBuffer_Put_Array_Empty_Throws()
        {
            // Create the Byte Buffer
            var uut = new ByteBuffer(1024);

            // create an array of length == 0, and try to put it into the buffer
            float[] data = new float[0];
            Assert.Throws<ArgumentException>(() => uut.Put(1024, data));

            var dataArraySegment = new ArraySegment<float>(new float[10], 5, 0);
            Assert.Throws<ArgumentException>(() => uut.Put(1024, dataArraySegment));

            fixed(float* floatPtr = data)
            {
                var dataPtr = (IntPtr)floatPtr;
                var dataPtrLength = 0;
                Assert.Throws<ArgumentException>(() => uut.Put<float>(1024, dataPtr, dataPtrLength));
            }
        }

        [FlatBuffersTestMethod]
        public unsafe void ByteBuffer_Put_IntPtr_NegativeSize_Throws()
        {
            // Create the Byte Buffer
            var uut = new ByteBuffer(1024);

            // create an array of length == 0, and try to put it into the buffer
            float[] data = new float[10];
            fixed(float* floatPtr = data)
            {
                var dataPtr = (IntPtr)floatPtr;
                var dataPtrLength = -1;
                Assert.Throws<ArgumentException>(() => uut.Put<float>(1024, dataPtr, dataPtrLength));
            }
        }

        #pragma warning disable 0169
        // These are purposely not used and the warning is suppress
        private struct dummyStruct
        {
            int a;
            float b;
        }
        #pragma warning restore 0169

        [FlatBuffersTestMethod]
        public unsafe void ByteBuffer_Put_Array_IncorrectType_Throws()
        {
            // Create the Byte Buffer
            var uut = new ByteBuffer(1024);

            // Create an array of dummy structures that shouldn't be
            // able to be put into the buffer
            var data = new dummyStruct[10];
            Assert.Throws<ArgumentException>(() => uut.Put(1024, data));

            var dataArraySegment = new ArraySegment<dummyStruct>(data);
            Assert.Throws<ArgumentException>(() => uut.Put(1024, dataArraySegment));

            fixed(dummyStruct* floatPtr = data)
            {
                var dataPtr = (IntPtr)floatPtr;
                var dataPtrLength = data.Length * sizeof(dummyStruct);
                Assert.Throws<ArgumentException>(() => uut.Put<dummyStruct>(1024, dataPtr, dataPtrLength));
            }
        }

        [FlatBuffersTestMethod]
        public void ByteBuffer_Get_Double()
        {
            var uut = new ByteBuffer(1024);
            double value = 3.14159265;
            uut.PutDouble(900, value);
            double getValue = uut.GetDouble(900);
            Assert.AreEqual(value, getValue);
        }

        [FlatBuffersTestMethod]
        public void ByteBuffer_Get_Float()
        {
            var uut = new ByteBuffer(1024);
            float value = 3.14159265F;
            uut.PutFloat(900, value);
            double getValue = uut.GetFloat(900);
            Assert.AreEqual(value, getValue);
        }
    }
}
