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