com.github.bloodshura.ignitium.ntv.struct.MappedStruct Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ignitium-native Show documentation
Show all versions of ignitium-native Show documentation
An API for working with native system APIs, with a higher-level interface.
The newest version!
package com.github.bloodshura.ignitium.ntv.struct;
import com.github.bloodshura.ignitium.collection.list.XList;
import com.github.bloodshura.ignitium.collection.list.impl.XArrayList;
import com.github.bloodshura.ignitium.collection.view.XBasicView;
import com.github.bloodshura.ignitium.collection.view.XView;
import com.github.bloodshura.ignitium.ntv.NativeException;
import com.github.bloodshura.ignitium.ntv.source.DataSource;
import com.sun.jna.Pointer;
import javax.annotation.Nonnull;
import java.util.function.Supplier;
public class MappedStruct {
final XList fields;
private final boolean cacheable;
private DataSource source;
public MappedStruct() {
this.cacheable = getClass().isAnnotationPresent(Cacheable.class);
this.fields = new XArrayList<>();
}
@Nonnull
public final XView getFields() {
return new XBasicView<>(fields);
}
@Nonnull
public final DataSource getSource() throws NativeException {
if (source == null) {
throw new NativeException("Cannot access the source of an unmapped struct (use MappedStruct::map)");
}
return source;
}
public final boolean isCacheable() {
return cacheable;
}
public final void map(@Nonnull DataSource source) {
unmap();
this.source = source;
}
public final void map(@Nonnull DataSource source, long offset) {
unmap();
this.source = source.withOffset(offset);
}
public final void map(@Nonnull DataSource source, @Nonnull Pointer offset) {
unmap();
this.source = source.withOffset(offset);
}
public final void unmap() {
getFields().forEach(field -> field.cachedValue = null);
this.source = null;
}
// Can't use method references here (like getSource()::readBoolean) because 'getSource()' will be called
// at the moment of instantiation/xxxField invocation, and not at getValue/setValue invocation, thus
// throwing a NativeException since this struct is not mapped yet.
@Nonnull
protected final MutableStructField addressField(int offset) {
// TODO 32-bit?
return new CommonStructField<>(this, offset, Long.BYTES, o -> getSource().readPointerAddress(o), (o, value) -> getSource().writePointerAddress(o, value));
}
@Nonnull
protected final MutableStructField boolField(int offset) {
return new CommonStructField<>(this, offset, Byte.BYTES, o -> getSource().readBoolean(o), (o, value) -> getSource().writeBoolean(o, value));
}
@Nonnull
protected final MutableStructField charField(int offset) {
return new CommonStructField<>(this, offset, Character.BYTES, o -> getSource().readChar(o), (o, value) -> getSource().writeChar(o, value));
}
@Nonnull
protected final MutableStructField doubleField(int offset) {
return new CommonStructField<>(this, offset, Double.BYTES, o -> getSource().readDouble(o), (o, value) -> getSource().writeDouble(o, value));
}
@Nonnull
protected final MutableStructField field(int offset, int size) {
return new CommonStructField<>(this, offset, size, o -> {
byte[] array = new byte[size];
getSource().read(o, array);
return array;
}, (o, value) -> {
getSource().write(o, value, 0, Math.min(value.length, size));
});
}
@Nonnull
protected final MutableStructField floatField(int offset) {
return new CommonStructField<>(this, offset, Float.BYTES, o -> getSource().readFloat(o), (o, value) -> getSource().writeFloat(o, value));
}
@Nonnull
protected final MutableStructField intField(int offset) {
return new CommonStructField<>(this, offset, Integer.BYTES, o -> getSource().readInt(o), (o, value) -> getSource().writeInt(o, value));
}
@Nonnull
protected final MutableStructField longField(int offset) {
return new CommonStructField<>(this, offset, Long.BYTES, o -> getSource().readLong(o), (o, value) -> getSource().writeLong(o, value));
}
@Nonnull
protected final MutableStructField pointerField(int offset) {
// TODO 32-bit?
return new CommonStructField<>(this, offset, Long.BYTES, o -> {
Pointer pointer = getSource().readPointer(o);
return pointer != null ? pointer : new Pointer(0L);
}, (o, value) -> getSource().writePointer(o, value));
}
@Nonnull
protected final MutableStructField shortField(int offset) {
return new CommonStructField<>(this, offset, Short.BYTES, o -> getSource().readShort(o), (o, value) -> getSource().writeShort(o, value));
}
@Nonnull
protected final StructField structField(@Nonnull E instance, int offset) throws NativeException {
return structField((Supplier) () -> instance, offset);
}
@Nonnull
protected final StructField structField(@Nonnull Supplier generator, int offset) throws NativeException {
E initialInstance = generator.get();
return new ForeignStructField<>(this, offset, initialInstance.getSize(), generator);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy