public int Put <T>(int offset, Span <T> x)
            where T : struct
        {
            if (x.Length == 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
                MemoryMarshal.Cast <T, byte>(x).CopyTo(_buffer.Span.Slice(offset, numBytes));
            }
            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. 2
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);
        }