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