예제 #1
0
        public byte ReadByte(long position)
        {
            EnsureSafeToRead(position, sizeof(byte));

            byte result;

            unsafe
            {
                byte *pointer = null;

                try
                {
                    _buffer.AcquirePointer(ref pointer);
                    result = *((byte *)(pointer + _offset + position));
                }
                finally
                {
                    if (pointer != null)
                    {
                        _buffer.ReleasePointer();
                    }
                }
            }
            return(result);
        }
예제 #2
0
        public override int Read([InAttribute][OutAttribute] byte[] buffer, int offset, int count)
        {
            if (closed)
            {
                throw new ObjectDisposedException("The stream is closed");
            }

            if (buffer == null)
            {
                throw new ArgumentNullException("buffer");
            }
            if (offset < 0)
            {
                throw new ArgumentOutOfRangeException("offset", "Non-negative number required.");
            }
            if (count < 0)
            {
                throw new ArgumentOutOfRangeException("count", "Non-negative number required.");
            }
            if ((buffer.Length - offset) < count)
            {
                throw new ArgumentException("The length of the buffer array minus the offset parameter is less than the count parameter");
            }

            if (fileaccess == FileAccess.Write)
            {
                throw new NotSupportedException("Stream does not support reading");
            }

            if (current_position >= length)
            {
                return(0);
            }

            int progress = current_position + count < length ? count : (int)(length - current_position);

#if NET_4_0
            if (safebuffer != null)
            {
                unsafe {
                    byte *ptr = null;
                    try {
                        safebuffer.AcquirePointer(ref ptr);
                        Marshal.Copy(new IntPtr(ptr + current_position), buffer, offset, progress);
                    } finally {
                        if (ptr != null)
                        {
                            safebuffer.ReleasePointer();
                        }
                    }
                }
            }
            else
#endif
            {
                Marshal.Copy(new IntPtr(initial_pointer.ToInt64() + current_position), buffer, offset, progress);
            }
            current_position += progress;
            return(progress);
        }
예제 #3
0
        internal int ReadCore(Span <byte> destination)
        {
            EnsureNotClosed();
            EnsureReadable();

            // Use a local variable to avoid a race where another thread
            // changes our position after we decide we can read some bytes.
            long pos = Interlocked.Read(ref _position);
            long len = Interlocked.Read(ref _length);
            long n   = Math.Min(len - pos, destination.Length);

            if (n <= 0)
            {
                return(0);
            }

            int nInt = (int)n; // Safe because n <= count, which is an Int32

            if (nInt < 0)
            {
                return(0);                                       // _position could be beyond EOF
            }
            Debug.Assert(pos + nInt >= 0, "_position + n >= 0"); // len is less than 2^63 -1.

            unsafe
            {
                fixed(byte *pBuffer = &MemoryMarshal.GetReference(destination))
                {
                    if (_buffer != null)
                    {
                        byte *pointer = null;

                        RuntimeHelpers.PrepareConstrainedRegions();
                        try
                        {
                            _buffer.AcquirePointer(ref pointer);
                            Buffer.Memcpy(pBuffer, pointer + pos + _offset, nInt);
                        }
                        finally
                        {
                            if (pointer != null)
                            {
                                _buffer.ReleasePointer();
                            }
                        }
                    }
                    else
                    {
                        Buffer.Memcpy(pBuffer, _mem + pos, nInt);
                    }
                }
            }
            Interlocked.Exchange(ref _position, pos + n);
            return(nInt);
        }
예제 #4
0
        public void Dispose()
        {
            if (IsDisposed)
            {
                return;
            }

            IsDisposed = true;
            if (View != null)
            {
                Buffer.ReleasePointer();

                // https://connect.microsoft.com/VisualStudio/feedback/details/552859/memorymappedviewaccessor-flush-throws-ioexception
                // View.Dispose();
                View.SafeMemoryMappedViewHandle.Dispose();
            }
            else if (CacheEntry != null)
            {
                CacheEntry.RemoveRef();
            }
            else
            {
                // Uninitialized
            }
        }
예제 #5
0
        [System.Security.SecuritySafeCritical]  // auto-generated
        protected void Initialize(SafeBuffer buffer, Int64 offset, Int64 capacity, FileAccess access)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException(nameof(buffer));
            }
            if (offset < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_NeedNonNegNum);
            }
            if (capacity < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(capacity), SR.ArgumentOutOfRange_NeedNonNegNum);
            }
            if (buffer.ByteLength < (UInt64)(offset + capacity))
            {
                throw new ArgumentException(SR.Argument_OffsetAndCapacityOutOfBounds);
            }
            if (access < FileAccess.Read || access > FileAccess.ReadWrite)
            {
                throw new ArgumentOutOfRangeException(nameof(access));
            }
            Contract.EndContractBlock();

            if (_isOpen)
            {
                throw new InvalidOperationException(SR.InvalidOperation_CalledTwice);
            }

            unsafe
            {
                byte *pointer = null;

                try
                {
                    buffer.AcquirePointer(ref pointer);
                    if (((byte *)((Int64)pointer + offset + capacity)) < pointer)
                    {
                        throw new ArgumentException(SR.Argument_UnmanagedMemAccessorWrapAround);
                    }
                }
                finally
                {
                    if (pointer != null)
                    {
                        buffer.ReleasePointer();
                    }
                }
            }

            _offset   = offset;
            _buffer   = buffer;
            _capacity = capacity;
            _access   = access;
            _isOpen   = true;
            _canRead  = (_access & FileAccess.Read) != 0;
            _canWrite = (_access & FileAccess.Write) != 0;
        }
예제 #6
0
        [System.Security.SecurityCritical]  // auto-generated
        private void Initialize(SafeBuffer buffer, long offset, long length, FileAccess access, bool skipSecurityCheck)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException("buffer");
            }
            if (offset < 0)
            {
                throw new ArgumentOutOfRangeException("offset", SR.ArgumentOutOfRange_NeedNonNegNum);
            }
            if (length < 0)
            {
                throw new ArgumentOutOfRangeException("length", SR.ArgumentOutOfRange_NeedNonNegNum);
            }
            if (buffer.ByteLength < (ulong)(offset + length))
            {
                throw new ArgumentException(SR.Argument_InvalidSafeBufferOffLen);
            }
            if (access < FileAccess.Read || access > FileAccess.ReadWrite)
            {
                throw new ArgumentOutOfRangeException("access");
            }
            Contract.EndContractBlock();

            if (_isOpen)
            {
                throw new InvalidOperationException(SR.InvalidOperation_CalledTwice);
            }

            // check for wraparound
            unsafe
            {
                byte *pointer = null;

                try
                {
                    buffer.AcquirePointer(ref pointer);
                    if ((pointer + offset + length) < pointer)
                    {
                        throw new ArgumentException(SR.ArgumentOutOfRange_UnmanagedMemStreamWrapAround);
                    }
                }
                finally
                {
                    if (pointer != null)
                    {
                        buffer.ReleasePointer();
                    }
                }
            }

            _offset   = offset;
            _buffer   = buffer;
            _length   = length;
            _capacity = length;
            _access   = access;
            _isOpen   = true;
        }
예제 #7
0
        protected void Initialize(SafeBuffer buffer, long offset, long length, FileAccess access)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException(nameof(buffer));
            }
            if (offset < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_NeedNonNegNum);
            }
            if (length < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_NeedNonNegNum);
            }
            if (buffer.ByteLength < (ulong)(offset + length))
            {
                throw new ArgumentException(SR.Argument_InvalidSafeBufferOffLen);
            }
            if (access < FileAccess.Read || access > FileAccess.ReadWrite)
            {
                throw new ArgumentOutOfRangeException(nameof(access));
            }
            Contract.EndContractBlock();

            if (_isOpen)
            {
                throw new InvalidOperationException(SR.InvalidOperation_CalledTwice);
            }

            // check for wraparound
            unsafe
            {
                byte *pointer = null;
                RuntimeHelpers.PrepareConstrainedRegions();
                try
                {
                    buffer.AcquirePointer(ref pointer);
                    if ((pointer + offset + length) < pointer)
                    {
                        throw new ArgumentException(SR.ArgumentOutOfRange_UnmanagedMemStreamWrapAround);
                    }
                }
                finally
                {
                    if (pointer != null)
                    {
                        buffer.ReleasePointer();
                    }
                }
            }

            _offset   = offset;
            _buffer   = buffer;
            _length   = length;
            _capacity = length;
            _access   = access;
            _isOpen   = true;
        }
예제 #8
0
            internal void Release()
            {
                IsDisposed = true;
                Buffer.ReleasePointer();

                // https://connect.microsoft.com/VisualStudio/feedback/details/552859/memorymappedviewaccessor-flush-throws-ioexception
                // View.Dispose();
                View.SafeMemoryMappedViewHandle.Dispose();
            }
예제 #9
0
        public unsafe void Write(SafeBuffer buffer)
        {
            if (buffer is null)
            {
                ExceptionUtil.ThrowArgumentNullException(nameof(buffer));
            }

            VerifyNotDisposed();

            ulong length = buffer.ByteLength;

            if (length == 0)
            {
                return;
            }

            // The largest multiple of 4096 that is under the large object heap limit.
            const int MaxBufferSize = 81920;

            int bufferSize = (int)Math.Min(length, MaxBufferSize);

            byte[] writeBuffer = this.arrayPool.Rent(bufferSize);

            byte *readPtr = null;

            System.Runtime.CompilerServices.RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                buffer.AcquirePointer(ref readPtr);

                fixed(byte *writePtr = writeBuffer)
                {
                    ulong totalBytesRead = 0;

                    while (totalBytesRead < length)
                    {
                        ulong bytesRead = Math.Min(length - totalBytesRead, MaxBufferSize);

                        Buffer.MemoryCopy(readPtr + totalBytesRead, writePtr, bytesRead, bytesRead);

                        this.stream.Write(writeBuffer, 0, (int)bytesRead);

                        totalBytesRead += bytesRead;
                    }
                }
            }
            finally
            {
                if (readPtr != null)
                {
                    buffer.ReleasePointer();
                }
            }

            this.arrayPool.Return(writeBuffer);
        }
예제 #10
0
#pragma warning restore 618
        protected void Initialize(SafeBuffer buffer, Int64 offset, Int64 capacity, FileAccess access)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException("buffer");
            }
            if (offset < 0)
            {
                throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
            }
            if (capacity < 0)
            {
                throw new ArgumentOutOfRangeException("capacity", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
            }
            if (buffer.ByteLength < (UInt64)(offset + capacity))
            {
                throw new ArgumentException(Environment.GetResourceString("Argument_OffsetAndCapacityOutOfBounds"));
            }
            if (access < FileAccess.Read || access > FileAccess.ReadWrite)
            {
                throw new ArgumentOutOfRangeException("access");
            }
            Contract.EndContractBlock();

            if (_isOpen)
            {
                throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CalledTwice"));
            }

            unsafe {
                byte *pointer = null;
                RuntimeHelpers.PrepareConstrainedRegions();
                try {
                    buffer.AcquirePointer(ref pointer);
                    if (((byte *)((Int64)pointer + offset + capacity)) < pointer)
                    {
                        throw new ArgumentException(Environment.GetResourceString("Argument_UnmanagedMemAccessorWrapAround"));
                    }
                }
                finally {
                    if (pointer != null)
                    {
                        buffer.ReleasePointer();
                    }
                }
            }

            _offset   = offset;
            _buffer   = buffer;
            _capacity = capacity;
            _access   = access;
            _isOpen   = true;
            _canRead  = (_access & FileAccess.Read) != 0;
            _canWrite = (_access & FileAccess.Write) != 0;
        }
        internal unsafe void Initialize(SafeBuffer buffer, long offset, long length, FileAccess access, bool skipSecurityCheck)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException("buffer");
            }
            if (offset < 0L)
            {
                throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
            }
            if (length < 0L)
            {
                throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
            }
            if (buffer.ByteLength < (offset + length))
            {
                throw new ArgumentException(Environment.GetResourceString("Argument_InvalidSafeBufferOffLen"));
            }
            if ((access < FileAccess.Read) || (access > FileAccess.ReadWrite))
            {
                throw new ArgumentOutOfRangeException("access");
            }
            if (this._isOpen)
            {
                throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CalledTwice"));
            }
            if (!skipSecurityCheck)
            {
                new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
            }
            byte *pointer = null;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                buffer.AcquirePointer(ref pointer);
                if (((pointer + offset) + length) < pointer)
                {
                    throw new ArgumentException(Environment.GetResourceString("ArgumentOutOfRange_UnmanagedMemStreamWrapAround"));
                }
            }
            finally
            {
                if (pointer != null)
                {
                    buffer.ReleasePointer();
                }
            }
            this._offset   = offset;
            this._buffer   = buffer;
            this._length   = length;
            this._capacity = length;
            this._access   = access;
            this._isOpen   = true;
        }
예제 #12
0
        /// <summary>
        /// Reads the specified number of bytes from the stream, starting from a specified point in the SafeBuffer.
        /// </summary>
        /// <param name="buffer">The buffer.</param>
        /// <param name="offset">The starting offset in the buffer.</param>
        /// <param name="count">The count.</param>
        /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is null.</exception>
        /// <exception cref="EndOfStreamException">The end of the stream has been reached.</exception>
        /// <exception cref="ObjectDisposedException">The object has been disposed.</exception>
        public unsafe void ProperRead(SafeBuffer buffer, ulong offset, ulong count)
        {
            if (buffer is null)
            {
                ExceptionUtil.ThrowArgumentNullException(nameof(buffer));
            }
            VerifyNotDisposed();

            if (count == 0)
            {
                return;
            }

            // The largest multiple of 4096 that is under the large object heap limit.
            const int MaxReadBufferSize = 81920;

            byte[] readBuffer = this.arrayPool.Rent((int)Math.Min(count, MaxReadBufferSize));

            byte *writePtr = null;

            System.Runtime.CompilerServices.RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                buffer.AcquirePointer(ref writePtr);

                fixed(byte *readPtr = readBuffer)
                {
                    ulong totalBytesRead = 0;

                    while (totalBytesRead < count)
                    {
                        ulong bytesRead = (ulong)ReadInternal(readBuffer, 0, (int)Math.Min(count - totalBytesRead, MaxReadBufferSize));

                        if (bytesRead == 0)
                        {
                            throw new EndOfStreamException();
                        }

                        Buffer.MemoryCopy(readPtr, writePtr + offset + totalBytesRead, bytesRead, bytesRead);

                        totalBytesRead += bytesRead;
                    }
                }
            }
            finally
            {
                if (writePtr != null)
                {
                    buffer.ReleasePointer();
                }
            }

            this.arrayPool.Return(readBuffer);
        }
예제 #13
0
        public override void Dispose()
        {
            Interlocked.Add(ref aggregatedTotalBytes, -TotalBytes);

            disposed = true;

            buffer.ReleasePointer();
            accessor.Dispose();
            backing.Dispose();

            GC.SuppressFinalize(this);
        }
 protected unsafe void Initialize(SafeBuffer buffer, long offset, long capacity, FileAccess access)
 {
     if (buffer == null)
     {
         throw new ArgumentNullException("buffer");
     }
     if (offset < 0L)
     {
         throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
     }
     if (capacity < 0L)
     {
         throw new ArgumentOutOfRangeException("capacity", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
     }
     if (buffer.ByteLength < (offset + capacity))
     {
         throw new ArgumentException(Environment.GetResourceString("Argument_OffsetAndCapacityOutOfBounds"));
     }
     if ((access < FileAccess.Read) || (access > FileAccess.ReadWrite))
     {
         throw new ArgumentOutOfRangeException("access");
     }
     if (this._isOpen)
     {
         throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CalledTwice"));
     }
     byte* pointer = null;
     RuntimeHelpers.PrepareConstrainedRegions();
     try
     {
         buffer.AcquirePointer(ref pointer);
         if (((IntPtr) ((((ulong) pointer) + offset) + ((ulong) capacity))) < pointer)
         {
             throw new ArgumentException(Environment.GetResourceString("Argument_UnmanagedMemAccessorWrapAround"));
         }
     }
     finally
     {
         if (pointer != null)
         {
             buffer.ReleasePointer();
         }
     }
     this._offset = offset;
     this._buffer = buffer;
     this._capacity = capacity;
     this._access = access;
     this._isOpen = true;
     this._canRead = (this._access & FileAccess.Read) != 0;
     this._canWrite = (this._access & FileAccess.Write) != 0;
 }
예제 #15
0
        public override void ReadBytes(Span <byte> dest, long offset)
        {
            CheckOffsets(offset, dest.Length);
            byte *pointer = null;

            mBuffer.AcquirePointer(ref pointer);
            try
            {
                new ReadOnlySpan <byte>(pointer + offset, dest.Length).CopyTo(dest);
            }
            finally
            {
                mBuffer.ReleasePointer();
            }
        }
예제 #16
0
        private void Dispose(bool disposing)
        {
            if (this.IsDisposed == false)
            {
                if (disposing)
                {
                    // no managed resources to dispose
                }

                _safeBuffer.ReleasePointer();
                _safeBuffer = null;

                this.IsDisposed = true;
            }
        }
예제 #17
0
        public static unsafe byte *DangerousGetPointer(this SafeBuffer buffer)
        {
            byte *pointer = null;

            RuntimeHelpers.PrepareConstrainedRegions();
            try {
                buffer.AcquirePointer(ref pointer);
            } finally {
                if (pointer != null)
                {
                    buffer.ReleasePointer();
                }
            }

            return(pointer);
        }
예제 #18
0
        protected override void Dispose(bool disposing)
        {
            if (_safeBuffer != null)
            {
                _safeBuffer.ReleasePointer();
                _safeBuffer = null;
            }

            if (_accessor != null)
            {
                _accessor.Dispose();
                _accessor = null;
            }

            _pointer = null;
        }
        protected override void Dispose(bool disposing)
        {
            if (safeBuffer != null)
            {
                safeBuffer.ReleasePointer();
                safeBuffer = null;
            }

            if (accessor != null)
            {
                accessor.Dispose();
                accessor = null;
            }

            pointer = null;
        }
예제 #20
0
파일: Segment.cs 프로젝트: fdoyon/capnpnet
        public Segment Init(Message message, SafeBuffer safeBuffer)
        {
            if (this.Message != null)
            {
                throw new InvalidOperationException("Segment already initialized");
            }

            if (safeBuffer.ByteLength % 8 != 0)
            {
                throw new ArgumentException("Memory length must be a multiple of 8 bytes");
            }

            this.Message = message;
            _byteLength  = (int)safeBuffer.ByteLength;

            _fixedMemHandle = safeBuffer;
            unsafe
            {
                byte *ptr = null;
                try
                {
                    // TODO: can we just use DangerousGetHandle?
                    safeBuffer.AcquirePointer(ref ptr);
                    _disposer        = new SafeBufferReleaser(safeBuffer);
                    _fixedMemPointer = new IntPtr(ptr);
                    return(this);
                }
                finally
                {
                    if (ptr != null)
                    {
                        if (_disposer == null)
                        {
                            _disposer.Dispose();
                        }
                        else
                        {
                            safeBuffer.ReleasePointer();
                        }
                    }
                }
            }
        }
예제 #21
0
        [System.Security.SecuritySafeCritical]  // auto-generated
        public override int Read([In, Out] byte[] buffer, int offset, int count)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
            }
            if (offset < 0)
            {
                throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
            }
            if (count < 0)
            {
                throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
            }
            if (buffer.Length - offset < count)
            {
                throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
            }
            Contract.EndContractBlock();  // Keep this in [....] with contract validation in ReadAsync

            if (!_isOpen)
            {
                __Error.StreamIsClosed();
            }
            if (!CanRead)
            {
                __Error.ReadNotSupported();
            }

            // Use a local variable to avoid a race where another thread
            // changes our position after we decide we can read some bytes.
            long pos = Interlocked.Read(ref _position);
            long len = Interlocked.Read(ref _length);
            long n   = len - pos;

            if (n > count)
            {
                n = count;
            }
            if (n <= 0)
            {
                return(0);
            }

            int nInt = (int)n;  // Safe because n <= count, which is an Int32

            if (nInt < 0)
            {
                nInt = 0;                                           // _position could be beyond EOF
            }
            Contract.Assert(pos + nInt >= 0, "_position + n >= 0"); // len is less than 2^63 -1.

            if (_buffer != null)
            {
                unsafe {
                    byte *pointer = null;
                    RuntimeHelpers.PrepareConstrainedRegions();
                    try {
                        _buffer.AcquirePointer(ref pointer);
                        Buffer.Memcpy(buffer, offset, pointer + pos + _offset, 0, nInt);
                    }
                    finally {
                        if (pointer != null)
                        {
                            _buffer.ReleasePointer();
                        }
                    }
                }
            }
            else
            {
                unsafe {
                    Buffer.Memcpy(buffer, offset, _mem + pos, 0, nInt);
                }
            }
            Interlocked.Exchange(ref _position, pos + n);
            return(nInt);
        }
예제 #22
0
        [System.Security.SecurityCritical]  // auto-generated
        internal void Initialize(SafeBuffer buffer, long offset, long length, FileAccess access, bool skipSecurityCheck)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException("buffer");
            }
            if (offset < 0)
            {
                throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
            }
            if (length < 0)
            {
                throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
            }
            if (buffer.ByteLength < (ulong)(offset + length))
            {
                throw new ArgumentException(Environment.GetResourceString("Argument_InvalidSafeBufferOffLen"));
            }
            if (access < FileAccess.Read || access > FileAccess.ReadWrite)
            {
                throw new ArgumentOutOfRangeException("access");
            }
            Contract.EndContractBlock();

            if (_isOpen)
            {
                throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CalledTwice"));
            }
#if FEATURE_MONO_CAS
            if (!skipSecurityCheck)
            {
#pragma warning disable 618
                new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
#pragma warning restore 618
            }
#endif

            // check for wraparound
            unsafe {
                byte *pointer = null;
                RuntimeHelpers.PrepareConstrainedRegions();
                try {
                    buffer.AcquirePointer(ref pointer);
                    if ((pointer + offset + length) < pointer)
                    {
                        throw new ArgumentException(Environment.GetResourceString("ArgumentOutOfRange_UnmanagedMemStreamWrapAround"));
                    }
                }
                finally {
                    if (pointer != null)
                    {
                        buffer.ReleasePointer();
                    }
                }
            }

            _offset   = offset;
            _buffer   = buffer;
            _length   = length;
            _capacity = length;
            _access   = access;
            _isOpen   = true;
        }
 public void Dispose()
 {
     buffer.ReleasePointer();
 }
예제 #24
0
        [System.Security.SecuritySafeCritical]  // auto-generated
        public override int Read([In, Out] byte[] buffer, int offset, int count)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException(nameof(buffer), SR.ArgumentNull_Buffer);
            }
            if (offset < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_NeedNonNegNum);
            }
            if (count < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum);
            }
            if (buffer.Length - offset < count)
            {
                throw new ArgumentException(SR.Argument_InvalidOffLen);
            }
            Contract.EndContractBlock();  // Keep this in sync with contract validation in ReadAsync

            if (!_isOpen)
            {
                throw Error.GetStreamIsClosed();
            }
            if (!CanRead)
            {
                throw Error.GetReadNotSupported();
            }

            // Use a local variable to avoid a race where another thread
            // changes our position after we decide we can read some bytes.
            long pos = Interlocked.Read(ref _position);
            long len = Interlocked.Read(ref _length);
            long n   = len - pos;

            if (n > count)
            {
                n = count;
            }
            if (n <= 0)
            {
                return(0);
            }

            int nInt = (int)n; // Safe because n <= count, which is an Int32

            if (nInt < 0)
            {
                return(0);                                       // _position could be beyond EOF
            }
            Debug.Assert(pos + nInt >= 0, "_position + n >= 0"); // len is less than 2^63 -1.

            unsafe
            {
                fixed(byte *pBuffer = buffer)
                {
                    if (_buffer != null)
                    {
                        byte *pointer = null;

                        try
                        {
                            _buffer.AcquirePointer(ref pointer);
                            Buffer.MemoryCopy(source: pointer + pos + _offset, destination: pBuffer + offset, destinationSizeInBytes: nInt, sourceBytesToCopy: nInt);
                        }
                        finally
                        {
                            if (pointer != null)
                            {
                                _buffer.ReleasePointer();
                            }
                        }
                    }
                    else
                    {
                        Buffer.MemoryCopy(source: _mem + pos, destination: pBuffer + offset, destinationSizeInBytes: nInt, sourceBytesToCopy: nInt);
                    }
                }
            }
            Interlocked.Exchange(ref _position, pos + n);
            return(nInt);
        }
예제 #25
0
        public char ReadChar(Int64 position)
        {
            EnsureSafeToRead(position, sizeof(char));

            char result;

            unsafe
            {
                byte *pointer = null;
                RuntimeHelpers.PrepareConstrainedRegions();
                try
                {
                    _buffer.AcquirePointer(ref pointer);
                    result = Unsafe.ReadUnaligned <char>(pointer + _offset + position);
                }
                finally
                {
                    if (pointer != null)
                    {
                        _buffer.ReleasePointer();
                    }
                }
            }

            return(result);
        }
예제 #26
0
        [System.Security.SecuritySafeCritical]  // auto-generated
        public char ReadChar(Int64 position)
        {
            int sizeOfType = sizeof(char);

            EnsureSafeToRead(position, sizeOfType);

            char result;

            unsafe
            {
                byte *pointer = null;

                try
                {
                    _buffer.AcquirePointer(ref pointer);
                    pointer += (_offset + position);

                    // check if pointer is aligned
                    if (((int)pointer & (sizeOfType - 1)) == 0)
                    {
                        result = *((char *)(pointer));
                    }
                    else
                    {
                        result = (char)(*pointer | *(pointer + 1) << 8);
                    }
                }
                finally
                {
                    if (pointer != null)
                    {
                        _buffer.ReleasePointer();
                    }
                }
            }

            return(result);
        }
예제 #27
0
        [System.Security.SecuritySafeCritical]  // auto-generated
        public char ReadChar(Int64 position)
        {
            int sizeOfType = sizeof(char);

            EnsureSafeToRead(position, sizeOfType);

            char result;

            unsafe {
                byte *pointer = null;
                RuntimeHelpers.PrepareConstrainedRegions();
                try {
                    _buffer.AcquirePointer(ref pointer);
                    pointer += (_offset + position);

#if ALIGN_ACCESS
                    // check if pointer is aligned
                    if (((int)pointer & (sizeOfType - 1)) == 0)
                    {
#endif
                    result = *((char *)(pointer));
#if ALIGN_ACCESS
                }
                else
                {
                    result = (char)(*pointer | *(pointer + 1) << 8);
                }
#endif
                }
                finally {
                    if (pointer != null)
                    {
                        _buffer.ReleasePointer();
                    }
                }
            }

            return(result);
        }