Beispiel #1
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);
        }
Beispiel #2
0
        /// <summary>
        /// Subclasses must call this method (or the other overload) to properly initialize all instance fields.
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="offset"></param>
        /// <param name="length"></param>
        /// <param name="access"></param>
        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));
            }

            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;
        }
        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;
        }
Beispiel #4
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), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
            }
            if (length < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(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(nameof(access));
            }
            Contract.EndContractBlock();

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

            // 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;
        }
#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;
        }
        protected void Initialize(SafeBuffer buffer, long offset, long capacity, FileAccess access)
        {
            ArgumentNullException.ThrowIfNull(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 < (ulong)(offset + capacity))
            {
                throw new ArgumentException(SR.Argument_OffsetAndCapacityOutOfBounds);
            }
            if (access < FileAccess.Read || access > FileAccess.ReadWrite)
            {
                throw new ArgumentOutOfRangeException(nameof(access));
            }

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

            unsafe
            {
                byte *pointer = null;

                try
                {
                    buffer.AcquirePointer(ref pointer);
                    if (((byte *)((long)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;
        }
Beispiel #7
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);
        }
        private SafeBufferPointer(SafeBuffer buffer)
        {
            this.buffer = buffer;

            unsafe
            {
                byte *p = null;
                buffer.AcquirePointer(ref p);
                Pointer = new IntPtr(p);
            }
        }
Beispiel #9
0
        public StreamHeaderRef(MemoryMappedViewAccessor accessor)
        {
            Accessor = accessor;
            Buffer   = accessor.GetSafeBuffer();

            byte *temp = null;

            Buffer.AcquirePointer(ref temp);

            Ptr = (StreamHeader *)temp;
        }
Beispiel #10
0
        internal static unsafe byte *AcquirePointer(object accessor, out SafeBuffer safeBuffer)
        {
            var memoryMappedViewAccessor = (MemoryMappedViewAccessor)accessor;

            safeBuffer = memoryMappedViewAccessor.SafeMemoryMappedViewHandle;

            byte *ptr = null;

            safeBuffer.AcquirePointer(ref ptr);

            return(ptr + memoryMappedViewAccessor.PointerOffset);
        }
Beispiel #11
0
 public CacheEntry(MemoryMappedViewAccessor view, long offset, uint size)
 {
     CreatedWhen = Time.Ticks;
     View        = view;
     Offset      = offset;
     Size        = size;
     IsDisposed  = false;
     _RefCount   = 1;
     Buffer      = view.GetSafeBuffer();
     Pointer     = null;
     Buffer.AcquirePointer(ref Pointer);
     PointerOffset = view.GetPointerOffset();
 }
 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;
 }
Beispiel #13
0
        internal unsafe static byte *AcquirePointer(object accessor, out SafeBuffer safeBuffer)
        {
            Debug.Assert(s_lazyIsAvailable.GetValueOrDefault());

            safeBuffer = (SafeBuffer)s_lazySafeMemoryMappedViewHandle.GetValue(accessor);

            byte *ptr = null;

            safeBuffer.AcquirePointer(ref ptr);

            long offset = (long)s_lazyPointerOffset.GetValue(accessor);

            return(ptr + offset);
        }
        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();
            }
        }
Beispiel #15
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);
        }
Beispiel #16
0
 public StreamRange(StreamRef stream, MemoryMappedViewAccessor view, long offset, uint size, long actualOffset, long actualSize)
 {
     Stream     = stream;
     View       = view;
     CacheEntry = default(ViewCache.CacheEntry);
     Offset     = offset;
     Size       = size;
     Buffer     = view.GetSafeBuffer();
     Pointer    = null;
     Buffer.AcquirePointer(ref Pointer);
     IsDisposed = false;
     unchecked {
         Pointer += view.GetPointerOffset();
         Pointer += (offset - actualOffset);
     }
 }
            public DisposableData(IDisposable accessor, SafeBuffer safeBuffer, long offset)
            {
#if FEATURE_CER
                // Make sure the current thread isn't aborted in between acquiring the pointer and assigning the fields.
                RuntimeHelpers.PrepareConstrainedRegions();
                try
                { /* intentionally left blank */ }
                finally
#endif
                {
                    byte *basePointer = null;
                    safeBuffer.AcquirePointer(ref basePointer);

                    _accessor   = accessor;
                    _safeBuffer = safeBuffer;
                    _pointer    = basePointer + offset;
                }
            }
            public DisposableData(IDisposable accessor, SafeBuffer safeBuffer, long offset)
            {
                // Make sure the current thread isn't aborted in between acquiring the pointer and assigning the fields.
#if !NETSTANDARD11
                RuntimeHelpers.PrepareConstrainedRegions();
#endif
                try
                {
                }
                finally
                {
                    byte *basePointer = null;
                    safeBuffer.AcquirePointer(ref basePointer);

                    _accessor   = accessor;
                    _safeBuffer = safeBuffer;
                    _pointer    = basePointer + offset;
                }
            }
Beispiel #19
0
        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();
                        }
                    }
                }
            }
        }
Beispiel #20
0
        internal unsafe static byte *AcquirePointer(object accessor, out SafeBuffer safeBuffer)
        {
            Debug.Assert(s_lazyIsAvailable.GetValueOrDefault());

            safeBuffer = (SafeBuffer)s_lazySafeMemoryMappedViewHandle.GetValue(accessor);

            byte *ptr = null;

            safeBuffer.AcquirePointer(ref ptr);

            try
            {
                long offset;
                if (s_lazyPointerOffset != null)
                {
                    offset = (long)s_lazyPointerOffset.GetValue(accessor);
                }
                else
                {
                    object internalView = s_lazyInternalViewField.GetValue(accessor);
                    offset = (long)s_lazyInternalPointerOffset.GetValue(internalView);
                }

                return(ptr + offset);
            }
            catch (MemberAccessException)
            {
                s_lazyIsAvailable = false;
                return(null);
            }
            catch (InvalidOperationException)
            {
                // thrown when accessing unapproved API in a Windows Store app
                s_lazyIsAvailable = false;
                return(null);
            }
            catch (TargetInvocationException ex)
            {
                ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
                throw;
            }
        }
Beispiel #21
0
        protected MemoryMappedBitmap(int width, int height, int stride, string mapName)
        {
            this.width  = width;
            this.height = height;
            this.stride = stride;

            int totalBytes = height * stride;

            Debug.Assert(totalBytes == this.TotalBytes);

            Interlocked.Add(ref aggregatedTotalBytes, totalBytes);

            // TODO: security - restrict access to only our process and child processes

            backingName = mapName;
            backing     = MemoryMappedFile.CreateOrOpen(mapName, totalBytes);
            accessor    = backing.CreateViewAccessor();
            FieldInfo field = typeof(UnmanagedMemoryAccessor).GetField("_buffer", BindingFlags.NonPublic | BindingFlags.Instance);

            buffer = (SafeBuffer)field.GetValue(accessor);
            buffer.AcquirePointer(ref scan0);
        }
Beispiel #22
0
        internal unsafe static byte *AcquirePointer(object accessor, out SafeBuffer safeBuffer)
        {
            Debug.Assert(lazyIsAvailable.GetValueOrDefault());

            safeBuffer = (SafeBuffer)lazySafeMemoryMappedViewHandle.GetValue(accessor);

            byte *ptr = null;

            safeBuffer.AcquirePointer(ref ptr);

            long offset;

            if (lazyPointerOffset != null)
            {
                offset = (long)lazyPointerOffset.GetValue(accessor);
            }
            else
            {
                object internalView = lazyInternalViewField.GetValue(accessor);
                offset = (long)lazyInternalPointerOffset.GetValue(internalView);
            }

            return(ptr + offset);
        }
        [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);
        }
        internal int ReadCore(Span <byte> destination)
        {
            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   = 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 = &destination.DangerousGetPinnableReference())
                {
                    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);
        }
        [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;
        }
        [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);
        }
Beispiel #27
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);
        }
Beispiel #28
0
        public static unsafe ref byte AcquirePointer(this SafeBuffer buffer)
        {
            byte *ptr = null;

            buffer.AcquirePointer(ref ptr);
            return(ref ptr[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);
        }
        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);
        }