All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.diozero.util.MmapBufferNativeJdk17.txt Maven / Gradle / Ivy

The newest version!
package com.diozero.util;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodType;

import com.diozero.api.RuntimeIOException;
import com.diozero.util.MmapByteBuffer;

import jdk.incubator.foreign.CLinker;
import jdk.incubator.foreign.FunctionDescriptor;
import jdk.incubator.foreign.LibraryLookup;
import jdk.incubator.foreign.MemoryAddress;
import jdk.incubator.foreign.ResourceScope;

public class MmapBufferNativeJdk17 {
	public static final int O_RDWR = 0x0002;
	public static final int O_SYNC = 0x0080;

	public static final int PROT_READ = 0x01;
	public static final int PROT_WRITE = 0x02;

	public static final int MAP_SHARED = 0x0001;

	private static final CLinker clinker = CLinker.getInstance();
	private static final LibraryLookup libLookup = LibraryLookup.ofDefault();
	private static ResourceScope resScope = ResourceScope.globalScope();

	public static MmapByteBuffer createMmapBuffer(String filename, long offset, long length) throws RuntimeIOException {
		int fd = open(filename, O_RDWR | O_SYNC);
		if (fd < 0) {
			throw new RuntimeIOException("Failed to open file '" + filename + "'");
		}

		long mmap_ptr = mmap64(0, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset);
		int rc = close(fd);
		if (mmap_ptr < 0) {
			throw new RuntimeIOException("Failed to mmap file '" + filename + "'");
		}

		MemoryAddress ma = MemoryAddress.ofLong(mmap_ptr);
		return new MmapByteBuffer(ma.toRawLongValue(), (int) length, ma.asSegment(length, resScope).asByteBuffer());
	}

	public static long mmap64(long addr, long length, int prot, int flags, int fd, long offset)
			throws RuntimeIOException {
		// void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t
		// offset);
		String method_name = "mmap";
		MethodHandle mh = clinker.downcallHandle(libLookup.lookup(method_name).get(),
				MethodType.methodType(long.class, long.class, long.class, int.class, int.class, int.class, long.class),
				FunctionDescriptor.of(CLinker.C_LONG, CLinker.C_LONG, CLinker.C_LONG, CLinker.C_INT, CLinker.C_INT,
						CLinker.C_INT, CLinker.C_LONG));

		System.out.format("Invoking %s(%d, %d, %d, %d, %d, %d)...%n", method_name, Long.valueOf(addr),
				Long.valueOf(length), Integer.valueOf(prot), Integer.valueOf(flags), Integer.valueOf(fd),
				Long.valueOf(offset));
		try {
			return ((Long) mh.invoke(Long.valueOf(addr), Long.valueOf(length), Integer.valueOf(prot),
					Integer.valueOf(flags), Integer.valueOf(fd), Long.valueOf(offset))).longValue();
		} catch (Throwable t) {
			throw new RuntimeIOException(t);
		}
	}

	public static int munmap64(long addr, int length) {
		// int munmap(void *addr, size_t length);
		String method_name = "munmap";
		MethodHandle mh = clinker.downcallHandle(libLookup.lookup(method_name).get(),
				MethodType.methodType(int.class, long.class, int.class),
				FunctionDescriptor.of(CLinker.C_INT, CLinker.C_LONG, CLinker.C_INT));

		System.out.format("Invoking %s(%d, %d)...%n", method_name, Long.valueOf(addr), Integer.valueOf(length));
		try {
			return ((Integer) mh.invoke(Long.valueOf(addr), Integer.valueOf(length))).intValue();
		} catch (Throwable t) {
			throw new RuntimeIOException(t);
		}
	}

	public static int open(String filename, int flags) {
		// int open(const char *, int);
		String method_name = "open";
		MethodHandle mh = clinker.downcallHandle(libLookup.lookup(method_name).get(),
				MethodType.methodType(int.class, MemoryAddress.class, int.class),
				FunctionDescriptor.of(CLinker.C_INT, CLinker.C_POINTER, CLinker.C_INT));

		System.out.format("Invoking %s(%s, %d)...%n", method_name, filename, Integer.valueOf(flags));
		try {
			return ((Integer) mh.invoke(CLinker.toCString(filename, resScope).address(), Integer.valueOf(flags)))
					.intValue();
		} catch (Throwable t) {
			throw new RuntimeIOException(t);
		}
	}

	public static int close(int fd) {
		// int close(int);
		String method_name = "close";
		MethodHandle mh = clinker.downcallHandle(libLookup.lookup(method_name).get(),
				MethodType.methodType(int.class, int.class), FunctionDescriptor.of(CLinker.C_INT, CLinker.C_INT));
		try {
			System.out.format("Invoking %s(%d)...%n", method_name, Integer.valueOf(fd));
			return ((Integer) mh.invoke(Integer.valueOf(fd))).intValue();
		} catch (Throwable t) {
			throw new RuntimeIOException(t);
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy