3 * $Date: 2006-03-18 15:59:33 -0600 (Sat, 18 Mar 2006) $
\r
6 * Copyright (C) 2003-2005 Miguel, Jmol Development, www.jmol.org
\r
8 * Contact: hansonr@stolaf.edu
\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
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
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
24 package javajs.util;
\r
27 import java.io.BufferedInputStream;
\r
28 import java.io.DataInputStream;
\r
29 import java.util.Map;
\r
32 import javajs.api.GenericBinaryDocument;
\r
33 import javajs.api.GenericZipTools;
\r
36 //import java.io.RandomAccessFile;
\r
38 /* a basic binary file reader (extended by CompoundDocument).
\r
40 * random access file info:
\r
41 * http://java.sun.com/docs/books/tutorial/essential/io/rafs.html
\r
43 * SHOOT! random access is only for applications, not applets!
\r
45 * Note that YOU are responsible for determining whether a file
\r
46 * is bigEndian or littleEndian; the default is bigEndian.
\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
54 public class BinaryDocument extends BC implements GenericBinaryDocument {
\r
59 public BinaryDocument() {
\r
63 // called by reflection
\r
65 protected DataInputStream stream;
\r
66 protected boolean isRandom = false;
\r
67 public boolean isBigEndian = true;
\r
68 protected GenericZipTools jzt;
\r
71 public void close() {
\r
75 } catch (Exception e) {
\r
83 public void setStream(GenericZipTools jzt, BufferedInputStream bis, boolean isBigEndian) {
\r
87 stream = new DataInputStream(bis);
\r
88 this.isBigEndian = isBigEndian;
\r
92 public void setStreamData(DataInputStream stream, boolean isBigEndian) {
\r
94 this.stream = stream;
\r
95 this.isBigEndian = isBigEndian;
\r
98 public void setRandom(boolean TF) {
\r
100 //CANNOT be random for web
\r
104 public byte readByte() throws Exception {
\r
106 return ioReadByte();
\r
109 private byte ioReadByte() throws Exception {
\r
110 byte b = stream.readByte();
\r
112 out.writeByteAsInt(b);
\r
117 public int readByteArray(byte[] b, int off, int len) throws Exception {
\r
118 int n = ioRead(b, off, len);
\r
123 private int ioRead(byte[] b, int off, int len) throws Exception {
\r
126 int n = stream.read(b, off, len);
\r
128 if (n > 0 && out != null)
\r
129 writeBytes(b, off, n);
\r
138 public void writeBytes(byte[] b, int off, int n) throws Exception {
\r
139 out.write(b, off, n);
\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
150 public short readShort() throws Exception {
\r
152 short n = (isBigEndian ? ioReadShort()
\r
153 : (short) ((ioReadByte() & 0xff)
\r
154 | (ioReadByte() & 0xff) << 8));
\r
158 * return (n > 0x7FFF ? n - 0x10000 : n);
\r
165 private short ioReadShort() throws Exception {
\r
166 short b = stream.readShort();
\r
173 public void writeShort(short i) throws Exception {
\r
174 out.writeByteAsInt(i >> 8);
\r
175 out.writeByteAsInt(i);
\r
179 public int readIntLE() throws Exception {
\r
181 return readLEInt();
\r
185 public int readInt() throws Exception {
\r
187 return (isBigEndian ? ioReadInt() : readLEInt());
\r
190 private int ioReadInt() throws Exception {
\r
191 int i = stream.readInt();
\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
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
213 public short swapBytesS(short n) {
\r
214 return (short) ((((n >> 8) & 0xff)
\r
215 | (n & 0xff) << 8));
\r
220 public int readUnsignedShort() throws Exception {
\r
222 int a = (ioReadByte() & 0xff);
\r
223 int b = (ioReadByte() & 0xff);
\r
224 return (isBigEndian ? (a << 8) + b : (b << 8) + a);
\r
228 public long readLong() throws Exception {
\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
241 private long ioReadLong() throws Exception {
\r
242 long b = stream.readLong();
\r
248 public void writeLong(long b) throws Exception {
\r
249 writeInt((int)((b >> 32) & 0xFFFFFFFFl));
\r
250 writeInt((int)(b & 0xFFFFFFFFl));
\r
253 private int readLEInt() throws Exception {
\r
255 return bytesToInt(t8, 0, false);
\r
258 byte[] t8 = new byte[8];
\r
261 public float readFloat() throws Exception {
\r
262 return intToFloat(readInt());
\r
266 public double readDouble() throws Exception {
\r
269 * reading the float equivalent here in JavaScript
\r
273 * this.readByteArray(this.t8, 0, 8);
\r
274 * return this.bytesToDoubleToFloat(this.t8, 0, this.isBigEndian);
\r
279 return (isBigEndian ? ioReadDouble() : Double.longBitsToDouble(readLELong()));
\r
283 private double ioReadDouble() throws Exception {
\r
284 double d = stream.readDouble();
\r
286 writeLong(Double.doubleToRawLongBits(d));
\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
302 public void seek(long offset) {
\r
303 // slower, but all that is available using the applet
\r
305 if (offset == nBytes)
\r
307 if (offset < nBytes) {
\r
309 if (out != null && nBytes != 0)
\r
316 stream.skipBytes((int)offset);
\r
318 readByteArray(new byte[(int)offset], 0, (int) offset);
\r
321 } catch (Exception e) {
\r
322 System.out.println(e.toString());
\r
329 public long getPosition() {
\r
335 public void setOutputChannel(OC out) {
\r
340 public SB getAllDataFiles(String binaryFileList, String firstFile) {
\r
345 public void getAllDataMapped(String replace, String string,
\r
346 Map<String, String> fileData) {
\r
350 /* random access -- application only:
\r
352 void seekFile(long offset) {
\r
355 } catch (Exception e) {
\r
356 System.out.println(e.getMessage());
\r