JAL-1807 Bob's JalviewJS prototype first commit
[jalviewjs.git] / src / javajs / util / BinaryDocument.java
1 /* $RCSfile$\r
2  * $Author: egonw $\r
3  * $Date: 2006-03-18 15:59:33 -0600 (Sat, 18 Mar 2006) $\r
4  * $Revision: 4652 $\r
5  *\r
6  * Copyright (C) 2003-2005  Miguel, Jmol Development, www.jmol.org\r
7  *\r
8  * Contact: hansonr@stolaf.edu\r
9  *\r
10  *  This library is free software; you can redistribute it and/or\r
11  *  modify it under the terms of the GNU Lesser General Public\r
12  *  License as published by the Free Software Foundation; either\r
13  *  version 2.1 of the License, or (at your option) any later version.\r
14  *\r
15  *  This library is distributed in the hope that it will be useful,\r
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
18  *  Lesser General Public License for more details.\r
19  *\r
20  *  You should have received a copy of the GNU Lesser General Public\r
21  *  License along with this library; if not, write to the Free Software\r
22  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\r
23  */\r
24 package javajs.util;\r
25 \r
26 \r
27 import java.io.BufferedInputStream;\r
28 import java.io.DataInputStream;\r
29 import java.util.Map;\r
30 \r
31 \r
32 import javajs.api.GenericBinaryDocument;\r
33 import javajs.api.GenericZipTools;\r
34 \r
35 \r
36 //import java.io.RandomAccessFile;\r
37 \r
38 /* a basic binary file reader (extended by CompoundDocument). \r
39  * \r
40  * random access file info: \r
41  * http://java.sun.com/docs/books/tutorial/essential/io/rafs.html\r
42  * \r
43  * SHOOT! random access is only for applications, not applets!\r
44  * \r
45  * Note that YOU are responsible for determining whether a file\r
46  * is bigEndian or littleEndian; the default is bigEndian.\r
47  * \r
48  * JavaScript note: readShort() malfunctioned because (short) (xx << 8) \r
49  * isn't the same as (int) (xx << 8); same problem in java.io.DataStream\r
50  * \r
51  * \r
52  */\r
53 \r
54 public class BinaryDocument extends BC implements GenericBinaryDocument {\r
55 \r
56   /**\r
57    * @j2sIgnore\r
58    */\r
59   public BinaryDocument() {  \r
60   }\r
61 \r
62 \r
63   // called by reflection\r
64   \r
65   protected DataInputStream stream;\r
66   protected boolean isRandom = false;\r
67   public boolean isBigEndian = true;\r
68   protected GenericZipTools jzt;\r
69 \r
70   @Override\r
71   public void close() {\r
72     if (stream != null)\r
73       try {\r
74         stream.close();\r
75       } catch (Exception e) {\r
76         // ignore\r
77       }\r
78     if (out != null)\r
79        out.closeChannel();\r
80   }\r
81   \r
82   @Override\r
83   public void setStream(GenericZipTools jzt, BufferedInputStream bis, boolean isBigEndian) {\r
84     if (jzt != null)\r
85       this.jzt = jzt;\r
86     if (bis != null)\r
87       stream = new DataInputStream(bis);\r
88     this.isBigEndian = isBigEndian;\r
89   }\r
90   \r
91   @Override\r
92   public void setStreamData(DataInputStream stream, boolean isBigEndian) {\r
93     if (stream != null)\r
94       this.stream = stream;\r
95     this.isBigEndian = isBigEndian;\r
96   }\r
97   \r
98   public void setRandom(boolean TF) {\r
99     isRandom = TF;\r
100     //CANNOT be random for web \r
101   }\r
102   \r
103   @Override\r
104   public byte readByte() throws Exception {\r
105     nBytes++;\r
106     return ioReadByte();\r
107   }\r
108 \r
109   private byte ioReadByte() throws Exception {\r
110     byte b = stream.readByte();\r
111     if (out != null)\r
112       out.writeByteAsInt(b);\r
113     return b;\r
114   }\r
115 \r
116   @Override\r
117   public int readByteArray(byte[] b, int off, int len) throws Exception {\r
118     int n = ioRead(b, off, len);\r
119     nBytes += n;\r
120     return n;\r
121   }\r
122 \r
123   private int ioRead(byte[] b, int off, int len) throws Exception {\r
124     int m = 0;\r
125     while (len > 0) {\r
126       int n = stream.read(b, off, len);\r
127       m += n;\r
128       if (n > 0 && out != null)\r
129         writeBytes(b, off, n);\r
130       if (n >= len)\r
131         break;\r
132       off += n;\r
133       len -= n;\r
134     }\r
135     return m;\r
136   }\r
137 \r
138   public void writeBytes(byte[] b, int off, int n) throws Exception {\r
139     out.write(b, off, n);\r
140   }\r
141 \r
142   @Override\r
143   public String readString(int nChar) throws Exception {\r
144     byte[] temp = new byte[nChar];\r
145     int n = readByteArray(temp, 0, nChar);\r
146     return new String(temp, 0, n, "UTF-8");\r
147   }\r
148   \r
149   @Override\r
150   public short readShort() throws Exception {\r
151     nBytes += 2;\r
152     short n = (isBigEndian ? ioReadShort()\r
153         : (short) ((ioReadByte() & 0xff) \r
154                  | (ioReadByte() & 0xff) << 8));\r
155     /**\r
156      * @j2sNative\r
157      *\r
158      * return (n > 0x7FFF ? n - 0x10000 : n);\r
159      */\r
160     {\r
161       return n;\r
162     }\r
163   }\r
164 \r
165   private short ioReadShort() throws Exception {\r
166     short b = stream.readShort();\r
167     if (out != null)\r
168       writeShort(b);\r
169     return b;\r
170   }\r
171 \r
172 \r
173   public void writeShort(short i) throws Exception {\r
174     out.writeByteAsInt(i >> 8);\r
175     out.writeByteAsInt(i);\r
176   }\r
177 \r
178   @Override\r
179   public int readIntLE() throws Exception {\r
180     nBytes += 4;\r
181     return readLEInt();\r
182   }\r
183   \r
184   @Override\r
185   public int readInt() throws Exception {\r
186     nBytes += 4;\r
187     return (isBigEndian ? ioReadInt() : readLEInt());\r
188   }\r
189   \r
190   private int ioReadInt() throws Exception {\r
191     int i = stream.readInt();\r
192     if (out != null)\r
193       writeInt(i);\r
194     return i;\r
195   }\r
196 \r
197   public void writeInt(int i) throws Exception {\r
198     out.writeByteAsInt(i >> 24);\r
199     out.writeByteAsInt(i >> 16);\r
200     out.writeByteAsInt(i >> 8);\r
201     out.writeByteAsInt(i);\r
202   }\r
203 \r
204   @Override\r
205   public int swapBytesI(int n) {\r
206     return (((n >> 24) & 0xff)\r
207         | ((n >> 16) & 0xff) << 8\r
208         | ((n >> 8) & 0xff) << 16 \r
209         | (n & 0xff) << 24);\r
210   }\r
211 \r
212   @Override\r
213   public short swapBytesS(short n) {\r
214     return (short) ((((n >> 8) & 0xff)\r
215         | (n & 0xff) << 8));\r
216   }\r
217 \r
218   \r
219   @Override\r
220   public int readUnsignedShort() throws Exception {\r
221     nBytes += 2;\r
222     int a = (ioReadByte() & 0xff);\r
223     int b = (ioReadByte() & 0xff);\r
224     return (isBigEndian ? (a << 8) + b : (b << 8) + a);\r
225   }\r
226   \r
227   @Override\r
228   public long readLong() throws Exception {\r
229     nBytes += 8;\r
230     return (isBigEndian ? ioReadLong()\r
231        : ((((long) ioReadByte()) & 0xff)\r
232         | (((long) ioReadByte()) & 0xff) << 8\r
233         | (((long) ioReadByte()) & 0xff) << 16\r
234         | (((long) ioReadByte()) & 0xff) << 24\r
235         | (((long) ioReadByte()) & 0xff) << 32\r
236         | (((long) ioReadByte()) & 0xff) << 40\r
237         | (((long) ioReadByte()) & 0xff) << 48 \r
238         | (((long) ioReadByte()) & 0xff) << 54));\r
239   }\r
240 \r
241   private long ioReadLong() throws Exception {\r
242     long b = stream.readLong();\r
243     if (out != null)\r
244       writeLong(b);\r
245     return b;\r
246   }\r
247 \r
248   public void writeLong(long b) throws Exception {\r
249     writeInt((int)((b >> 32) & 0xFFFFFFFFl));\r
250     writeInt((int)(b & 0xFFFFFFFFl));\r
251   }\r
252 \r
253   private int readLEInt() throws Exception {\r
254     ioRead(t8, 0, 4);\r
255     return bytesToInt(t8, 0, false);\r
256   }\r
257 \r
258   byte[] t8 = new byte[8];\r
259   \r
260   @Override\r
261   public float readFloat() throws Exception {\r
262     return intToFloat(readInt());\r
263   }\r
264 \r
265   @Override\r
266   public double readDouble() throws Exception {\r
267     /**\r
268      * \r
269      * reading the float equivalent here in JavaScript\r
270      * \r
271      * @j2sNative\r
272      * \r
273      * this.readByteArray(this.t8, 0, 8);\r
274      * return this.bytesToDoubleToFloat(this.t8, 0, this.isBigEndian);\r
275      *  \r
276      */\r
277     {\r
278       nBytes += 8;\r
279       return (isBigEndian ? ioReadDouble() : Double.longBitsToDouble(readLELong()));  \r
280     }\r
281   }\r
282   \r
283   private double ioReadDouble() throws Exception {\r
284     double d = stream.readDouble();\r
285     if (out != null)\r
286       writeLong(Double.doubleToRawLongBits(d));\r
287     return d;\r
288   }\r
289 \r
290   private long readLELong() throws Exception {\r
291     return ((((long) ioReadByte()) & 0xff)\r
292           | (((long) ioReadByte()) & 0xff) << 8\r
293           | (((long) ioReadByte()) & 0xff) << 16 \r
294           | (((long) ioReadByte()) & 0xff) << 24\r
295           | (((long) ioReadByte()) & 0xff) << 32\r
296           | (((long) ioReadByte()) & 0xff) << 40\r
297           | (((long) ioReadByte()) & 0xff) << 48\r
298           | (((long) ioReadByte()) & 0xff) << 56);\r
299   }\r
300 \r
301   @Override\r
302   public void seek(long offset) {\r
303     // slower, but all that is available using the applet\r
304     try {\r
305       if (offset == nBytes)\r
306         return;\r
307       if (offset < nBytes) {\r
308         stream.reset();\r
309         if (out != null && nBytes != 0)\r
310           out.reset();\r
311         nBytes = 0;\r
312       } else {\r
313         offset -= nBytes;\r
314       }\r
315       if (out == null) {\r
316         stream.skipBytes((int)offset);\r
317       } else {\r
318         readByteArray(new byte[(int)offset], 0, (int) offset);\r
319       }\r
320       nBytes += offset;\r
321     } catch (Exception e) {\r
322       System.out.println(e.toString());\r
323     }\r
324   }\r
325 \r
326   long nBytes;\r
327   \r
328   @Override\r
329   public long getPosition() {\r
330     return nBytes;\r
331   }\r
332 \r
333   OC out;\r
334   @Override\r
335   public void setOutputChannel(OC out) {\r
336       this.out = out;\r
337   }\r
338 \r
339   @Override\r
340   public SB getAllDataFiles(String binaryFileList, String firstFile) {\r
341     return null;\r
342   }\r
343 \r
344   @Override\r
345   public void getAllDataMapped(String replace, String string,\r
346                                Map<String, String> fileData) {\r
347   }\r
348 \r
349 \r
350 /*  random access -- application only:\r
351  * \r
352     void seekFile(long offset) {\r
353     try {\r
354       file.seek(offset);\r
355     } catch (Exception e) {\r
356       System.out.println(e.getMessage());\r
357     }\r
358   }\r
359 */\r
360 }\r