-package org.simantics.db.server.internal;\r
-\r
-import java.nio.ByteBuffer;\r
-import java.util.Arrays;\r
-\r
-import org.simantics.fastlz.FastLZ;\r
-import org.simantics.fastlz.FastLZJava;\r
-\r
-\r
-/**\r
- * @author Tuukka Lehtonen\r
- */\r
-public class ClusterDecompressor {\r
-\r
- private byte[] inflateBuffer;\r
-\r
- public Object[] inflateCluster(int inflateSize, ByteBuffer deflatedCluster)\r
- throws CompressionException {\r
- int deflatedSize = deflatedCluster.limit();\r
- Object[] arrays = new Object[3];\r
- int inflated = decompressCluster(deflatedCluster, deflatedSize, inflateSize, arrays);\r
- if (inflated != inflateSize)\r
- throw new CompressionException("decompression error, inflated "\r
- + inflated + " bytes when " + inflateSize + " expected.");\r
- return arrays;\r
- }\r
-\r
- /**\r
- * Wrapper for the old native direct byte buffer version of cluster\r
- * decompression.\r
- *\r
- * @param deflated\r
- * @param deflatedSize\r
- * @param inflatedSize\r
- * @param arrays\r
- * expects an array of 3 elements. The decompression result will\r
- * be stored in here. [0] = cluster long array (long[]), [1] =\r
- * cluster int array (int[]), [2] = cluster byte array (byte[]).\r
- * @return the amount of bytes inflated from the deflated cluster. Matches\r
- * inflatedSize when successful.\r
- *\r
- * @see FastLZ#decompressCluster(ByteBuffer, int, int, Object[])\r
- */\r
- public int decompressCluster(ByteBuffer deflated, int deflatedSize, int inflatedSize, Object[] arrays) {\r
- if (deflated.isDirect()) {\r
- if (FastLZ.isNativeInitialized()) {\r
- FastLZ.decompressCluster(deflated, deflatedSize, inflatedSize, arrays);\r
- return inflatedSize;\r
- }\r
- // REALLY SLOW FALLBACK: java code for direct byte buffers\r
- }\r
- byte[] array = null;\r
- if (deflated.hasArray()) {\r
- array = deflated.array();\r
- } else {\r
- // SLOW FALLBACK: read-only heap byte buffer\r
- array = new byte[deflatedSize];\r
- int pos = deflated.position();\r
- deflated.position(0);\r
- deflated.get(array, 0, deflatedSize);\r
- deflated.position(pos);\r
- }\r
- return decompressCluster(array, deflatedSize, inflatedSize, arrays);\r
- }\r
-\r
- /**\r
- * @param deflated\r
- * @param deflatedSize\r
- * @param inflatedSize\r
- * @param arrays\r
- * @return\r
- */\r
- public synchronized int decompressCluster(byte[] deflated, int deflatedSize, int inflatedSize, Object[] arrays) {\r
- if (inflateBuffer == null) {\r
- inflateBuffer = new byte[inflatedSize];\r
- } else if (inflateBuffer.length < inflatedSize) {\r
- inflateBuffer = new byte[inflatedSize];\r
- }\r
- return decompressCluster(deflated, deflatedSize, inflateBuffer, inflatedSize, arrays);\r
- }\r
-\r
- /**\r
- * @param deflated\r
- * @param deflatedSize\r
- * @param inflated\r
- * @param inflatedSize\r
- * @param arrays\r
- * @return amount of bytes inflated from the original deflated buffer.\r
- * Should match inflatedSize if everything went ok, otherwise will\r
- * not.\r
- */\r
- public static int decompressCluster(byte[] deflated, int deflatedSize, byte[] inflated, int inflatedSize, Object[] arrays) {\r
- if (inflated.length < inflatedSize)\r
- throw new IllegalArgumentException("inflate buffer size (" + inflated.length + ") is smaller than inflated size (" + inflatedSize + ")");\r
-\r
- int decompressedBytes = FastLZJava.decompress(deflated, 0, deflatedSize, inflated, 0, inflatedSize);\r
- if (decompressedBytes != inflatedSize)\r
- return decompressedBytes;\r
-\r
- int offset = 0;\r
-\r
- int longCount = readInt(inflated, offset);\r
- long[] longs = new long[longCount];\r
- copyLongs(inflated, offset + 4, longs);\r
- offset += 4 + 8*longCount;\r
-\r
- int intCount = readInt(inflated, offset);\r
- int[] ints = new int[intCount];\r
- copyInts(inflated, offset + 4, ints);\r
- offset += 4 + 4*intCount;\r
-\r
- int byteCount = readInt(inflated, offset);\r
- byte[] bytes = Arrays.copyOfRange(inflated, offset + 4, offset + 4 + byteCount);\r
-\r
- arrays[0] = longs;\r
- arrays[1] = ints;\r
- arrays[2] = bytes;\r
-\r
- return decompressedBytes;\r
- }\r
-\r
- private static void copyInts(byte[] bytes, int i, int[] ints) {\r
- int offset = i;\r
- int count = ints.length;\r
- for (int a = 0; a < count; ++a, offset += 4) {\r
- int value = (((int) bytes[offset] & 0xff)) |\r
- (((int) bytes[offset+1] & 0xff) << 8) |\r
- (((int) bytes[offset+2] & 0xff) << 16) |\r
- (((int) bytes[offset+3] & 0xff) << 24);\r
- ints[a] = value;\r
- }\r
- }\r
-\r
- private static void copyLongs(byte[] bytes, int i, long[] longs) {\r
- int offset = i;\r
- int count = longs.length;\r
- for (int a = 0; a < count; ++a, offset += 8) {\r
- long value = (((long) bytes[offset] & 0xff)) |\r
- (((long) bytes[offset+1] & 0xff) << 8) |\r
- (((long) bytes[offset+2] & 0xff) << 16) |\r
- (((long) bytes[offset+3] & 0xff) << 24) |\r
- (((long) bytes[offset+4] & 0xff) << 32) |\r
- (((long) bytes[offset+5] & 0xff) << 40) |\r
- (((long) bytes[offset+6] & 0xff) << 48) |\r
- (((long) bytes[offset+7] & 0xff) << 56);\r
- longs[a] = value;\r
- }\r
- }\r
-\r
- private static int readInt(byte[] array, int offset) {\r
- return (((int) array[offset] & 0xff)) |\r
- (((int) array[offset+1] & 0xff) << 8) |\r
- (((int) array[offset+2] & 0xff) << 16) |\r
- (((int) array[offset+3] & 0xff) << 24);\r
- }\r
-\r
-}\r
+package org.simantics.db.server.internal;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+import org.simantics.fastlz.FastLZ;
+import org.simantics.fastlz.FastLZJava;
+
+
+/**
+ * @author Tuukka Lehtonen
+ */
+public class ClusterDecompressor {
+
+ private byte[] inflateBuffer;
+
+ public Object[] inflateCluster(int inflateSize, ByteBuffer deflatedCluster)
+ throws CompressionException {
+ int deflatedSize = deflatedCluster.limit();
+ Object[] arrays = new Object[3];
+ int inflated = decompressCluster(deflatedCluster, deflatedSize, inflateSize, arrays);
+ if (inflated != inflateSize)
+ throw new CompressionException("decompression error, inflated "
+ + inflated + " bytes when " + inflateSize + " expected.");
+ return arrays;
+ }
+
+ /**
+ * Wrapper for the old native direct byte buffer version of cluster
+ * decompression.
+ *
+ * @param deflated
+ * @param deflatedSize
+ * @param inflatedSize
+ * @param arrays
+ * expects an array of 3 elements. The decompression result will
+ * be stored in here. [0] = cluster long array (long[]), [1] =
+ * cluster int array (int[]), [2] = cluster byte array (byte[]).
+ * @return the amount of bytes inflated from the deflated cluster. Matches
+ * inflatedSize when successful.
+ *
+ * @see FastLZ#decompressCluster(ByteBuffer, int, int, Object[])
+ */
+ public int decompressCluster(ByteBuffer deflated, int deflatedSize, int inflatedSize, Object[] arrays) {
+ if (deflated.isDirect()) {
+ if (FastLZ.isNativeInitialized()) {
+ FastLZ.decompressCluster(deflated, deflatedSize, inflatedSize, arrays);
+ return inflatedSize;
+ }
+ // REALLY SLOW FALLBACK: java code for direct byte buffers
+ }
+ byte[] array = null;
+ if (deflated.hasArray()) {
+ array = deflated.array();
+ } else {
+ // SLOW FALLBACK: read-only heap byte buffer
+ array = new byte[deflatedSize];
+ int pos = deflated.position();
+ deflated.position(0);
+ deflated.get(array, 0, deflatedSize);
+ deflated.position(pos);
+ }
+ return decompressCluster(array, deflatedSize, inflatedSize, arrays);
+ }
+
+ /**
+ * @param deflated
+ * @param deflatedSize
+ * @param inflatedSize
+ * @param arrays
+ * @return
+ */
+ public synchronized int decompressCluster(byte[] deflated, int deflatedSize, int inflatedSize, Object[] arrays) {
+ if (inflateBuffer == null) {
+ inflateBuffer = new byte[inflatedSize];
+ } else if (inflateBuffer.length < inflatedSize) {
+ inflateBuffer = new byte[inflatedSize];
+ }
+ return decompressCluster(deflated, deflatedSize, inflateBuffer, inflatedSize, arrays);
+ }
+
+ /**
+ * @param deflated
+ * @param deflatedSize
+ * @param inflated
+ * @param inflatedSize
+ * @param arrays
+ * @return amount of bytes inflated from the original deflated buffer.
+ * Should match inflatedSize if everything went ok, otherwise will
+ * not.
+ */
+ public static int decompressCluster(byte[] deflated, int deflatedSize, byte[] inflated, int inflatedSize, Object[] arrays) {
+ if (inflated.length < inflatedSize)
+ throw new IllegalArgumentException("inflate buffer size (" + inflated.length + ") is smaller than inflated size (" + inflatedSize + ")");
+
+ int decompressedBytes = FastLZJava.decompress(deflated, 0, deflatedSize, inflated, 0, inflatedSize);
+ if (decompressedBytes != inflatedSize)
+ return decompressedBytes;
+
+ int offset = 0;
+
+ int longCount = readInt(inflated, offset);
+ long[] longs = new long[longCount];
+ copyLongs(inflated, offset + 4, longs);
+ offset += 4 + 8*longCount;
+
+ int intCount = readInt(inflated, offset);
+ int[] ints = new int[intCount];
+ copyInts(inflated, offset + 4, ints);
+ offset += 4 + 4*intCount;
+
+ int byteCount = readInt(inflated, offset);
+ byte[] bytes = Arrays.copyOfRange(inflated, offset + 4, offset + 4 + byteCount);
+
+ arrays[0] = longs;
+ arrays[1] = ints;
+ arrays[2] = bytes;
+
+ return decompressedBytes;
+ }
+
+ private static void copyInts(byte[] bytes, int i, int[] ints) {
+ int offset = i;
+ int count = ints.length;
+ for (int a = 0; a < count; ++a, offset += 4) {
+ int value = (((int) bytes[offset] & 0xff)) |
+ (((int) bytes[offset+1] & 0xff) << 8) |
+ (((int) bytes[offset+2] & 0xff) << 16) |
+ (((int) bytes[offset+3] & 0xff) << 24);
+ ints[a] = value;
+ }
+ }
+
+ private static void copyLongs(byte[] bytes, int i, long[] longs) {
+ int offset = i;
+ int count = longs.length;
+ for (int a = 0; a < count; ++a, offset += 8) {
+ long value = (((long) bytes[offset] & 0xff)) |
+ (((long) bytes[offset+1] & 0xff) << 8) |
+ (((long) bytes[offset+2] & 0xff) << 16) |
+ (((long) bytes[offset+3] & 0xff) << 24) |
+ (((long) bytes[offset+4] & 0xff) << 32) |
+ (((long) bytes[offset+5] & 0xff) << 40) |
+ (((long) bytes[offset+6] & 0xff) << 48) |
+ (((long) bytes[offset+7] & 0xff) << 56);
+ longs[a] = value;
+ }
+ }
+
+ private static int readInt(byte[] array, int offset) {
+ return (((int) array[offset] & 0xff)) |
+ (((int) array[offset+1] & 0xff) << 8) |
+ (((int) array[offset+2] & 0xff) << 16) |
+ (((int) array[offset+3] & 0xff) << 24);
+ }
+
+}