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

host.anzo.commons.io.binary.FileBinaryWriter Maven / Gradle / Ivy

package host.anzo.commons.io.binary;

import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.lang.reflect.Field;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.FileChannel;
import java.nio.file.Path;
import java.util.Arrays;

/**
 * @author ANZO
 */
@Slf4j
public class FileBinaryWriter implements AutoCloseable {
	@Getter
	private ByteBuffer byteBuffer;

	private FileChannel roChannel = null;

	@SuppressWarnings("unused")
	public FileBinaryWriter(int capacity) {
		this(ByteBuffer.allocate(capacity));
	}

	@SuppressWarnings("unused")
	public FileBinaryWriter(ByteBuffer byteBuffer) {
		this.byteBuffer = byteBuffer;
		this.byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
	}

	@SuppressWarnings({"unused", "resource"})
	public FileBinaryWriter(@NotNull Path path) throws IOException {
		this.roChannel = new RandomAccessFile(path.toFile(), "r").getChannel();
		this.byteBuffer = roChannel.map(FileChannel.MapMode.READ_ONLY, 0, roChannel.size()).load();
		this.byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
	}

	@SuppressWarnings("unused")
	private FileBinaryWriter(byte[] byteBuffer) {
		this(ByteBuffer.wrap(byteBuffer));
	}

	public void writeC(int data) {
		byteBuffer.put((byte) data);
	}
	public void writeCB(boolean value) {
		byteBuffer.put(value ? (byte) 1 : (byte) 0);
	}

	public void writeF(float value) {
		byteBuffer.putFloat(value);
	}
	public void writeFF(double value) {
		byteBuffer.putDouble(value);
	}

	public void writeH(int value) {
		byteBuffer.putShort((short) value);
	}

	public void writeD(int value) {
		byteBuffer.putInt(value);
	}

	public void writeD(long value) {
		byteBuffer.putInt((int)(value & 0xFFFFFFFF));
	}

	public void writeQ(long value) {
		byteBuffer.putLong(value);
	}

	public void writeB(byte[] data) {
		byteBuffer.put(data);
	}

	public void writeB(byte data) {
		byteBuffer.put(data);
	}

	public void writeS(CharSequence charSequence) {
		if (charSequence != null) {
			int length = charSequence.length();
			for (int i = 0; i < length; i++) {
				byteBuffer.putChar(charSequence.charAt(i));
			}
		}
		byteBuffer.putChar('\000');
	}

	public final void writeS(CharSequence charSequence, int size) {
		if (charSequence == null) {
			byteBuffer.put(new byte[size]);
		}
		else {
			final int startPosition = byteBuffer.position();
			for (int i = 0; i < charSequence.length(); i++) {
				if ((byteBuffer.position() - startPosition) < size) {
					byteBuffer.putChar(charSequence.charAt(i));
				}
			}
			final int length = byteBuffer.position() - startPosition;
			if (length < size) {
				writeB(new byte[size - length]);
			}
		}
	}

	public void writeQS(@NotNull CharSequence charSequence) {
		int length = charSequence.length();
		writeQ(length);
		for (int i = 0; i < length; i++) {
			byteBuffer.putChar(charSequence.charAt(i));
		}
	}

	public void write(@NotNull Field field, Object object) throws IllegalAccessException {
		switch (field.getType().getTypeName()) {
			case "java.lang.Byte":
			case "byte":
			case "java.lang.Boolean":
			case "boolean":
				writeB(field.getByte(object));
				break;
			case "int":
			case "java.lang.Integer":
				writeD(field.getInt(object));
				break;
			case "java.lang.Short":
			case "short":
				writeH(field.getShort(object));
				break;
			case "java.lang.Long":
			case "long":
				writeQ(field.getLong(object));
				break;
			case "java.lang.Float":
			case "float":
				writeF(field.getFloat(object));
				break;
			case "java.lang.Double":
			case "double":
				writeFF(field.getDouble(object));
			default:
				log.error("Unsupported class [{}]", field.getType().getTypeName());
				break;
		}
	}

	public void setPosition(int position) {
		byteBuffer.position(position);
	}

	public int getPosition() {
		return byteBuffer.position();
	}

	public String getPositionHex() {
		return Integer.toHexString(getPosition());
	}

	public int getAvailableBytes() {
		return byteBuffer.remaining();
	}

	public void trim() {
		final int dataEndPosition = getPosition();
		byteBuffer = ByteBuffer.wrap(byteBuffer.array(), 0, dataEndPosition);
	}

	public byte[] toByteArray() {
		return Arrays.copyOfRange(byteBuffer.array(), 0, getPosition());
	}

	public void writeToFile(Path path) {
		try (FileOutputStream outputStream = new FileOutputStream(path.toFile(), false);
				FileChannel channel = outputStream.getChannel()) {
			trim();
			channel.write(byteBuffer);
		}
		catch (Exception e) {
			log.error("Error while writing buffer to file [{}]", path.toString(), e);
		}
	}

	@Override
	public void close() throws IOException {
		if (roChannel != null) {
			try {
				roChannel.close();
			}
			catch (IOException e) {
				log.error("Error while closing FileBinaryWriter channel!", e);
			}
		}
		if (byteBuffer != null) {
			try {
				byteBuffer.clear();
			}
			catch (Exception e) {
				log.error("Error while closing FileBinaryWriter buffer!", e);
			}
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy