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); }