package org.simantics.db.common; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import org.simantics.db.common.utils.Logger; final public class ByteFileWriter { public static int BUFFER = 65536; private FileChannel channel; private FileOutputStream out; byte[] bytes = new byte[BUFFER]; ByteBuffer bb = ByteBuffer.wrap(bytes); int byteIndex = 0; public ByteFileWriter(File file) throws FileNotFoundException { out = new FileOutputStream(file); channel = out.getChannel(); } public void write(short s) { // System.err.println("write " + s); if(byteIndex < (BUFFER-2)) { bytes[byteIndex++] = (byte)(s&0xff); bytes[byteIndex++] = (byte)((s>>>8)&0xff); } else { int has = BUFFER-byteIndex; if(has == 0) writeReset(BUFFER); bytes[byteIndex++] = (byte)(s&0xff); if(has == 1) writeReset(BUFFER); bytes[byteIndex++] = (byte)((s>>>8)&0xff); if(has == 2) writeReset(BUFFER); } } public void write(int i) { // System.err.println("write " + i); if(byteIndex < (BUFFER-4)) { bytes[byteIndex++] = (byte)(i&0xff); bytes[byteIndex++] = (byte)((i>>>8)&0xff); bytes[byteIndex++] = (byte)((i>>>16)&0xff); bytes[byteIndex++] = (byte)((i>>>24)&0xff); } else { int has = BUFFER-byteIndex; if(has == 0) writeReset(BUFFER); bytes[byteIndex++] = (byte)(i&0xff); if(has == 1) writeReset(BUFFER); bytes[byteIndex++] = (byte)((i>>>8)&0xff); if(has == 2) writeReset(BUFFER); bytes[byteIndex++] = (byte)((i>>>16)&0xff); if(has == 3) writeReset(BUFFER); bytes[byteIndex++] = (byte)((i>>>24)&0xff); if(has == 4) writeReset(BUFFER); } } public void write(long l) { // System.err.println("write " + l); if(byteIndex < (BUFFER-8)) { bytes[byteIndex++] = (byte)(l&0xff); bytes[byteIndex++] = (byte)((l>>>8)&0xff); bytes[byteIndex++] = (byte)((l>>>16)&0xff); bytes[byteIndex++] = (byte)((l>>>24)&0xff); bytes[byteIndex++] = (byte)((l>>>32)&0xff); bytes[byteIndex++] = (byte)((l>>>40)&0xff); bytes[byteIndex++] = (byte)((l>>>48)&0xff); bytes[byteIndex++] = (byte)((l>>>56)&0xff); } else { int has = BUFFER-byteIndex; if(has == 0) writeReset(BUFFER); bytes[byteIndex++] = (byte)(l&0xff); if(has == 1) writeReset(BUFFER); bytes[byteIndex++] = (byte)((l>>>8)&0xff); if(has == 2) writeReset(BUFFER); bytes[byteIndex++] = (byte)((l>>>16)&0xff); if(has == 3) writeReset(BUFFER); bytes[byteIndex++] = (byte)((l>>>24)&0xff); if(has == 4) writeReset(BUFFER); bytes[byteIndex++] = (byte)((l>>>32)&0xff); if(has == 5) writeReset(BUFFER); bytes[byteIndex++] = (byte)((l>>>40)&0xff); if(has == 6) writeReset(BUFFER); bytes[byteIndex++] = (byte)((l>>>48)&0xff); if(has == 7) writeReset(BUFFER); bytes[byteIndex++] = (byte)((l>>>56)&0xff); if(has == 8) writeReset(BUFFER); } } public void write(byte[] data) { int offset = 0; int left = data.length; int has = BUFFER-byteIndex; if(has > left) { System.arraycopy(data, 0, bytes, byteIndex, left); byteIndex += left; } else if(has == left) { System.arraycopy(data, 0, bytes, byteIndex, left); writeReset(BUFFER); } else { System.arraycopy(data, 0, bytes, byteIndex, has); writeReset(BUFFER); left -= has; offset += has; while(left > 0) { int length = Math.min(left, BUFFER); System.arraycopy(data, offset, bytes, 0, length); offset += length; left -= length; if(length < BUFFER) byteIndex = length; else writeReset(BUFFER); } } } public void commit() { try { if(byteIndex > 0) writeReset(byteIndex); //channel.force(false); out.close(); } catch (IOException e) { Logger.defaultLogError(e); } } private void writeReset(int size) { byteIndex = 0; bb.position(0); bb.limit(size); try { for(int got=0;got < size;) { got += channel.write(bb); if(got == -1) { new Exception().printStackTrace(); return; } } } catch (IOException e) { e.printStackTrace(); } } }