예제 #1
0
        /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is null.</exception>
        /// <exception cref="ArgumentOutOfRangeException">Range specified by <paramref name="start"/> and <paramref name="byteCount"/> falls outside of the bounds of the <paramref name="buffer"/>.</exception>
        /// <exception cref="InvalidOperationException">Builder is not writable, it has been linked with another one.</exception>
        public unsafe void WriteBytes(byte[] buffer, int start, int byteCount)
        {
            if (buffer == null)
            {
                Throw.ArgumentNull(nameof(buffer));
            }

            BlobUtilities.ValidateRange(buffer.Length, start, byteCount, nameof(byteCount));

            if (!IsHead)
            {
                Throw.InvalidOperationBuilderAlreadyLinked();
            }

            // an empty array has no element pointer:
            if (buffer.Length == 0)
            {
                return;
            }

            fixed(byte *ptr = &buffer[0])
            {
                WriteBytesUnchecked(ptr + start, byteCount);
            }
        }
예제 #2
0
        /// <exception cref="ArgumentOutOfRangeException">Range specified by <paramref name="start"/> and <paramref name="byteCount"/> falls outside of the bounds of the buffer content.</exception>
        /// <exception cref="InvalidOperationException">Content is not available, the builder has been linked with another one.</exception>
        public byte[] ToArray(int start, int byteCount)
        {
            BlobUtilities.ValidateRange(Count, start, byteCount);

            var result = new byte[byteCount];

            int chunkStartPosition = 0;
            int resultOffset       = 0;

            foreach (var chunk in GetChunks())
            {
                int chunkEndPosition = chunkStartPosition + chunk.Length;

                if (chunkEndPosition > start)
                {
                    int bytesToCopy = Math.Min(chunk.Length, result.Length - resultOffset);
                    if (bytesToCopy == 0)
                    {
                        break;
                    }

                    Array.Copy(chunk._buffer, Math.Max(start - chunkStartPosition, 0), result, resultOffset, bytesToCopy);

                    resultOffset += bytesToCopy;
                }

                chunkStartPosition = chunkEndPosition;
            }

            Debug.Assert(resultOffset == result.Length);
            return(result);
        }
예제 #3
0
        /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is null.</exception>
        /// <exception cref="ArgumentOutOfRangeException">Range specified by <paramref name="start"/> and <paramref name="byteCount"/> falls outside of the bounds of the <paramref name="buffer"/>.</exception>
        /// <exception cref="InvalidOperationException">Builder is not writable, it has been linked with another one.</exception>
        public unsafe void WriteBytes(byte[] buffer, int start, int byteCount)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException(nameof(buffer));
            }

            BlobUtilities.ValidateRange(buffer.Length, start, byteCount);

            if (!IsHead)
            {
                ThrowHeadRequired();
            }

            // an empty array has no element pointer:
            if (buffer.Length == 0)
            {
                return;
            }

            fixed(byte *ptr = buffer)
            {
                WriteBytesUnchecked(ptr + start, byteCount);
            }
        }
예제 #4
0
        /// <exception cref="ArgumentOutOfRangeException">Range specified by <paramref name="start"/> and <paramref name="byteCount"/> falls outside of the bounds of the buffer content.</exception>
        public byte[] ToArray(int start, int byteCount)
        {
            BlobUtilities.ValidateRange(Length, start, byteCount, nameof(byteCount));

            var result = new byte[byteCount];
            Array.Copy(_buffer, _start + start, result, 0, byteCount);
            return result;
        }
예제 #5
0
        /// <exception cref="ArgumentOutOfRangeException">Range specified by <paramref name="start"/> and <paramref name="byteCount"/> falls outside of the bounds of the buffer content.</exception>
        public byte[] ToArray(int start, int byteCount)
        {
            BlobUtilities.ValidateRange(Length, start, byteCount);

            var result = new byte[byteCount];

            Buffer.BlockCopy(_buffer, _start + start, result, 0, byteCount);
            return(result);
        }
예제 #6
0
        /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is null.</exception>
        /// <exception cref="ArgumentOutOfRangeException">Range specified by <paramref name="start"/> and <paramref name="byteCount"/> falls outside of the bounds of the <paramref name="buffer"/>.</exception>
        public unsafe void WriteBytes(byte[] buffer, int start, int byteCount)
        {
            if (buffer == null)
            {
                Throw.ArgumentNull(nameof(buffer));
            }

            BlobUtilities.ValidateRange(buffer.Length, start, byteCount, nameof(byteCount));

            // an empty array has no element pointer:
            if (buffer.Length == 0)
            {
                return;
            }

            fixed (byte* ptr = &buffer[0])
            {
                WriteBytes(ptr + start, byteCount);
            }
        }
예제 #7
0
        /// <exception cref="ArgumentOutOfRangeException">Range specified by <paramref name="start"/> and <paramref name="byteCount"/> falls outside of the bounds of the buffer content.</exception>
        /// <exception cref="InvalidOperationException">Content is not available, the builder has been linked with another one.</exception>
        public byte[] ToArray(int start, int byteCount)
        {
            BlobUtilities.ValidateRange(Count, start, byteCount, nameof(byteCount));

            var result = new byte[byteCount];

            int chunkStart  = 0;
            int bufferStart = start;
            int bufferEnd   = start + byteCount;

            foreach (var chunk in GetChunks())
            {
                int chunkEnd = chunkStart + chunk.Length;
                Debug.Assert(bufferStart >= chunkStart);

                if (chunkEnd > bufferStart)
                {
                    int bytesToCopy = Math.Min(bufferEnd, chunkEnd) - bufferStart;
                    Debug.Assert(bytesToCopy >= 0);

                    Array.Copy(chunk._buffer, bufferStart - chunkStart, result, bufferStart - start, bytesToCopy);
                    bufferStart += bytesToCopy;

                    if (bufferStart == bufferEnd)
                    {
                        break;
                    }
                }

                chunkStart = chunkEnd;
            }

            Debug.Assert(bufferStart == bufferEnd);

            return(result);
        }
예제 #8
0
 /// <summary>
 /// Reads the content of a part of the block into an array.
 /// </summary>
 /// <exception cref="ArgumentOutOfRangeException">Specified range is not contained within the block.</exception>
 public ImmutableArray <byte> GetContent(int start, int length)
 {
     BlobUtilities.ValidateRange(Length, start, length, nameof(length));
     return(_block?.GetContentUnchecked(_offset + start, length) ?? ImmutableArray <byte> .Empty);
 }
예제 #9
0
 /// <summary>
 /// Creates <see cref="BlobReader"/> for a blob spanning a part of the block.
 /// </summary>
 /// <exception cref="ArgumentOutOfRangeException">Specified range is not contained within the block.</exception>
 public unsafe BlobReader GetReader(int start, int length)
 {
     BlobUtilities.ValidateRange(Length, start, length, nameof(length));
     return(new BlobReader(Pointer + start, length));
 }
예제 #10
0
 public unsafe BlobReader CreateReader(int start, int count)
 {
     BlobUtilities.ValidateRange(_blob.Length, start, count);
     return(new BlobReader((byte *)_bytes.AddrOfPinnedObject() + start, count));
 }