Пример #1
0
 ByteArrayDataReaderFactory(byte[] data, string filename)
 {
     this.filename = filename;
     length        = (uint)data.Length;
     stream        = DataStreamFactory.Create(data);
     this.data     = data;
 }
            public static void Mmap(MemoryMappedDataReaderFactory creator, bool mapAsImage)
            {
                using (var fileHandle = CreateFile(creator.filename, GENERIC_READ, FILE_SHARE_READ, IntPtr.Zero, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, IntPtr.Zero)) {
                    if (fileHandle.IsInvalid)
                    {
                        throw new IOException($"Could not open file {creator.filename} for reading. Error: {Marshal.GetLastWin32Error():X8}");
                    }

                    uint sizeLo = GetFileSize(fileHandle, out uint sizeHi);
                    int  hr;
                    if (sizeLo == INVALID_FILE_SIZE && (hr = Marshal.GetLastWin32Error()) != NO_ERROR)
                    {
                        throw new IOException($"Could not get file size. File: {creator.filename}, error: {hr:X8}");
                    }
                    var fileSize = ((long)sizeHi << 32) | sizeLo;

                    using (var fileMapping = CreateFileMapping(fileHandle, IntPtr.Zero, PAGE_READONLY | (mapAsImage ? SEC_IMAGE : 0), 0, 0, null)) {
                        if (fileMapping.IsInvalid)
                        {
                            throw new MemoryMappedIONotSupportedException($"Could not create a file mapping object. File: {creator.filename}, error: {Marshal.GetLastWin32Error():X8}");
                        }
                        creator.data = MapViewOfFile(fileMapping, FILE_MAP_READ, 0, 0, UIntPtr.Zero);
                        if (creator.data == IntPtr.Zero)
                        {
                            throw new MemoryMappedIONotSupportedException($"Could not map file {creator.filename}. Error: {Marshal.GetLastWin32Error():X8}");
                        }
                        creator.length = (uint)fileSize;
                        creator.osType = OSType.Windows;
                        creator.stream = DataStreamFactory.Create((byte *)creator.data);
                    }
                }
            }
            public static void Mmap(MemoryMappedDataReaderFactory creator, bool mapAsImage)
            {
                int fd = open(creator.filename, O_RDONLY);

                try {
                    if (fd < 0)
                    {
                        throw new IOException($"Could not open file {creator.filename} for reading. Error: {fd}");
                    }

                    long   size;
                    IntPtr data;

                    if (IntPtr.Size == 4)
                    {
                        size = lseek32(fd, 0, SEEK_END);
                        if (size == -1)
                        {
                            throw new MemoryMappedIONotSupportedException($"Could not get length of {creator.filename} (lseek failed): {Marshal.GetLastWin32Error()}");
                        }

                        data = mmap32(IntPtr.Zero, (IntPtr)size, PROT_READ, MAP_PRIVATE, fd, 0);
                        if (data == new IntPtr(-1) || data == IntPtr.Zero)
                        {
                            throw new MemoryMappedIONotSupportedException($"Could not map file {creator.filename}. Error: {Marshal.GetLastWin32Error()}");
                        }
                    }
                    else
                    {
                        size = lseek64(fd, 0, SEEK_END);
                        if (size == -1)
                        {
                            throw new MemoryMappedIONotSupportedException($"Could not get length of {creator.filename} (lseek failed): {Marshal.GetLastWin32Error()}");
                        }

                        data = mmap64(IntPtr.Zero, (IntPtr)size, PROT_READ, MAP_PRIVATE, fd, 0);
                        if (data == new IntPtr(-1) || data == IntPtr.Zero)
                        {
                            throw new MemoryMappedIONotSupportedException($"Could not map file {creator.filename}. Error: {Marshal.GetLastWin32Error()}");
                        }
                    }

                    creator.data           = data;
                    creator.length         = (uint)size;
                    creator.origDataLength = size;
                    creator.osType         = OSType.Unix;
                    creator.stream         = DataStreamFactory.Create((byte *)creator.data);
                }
                finally {
                    if (fd >= 0)
                    {
                        close(fd);
                    }
                }
            }
        /// <summary>
        /// Call this to disable memory mapped I/O. This must only be called if no other code is
        /// trying to access the memory since that could lead to an exception.
        /// </summary>
        internal void UnsafeDisableMemoryMappedIO()
        {
            if (!(dataAry is null))
            {
                return;
            }
            var newAry = new byte[length];

            Marshal.Copy(data, newAry, 0, newAry.Length);
            FreeMemoryMappedIoData();
            length   = (uint)newAry.Length;
            dataAry  = newAry;
            gcHandle = GCHandle.Alloc(dataAry, GCHandleType.Pinned);
            data     = gcHandle.AddrOfPinnedObject();
            stream   = DataStreamFactory.Create((byte *)data);
            DataReaderInvalidated?.Invoke(this, EventArgs.Empty);
        }
 NativeMemoryDataReaderFactory(byte *data, uint length, string filename)
 {
     this.filename = filename;
     this.length   = length;
     stream        = DataStreamFactory.Create(data);
 }