Esempio n. 1
0
        /// <summary>
        /// Add an array of type T to the buffer (aligns the data and grows if necessary).
        /// </summary>
        /// <typeparam name="T">The type of the input data</typeparam>
        /// <param name="x">The array to copy data from</param>
        public void Add <T>(T[] x)
            where T : struct
        {
            if (x == null)
            {
                throw new ArgumentNullException("Cannot add a null array");
            }

            if (x.Length == 0)
            {
                // don't do anything if the array is empty
                return;
            }

            if (!ByteBuffer.IsSupportedType <T>())
            {
                throw new ArgumentException("Cannot add this Type array to the builder");
            }

            int size = ByteBuffer.SizeOf <T>();

            // Need to prep on size (for data alignment) and then we pass the
            // rest of the length (minus 1) as additional bytes
            Prep(size, size * (x.Length - 1));
            Put(x);
        }
Esempio n. 2
0
        /// <summary>
        /// Add a span of type T to the buffer (aligns the data and grows if necessary).
        /// </summary>
        /// <typeparam name="T">The type of the input data</typeparam>
        /// <param name="x">The span to copy data from</param>
        public void Add <T>(Span <T> x)
            where T : struct
        {
            if (!ByteBuffer.IsSupportedType <T>())
            {
                throw new ArgumentException("Cannot add this Type array to the builder");
            }

            int size = ByteBuffer.SizeOf <T>();

            // Need to prep on size (for data alignment) and then we pass the
            // rest of the length (minus 1) as additional bytes
            Prep(size, size * (x.Length - 1));
            Put(x);
        }
Esempio n. 3
0
        /// <summary>
        /// Copies an array segment of type T into this buffer, ending at the
        /// given offset into this buffer. The starting offset is calculated
        /// based on the count of the array segment and is the value returned.
        /// </summary>
        /// <typeparam name="T">The type of the input data (must be a struct)
        /// </typeparam>
        /// <param name="offset">The offset into this buffer where the copy
        /// will end</param>
        /// <param name="x">The array segment to copy data from</param>
        /// <returns>The 'start' location of this buffer now, after the copy
        /// completed</returns>
        public int Put <T>(int offset, ArraySegment <T> x)
            where T : struct
        {
            if (x.Equals(default(ArraySegment <T>)))
            {
                throw new ArgumentNullException("Cannot put a uninitialized array segment");
            }

            if (x.Count == 0)
            {
                throw new ArgumentException("Cannot put an empty array");
            }

            if (!IsSupportedType <T>())
            {
                throw new ArgumentException("Cannot put an array of type "
                                            + typeof(T) + " into this buffer");
            }

            if (BitConverter.IsLittleEndian)
            {
                int numBytes = ByteBuffer.ArraySize(x);
                offset -= numBytes;
                AssertOffsetAndLength(offset, numBytes);
                // if we are LE, just do a block copy
#if ENABLE_SPAN_T && (UNSAFE_BYTEBUFFER || NETSTANDARD2_1)
                MemoryMarshal.Cast <T, byte>(x).CopyTo(_buffer.Span.Slice(offset, numBytes));
#else
                var srcOffset = ByteBuffer.SizeOf <T>() * x.Offset;
                Buffer.BlockCopy(x.Array, srcOffset, _buffer.Buffer, offset, numBytes);
#endif
            }
            else
            {
                throw new NotImplementedException("Big Endian Support not implemented yet " +
                                                  "for putting typed arrays");
                // if we are BE, we have to swap each element by itself
                //for(int i = x.Length - 1; i >= 0; i--)
                //{
                //  todo: low priority, but need to genericize the Put<T>() functions
                //}
            }
            return(offset);
        }
Esempio n. 4
0
        /// <summary>
        /// Adds the data of type T pointed to by the given pointer to the buffer (aligns the data and grows if necessary).
        /// </summary>
        /// <typeparam name="T">The type of the input data</typeparam>
        /// <param name="ptr">The pointer to copy data from</param>
        /// <param name="sizeInBytes">The data size in bytes</param>
        public void Add <T>(IntPtr ptr, int sizeInBytes)
            where T : struct
        {
            if (sizeInBytes == 0)
            {
                // don't do anything if the array is empty
                return;
            }

            if (ptr == IntPtr.Zero)
            {
                throw new ArgumentNullException("Cannot add a null pointer");
            }

            if (sizeInBytes < 0)
            {
                throw new ArgumentOutOfRangeException("sizeInBytes", "sizeInBytes cannot be negative");
            }

            if (!ByteBuffer.IsSupportedType <T>())
            {
                throw new ArgumentException("Cannot add this Type array to the builder");
            }

            int size = ByteBuffer.SizeOf <T>();

            if ((sizeInBytes % size) != 0)
            {
                throw new ArgumentException("The given size in bytes " + sizeInBytes + " doesn't match the element size of T ( " + size + ")", "sizeInBytes");
            }

            // Need to prep on size (for data alignment) and then we pass the
            // rest of the length (minus 1) as additional bytes
            Prep(size, sizeInBytes - size);
            Put <T>(ptr, sizeInBytes);
        }