--- /dev/null
+package org.simantics.scl.runtime.io;\r
+\r
+import gnu.trove.list.array.TByteArrayList;\r
+\r
+import java.io.EOFException;\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+import java.io.OutputStream;\r
+import java.nio.charset.Charset;\r
+\r
+public class SclIO {\r
+\r
+ private static final Charset UTF8 = Charset.forName("UTF-8");\r
+ \r
+ public static byte readByte(InputStream in) throws IOException {\r
+ int ch1 = in.read();\r
+ if(ch1 < 0)\r
+ throw new EOFException();\r
+ return (byte)ch1;\r
+ }\r
+ \r
+ public static boolean readBoolean(InputStream in) throws IOException {\r
+ int ch1 = in.read();\r
+ if(ch1 < 0)\r
+ throw new EOFException();\r
+ return ch1 != 0;\r
+ }\r
+ \r
+ public static char readCharacter(InputStream in) throws IOException {\r
+ int ch1 = in.read();\r
+ int ch2 = in.read();\r
+ if ((ch1 | ch2) < 0)\r
+ throw new EOFException();\r
+ return (char)((ch1 << 8) + ch2);\r
+ }\r
+ \r
+ public static short readShort(InputStream in) throws IOException {\r
+ int ch1 = in.read();\r
+ int ch2 = in.read();\r
+ if ((ch1 | ch2) < 0)\r
+ throw new EOFException();\r
+ return (short)((ch1 << 8) + ch2);\r
+ }\r
+ \r
+ public static int readInteger(InputStream in) throws IOException {\r
+ int ch1 = in.read();\r
+ int ch2 = in.read();\r
+ int ch3 = in.read();\r
+ int ch4 = in.read();\r
+ if ((ch1 | ch2 | ch3 | ch4) < 0)\r
+ throw new EOFException();\r
+ return (ch1 << 24) + (ch2 << 16) + (ch3 << 8) + ch4;\r
+ }\r
+\r
+ public static long readLong(InputStream in) throws IOException {\r
+ int ch1 = in.read();\r
+ int ch2 = in.read();\r
+ int ch3 = in.read();\r
+ int ch4 = in.read();\r
+ int ch5 = in.read();\r
+ int ch6 = in.read();\r
+ int ch7 = in.read();\r
+ int ch8 = in.read();\r
+ if ((ch1 | ch2 | ch3 | ch4 | ch5 | ch6 | ch7 | ch8) < 0)\r
+ throw new EOFException();\r
+ return ((long)ch1 << 56) +\r
+ ((long)ch2 << 48) +\r
+ ((long)ch3 << 40) +\r
+ ((long)ch4 << 32) +\r
+ ((long)ch5 << 24) +\r
+ (ch6 << 16) +\r
+ (ch7 << 8) +\r
+ ch8;\r
+ }\r
+\r
+ public static float readFloat(InputStream in) throws IOException {\r
+ return Float.intBitsToFloat(readInteger(in));\r
+ }\r
+\r
+ public static double readDouble(InputStream in) throws IOException {\r
+ return Double.longBitsToDouble(readLong(in));\r
+ }\r
+\r
+ public static int readLength(InputStream in) throws IOException {\r
+ int length = in.read()&0xff; \r
+ if(length >= 0x80) {\r
+ if(length >= 0xc0) {\r
+ if(length >= 0xe0) {\r
+ if(length >= 0xf0) {\r
+ length &= 0x0f;\r
+ length += in.read()<<3;\r
+ length += in.read()<<11;\r
+ length += in.read()<<19;\r
+ length += 0x10204080;\r
+ }\r
+ else {\r
+ length &= 0x1f;\r
+ length += in.read()<<4;\r
+ length += in.read()<<12;\r
+ length += in.read()<<20;\r
+ length += 0x204080;\r
+ }\r
+ }\r
+ else {\r
+ length &= 0x3f;\r
+ length += in.read()<<5;\r
+ length += in.read()<<13;\r
+ length += 0x4080;\r
+ }\r
+ }\r
+ else {\r
+ length &= 0x7f;\r
+ length += in.read()<<6;\r
+ length += 0x80;\r
+ }\r
+ }\r
+ return length;\r
+ } \r
+\r
+ private static byte[] readFully(InputStream in, int length) throws IOException {\r
+ byte[] result = new byte[length];\r
+ int cur = 0;\r
+ while(cur < length) {\r
+ int c = in.read(result, cur, length-cur);\r
+ if(c <= 0)\r
+ throw new EOFException();\r
+ cur += c;\r
+ }\r
+ return result;\r
+ }\r
+ \r
+ public static byte[] readByteArray(InputStream in) throws IOException {\r
+ int length = readLength(in);\r
+ return readFully(in, length);\r
+ }\r
+\r
+ public static double[] readDoubleArray(InputStream in) throws IOException {\r
+ int length = readLength(in);\r
+ double[] result = new double[length];\r
+ for(int i=0;i<length;++i)\r
+ result[i] = readDouble(in);\r
+ return result;\r
+ }\r
+ \r
+ public static String readString(InputStream in) throws IOException {\r
+ return new String(readByteArray(in), UTF8);\r
+ }\r
+ \r
+ public static byte[] readAllByteArrayAndClose(InputStream in) throws IOException {\r
+ try {\r
+ TByteArrayList l = new TByteArrayList();\r
+ byte[] buffer = new byte[1024];\r
+ while(true) {\r
+ int c = in.read(buffer, 0, buffer.length);\r
+ if(c <= 0)\r
+ break;\r
+ l.add(buffer, 0, c);\r
+ }\r
+ return l.toArray();\r
+ }\r
+ finally {\r
+ if(in != null)\r
+ in.close();\r
+ }\r
+ }\r
+ \r
+ public static String readAllStringAndClose(InputStream in) throws IOException {\r
+ return new String(readAllByteArrayAndClose(in), UTF8);\r
+ }\r
+ \r
+ public static void writeByte(OutputStream out, byte v) throws IOException {\r
+ out.write((int)v);\r
+ }\r
+ \r
+ public static void writeBoolean(OutputStream out, boolean v) throws IOException {\r
+ out.write(v ? 1 : 0);\r
+ }\r
+ \r
+ public static void writeCharacter(OutputStream out, char v) throws IOException {\r
+ out.write((int)(v >>> 8));\r
+ out.write((int)(v));\r
+ }\r
+ \r
+ public static void writeShort(OutputStream out, short v) throws IOException {\r
+ out.write((int)(v >>> 8));\r
+ out.write((int)(v));\r
+ }\r
+ \r
+ public static void writeInteger(OutputStream out, int v) throws IOException {\r
+ out.write(v >>> 24);\r
+ out.write(v >>> 16);\r
+ out.write(v >>> 8);\r
+ out.write(v);\r
+ }\r
+ \r
+ public static void writeLong(OutputStream out, long v) throws IOException {\r
+ out.write((int)(v >>> 56));\r
+ out.write((int)(v >>> 48));\r
+ out.write((int)(v >>> 40));\r
+ out.write((int)(v >>> 32)); \r
+ out.write((int)(v >>> 24));\r
+ out.write((int)(v >>> 16));\r
+ out.write((int)(v >>> 8));\r
+ out.write((int)v);\r
+ }\r
+ \r
+ public static void writeFloat(OutputStream out, float v) throws IOException {\r
+ writeInteger(out, Float.floatToRawIntBits(v));\r
+ }\r
+ \r
+ public static void writeDouble(OutputStream out, double v) throws IOException {\r
+ writeLong(out, Double.doubleToRawLongBits(v));\r
+ }\r
+ \r
+ public static void writeLength(OutputStream out, int length) throws IOException { \r
+ if(length < 0x80) {\r
+ out.write(length);\r
+ }\r
+ else {\r
+ length -= 0x80;\r
+ if(length < 0x4000) {\r
+ out.write( ((length&0x3f) | 0x80) );\r
+ out.write( (length>>>6) );\r
+ }\r
+ else {\r
+ length -= 0x4000;\r
+ if(length < 0x200000) {\r
+ out.write( (length&0x1f) | 0xc0 );\r
+ out.write( length>>>5 );\r
+ out.write( length>>>13 ); \r
+ }\r
+ else {\r
+ length -= 0x200000;\r
+ if(length < 0x10000000) {\r
+ out.write( (length&0x0f) | 0xe0 );\r
+ out.write( length>>>4 );\r
+ out.write( length>>>12 ); \r
+ out.write( length>>>20 );\r
+ }\r
+ else {\r
+ length -= 0x10000000;\r
+ out.write( ((length&0x07) | 0xf0) );\r
+ out.write( length>>>3 );\r
+ out.write( length>>>11 ); \r
+ out.write( length>>>19 );\r
+ out.write( length>>>27 );\r
+ }\r
+ } \r
+ }\r
+ } \r
+ }\r
+ \r
+ public static void writeByteArray(OutputStream out, byte[] v) throws IOException {\r
+ writeLength(out, v.length);\r
+ out.write(v);\r
+ }\r
+ \r
+ public static void writeDoubleArray(OutputStream out, double[] v) throws IOException {\r
+ writeLength(out, v.length);\r
+ for(double s : v)\r
+ writeDouble(out, s);\r
+ }\r
+ \r
+ public static void writeString(OutputStream out, String v) throws IOException {\r
+ writeByteArray(out, v.getBytes(UTF8));\r
+ }\r
+\r
+ public static int ioSizeString(String v) {\r
+ return ioSizeLength(v.length()) + v.getBytes().length;\r
+ }\r
+ \r
+ public static int ioSizeLength(int length) {\r
+ if(length < 0x80)\r
+ return 1;\r
+ if(length < 0x4080)\r
+ return 2;\r
+ if(length < 0x204080)\r
+ return 3;\r
+ if(length < 0x10204080)\r
+ return 4;\r
+ return 5;\r
+ }\r
+}\r