lose embedded source jars from upstream branch
[debian/openrocket] / core / src / net / sf / openrocket / file / GeneralRocketLoader.java
1 package net.sf.openrocket.file;
2
3 import java.io.BufferedInputStream;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.nio.charset.Charset;
7 import java.util.Arrays;
8 import java.util.zip.GZIPInputStream;
9 import java.util.zip.ZipEntry;
10 import java.util.zip.ZipInputStream;
11
12 import net.sf.openrocket.document.OpenRocketDocument;
13 import net.sf.openrocket.file.openrocket.importt.OpenRocketLoader;
14 import net.sf.openrocket.file.rocksim.importt.RocksimLoader;
15
16
17 /**
18  * A rocket loader that auto-detects the document type and uses the appropriate
19  * loading.  Supports loading of GZIPed files as well with transparent
20  * uncompression.
21  * 
22  * @author Sampo Niskanen <sampo.niskanen@iki.fi>
23  */
24 public class GeneralRocketLoader extends AbstractRocketLoader {
25         
26         private static final int READ_BYTES = 300;
27         
28         private static final byte[] GZIP_SIGNATURE = { 31, -117 }; // 0x1f, 0x8b
29         private static final byte[] ZIP_SIGNATURE = "PK".getBytes(Charset.forName("US-ASCII"));
30         private static final byte[] OPENROCKET_SIGNATURE = "<openrocket".getBytes(Charset.forName("US-ASCII"));
31         private static final byte[] ROCKSIM_SIGNATURE = "<RockSimDoc".getBytes(Charset.forName("US-ASCII"));
32         
33         private final OpenRocketLoader openRocketLoader = new OpenRocketLoader();
34         
35         private final RocksimLoader rocksimLoader = new RocksimLoader();
36         
37         @Override
38         protected OpenRocketDocument loadFromStream(InputStream source, MotorFinder motorFinder) throws IOException,
39                         RocketLoadException {
40                 
41                 // Check for mark() support
42                 if (!source.markSupported()) {
43                         source = new BufferedInputStream(source);
44                 }
45                 
46                 // Read using mark()
47                 byte[] buffer = new byte[READ_BYTES];
48                 int count;
49                 source.mark(READ_BYTES + 10);
50                 count = source.read(buffer);
51                 source.reset();
52                 
53                 if (count < 10) {
54                         throw new RocketLoadException("Unsupported or corrupt file.");
55                 }
56                 
57                 // Detect the appropriate loader
58                 
59                 // Check for GZIP
60                 if (buffer[0] == GZIP_SIGNATURE[0] && buffer[1] == GZIP_SIGNATURE[1]) {
61                         OpenRocketDocument doc = loadFromStream(new GZIPInputStream(source), motorFinder);
62                         doc.getDefaultStorageOptions().setCompressionEnabled(true);
63                         return doc;
64                 }
65                 
66                 // Check for ZIP (for future compatibility)
67                 if (buffer[0] == ZIP_SIGNATURE[0] && buffer[1] == ZIP_SIGNATURE[1]) {
68                         // Search for entry with name *.ork
69                         ZipInputStream in = new ZipInputStream(source);
70                         while (true) {
71                                 ZipEntry entry = in.getNextEntry();
72                                 if (entry == null) {
73                                         throw new RocketLoadException("Unsupported or corrupt file.");
74                                 }
75                                 if (entry.getName().matches(".*\\.[oO][rR][kK]$")) {
76                                         OpenRocketDocument doc = loadFromStream(in, motorFinder);
77                                         doc.getDefaultStorageOptions().setCompressionEnabled(true);
78                                         return doc;
79                                 }
80                         }
81                 }
82                 
83                 // Check for OpenRocket
84                 int match = 0;
85                 for (int i = 0; i < count; i++) {
86                         if (buffer[i] == OPENROCKET_SIGNATURE[match]) {
87                                 match++;
88                                 if (match == OPENROCKET_SIGNATURE.length) {
89                                         return loadUsing(source, openRocketLoader, motorFinder);
90                                 }
91                         } else {
92                                 match = 0;
93                         }
94                 }
95                 
96                 byte[] typeIdentifier = Arrays.copyOf(buffer, ROCKSIM_SIGNATURE.length);
97                 if (Arrays.equals(ROCKSIM_SIGNATURE, typeIdentifier)) {
98                         return loadUsing(source, rocksimLoader, motorFinder);
99                 }
100                 throw new RocketLoadException("Unsupported or corrupt file.");
101         }
102         
103         private OpenRocketDocument loadUsing(InputStream source, RocketLoader loader, MotorFinder motorFinder)
104                         throws RocketLoadException {
105                 warnings.clear();
106                 OpenRocketDocument doc = loader.load(source, motorFinder);
107                 warnings.addAll(loader.getWarnings());
108                 return doc;
109         }
110 }