updates for 0.9.3
[debian/openrocket] / 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.zip.GZIPInputStream;
8
9 import net.sf.openrocket.document.OpenRocketDocument;
10
11
12 /**
13  * A rocket loader that auto-detects the document type and uses the appropriate
14  * loading.  Supports loading of GZIPed files as well with transparent
15  * uncompression.
16  * 
17  * @author Sampo Niskanen <sampo.niskanen@iki.fi>
18  */
19 public class GeneralRocketLoader extends RocketLoader {
20
21         private static final int READ_BYTES = 300;
22         
23         private static final byte[] GZIP_SIGNATURE = { 31, -117 };  // 0x1f, 0x8b
24         private static final byte[] OPENROCKET_SIGNATURE = 
25                 "<openrocket".getBytes(Charset.forName("US-ASCII"));
26         
27         private final OpenRocketLoader openRocketLoader = new OpenRocketLoader();
28         
29         @Override
30         protected OpenRocketDocument loadFromStream(InputStream source) throws IOException,
31                         RocketLoadException {
32
33                 // Check for mark() support
34                 if (!source.markSupported()) {
35                         source = new BufferedInputStream(source);
36                 }
37                 
38                 // Read using mark()
39                 byte[] buffer = new byte[READ_BYTES];
40                 int count;
41                 source.mark(READ_BYTES + 10);
42                 count = source.read(buffer);
43                 source.reset();
44                 
45                 if (count < 10) {
46                         throw new RocketLoadException("Unsupported or corrupt file.");
47                 }
48                 
49                 // Detect the appropriate loader
50
51                 // Check for GZIP
52                 if (buffer[0] == GZIP_SIGNATURE[0]  &&  buffer[1] == GZIP_SIGNATURE[1]) {
53                         OpenRocketDocument doc = loadFromStream(new GZIPInputStream(source));
54                         doc.getDefaultStorageOptions().setCompressionEnabled(true);
55                         return doc;
56                 }
57                 
58                 // Check for OpenRocket
59                 int match = 0;
60                 for (int i=0; i < count; i++) {
61                         if (buffer[i] == OPENROCKET_SIGNATURE[match]) {
62                                 match++;
63                                 if (match == OPENROCKET_SIGNATURE.length) {
64                                         return loadUsing(source, openRocketLoader);
65                                 }
66                         } else {
67                                 match = 0;
68                         }
69                 }
70                 
71                 throw new RocketLoadException("Unsupported or corrupt file.");
72         }
73         
74         private OpenRocketDocument loadUsing(InputStream source, RocketLoader loader) 
75         throws RocketLoadException {
76                 warnings.clear();
77                 OpenRocketDocument doc = loader.load(source);
78                 warnings.addAll(loader.getWarnings());
79                 return doc;
80         }
81 }