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