internal static MemoryMappedDataReaderFactory CreateUnix(string filename, bool mapAsImage) { if (!canTryUnix) { return(null); } var creator = new MemoryMappedDataReaderFactory(GetFullPath(filename)); try { Unix.Mmap(creator, mapAsImage); if (mapAsImage) // Only check this if we know that mmap() works, i.e., if above call succeeds { creator.Dispose(); throw new ArgumentException("mapAsImage == true is not supported on this OS"); } return(creator); } catch (MemoryMappedIONotSupportedException ex) { Debug.WriteLine($"mmap'd IO didn't work: {ex.Message}"); } catch (EntryPointNotFoundException) { } catch (DllNotFoundException) { } canTryUnix = false; return(null); }
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); } } }
static DataReaderFactory CreateDataReaderFactory(string fileName, bool mapAsImage) { if (!isUnix) { return(MemoryMappedDataReaderFactory.CreateWindows(fileName, mapAsImage)); } else { return(MemoryMappedDataReaderFactory.CreateUnix(fileName, mapAsImage)); } }
internal static MemoryMappedDataReaderFactory CreateWindows(string filename, bool mapAsImage) { if (!canTryWindows) { return(null); } var creator = new MemoryMappedDataReaderFactory(GetFullPath(filename)); try { Windows.Mmap(creator, mapAsImage); return(creator); } catch (EntryPointNotFoundException) { } catch (DllNotFoundException) { } canTryWindows = false; return(null); }