Example #1
0
        public ReadOnlyBuffer(OwnedMemory <byte> data, int offset, int length)
        {
            if (data == null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.data);
            }

            if (offset < 0)
            {
                ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.offset);
            }

            if (length < 0 || length > data.Length - offset)
            {
                ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.length);
            }


            BufferStart = new Position(data, offset);
            BufferEnd   = new Position(data, offset + length);
        }
Example #2
0
        private static long GetLength(Position begin, Position end)
        {
            if (begin.Segment == null)
            {
                return(0);
            }

            var segment = begin.Segment;

            switch (segment)
            {
            case IMemoryList <byte> bufferSegment:
                return(GetLength(bufferSegment, begin.Index, end.GetSegment <IMemoryList <byte> >(), end.Index));

            case byte[] _:
            case OwnedMemory <byte> _:
                return(end.Index - begin.Index);
            }

            ThrowHelper.ThrowInvalidOperationException(ExceptionResource.UnexpectedSegmentType);
            return(default);
Example #3
0
        private static Position SeekMultiSegment(Position begin, Position end, long bytes, bool checkEndReachable)
        {
            Position result      = default;
            var      foundResult = false;
            var      current     = begin;

            while (TryGetBuffer(begin, end, out var memory, out begin))
            {
                // We need to loop up until the end to make sure start and end are connected
                // if end is not trusted
                if (!foundResult)
                {
                    // We would prefer to put cursor in the beginning of next segment
                    // then past the end of previous one, but only if next exists

                    if (memory.Length > bytes ||
                        (memory.Length == bytes && begin.Segment == null))
                    {
                        result      = new Position(current.Segment, current.Index + (int)bytes);
                        foundResult = true;
                        if (!checkEndReachable)
                        {
                            break;
                        }
                    }

                    bytes -= memory.Length;
                }
                current = begin;
            }

            if (!foundResult)
            {
                ThrowHelper.ThrowCursorOutOfBoundsException();
            }

            return(result);
        }
            public sealed override MemoryHandle Pin(int byteOffset = 0)
            {
                unsafe
                {
                    Retain(); // this checks IsDisposed

                    try
                    {
                        if ((IntPtr.Size == 4 && (uint)byteOffset > (uint)_array.Length * (uint)Unsafe.SizeOf <T>()) ||
                            (IntPtr.Size != 4 && (ulong)byteOffset > (uint)_array.Length * (ulong)Unsafe.SizeOf <T>()))
                        {
                            ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.byteOffset);
                        }

                        GCHandle handle = GCHandle.Alloc(_array, GCHandleType.Pinned);
                        return(new MemoryHandle(this, ((byte *)handle.AddrOfPinnedObject()) + byteOffset, handle));
                    }
                    catch
                    {
                        Release();
                        throw;
                    }
                }
            }
Example #5
0
        internal static bool TryGetBuffer(Position begin, Position end, out ReadOnlyMemory <byte> data, out Position next)
        {
            var segment = begin.Segment;

            switch (segment)
            {
            case null:
                data = default;
                next = default;
                return(false);

            case IMemoryList <byte> bufferSegment:
                var startIndex = begin.Index;
                var endIndex   = bufferSegment.Memory.Length;

                if (segment == end.Segment)
                {
                    endIndex = end.Index;
                    next     = default;
                }
                else
                {
                    var nextSegment = bufferSegment.Next;
                    if (nextSegment == null)
                    {
                        if (end.Segment != null)
                        {
                            ThrowHelper.ThrowInvalidOperationException(ExceptionResource.EndCursorNotReached);
                        }

                        next = default;
                    }
                    else
                    {
                        next = new Position(nextSegment, 0);
                    }
                }

                data = bufferSegment.Memory.Slice(startIndex, endIndex - startIndex);

                return(true);


            case OwnedMemory <byte> ownedMemory:
                data = ownedMemory.Memory.Slice(begin.Index, end.Index - begin.Index);

                if (segment != end.Segment)
                {
                    ThrowHelper.ThrowInvalidOperationException(ExceptionResource.EndCursorNotReached);
                }

                next = default;
                return(true);

            case byte[] array:
                data = new Memory <byte>(array, begin.Index, end.Index - begin.Index);

                if (segment != end.Segment)
                {
                    ThrowHelper.ThrowInvalidOperationException(ExceptionResource.EndCursorNotReached);
                }
                next = default;
                return(true);
            }

            ThrowHelper.ThrowNotSupportedException();
            next = default;
            return(false);
        }