import java.io.File;
import java.io.IOException;
import java.io.InputStream;
-import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
import java.util.ArrayList;
import java.util.Arrays;
import org.simantics.graph.representation.Extensions;
import org.simantics.graph.representation.External;
import org.simantics.graph.representation.Identity;
+import org.simantics.graph.representation.InputChannel;
import org.simantics.graph.representation.Internal;
import org.simantics.graph.representation.Root;
import org.simantics.graph.representation.Value;
final public class StreamingTransferableGraphFileReader extends ByteFileReader {
-
- final static class InputChannel implements ReadableByteChannel {
-
- final private InputStream stream;
-
- public InputChannel(InputStream stream) {
- this.stream = stream;
- }
-
- @Override
- public boolean isOpen() {
- return true;
- }
-
- @Override
- public void close() throws IOException {
- }
-
- @Override
- public int read(ByteBuffer dst) throws IOException {
- int pos = dst.position();
- int limit = dst.limit();
- int i=stream.read(dst.array(), pos, limit-pos);
- return i;
- }
-
- }
private static boolean init = true;
Extensions extensions;
int resourceCount;
- private int identities;
- private int stmLength;
- private int valueLength;
+ private int identities = -1;
+ private int stmLength = -1;
+ private int valueLength = -1;
public FileTransferableGraphSource() throws Exception {
init();
@Override
public int getIdentityCount() throws Exception {
- identities = safeInt();
+ if(identities == -1) {
+ identities = safeInt();
+ }
return identities;
}
@Override
public int getStatementCount() throws Exception {
- stmLength = safeInt();
+ if(stmLength == -1) {
+ stmLength = safeInt();
+ }
return stmLength;
}
@Override
public int getValueCount() throws Exception {
- valueLength = safeInt();
+ if(valueLength == -1) {
+ valueLength = safeInt();
+ }
return valueLength;
}
@Override
public void forStatements(ReadGraph graph, TransferableGraphSourceProcedure<int[]> procedure) throws Exception {
-
+
int[] value = new int[4];
+ int stmLength = getStatementCount();
+
for(int stmIndex=0;stmIndex<stmLength;) {
-
+
value[stmIndex & 3] = safeInt();
stmIndex++;
if((stmIndex & 3) == 0) procedure.execute(value);
-
+
// Cached bytes
int avail = (SIZE-byteIndex) >> 2;
int allowed = Math.min(stmLength-stmIndex, avail);
// statements[stmIndex++] = ((bytes[index++]&0xff)<<24) | ((bytes[index++]&0xff)<<16) | ((bytes[index++]&0xff)<<8) | ((bytes[index++]&0xff));
}
byteIndex += allowed<<2;
-
+
}
-
+
}
@Override
public void forIdentities(ReadGraph graph, TransferableGraphSourceProcedure<Identity> procedure) throws Exception {
-
+
+ int identities = getIdentityCount();
+
for(int i=0;i<identities;i++) {
-
+
int rid = safeInt();
byte type = bytes[byteIndex++];
// External
if(type == 1) {
-
+
int parent = safeInt();
- int nameLen = bytes[byteIndex++]&0xff;
-
+ int nameLen = getDynamicUInt32();
if(byteIndex+nameLen < SIZE) {
procedure.execute(new Identity(rid, new External(parent, utf(bytes, byteIndex, byteIndex + nameLen))));
byteIndex += nameLen;
} else {
procedure.execute(new Identity(rid, new External(parent, utf(safeBytes(nameLen), 0, nameLen))));
}
-
}
// Internal
else if(type == 3) {
-
+
int parent = safeInt();
- int nameLen = bytes[byteIndex++]&0xff;
+ int nameLen = getDynamicUInt32();
if(byteIndex+nameLen < SIZE) {
procedure.execute(new Identity(rid, new Internal(parent, utf(bytes, byteIndex, byteIndex + nameLen))));
byteIndex += nameLen;
} else {
procedure.execute(new Identity(rid, new Internal(parent, utf(safeBytes(nameLen), 0, nameLen))));
}
-
+
}
// Root
else if(type == 0) {
-
- int nameLen = bytes[byteIndex++]&0xff;
+
+ int nameLen = getDynamicUInt32();
String name = utf(safeBytes(nameLen), 0, nameLen);
- int nameLen2 = bytes[byteIndex++]&0xff;
+ int nameLen2 = getDynamicUInt32();
String rType = utf(safeBytes(nameLen2), 0, nameLen2);
procedure.execute(new Identity(rid, new Root(name, rType)));
- } else if(type == 2) {
- throw new UnsupportedOperationException();
+ }
+ // Optional
+ else if(type == 2) {
+ throw new UnsupportedOperationException("Optional identities not supported");
+ } else {
+ throw new IllegalStateException("Unsupported identity type " + type);
}
}
-
+
}
@Override
public void forValues(ReadGraph graph, TransferableGraphSourceProcedure<Value> procedure) throws Exception {
-
+
+ int valueLength = getValueCount();
+
Serializer variantSerializer = Bindings.getSerializerUnchecked(Bindings.VARIANT);
-
+
List<Object> idcontext = new ArrayList<>();
-
+
for(int i=0;i<valueLength;i++) {
int resource = safeInt();
+ idcontext.clear();
Variant value = (Variant)variantSerializer
- .deserialize((DataInput)dis, idcontext);
+ .deserialize((DataInput)dis, idcontext);
procedure.execute(new Value(resource, value));
}
-
-
+
}
-
+
@Override
public void forValues2(ReadGraph graph, TransferableGraphSourceValueProcedure procedure) throws Exception {
Binding datatypeBinding = Bindings.getBinding(Datatype.class);
Serializer datatypeSerializer = Bindings.getSerializerUnchecked(datatypeBinding);
-
+
List<Object> idContext = new ArrayList<>();
-
+
for(int i=0;i<valueLength;i++) {
int resource = safeInt();
idContext.clear();
Datatype type = (Datatype)datatypeSerializer.deserialize((DataInput)dis, idContext);
procedure.execute(resource, type, dis);
}
-
+
}
@Override
public TransferableGraphSource readTG() throws Exception {
if(getSize() == 0) return null;
-
+
return new FileTransferableGraphSource();
}