-/*******************************************************************************\r
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
- * in Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- * VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.db.procore.cluster;\r
-\r
-import java.util.Vector;\r
-\r
-import org.simantics.db.exception.InternalException;\r
-import org.simantics.db.exception.RuntimeDatabaseException;\r
-import org.simantics.db.procore.cluster.CCSParser.ReferenceType;\r
-import org.simantics.db.procore.cluster.CCSParser.StmEnum;\r
-import org.simantics.db.service.ClusterUID;\r
-\r
-public class ClusterChangeSet implements ClusterChangeSetI {\r
- static interface IteratorI {\r
- }\r
- static private final boolean DEBUG = false;\r
- static private final int HEADER_SIZE = 20;\r
- private final int version;\r
- private final ClusterUID clusterUID;\r
- private final byte[] bytes;\r
-\r
- public static ClusterChangeSetI create(byte[] rawData, String compressionCodec)\r
- throws InternalException {\r
- \r
- // TODO: Find maybe a better way to do this\r
- byte[] bytes;\r
- if (compressionCodec.equals("LZ4")) {\r
- LZ4.DecompressStruct data = LZ4.decompress(rawData);\r
- bytes = data.bytes;\r
- } else if (compressionCodec.equals("FLZ")) {\r
- FastLZ.DecompressStruct data = FastLZ.decompress(rawData);\r
- bytes = data.bytes;\r
- } else {\r
- throw new RuntimeDatabaseException("No compressionCodec given!");\r
- }\r
- return new ClusterChangeSet(bytes);\r
- }\r
- @Override\r
- public String toString() {\r
- return "cid=" + clusterUID + " len=" + bytes.length; \r
- }\r
- private ClusterChangeSet(byte[] abytes) {\r
- this.bytes = abytes;\r
- if (bytes.length < HEADER_SIZE + 4)\r
- throw new RuntimeDatabaseException("Cluster change must contain header and size. length=" + bytes.length);\r
- version = CCSParser.getInt(bytes, 0);\r
- if (version <1 || version > 2)\r
- throw new RuntimeDatabaseException("Unsupported cluster change set version=" + version);\r
- clusterUID = ClusterUID.make(abytes, 4);\r
- if (ClusterUID.Null.equals(clusterUID))\r
- throw new RuntimeDatabaseException("Cluster uid can not be null.");\r
- if (DEBUG)\r
- System.out.println("DEBUG: Cluster uid=" + clusterUID);\r
- int p = HEADER_SIZE;\r
- int size = CCSParser.getInt(bytes, p);\r
- if (2 == version) {\r
- System.out.println("Cluster change set version=2 is not supported. skipping...");\r
- return;\r
- }\r
- for (; size > 0; size = CCSParser.getInt(bytes, p)) {\r
- mBlocks.push_back(new ClusterChangeSetBlock(p+=4, size, bytes));\r
- p += size; // skip block data\r
- } \r
- }\r
- @Override\r
- public ClusterUID getClusterUID() {\r
- return clusterUID;\r
- }\r
- private boolean updateRequired() {\r
- return false;\r
- }\r
- private void update() {\r
- }\r
- @Override\r
- public void getNextOperation(Operation ar) {\r
- Iterator pIterator = null;\r
- if (null == ar.iterator) {\r
- if (updateRequired())\r
- this.update();\r
- int N = mBlocks.size();\r
- if (0 == N) {\r
- ar.type = OperationEnum.EndOf;\r
- return;\r
- }\r
- pIterator = new Iterator(N-1);\r
- ar.iterator = pIterator;\r
- } else\r
- pIterator = (Iterator)ar.iterator;\r
- if (pIterator.block > pIterator.lastBlock) {\r
- ar.type = OperationEnum.EndOf;\r
- ar.iterator = null;\r
- return;\r
- } else if (pIterator.offset >= mBlocks.get(pIterator.block).size) {\r
- ++pIterator.block;\r
- pIterator.foreignTable.init();\r
- pIterator.offset = 0;\r
- if (pIterator.block > pIterator.lastBlock) {\r
- ar.type = OperationEnum.EndOf;\r
- ar.iterator = null;\r
- return;\r
- }\r
- }\r
- if (pIterator.offset >= mBlocks.get(pIterator.block).size) {\r
- ++pIterator.block;\r
- pIterator.foreignTable.init();\r
- pIterator.offset = 0;\r
- if (pIterator.block > pIterator.lastBlock) {\r
- ar.type = OperationEnum.EndOf;\r
- ar.iterator = null;\r
- return;\r
- }\r
- }\r
- ClusterChangeSetBlock r = mBlocks.get(pIterator.block);\r
- int inc = next(ar, pIterator, r.bytes, r.offset + pIterator.offset, r.offset + r.size);\r
- if (inc <= 0) {\r
- if (inc < 0)\r
- System.out.println("Iterarto offset increment is negative!");\r
- ar.type = OperationEnum.EndOf;\r
- ar.iterator = null;\r
- } else\r
- pIterator.offset += inc;\r
- }\r
- private int next(Operation ar, Iterator pIterator, byte[] bytes, int ab, int ae) {\r
- CCSParser.Args args = new CCSParser.Args(clusterUID, pIterator.foreignTable, ar);\r
- final int pe = ae;\r
- final int pb = ab;\r
- int p = pb;\r
- if (p < pe) {\r
- if (DEBUG)\r
- System.out.println("CCS.next offset=" + p);\r
- short ri = 0; // resource index\r
- short kraa = (short)(bytes[p] & 0xFF); \r
- switch (kraa) {\r
- case 0: case 1: case 2: case 3:\r
- //0x000000?? add - ri12 + pi14 + oi14 = 40 / 8 = 5\r
- p = CCSParser.parseStm(StmEnum.Add, args, bytes, p, 2, ReferenceType.Local, ReferenceType.Local);\r
- break;\r
- case 4: case 5: case 6: case 7:\r
- //0x000001?? rem - ri12 + pi14 + oi14 = 40 / 8 = 5\r
- p = CCSParser.parseStm(StmEnum.Remove, args, bytes, p, 2, ReferenceType.Local, ReferenceType.Local);\r
- break;\r
- case 8: case 9: case 10: case 11:\r
- //0x000010?? add - ri12 + pi14 + oc62 = 88 / 8 = 11\r
- p = CCSParser.parseStm(StmEnum.Add, args, bytes, p, 2, ReferenceType.Local, ReferenceType.ForeignLong);\r
- break;\r
- case 12: case 13: case 14: case 15:\r
- //0x000011?? rem - ri12 + pi14 + oc62 = 88 / 8 = 11\r
- p = CCSParser.parseStm(StmEnum.Remove, args, bytes, p, 2, ReferenceType.Local, ReferenceType.ForeignLong);\r
- break;\r
- case 16: case 17: case 18: case 19:\r
- //0x000100?? add - ri12 + pc62 + oi14 = 88 / 8 = 11\r
- p = CCSParser.parseStm(StmEnum.Add, args, bytes, p, 2, ReferenceType.ForeignLong, ReferenceType.Local);\r
- break;\r
- case 20: case 21: case 22: case 23:\r
- //0x000101?? rem - ri12 + pc62 + oi14 = 88 / 8 = 11\r
- p = CCSParser.parseStm(StmEnum.Remove, args, bytes, p, 2, ReferenceType.ForeignLong, ReferenceType.Local);\r
- break;\r
- case 24: case 25: case 26: case 27:\r
- //0x000110?? add - ri12 + pc62 + oc62 = 136 / 8 = 17\r
- p = CCSParser.parseStm(StmEnum.Add, args, bytes, p, 2, ReferenceType.ForeignLong, ReferenceType.ForeignLong);\r
- break;\r
- case 28: case 29: case 30: case 31:\r
- //0x000111?? rem - ri12 + pc62 + oc62 = 136 / 8 = 17\r
- p = CCSParser.parseStm(StmEnum.Remove, args, bytes, p, 2, ReferenceType.ForeignLong, ReferenceType.ForeignLong);\r
- break;\r
- case 32: case 33: case 34: case 35:\r
- case 36: case 37: case 38: case 39:\r
- case 40: case 41: case 42: case 43:\r
- case 44: case 45: case 46: case 47: case 48:\r
- //0x0010???? rem - ri10 + pr08 + oi14 = 32 / 8 = 4\r
- p = CCSParser.parseStm(StmEnum.Remove, args, bytes, p, 4, ReferenceType.ForeignShort, ReferenceType.Local);\r
- break;\r
- case 49:\r
- //0x00110001 rem - ri14 + pi14 + pr08 + pad4 = 40 / 8 = 5\r
- p = CCSParser.parseStm(StmEnum.Remove, args, bytes, p, 0, ReferenceType.Local, ReferenceType.ForeignShort);\r
- break;\r
- case 50:\r
- //0x00110010 rem - ri14 + pr08 + oc62 + pad4 = 88 / 8 = 11\r
- p = CCSParser.parseStm(StmEnum.Remove, args, bytes, p, 0, ReferenceType.ForeignShort, ReferenceType.ForeignLong);\r
- break;\r
- case 51:\r
- //0x00110011 rem - ri14 + pc62 + or08 + pad4 = 88 / 8 = 11\r
- p = CCSParser.parseStm(StmEnum.Remove, args, bytes, p, 0, ReferenceType.ForeignLong, ReferenceType.ForeignShort);\r
- break;\r
- case 52: //0x00110100 cre - ri14 + pad2 = 16 / 8 = 2\r
- ri = CCSParser.getShort(bytes, p+1);\r
- if (DEBUG)\r
- System.out.println("Creating resource r=" + ri + " rc=" + clusterUID);\r
- args.createResource(ri);\r
- p += 3;\r
- break;\r
- case 53: {\r
- //0x00110101 set - ri14 + sz18 = 32 / 8 = 4 + sz * bytes\r
- int t = CCSParser.getInt(bytes, p + 1);\r
- ri = (short)(t & 0x3FFF); \r
- int s = t >>> 14;\r
- args.setValue(ri, bytes, p + 5, s);\r
- p += 5 + s;\r
- break; }\r
- case 54: //0x00110110 del - ri14 + pad2 = 16 / 8 = 2\r
- ri = CCSParser.getShort(bytes, p+1);\r
- args.deleteValue(ri);\r
- p += 3;\r
- break;\r
- case 55: {\r
- //0x00110111 mod - ri14 + of58 + sz16 = 88 / 8 = 11 + sz * bytes\r
- ri = CCSParser.getShort(bytes, p+1);\r
- ri &= (1<<14)-1; // mask top 2 bits\r
- long vo = CCSParser.getLongN(bytes, p+3, 7); // get low 7 bytes\r
- vo |= (long)(bytes[p+2] & 0xC0) << (56-6); // add the top 2 bits\r
- p += 10;\r
- int vsize = CCSParser.getShort(bytes, p);\r
- if (vsize < 0)\r
- vsize += 65536;\r
- p += 2;\r
- if (DEBUG)\r
- System.out.println("Modifying value r=" + ri + " rc=" + args.clusterUID +\r
- " value offset=" + vo + " size=" + vsize);\r
- if (pe - p < vsize)\r
- throw new RuntimeException("Illegal size=" + vsize + " limit=" + (pe - p));\r
- args.modifyValue(ri, vo, vsize, bytes, p);\r
- p += vsize;\r
- break; }\r
- case 56: case 57: case 58: case 59:\r
- case 60: case 61: case 62: case 63: {\r
- //0x00111??? set - ri14 + sz2 = 16 / 8 = 2 + sz * bytes;\r
- byte s = (byte)(bytes[p] & 0x7);\r
- s <<= 2;\r
- ri = CCSParser.getShort(bytes, p+1);\r
- ri &= 0x3FFF; \r
- byte t = bytes[p + 2];\r
- s |= (t &0xFF) >> 6;\r
- args.setValue(ri, bytes, p + 3, s);\r
- p += 3 + s;\r
- break; }\r
- case 64: case 65: case 66: case 67:\r
- case 68: case 69: case 70: case 71:\r
- case 72: case 73: case 74: case 75:\r
- case 76: case 77: case 78: case 79:\r
- case 80: case 81: case 82: case 83:\r
- case 84: case 85: case 86: case 87:\r
- case 88: case 89: case 90: case 91:\r
- case 92: case 93: case 94: case 95:\r
- case 96: case 97: case 98: case 99:\r
- case 100: case 101: case 102: case 103:\r
- case 104: case 105: case 106: case 107:\r
- case 108: case 109: case 110: case 111:\r
- case 112: case 113: case 114: case 115:\r
- case 116: case 117: case 118: case 119:\r
- case 120: case 121: case 122: case 123:\r
- case 124: case 125: case 126: case 127:\r
- //0x01?????? add - ri08 + pr08 + or08 = 24 / 8 = 3\r
- p = CCSParser.parseStm(StmEnum.Add, args, bytes, p, 6, ReferenceType.ForeignShort, ReferenceType.ForeignShort);\r
- break;\r
- case 128: case 129: case 130: case 131:\r
- case 132: case 133: case 134: case 135:\r
- case 136: case 137: case 138: case 139:\r
- case 140: case 141: case 142: case 143:\r
- case 144: case 145: case 146: case 147:\r
- case 148: case 149: case 150: case 151:\r
- case 152: case 153: case 154: case 155:\r
- case 156: case 157: case 158: case 159:\r
- case 160: case 161: case 162: case 163:\r
- case 164: case 165: case 166: case 167:\r
- case 168: case 169: case 170: case 171:\r
- case 172: case 173: case 174: case 175:\r
- case 176: case 177: case 178: case 179:\r
- case 180: case 181: case 182: case 183:\r
- case 184: case 185: case 186: case 187:\r
- case 188: case 189: case 190:case 191:\r
- //0x10?????? rem - ri08 + pr08 + or08 = 24 / 8 = 3\r
- p = CCSParser.parseStm(StmEnum.Remove, args, bytes, p, 6, ReferenceType.ForeignShort, ReferenceType.ForeignShort);\r
- break;\r
- case 192: case 193: case 194: case 195:\r
- case 196: case 197: case 198: case 199:\r
- case 200: case 201: case 202: case 203:\r
- case 204: case 205: case 206: case 207:\r
- //0x1100???? add - ri10 + pi14 + pr08 = 32 / 8 = 4\r
- p = CCSParser.parseStm(StmEnum.Add, args, bytes, p, 4, ReferenceType.Local, ReferenceType.ForeignShort);\r
- break;\r
- case 208: case 209: case 210: case 211:\r
- case 212: case 213: case 214: case 215:\r
- case 216: case 217: case 218: case 219:\r
- case 220: case 221: case 222: case 223:\r
- //0x1101???? add - ri10 + pr08 + oi14 = 32 / 8 = 4\r
- p = CCSParser.parseStm(StmEnum.Add, args, bytes, p, 4, ReferenceType.ForeignShort, ReferenceType.Local);\r
- break;\r
- case 224: case 225: case 226: case 227:\r
- case 228: case 229: case 230: case 231:\r
- case 232: case 233: case 234: case 235:\r
- case 236: case 237: case 238: case 239:\r
- //0x1110???? add - ri10 + pr08 + oc62 = 80 / 8 = 10 \r
- p = CCSParser.parseStm(StmEnum.Add, args, bytes, p, 4, ReferenceType.ForeignShort, ReferenceType.ForeignLong);\r
- break;\r
- case 240: case 241: case 242: case 243:\r
- case 244: case 245: case 246: case 247:\r
- case 248: case 249: case 250: case 251:\r
- case 252: case 253: case 254: case 255:\r
- //0x1111???? add - ri10 + pc62 + or08 = 80 / 8 = 10 \r
- p = CCSParser.parseStm(StmEnum.Add, args, bytes, p, 4, ReferenceType.ForeignLong, ReferenceType.ForeignShort);\r
- break;\r
- default:\r
- throw new RuntimeException("Internal error, contact application support.");\r
- }\r
- }\r
- return p - pb;\r
- }\r
- private static class ClusterChangeSetBlock {\r
- ClusterChangeSetBlock(int offset, int size, byte[] bytes) {\r
- this.bytes = bytes;\r
- this.offset = offset;\r
- this.size = size;\r
- }\r
- byte[] bytes;\r
- int offset;\r
- int size;\r
- }\r
- private static class Blocks {\r
- Blocks() {\r
- mBlocks = new Vector<ClusterChangeSetBlock>();\r
- mBlocks.ensureCapacity(BLOCK_INCREMENT);\r
- }\r
- int size() {\r
- return mBlocks.size();\r
- }\r
- void push_back(ClusterChangeSetBlock ar) {\r
- if (mBlocks.size() == mBlocks.capacity())\r
- mBlocks.ensureCapacity(mBlocks.size() + BLOCK_INCREMENT);\r
- mBlocks.add(ar);\r
- }\r
- ClusterChangeSetBlock get(int i) {\r
- return mBlocks.get(i);\r
- }\r
- // How many block elements are allocated when out of space.\r
- private static final int BLOCK_INCREMENT = 10;\r
- private Vector<ClusterChangeSetBlock> mBlocks;\r
- }\r
- private static class Iterator implements IteratorI {\r
- Iterator(int lastBlock) {\r
- this.lastBlock = lastBlock;\r
- this.foreignTable = new CCSParser.ForeignTable(); \r
- }\r
- int lastBlock;\r
- int block;\r
- int offset;\r
- CCSParser.ForeignTable foreignTable;\r
- }\r
- private Blocks mBlocks = new Blocks();\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.db.procore.cluster;
+
+import java.util.Vector;
+
+import org.simantics.db.exception.InternalException;
+import org.simantics.db.exception.RuntimeDatabaseException;
+import org.simantics.db.procore.cluster.CCSParser.ReferenceType;
+import org.simantics.db.procore.cluster.CCSParser.StmEnum;
+import org.simantics.db.service.ClusterUID;
+
+public class ClusterChangeSet implements ClusterChangeSetI {
+ static interface IteratorI {
+ }
+ static private final boolean DEBUG = false;
+ static private final int HEADER_SIZE = 20;
+ private final int version;
+ private final ClusterUID clusterUID;
+ private final byte[] bytes;
+
+ public static ClusterChangeSetI create(byte[] rawData, String compressionCodec)
+ throws InternalException {
+
+ // TODO: Find maybe a better way to do this
+ byte[] bytes;
+ if (compressionCodec.equals("LZ4")) {
+ LZ4.DecompressStruct data = LZ4.decompress(rawData);
+ bytes = data.bytes;
+ } else if (compressionCodec.equals("FLZ")) {
+ FastLZ.DecompressStruct data = FastLZ.decompress(rawData);
+ bytes = data.bytes;
+ } else {
+ throw new RuntimeDatabaseException("No compressionCodec given!");
+ }
+ return new ClusterChangeSet(bytes);
+ }
+ @Override
+ public String toString() {
+ return "cid=" + clusterUID + " len=" + bytes.length;
+ }
+ private ClusterChangeSet(byte[] abytes) {
+ this.bytes = abytes;
+ if (bytes.length < HEADER_SIZE + 4)
+ throw new RuntimeDatabaseException("Cluster change must contain header and size. length=" + bytes.length);
+ version = CCSParser.getInt(bytes, 0);
+ if (version <1 || version > 2)
+ throw new RuntimeDatabaseException("Unsupported cluster change set version=" + version);
+ clusterUID = ClusterUID.make(abytes, 4);
+ if (ClusterUID.Null.equals(clusterUID))
+ throw new RuntimeDatabaseException("Cluster uid can not be null.");
+ if (DEBUG)
+ System.out.println("DEBUG: Cluster uid=" + clusterUID);
+ int p = HEADER_SIZE;
+ int size = CCSParser.getInt(bytes, p);
+ if (2 == version) {
+ System.out.println("Cluster change set version=2 is not supported. skipping...");
+ return;
+ }
+ for (; size > 0; size = CCSParser.getInt(bytes, p)) {
+ mBlocks.push_back(new ClusterChangeSetBlock(p+=4, size, bytes));
+ p += size; // skip block data
+ }
+ }
+ @Override
+ public ClusterUID getClusterUID() {
+ return clusterUID;
+ }
+ private boolean updateRequired() {
+ return false;
+ }
+ private void update() {
+ }
+ @Override
+ public void getNextOperation(Operation ar) {
+ Iterator pIterator = null;
+ if (null == ar.iterator) {
+ if (updateRequired())
+ this.update();
+ int N = mBlocks.size();
+ if (0 == N) {
+ ar.type = OperationEnum.EndOf;
+ return;
+ }
+ pIterator = new Iterator(N-1);
+ ar.iterator = pIterator;
+ } else
+ pIterator = (Iterator)ar.iterator;
+ if (pIterator.block > pIterator.lastBlock) {
+ ar.type = OperationEnum.EndOf;
+ ar.iterator = null;
+ return;
+ } else if (pIterator.offset >= mBlocks.get(pIterator.block).size) {
+ ++pIterator.block;
+ pIterator.foreignTable.init();
+ pIterator.offset = 0;
+ if (pIterator.block > pIterator.lastBlock) {
+ ar.type = OperationEnum.EndOf;
+ ar.iterator = null;
+ return;
+ }
+ }
+ if (pIterator.offset >= mBlocks.get(pIterator.block).size) {
+ ++pIterator.block;
+ pIterator.foreignTable.init();
+ pIterator.offset = 0;
+ if (pIterator.block > pIterator.lastBlock) {
+ ar.type = OperationEnum.EndOf;
+ ar.iterator = null;
+ return;
+ }
+ }
+ ClusterChangeSetBlock r = mBlocks.get(pIterator.block);
+ int inc = next(ar, pIterator, r.bytes, r.offset + pIterator.offset, r.offset + r.size);
+ if (inc <= 0) {
+ if (inc < 0)
+ System.out.println("Iterarto offset increment is negative!");
+ ar.type = OperationEnum.EndOf;
+ ar.iterator = null;
+ } else
+ pIterator.offset += inc;
+ }
+ private int next(Operation ar, Iterator pIterator, byte[] bytes, int ab, int ae) {
+ CCSParser.Args args = new CCSParser.Args(clusterUID, pIterator.foreignTable, ar);
+ final int pe = ae;
+ final int pb = ab;
+ int p = pb;
+ if (p < pe) {
+ if (DEBUG)
+ System.out.println("CCS.next offset=" + p);
+ short ri = 0; // resource index
+ short kraa = (short)(bytes[p] & 0xFF);
+ switch (kraa) {
+ case 0: case 1: case 2: case 3:
+ //0x000000?? add - ri12 + pi14 + oi14 = 40 / 8 = 5
+ p = CCSParser.parseStm(StmEnum.Add, args, bytes, p, 2, ReferenceType.Local, ReferenceType.Local);
+ break;
+ case 4: case 5: case 6: case 7:
+ //0x000001?? rem - ri12 + pi14 + oi14 = 40 / 8 = 5
+ p = CCSParser.parseStm(StmEnum.Remove, args, bytes, p, 2, ReferenceType.Local, ReferenceType.Local);
+ break;
+ case 8: case 9: case 10: case 11:
+ //0x000010?? add - ri12 + pi14 + oc62 = 88 / 8 = 11
+ p = CCSParser.parseStm(StmEnum.Add, args, bytes, p, 2, ReferenceType.Local, ReferenceType.ForeignLong);
+ break;
+ case 12: case 13: case 14: case 15:
+ //0x000011?? rem - ri12 + pi14 + oc62 = 88 / 8 = 11
+ p = CCSParser.parseStm(StmEnum.Remove, args, bytes, p, 2, ReferenceType.Local, ReferenceType.ForeignLong);
+ break;
+ case 16: case 17: case 18: case 19:
+ //0x000100?? add - ri12 + pc62 + oi14 = 88 / 8 = 11
+ p = CCSParser.parseStm(StmEnum.Add, args, bytes, p, 2, ReferenceType.ForeignLong, ReferenceType.Local);
+ break;
+ case 20: case 21: case 22: case 23:
+ //0x000101?? rem - ri12 + pc62 + oi14 = 88 / 8 = 11
+ p = CCSParser.parseStm(StmEnum.Remove, args, bytes, p, 2, ReferenceType.ForeignLong, ReferenceType.Local);
+ break;
+ case 24: case 25: case 26: case 27:
+ //0x000110?? add - ri12 + pc62 + oc62 = 136 / 8 = 17
+ p = CCSParser.parseStm(StmEnum.Add, args, bytes, p, 2, ReferenceType.ForeignLong, ReferenceType.ForeignLong);
+ break;
+ case 28: case 29: case 30: case 31:
+ //0x000111?? rem - ri12 + pc62 + oc62 = 136 / 8 = 17
+ p = CCSParser.parseStm(StmEnum.Remove, args, bytes, p, 2, ReferenceType.ForeignLong, ReferenceType.ForeignLong);
+ break;
+ case 32: case 33: case 34: case 35:
+ case 36: case 37: case 38: case 39:
+ case 40: case 41: case 42: case 43:
+ case 44: case 45: case 46: case 47: case 48:
+ //0x0010???? rem - ri10 + pr08 + oi14 = 32 / 8 = 4
+ p = CCSParser.parseStm(StmEnum.Remove, args, bytes, p, 4, ReferenceType.ForeignShort, ReferenceType.Local);
+ break;
+ case 49:
+ //0x00110001 rem - ri14 + pi14 + pr08 + pad4 = 40 / 8 = 5
+ p = CCSParser.parseStm(StmEnum.Remove, args, bytes, p, 0, ReferenceType.Local, ReferenceType.ForeignShort);
+ break;
+ case 50:
+ //0x00110010 rem - ri14 + pr08 + oc62 + pad4 = 88 / 8 = 11
+ p = CCSParser.parseStm(StmEnum.Remove, args, bytes, p, 0, ReferenceType.ForeignShort, ReferenceType.ForeignLong);
+ break;
+ case 51:
+ //0x00110011 rem - ri14 + pc62 + or08 + pad4 = 88 / 8 = 11
+ p = CCSParser.parseStm(StmEnum.Remove, args, bytes, p, 0, ReferenceType.ForeignLong, ReferenceType.ForeignShort);
+ break;
+ case 52: //0x00110100 cre - ri14 + pad2 = 16 / 8 = 2
+ ri = CCSParser.getShort(bytes, p+1);
+ if (DEBUG)
+ System.out.println("Creating resource r=" + ri + " rc=" + clusterUID);
+ args.createResource(ri);
+ p += 3;
+ break;
+ case 53: {
+ //0x00110101 set - ri14 + sz18 = 32 / 8 = 4 + sz * bytes
+ int t = CCSParser.getInt(bytes, p + 1);
+ ri = (short)(t & 0x3FFF);
+ int s = t >>> 14;
+ args.setValue(ri, bytes, p + 5, s);
+ p += 5 + s;
+ break; }
+ case 54: //0x00110110 del - ri14 + pad2 = 16 / 8 = 2
+ ri = CCSParser.getShort(bytes, p+1);
+ args.deleteValue(ri);
+ p += 3;
+ break;
+ case 55: {
+ //0x00110111 mod - ri14 + of58 + sz16 = 88 / 8 = 11 + sz * bytes
+ ri = CCSParser.getShort(bytes, p+1);
+ ri &= (1<<14)-1; // mask top 2 bits
+ long vo = CCSParser.getLongN(bytes, p+3, 7); // get low 7 bytes
+ vo |= (long)(bytes[p+2] & 0xC0) << (56-6); // add the top 2 bits
+ p += 10;
+ int vsize = CCSParser.getShort(bytes, p);
+ if (vsize < 0)
+ vsize += 65536;
+ p += 2;
+ if (DEBUG)
+ System.out.println("Modifying value r=" + ri + " rc=" + args.clusterUID +
+ " value offset=" + vo + " size=" + vsize);
+ if (pe - p < vsize)
+ throw new RuntimeException("Illegal size=" + vsize + " limit=" + (pe - p));
+ args.modifyValue(ri, vo, vsize, bytes, p);
+ p += vsize;
+ break; }
+ case 56: case 57: case 58: case 59:
+ case 60: case 61: case 62: case 63: {
+ //0x00111??? set - ri14 + sz2 = 16 / 8 = 2 + sz * bytes;
+ byte s = (byte)(bytes[p] & 0x7);
+ s <<= 2;
+ ri = CCSParser.getShort(bytes, p+1);
+ ri &= 0x3FFF;
+ byte t = bytes[p + 2];
+ s |= (t &0xFF) >> 6;
+ args.setValue(ri, bytes, p + 3, s);
+ p += 3 + s;
+ break; }
+ case 64: case 65: case 66: case 67:
+ case 68: case 69: case 70: case 71:
+ case 72: case 73: case 74: case 75:
+ case 76: case 77: case 78: case 79:
+ case 80: case 81: case 82: case 83:
+ case 84: case 85: case 86: case 87:
+ case 88: case 89: case 90: case 91:
+ case 92: case 93: case 94: case 95:
+ case 96: case 97: case 98: case 99:
+ case 100: case 101: case 102: case 103:
+ case 104: case 105: case 106: case 107:
+ case 108: case 109: case 110: case 111:
+ case 112: case 113: case 114: case 115:
+ case 116: case 117: case 118: case 119:
+ case 120: case 121: case 122: case 123:
+ case 124: case 125: case 126: case 127:
+ //0x01?????? add - ri08 + pr08 + or08 = 24 / 8 = 3
+ p = CCSParser.parseStm(StmEnum.Add, args, bytes, p, 6, ReferenceType.ForeignShort, ReferenceType.ForeignShort);
+ break;
+ case 128: case 129: case 130: case 131:
+ case 132: case 133: case 134: case 135:
+ case 136: case 137: case 138: case 139:
+ case 140: case 141: case 142: case 143:
+ case 144: case 145: case 146: case 147:
+ case 148: case 149: case 150: case 151:
+ case 152: case 153: case 154: case 155:
+ case 156: case 157: case 158: case 159:
+ case 160: case 161: case 162: case 163:
+ case 164: case 165: case 166: case 167:
+ case 168: case 169: case 170: case 171:
+ case 172: case 173: case 174: case 175:
+ case 176: case 177: case 178: case 179:
+ case 180: case 181: case 182: case 183:
+ case 184: case 185: case 186: case 187:
+ case 188: case 189: case 190:case 191:
+ //0x10?????? rem - ri08 + pr08 + or08 = 24 / 8 = 3
+ p = CCSParser.parseStm(StmEnum.Remove, args, bytes, p, 6, ReferenceType.ForeignShort, ReferenceType.ForeignShort);
+ break;
+ case 192: case 193: case 194: case 195:
+ case 196: case 197: case 198: case 199:
+ case 200: case 201: case 202: case 203:
+ case 204: case 205: case 206: case 207:
+ //0x1100???? add - ri10 + pi14 + pr08 = 32 / 8 = 4
+ p = CCSParser.parseStm(StmEnum.Add, args, bytes, p, 4, ReferenceType.Local, ReferenceType.ForeignShort);
+ break;
+ case 208: case 209: case 210: case 211:
+ case 212: case 213: case 214: case 215:
+ case 216: case 217: case 218: case 219:
+ case 220: case 221: case 222: case 223:
+ //0x1101???? add - ri10 + pr08 + oi14 = 32 / 8 = 4
+ p = CCSParser.parseStm(StmEnum.Add, args, bytes, p, 4, ReferenceType.ForeignShort, ReferenceType.Local);
+ break;
+ case 224: case 225: case 226: case 227:
+ case 228: case 229: case 230: case 231:
+ case 232: case 233: case 234: case 235:
+ case 236: case 237: case 238: case 239:
+ //0x1110???? add - ri10 + pr08 + oc62 = 80 / 8 = 10
+ p = CCSParser.parseStm(StmEnum.Add, args, bytes, p, 4, ReferenceType.ForeignShort, ReferenceType.ForeignLong);
+ break;
+ case 240: case 241: case 242: case 243:
+ case 244: case 245: case 246: case 247:
+ case 248: case 249: case 250: case 251:
+ case 252: case 253: case 254: case 255:
+ //0x1111???? add - ri10 + pc62 + or08 = 80 / 8 = 10
+ p = CCSParser.parseStm(StmEnum.Add, args, bytes, p, 4, ReferenceType.ForeignLong, ReferenceType.ForeignShort);
+ break;
+ default:
+ throw new RuntimeException("Internal error, contact application support.");
+ }
+ }
+ return p - pb;
+ }
+ private static class ClusterChangeSetBlock {
+ ClusterChangeSetBlock(int offset, int size, byte[] bytes) {
+ this.bytes = bytes;
+ this.offset = offset;
+ this.size = size;
+ }
+ byte[] bytes;
+ int offset;
+ int size;
+ }
+ private static class Blocks {
+ Blocks() {
+ mBlocks = new Vector<ClusterChangeSetBlock>();
+ mBlocks.ensureCapacity(BLOCK_INCREMENT);
+ }
+ int size() {
+ return mBlocks.size();
+ }
+ void push_back(ClusterChangeSetBlock ar) {
+ if (mBlocks.size() == mBlocks.capacity())
+ mBlocks.ensureCapacity(mBlocks.size() + BLOCK_INCREMENT);
+ mBlocks.add(ar);
+ }
+ ClusterChangeSetBlock get(int i) {
+ return mBlocks.get(i);
+ }
+ // How many block elements are allocated when out of space.
+ private static final int BLOCK_INCREMENT = 10;
+ private Vector<ClusterChangeSetBlock> mBlocks;
+ }
+ private static class Iterator implements IteratorI {
+ Iterator(int lastBlock) {
+ this.lastBlock = lastBlock;
+ this.foreignTable = new CCSParser.ForeignTable();
+ }
+ int lastBlock;
+ int block;
+ int offset;
+ CCSParser.ForeignTable foreignTable;
+ }
+ private Blocks mBlocks = new Blocks();
+}