create changelog entry
[debian/openrocket] / core / src / net / sf / openrocket / file / GeneralRocketLoader.java
index b6117f787e56409914747ef79730f8b242747063..da6858d89cb912f9e424a172c79ccc6b7cbc71d9 100644 (file)
@@ -1,14 +1,19 @@
 package net.sf.openrocket.file;
 
-import net.sf.openrocket.document.OpenRocketDocument;
-import net.sf.openrocket.file.openrocket.OpenRocketLoader;
-
 import java.io.BufferedInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.nio.charset.Charset;
 import java.util.Arrays;
 import java.util.zip.GZIPInputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+import net.sf.openrocket.document.OpenRocketDocument;
+import net.sf.openrocket.file.openrocket.importt.OpenRocketLoader;
+import net.sf.openrocket.file.rocksim.importt.RocksimLoader;
+import net.sf.openrocket.util.ArrayUtils;
+import net.sf.openrocket.util.TextUtil;
 
 
 /**
@@ -18,24 +23,23 @@ import java.util.zip.GZIPInputStream;
  * 
  * @author Sampo Niskanen <sampo.niskanen@iki.fi>
  */
-public class GeneralRocketLoader extends RocketLoader {
-
+public class GeneralRocketLoader extends AbstractRocketLoader {
+       
        private static final int READ_BYTES = 300;
        
-       private static final byte[] GZIP_SIGNATURE = { 31, -117 };  // 0x1f, 0x8b
-       private static final byte[] OPENROCKET_SIGNATURE = 
-               "<openrocket".getBytes(Charset.forName("US-ASCII"));
-    private static final byte[] ROCKSIM_SIGNATURE = 
-        "<RockSimDoc".getBytes(Charset.forName("US-ASCII"));
+       private static final byte[] GZIP_SIGNATURE = { 31, -117 }; // 0x1f, 0x8b
+       private static final byte[] ZIP_SIGNATURE = TextUtil.convertStringToBytes("PK",Charset.forName("US-ASCII"));
+       private static final byte[] OPENROCKET_SIGNATURE = TextUtil.convertStringToBytes("<openrocket",Charset.forName("US-ASCII"));
+       private static final byte[] ROCKSIM_SIGNATURE = TextUtil.convertStringToBytes("<RockSimDoc",Charset.forName("US-ASCII"));
        
        private final OpenRocketLoader openRocketLoader = new OpenRocketLoader();
-    
-    private final net.sf.openrocket.file.rocksim.importt.RocksimLoader rocksimLoader = new net.sf.openrocket.file.rocksim.importt.RocksimLoader();
+       
+       private final RocksimLoader rocksimLoader = new RocksimLoader();
        
        @Override
-       protected OpenRocketDocument loadFromStream(InputStream source) throws IOException,
+       protected OpenRocketDocument loadFromStream(InputStream source, MotorFinder motorFinder) throws IOException,
                        RocketLoadException {
-
+               
                // Check for mark() support
                if (!source.markSupported()) {
                        source = new BufferedInputStream(source);
@@ -53,38 +57,58 @@ public class GeneralRocketLoader extends RocketLoader {
                }
                
                // Detect the appropriate loader
-
+               
                // Check for GZIP
-               if (buffer[0] == GZIP_SIGNATURE[0]  &&  buffer[1] == GZIP_SIGNATURE[1]) {
-                       OpenRocketDocument doc = loadFromStream(new GZIPInputStream(source));
+               if (buffer[0] == GZIP_SIGNATURE[0] && buffer[1] == GZIP_SIGNATURE[1]) {
+                       OpenRocketDocument doc = loadFromStream(new GZIPInputStream(source), motorFinder);
                        doc.getDefaultStorageOptions().setCompressionEnabled(true);
                        return doc;
                }
                
+               // Check for ZIP (for future compatibility)
+               if (buffer[0] == ZIP_SIGNATURE[0] && buffer[1] == ZIP_SIGNATURE[1]) {
+                       // Search for entry with name *.ork
+                       ZipInputStream in = new ZipInputStream(source);
+                       while (true) {
+                               ZipEntry entry = in.getNextEntry();
+                               if (entry == null) {
+                                       throw new RocketLoadException("Unsupported or corrupt file.");
+                               }
+                               if (entry.getName().matches(".*\\.[oO][rR][kK]$")) {
+                                       OpenRocketDocument doc = loadFromStream(in, motorFinder);
+                                       doc.getDefaultStorageOptions().setCompressionEnabled(true);
+                                       return doc;
+                               } else if ( entry.getName().matches(".*\\.[rR][kK][tT]$")) {
+                                       OpenRocketDocument doc = loadFromStream(in, motorFinder);
+                                       return doc;
+                               }
+                       }
+               }
+               
                // Check for OpenRocket
                int match = 0;
-               for (int i=0; i < count; i++) {
+               for (int i = 0; i < count; i++) {
                        if (buffer[i] == OPENROCKET_SIGNATURE[match]) {
                                match++;
                                if (match == OPENROCKET_SIGNATURE.length) {
-                                       return loadUsing(source, openRocketLoader);
+                                       return loadUsing(source, openRocketLoader, motorFinder);
                                }
                        } else {
                                match = 0;
                        }
                }
-
-        byte[] typeIdentifier = Arrays.copyOf(buffer, ROCKSIM_SIGNATURE.length);
-        if (Arrays.equals(ROCKSIM_SIGNATURE, typeIdentifier)) {
-            return loadUsing(source, rocksimLoader);            
-        }
+               
+               byte[] typeIdentifier = ArrayUtils.copyOf(buffer, ROCKSIM_SIGNATURE.length);
+               if (Arrays.equals(ROCKSIM_SIGNATURE, typeIdentifier)) {
+                       return loadUsing(source, rocksimLoader, motorFinder);
+               }
                throw new RocketLoadException("Unsupported or corrupt file.");
        }
        
-       private OpenRocketDocument loadUsing(InputStream source, RocketLoader loader
-       throws RocketLoadException {
+       private OpenRocketDocument loadUsing(InputStream source, RocketLoader loader, MotorFinder motorFinder)
+                       throws RocketLoadException {
                warnings.clear();
-               OpenRocketDocument doc = loader.load(source);
+               OpenRocketDocument doc = loader.load(source, motorFinder);
                warnings.addAll(loader.getWarnings());
                return doc;
        }