]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.graph/src/org/simantics/graph/representation/TransferableGraphFileReader.java
Finalizing improve startup time for fresh or rollback'd session
[simantics/platform.git] / bundles / org.simantics.graph / src / org / simantics / graph / representation / TransferableGraphFileReader.java
index 077eb6617a1703f3cbffa913633e2b4c738f95ab..56a112e4d02e7a7e768375618bf687bab437b3ef 100644 (file)
@@ -14,6 +14,7 @@ import org.simantics.databoard.Bindings;
 import org.simantics.databoard.Datatypes;
 import org.simantics.databoard.binding.error.RuntimeDatatypeConstructionException;
 import org.simantics.databoard.binding.mutable.Variant;
+import org.simantics.databoard.container.DataContainer;
 import org.simantics.databoard.container.DataContainers;
 import org.simantics.databoard.serialization.RuntimeSerializerConstructionException;
 import org.simantics.databoard.serialization.Serializer;
@@ -22,6 +23,10 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 
+/**
+ * It is recommended to use {@link #read(File)} and {@link #read(InputStream)}
+ * for reading to ensure proper resource handling.
+ */
 final public class TransferableGraphFileReader extends ByteFileReader {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(TransferableGraphFileReader.class);
@@ -53,11 +58,11 @@ final public class TransferableGraphFileReader 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;
@@ -65,17 +70,25 @@ final public class TransferableGraphFileReader extends ByteFileReader {
 
                @Override
                public void close() throws IOException {
+                       // NOTE: it is an intentional choice not to close the underlying stream here
+                       // InputStreams given directly to TransferableGraphFileReader are expected to
+                       // be closed outside of this implementation.
                }
 
                @Override
                public int read(ByteBuffer dst) throws IOException {
-                       int pos = dst.position();
+                       int nRead;
+                       int size = 0;
+                       int position = dst.position();
                        int limit = dst.limit();
-                       int i=stream.read(dst.array(), pos, limit-pos);
-                       //LOGGER.warn("Read " + i + " (expected " + dst.array().length + ")");
-                       return i;
+                       // The users of this channel expect that the data is fully read at this point
+                       while ((nRead = stream.read(dst.array(), position, limit - position)) != -1 && limit - position > 0) {
+                               size += nRead;
+                               position += nRead;
+                       }
+                       return size;
                }
-               
+
        }
        
        private static boolean init = true;
@@ -83,7 +96,37 @@ final public class TransferableGraphFileReader extends ByteFileReader {
        final private static int SIZE = 1<<18;
        final private static int HEADER = headerSize();
        final private int header;
-       
+
+       /**
+        * Reads a {@link DataContainer} containing a {@link TransferableGraph1}
+        * structure from the specified {@link File}.
+        * 
+        * @param file the file to read from
+        * @return the TG contained by the file
+        * @throws IOException
+        */
+       public static TransferableGraph1 read(File file) throws IOException {
+               try (TransferableGraphFileReader reader = new TransferableGraphFileReader(file)) {
+                       return reader.readTG();
+               }
+       }
+
+       /**
+        * Reads a {@link DataContainer} containing a {@link TransferableGraph1}
+        * structure from the specified InputStream. Note that this implementation does
+        * not close the specified <code>input</code> stream, it is expected to be
+        * closed by the caller.
+        * 
+        * @param input the input stream to read from
+        * @return the TG contained by the stream
+        * @throws IOException
+        */
+       public static TransferableGraph1 read(InputStream input) throws IOException {
+               try (TransferableGraphFileReader reader = new TransferableGraphFileReader(input)) {
+                       return reader.readTG();
+               }
+       }
+
        public TransferableGraphFileReader(File file) throws IOException {
                super(file, SIZE);
                if(init) {
@@ -263,7 +306,7 @@ final public class TransferableGraphFileReader extends ByteFileReader {
                
                for(int i=0;i<valueLength;i++) {
                        int resource = safeInt();
-                       idcontext.clear();
+                       //idcontext.clear();
                        Variant value = (Variant)variantSerializer
                                .deserialize((DataInput)dis, idcontext);
                        values[i] = new Value(resource, value);