001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: /* $Id: SeekableStream.java 496556 2007-01-16 00:59:48Z cam $ */
019:
020: package org.apache.xmlgraphics.image.codec.util;
021:
022: import java.io.DataInput;
023: import java.io.DataInputStream;
024: import java.io.EOFException;
025: import java.io.IOException;
026: import java.io.InputStream;
027:
028: /**
029: * An abstract subclass of <code>java.io.InputStream</code> that allows seeking
030: * within the input, similar to the <code>RandomAccessFile</code> class.
031: * Additionally, the <code>DataInput</code> interface is supported and extended
032: * to include support for little-endian representations of fundamental data
033: * types.
034: *
035: * <p> In addition to the familiar methods from <code>InputStream</code>, the
036: * methods <code>getFilePointer()</code>, <code>seek()</code>, are defined as in
037: * the <code>RandomAccessFile</code> class. The <code>canSeekBackwards()</code>
038: * method will return <code>true</code> if it is permissible to seek to a
039: * position earlier in the stream than the current value of
040: * <code>getFilePointer()</code>. Some subclasses of
041: * <code>SeekableStream</code> guarantee the ability to seek backwards while
042: * others may not offer this feature in the interest of providing greater
043: * efficiency for those users who do not require it.
044: *
045: * <p> The <code>DataInput</code> interface is supported as well. This included
046: * the <code>skipBytes()</code> and <code>readFully()</code> methods and a
047: * variety of <code>read</code> methods for various data types.
048: *
049: * <p> A number of concrete subclasses of <code>SeekableStream</code> are
050: * supplied in the <code>com.sun.media.jai.codec</code> package.
051: *
052: * <p> Three classes are provided for the purpose of adapting a standard
053: * <code>InputStream</code> to the <code>SeekableStream</code> interface.
054: * <code>ForwardSeekableStream</code> does not allows seeking backwards, but is
055: * inexpensive to use. <code>FileCacheSeekableStream</code> maintains a copy of
056: * all of the data read from the input in a temporary file; this file will be
057: * discarded automatically when the <code>FileSeekableStream</code> is
058: * finalized, or when the JVM exits normally.
059: * <code>FileCacheSeekableStream</code> is intended to be reasonably efficient
060: * apart from the unavoidable use of disk space. In circumstances where the
061: * creation of a temporary file is not possible,
062: * <code>MemoryCacheSeekableStream</code> may be used.
063: * <code>MemoryCacheSeekableStream</code> creates a potentially large in-memory
064: * buffer to store the stream data and so should be avoided when possible.
065: *
066: * <p> The <code>FileSeekableStream</code> class wraps a <code>File</code> or
067: * <code>RandomAccessFile</code>. It forwards requests to the real underlying
068: * file. It performs a limited amount of caching in order to avoid excessive
069: * I/O costs.
070: *
071: * <p> The <code>SegmentedSeekableStream</code> class performs a different sort
072: * of function. It creates a <code>SeekableStream</code> from another
073: * <code>SeekableStream</code> by selecting a series of portions or "segments".
074: * Each segment starts at a specified location within the source
075: * <code>SeekableStream</code> and extends for a specified number of bytes. The
076: * <code>StreamSegmentMapper</code> interface and <code>StreamSegment</code>
077: * class may be used to compute the segment positions dynamically.
078: *
079: * <p> A convenience methods, <code>wrapInputStream</code> is provided to
080: * construct a suitable <code>SeekableStream</code> instance whose data is
081: * supplied by a given <code>InputStream</code>. The caller, by means of the
082: * <code>canSeekBackwards</code> parameter, determines whether support for
083: * seeking backwards is required.
084: *
085: */
086: public abstract class SeekableStream extends InputStream implements
087: DataInput {
088:
089: /**
090: * Returns a <code>SeekableStream</code> that will read from a
091: * given <code>InputStream</code>, optionally including support
092: * for seeking backwards. This is a convenience method that
093: * avoids the need to instantiate specific subclasses of
094: * <code>SeekableStream</code> depending on the current security
095: * model.
096: *
097: * @param is An <code>InputStream</code>.
098: * @param canSeekBackwards <code>true</code> if the ability to seek
099: * backwards in the output is required.
100: * @return An instance of <code>SeekableStream</code>.
101: */
102: public static SeekableStream wrapInputStream(InputStream is,
103: boolean canSeekBackwards) {
104: SeekableStream stream = null;
105:
106: if (canSeekBackwards) {
107: try {
108: stream = new FileCacheSeekableStream(is);
109: } catch (Exception e) {
110: stream = new MemoryCacheSeekableStream(is);
111: }
112: } else {
113: stream = new ForwardSeekableStream(is);
114: }
115: return stream;
116: }
117:
118: // Methods from InputStream
119:
120: /**
121: * Reads the next byte of data from the input stream. The value byte is
122: * returned as an <code>int</code> in the range <code>0</code> to
123: * <code>255</code>. If no byte is available because the end of the stream
124: * has been reached, the value <code>-1</code> is returned. This method
125: * blocks until input data is available, the end of the stream is detected,
126: * or an exception is thrown.
127: *
128: * <p> A subclass must provide an implementation of this method.
129: *
130: * @return the next byte of data, or <code>-1</code> if the end of the
131: * stream is reached.
132: * @exception IOException if an I/O error occurs.
133: */
134: public abstract int read() throws IOException;
135:
136: /**
137: * Reads up to <code>len</code> bytes of data from the input stream into
138: * an array of bytes. An attempt is made to read as many as
139: * <code>len</code> bytes, but a smaller number may be read, possibly
140: * zero. The number of bytes actually read is returned as an integer.
141: *
142: * <p> This method blocks until input data is available, end of stream is
143: * detected, or an exception is thrown.
144: *
145: * <p> If <code>b</code> is <code>null</code>, a
146: * <code>NullPointerException</code> is thrown.
147: *
148: * <p> If <code>off</code> is negative, or <code>len</code> is negative, or
149: * <code>off+len</code> is greater than the length of the array
150: * <code>b</code>, then an <code>IndexOutOfBoundsException</code> is
151: * thrown.
152: *
153: * <p> If <code>len</code> is zero, then no bytes are read and
154: * <code>0</code> is returned; otherwise, there is an attempt to read at
155: * least one byte. If no byte is available because the stream is at end of
156: * stream, the value <code>-1</code> is returned; otherwise, at least one
157: * byte is read and stored into <code>b</code>.
158: *
159: * <p> The first byte read is stored into element <code>b[off]</code>, the
160: * next one into <code>b[off+1]</code>, and so on. The number of bytes read
161: * is, at most, equal to <code>len</code>. Let <i>k</i> be the number of
162: * bytes actually read; these bytes will be stored in elements
163: * <code>b[off]</code> through <code>b[off+</code><i>k</i><code>-1]</code>,
164: * leaving elements <code>b[off+</code><i>k</i><code>]</code> through
165: * <code>b[off+len-1]</code> unaffected.
166: *
167: * <p> In every case, elements <code>b[0]</code> through
168: * <code>b[off]</code> and elements <code>b[off+len]</code> through
169: * <code>b[b.length-1]</code> are unaffected.
170: *
171: * <p> If the first byte cannot be read for any reason other than end of
172: * stream, then an <code>IOException</code> is thrown. In particular, an
173: * <code>IOException</code> is thrown if the input stream has been closed.
174: *
175: * <p> A subclass must provide an implementation of this method.
176: *
177: * @param b the buffer into which the data is read.
178: * @param off the start offset in array <code>b</code>
179: * at which the data is written.
180: * @param len the maximum number of bytes to read.
181: * @return the total number of bytes read into the buffer, or
182: * <code>-1</code> if there is no more data because the end of
183: * the stream has been reached.
184: * @exception IOException if an I/O error occurs.
185: */
186: public abstract int read(byte[] b, int off, int len)
187: throws IOException;
188:
189: // Implemented in InputStream:
190: //
191: // public int read(byte[] b) throws IOException {
192: // public long skip(long n) throws IOException
193: // public int available) throws IOException
194: // public void close() throws IOException;
195:
196: /** Marked position */
197: protected long markPos = -1L;
198:
199: /**
200: * Marks the current file position for later return using
201: * the <code>reset()</code> method.
202: */
203: public synchronized void mark(int readLimit) {
204: try {
205: markPos = getFilePointer();
206: } catch (IOException e) {
207: markPos = -1L;
208: }
209: }
210:
211: /**
212: * Returns the file position to its position at the time of
213: * the immediately previous call to the <code>mark()</code>
214: * method.
215: */
216: public synchronized void reset() throws IOException {
217: if (markPos != -1) {
218: seek(markPos);
219: }
220: }
221:
222: /**
223: * Returns <code>true</code> if marking is supported.
224: * Marking is automatically supported for <code>SeekableStream</code>
225: * subclasses that support seeking backeards. Subclasses that do
226: * not support seeking backwards but do support marking must override
227: * this method.
228: */
229: public boolean markSupported() {
230: return canSeekBackwards();
231: }
232:
233: /**
234: * Returns <code>true</code> if this object supports calls to
235: * <code>seek(pos)</code> with an offset <code>pos</code> smaller
236: * than the current offset, as returned by <code>getFilePointer</code>.
237: */
238: public boolean canSeekBackwards() {
239: return false;
240: }
241:
242: /**
243: * Returns the current offset in this stream.
244: *
245: * @return the offset from the beginning of the stream, in bytes,
246: * at which the next read occurs.
247: * @exception IOException if an I/O error occurs.
248: */
249: public abstract long getFilePointer() throws IOException;
250:
251: /**
252: * Sets the offset, measured from the beginning of this
253: * stream, at which the next read occurs.
254: *
255: * <p> If <code>canSeekBackwards()</code> returns <code>false</code>,
256: * then setting <code>pos</code> to an offset smaller than
257: * the current value of <code>getFilePointer()</code> will have
258: * no effect.
259: *
260: * @param pos the offset position, measured in bytes from the
261: * beginning of the stream, at which to set the stream
262: * pointer.
263: * @exception IOException if <code>pos</code> is less than
264: * <code>0</code> or if an I/O error occurs.
265: */
266: public abstract void seek(long pos) throws IOException;
267:
268: // Methods from RandomAccessFile
269:
270: /**
271: * Reads <code>b.length</code> bytes from this stream into the byte
272: * array, starting at the current stream pointer. This method reads
273: * repeatedly from the stream until the requested number of bytes are
274: * read. This method blocks until the requested number of bytes are
275: * read, the end of the stream is detected, or an exception is thrown.
276: *
277: * @param b the buffer into which the data is read.
278: * @exception EOFException if this stream reaches the end before reading
279: * all the bytes.
280: * @exception IOException if an I/O error occurs.
281: */
282: public final void readFully(byte[] b) throws IOException {
283: readFully(b, 0, b.length);
284: }
285:
286: /**
287: * Reads exactly <code>len</code> bytes from this stream into the byte
288: * array, starting at the current stream pointer. This method reads
289: * repeatedly from the stream until the requested number of bytes are
290: * read. This method blocks until the requested number of bytes are
291: * read, the end of the stream is detected, or an exception is thrown.
292: *
293: * @param b the buffer into which the data is read.
294: * @param off the start offset of the data.
295: * @param len the number of bytes to read.
296: * @exception EOFException if this stream reaches the end before reading
297: * all the bytes.
298: * @exception IOException if an I/O error occurs.
299: */
300: public final void readFully(byte[] b, int off, int len)
301: throws IOException {
302: int n = 0;
303: do {
304: int count = this .read(b, off + n, len - n);
305: if (count < 0)
306: throw new EOFException();
307: n += count;
308: } while (n < len);
309: }
310:
311: // Methods from DataInput, plus little-endian versions
312:
313: /**
314: * Attempts to skip over <code>n</code> bytes of input discarding the
315: * skipped bytes.
316: * <p>
317: *
318: * This method may skip over some smaller number of bytes, possibly zero.
319: * This may result from any of a number of conditions; reaching end of
320: * stream before <code>n</code> bytes have been skipped is only one
321: * possibility. This method never throws an <code>EOFException</code>.
322: * The actual number of bytes skipped is returned. If <code>n</code>
323: * is negative, no bytes are skipped.
324: *
325: * @param n the number of bytes to be skipped.
326: * @return the actual number of bytes skipped.
327: * @exception IOException if an I/O error occurs.
328: */
329: public int skipBytes(int n) throws IOException {
330: if (n <= 0) {
331: return 0;
332: }
333: return (int) skip(n);
334: }
335:
336: /**
337: * Reads a <code>boolean</code> from this stream. This method reads a
338: * single byte from the stream, starting at the current stream pointer.
339: * A value of <code>0</code> represents
340: * <code>false</code>. Any other value represents <code>true</code>.
341: * This method blocks until the byte is read, the end of the stream
342: * is detected, or an exception is thrown.
343: *
344: * @return the <code>boolean</code> value read.
345: * @exception EOFException if this stream has reached the end.
346: * @exception IOException if an I/O error occurs.
347: */
348: public final boolean readBoolean() throws IOException {
349: int ch = this .read();
350: if (ch < 0)
351: throw new EOFException();
352: return (ch != 0);
353: }
354:
355: /**
356: * Reads a signed eight-bit value from this stream. This method reads a
357: * byte from the stream, starting from the current stream pointer.
358: * If the byte read is <code>b</code>, where
359: * <code>0 <= b <= 255</code>,
360: * then the result is:
361: * <blockquote><pre>
362: * (byte)(b)
363: * </pre></blockquote>
364: * <p>
365: * This method blocks until the byte is read, the end of the stream
366: * is detected, or an exception is thrown.
367: *
368: * @return the next byte of this stream as a signed eight-bit
369: * <code>byte</code>.
370: * @exception EOFException if this stream has reached the end.
371: * @exception IOException if an I/O error occurs.
372: */
373: public final byte readByte() throws IOException {
374: int ch = this .read();
375: if (ch < 0)
376: throw new EOFException();
377: return (byte) (ch);
378: }
379:
380: /**
381: * Reads an unsigned eight-bit number from this stream. This method reads
382: * a byte from this stream, starting at the current stream pointer,
383: * and returns that byte.
384: * <p>
385: * This method blocks until the byte is read, the end of the stream
386: * is detected, or an exception is thrown.
387: *
388: * @return the next byte of this stream, interpreted as an unsigned
389: * eight-bit number.
390: * @exception EOFException if this stream has reached the end.
391: * @exception IOException if an I/O error occurs.
392: */
393: public final int readUnsignedByte() throws IOException {
394: int ch = this .read();
395: if (ch < 0)
396: throw new EOFException();
397: return ch;
398: }
399:
400: /**
401: * Reads a signed 16-bit number from this stream.
402: * The method reads two
403: * bytes from this stream, starting at the current stream pointer.
404: * If the two bytes read, in order, are
405: * <code>b1</code> and <code>b2</code>, where each of the two values is
406: * between <code>0</code> and <code>255</code>, inclusive, then the
407: * result is equal to:
408: * <blockquote><pre>
409: * (short)((b1 << 8) | b2)
410: * </pre></blockquote>
411: * <p>
412: * This method blocks until the two bytes are read, the end of the
413: * stream is detected, or an exception is thrown.
414: *
415: * @return the next two bytes of this stream, interpreted as a signed
416: * 16-bit number.
417: * @exception EOFException if this stream reaches the end before reading
418: * two bytes.
419: * @exception IOException if an I/O error occurs.
420: */
421: public final short readShort() throws IOException {
422: int ch1 = this .read();
423: int ch2 = this .read();
424: if ((ch1 | ch2) < 0)
425: throw new EOFException();
426: return (short) ((ch1 << 8) + (ch2 << 0));
427: }
428:
429: /**
430: * Reads a signed 16-bit number from this stream in little-endian order.
431: * The method reads two
432: * bytes from this stream, starting at the current stream pointer.
433: * If the two bytes read, in order, are
434: * <code>b1</code> and <code>b2</code>, where each of the two values is
435: * between <code>0</code> and <code>255</code>, inclusive, then the
436: * result is equal to:
437: * <blockquote><pre>
438: * (short)((b2 << 8) | b1)
439: * </pre></blockquote>
440: * <p>
441: * This method blocks until the two bytes are read, the end of the
442: * stream is detected, or an exception is thrown.
443: *
444: * @return the next two bytes of this stream, interpreted as a signed
445: * 16-bit number.
446: * @exception EOFException if this stream reaches the end before reading
447: * two bytes.
448: * @exception IOException if an I/O error occurs.
449: */
450: public final short readShortLE() throws IOException {
451: int ch1 = this .read();
452: int ch2 = this .read();
453: if ((ch1 | ch2) < 0)
454: throw new EOFException();
455: return (short) ((ch2 << 8) + (ch1 << 0));
456: }
457:
458: /**
459: * Reads an unsigned 16-bit number from this stream. This method reads
460: * two bytes from the stream, starting at the current stream pointer.
461: * If the bytes read, in order, are
462: * <code>b1</code> and <code>b2</code>, where
463: * <code>0 <= b1, b2 <= 255</code>,
464: * then the result is equal to:
465: * <blockquote><pre>
466: * (b1 << 8) | b2
467: * </pre></blockquote>
468: * <p>
469: * This method blocks until the two bytes are read, the end of the
470: * stream is detected, or an exception is thrown.
471: *
472: * @return the next two bytes of this stream, interpreted as an
473: * unsigned 16-bit integer.
474: * @exception EOFException if this stream reaches the end before reading
475: * two bytes.
476: * @exception IOException if an I/O error occurs.
477: */
478: public final int readUnsignedShort() throws IOException {
479: int ch1 = this .read();
480: int ch2 = this .read();
481: if ((ch1 | ch2) < 0)
482: throw new EOFException();
483: return (ch1 << 8) + (ch2 << 0);
484: }
485:
486: /**
487: * Reads an unsigned 16-bit number from this stream in little-endian order.
488: * This method reads
489: * two bytes from the stream, starting at the current stream pointer.
490: * If the bytes read, in order, are
491: * <code>b1</code> and <code>b2</code>, where
492: * <code>0 <= b1, b2 <= 255</code>,
493: * then the result is equal to:
494: * <blockquote><pre>
495: * (b2 << 8) | b1
496: * </pre></blockquote>
497: * <p>
498: * This method blocks until the two bytes are read, the end of the
499: * stream is detected, or an exception is thrown.
500: *
501: * @return the next two bytes of this stream, interpreted as an
502: * unsigned 16-bit integer.
503: * @exception EOFException if this stream reaches the end before reading
504: * two bytes.
505: * @exception IOException if an I/O error occurs.
506: */
507: public final int readUnsignedShortLE() throws IOException {
508: int ch1 = this .read();
509: int ch2 = this .read();
510: if ((ch1 | ch2) < 0)
511: throw new EOFException();
512: return (ch2 << 8) + (ch1 << 0);
513: }
514:
515: /**
516: * Reads a Unicode character from this stream. This method reads two
517: * bytes from the stream, starting at the current stream pointer.
518: * If the bytes read, in order, are
519: * <code>b1</code> and <code>b2</code>, where
520: * <code>0 <= b1, b2 <= 255</code>,
521: * then the result is equal to:
522: * <blockquote><pre>
523: * (char)((b1 << 8) | b2)
524: * </pre></blockquote>
525: * <p>
526: * This method blocks until the two bytes are read, the end of the
527: * stream is detected, or an exception is thrown.
528: *
529: * @return the next two bytes of this stream as a Unicode character.
530: * @exception EOFException if this stream reaches the end before reading
531: * two bytes.
532: * @exception IOException if an I/O error occurs.
533: */
534: public final char readChar() throws IOException {
535: int ch1 = this .read();
536: int ch2 = this .read();
537: if ((ch1 | ch2) < 0)
538: throw new EOFException();
539: return (char) ((ch1 << 8) + (ch2 << 0));
540: }
541:
542: /**
543: * Reads a Unicode character from this stream in little-endian order.
544: * This method reads two
545: * bytes from the stream, starting at the current stream pointer.
546: * If the bytes read, in order, are
547: * <code>b1</code> and <code>b2</code>, where
548: * <code>0 <= b1, b2 <= 255</code>,
549: * then the result is equal to:
550: * <blockquote><pre>
551: * (char)((b2 << 8) | b1)
552: * </pre></blockquote>
553: * <p>
554: * This method blocks until the two bytes are read, the end of the
555: * stream is detected, or an exception is thrown.
556: *
557: * @return the next two bytes of this stream as a Unicode character.
558: * @exception EOFException if this stream reaches the end before reading
559: * two bytes.
560: * @exception IOException if an I/O error occurs.
561: */
562: public final char readCharLE() throws IOException {
563: int ch1 = this .read();
564: int ch2 = this .read();
565: if ((ch1 | ch2) < 0)
566: throw new EOFException();
567: return (char) ((ch2 << 8) + (ch1 << 0));
568: }
569:
570: /**
571: * Reads a signed 32-bit integer from this stream. This method reads 4
572: * bytes from the stream, starting at the current stream pointer.
573: * If the bytes read, in order, are <code>b1</code>,
574: * <code>b2</code>, <code>b3</code>, and <code>b4</code>, where
575: * <code>0 <= b1, b2, b3, b4 <= 255</code>,
576: * then the result is equal to:
577: * <blockquote><pre>
578: * (b1 << 24) | (b2 << 16) + (b3 << 8) + b4
579: * </pre></blockquote>
580: * <p>
581: * This method blocks until the four bytes are read, the end of the
582: * stream is detected, or an exception is thrown.
583: *
584: * @return the next four bytes of this stream, interpreted as an
585: * <code>int</code>.
586: * @exception EOFException if this stream reaches the end before reading
587: * four bytes.
588: * @exception IOException if an I/O error occurs.
589: */
590: public final int readInt() throws IOException {
591: int ch1 = this .read();
592: int ch2 = this .read();
593: int ch3 = this .read();
594: int ch4 = this .read();
595: if ((ch1 | ch2 | ch3 | ch4) < 0)
596: throw new EOFException();
597: return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
598: }
599:
600: /**
601: * Reads a signed 32-bit integer from this stream in little-endian order.
602: * This method reads 4
603: * bytes from the stream, starting at the current stream pointer.
604: * If the bytes read, in order, are <code>b1</code>,
605: * <code>b2</code>, <code>b3</code>, and <code>b4</code>, where
606: * <code>0 <= b1, b2, b3, b4 <= 255</code>,
607: * then the result is equal to:
608: * <blockquote><pre>
609: * (b4 << 24) | (b3 << 16) + (b2 << 8) + b1
610: * </pre></blockquote>
611: * <p>
612: * This method blocks until the four bytes are read, the end of the
613: * stream is detected, or an exception is thrown.
614: *
615: * @return the next four bytes of this stream, interpreted as an
616: * <code>int</code>.
617: * @exception EOFException if this stream reaches the end before reading
618: * four bytes.
619: * @exception IOException if an I/O error occurs.
620: */
621: public final int readIntLE() throws IOException {
622: int ch1 = this .read();
623: int ch2 = this .read();
624: int ch3 = this .read();
625: int ch4 = this .read();
626: if ((ch1 | ch2 | ch3 | ch4) < 0)
627: throw new EOFException();
628: return ((ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0));
629: }
630:
631: /**
632: * Reads an unsigned 32-bit integer from this stream. This method reads 4
633: * bytes from the stream, starting at the current stream pointer.
634: * If the bytes read, in order, are <code>b1</code>,
635: * <code>b2</code>, <code>b3</code>, and <code>b4</code>, where
636: * <code>0 <= b1, b2, b3, b4 <= 255</code>,
637: * then the result is equal to:
638: * <blockquote><pre>
639: * (b1 << 24) | (b2 << 16) + (b3 << 8) + b4
640: * </pre></blockquote>
641: * <p>
642: * This method blocks until the four bytes are read, the end of the
643: * stream is detected, or an exception is thrown.
644: *
645: * @return the next four bytes of this stream, interpreted as a
646: * <code>long</code>.
647: * @exception EOFException if this stream reaches the end before reading
648: * four bytes.
649: * @exception IOException if an I/O error occurs.
650: */
651: public final long readUnsignedInt() throws IOException {
652: long ch1 = this .read();
653: long ch2 = this .read();
654: long ch3 = this .read();
655: long ch4 = this .read();
656: if ((ch1 | ch2 | ch3 | ch4) < 0)
657: throw new EOFException();
658: return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
659: }
660:
661: private byte[] ruileBuf = new byte[4];
662:
663: /**
664: * Reads an unsigned 32-bit integer from this stream in little-endian
665: * order. This method reads 4
666: * bytes from the stream, starting at the current stream pointer.
667: * If the bytes read, in order, are <code>b1</code>,
668: * <code>b2</code>, <code>b3</code>, and <code>b4</code>, where
669: * <code>0 <= b1, b2, b3, b4 <= 255</code>,
670: * then the result is equal to:
671: * <blockquote><pre>
672: * (b4 << 24) | (b3 << 16) + (b2 << 8) + b1
673: * </pre></blockquote>
674: * <p>
675: * This method blocks until the four bytes are read, the end of the
676: * stream is detected, or an exception is thrown.
677: *
678: * @return the next four bytes of this stream, interpreted as a
679: * <code>long</code>.
680: * @exception EOFException if this stream reaches the end before reading
681: * four bytes.
682: * @exception IOException if an I/O error occurs.
683: */
684: public final long readUnsignedIntLE() throws IOException {
685: this .readFully(ruileBuf);
686: long ch1 = (ruileBuf[0] & 0xff);
687: long ch2 = (ruileBuf[1] & 0xff);
688: long ch3 = (ruileBuf[2] & 0xff);
689: long ch4 = (ruileBuf[3] & 0xff);
690:
691: return ((ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0));
692: }
693:
694: /**
695: * Reads a signed 64-bit integer from this stream. This method reads eight
696: * bytes from the stream, starting at the current stream pointer.
697: * If the bytes read, in order, are
698: * <code>b1</code>, <code>b2</code>, <code>b3</code>,
699: * <code>b4</code>, <code>b5</code>, <code>b6</code>,
700: * <code>b7</code>, and <code>b8,</code> where:
701: * <blockquote><pre>
702: * 0 <= b1, b2, b3, b4, b5, b6, b7, b8 <=255,
703: * </pre></blockquote>
704: * <p>
705: * then the result is equal to:
706: * <p><blockquote><pre>
707: * ((long)b1 << 56) + ((long)b2 << 48)
708: * + ((long)b3 << 40) + ((long)b4 << 32)
709: * + ((long)b5 << 24) + ((long)b6 << 16)
710: * + ((long)b7 << 8) + b8
711: * </pre></blockquote>
712: * <p>
713: * This method blocks until the eight bytes are read, the end of the
714: * stream is detected, or an exception is thrown.
715: *
716: * @return the next eight bytes of this stream, interpreted as a
717: * <code>long</code>.
718: * @exception EOFException if this stream reaches the end before reading
719: * eight bytes.
720: * @exception IOException if an I/O error occurs.
721: */
722: public final long readLong() throws IOException {
723: return ((long) (readInt()) << 32) + (readInt() & 0xFFFFFFFFL);
724: }
725:
726: /**
727: * Reads a signed 64-bit integer from this stream in little-endian
728: * order. This method reads eight
729: * bytes from the stream, starting at the current stream pointer.
730: * If the bytes read, in order, are
731: * <code>b1</code>, <code>b2</code>, <code>b3</code>,
732: * <code>b4</code>, <code>b5</code>, <code>b6</code>,
733: * <code>b7</code>, and <code>b8,</code> where:
734: * <blockquote><pre>
735: * 0 <= b1, b2, b3, b4, b5, b6, b7, b8 <=255,
736: * </pre></blockquote>
737: * <p>
738: * then the result is equal to:
739: * <p><blockquote><pre>
740: * ((long)b1 << 56) + ((long)b2 << 48)
741: * + ((long)b3 << 40) + ((long)b4 << 32)
742: * + ((long)b5 << 24) + ((long)b6 << 16)
743: * + ((long)b7 << 8) + b8
744: * </pre></blockquote>
745: * <p>
746: * This method blocks until the eight bytes are read, the end of the
747: * stream is detected, or an exception is thrown.
748: *
749: * @return the next eight bytes of this stream, interpreted as a
750: * <code>long</code>.
751: * @exception EOFException if this stream reaches the end before reading
752: * eight bytes.
753: * @exception IOException if an I/O error occurs.
754: */
755: public final long readLongLE() throws IOException {
756: int i1 = readIntLE();
757: int i2 = readIntLE();
758: return ((long) i2 << 32) + (i1 & 0xFFFFFFFFL);
759: }
760:
761: /**
762: * Reads a <code>float</code> from this stream. This method reads an
763: * <code>int</code> value, starting at the current stream pointer,
764: * as if by the <code>readInt</code> method
765: * and then converts that <code>int</code> to a <code>float</code>
766: * using the <code>intBitsToFloat</code> method in class
767: * <code>Float</code>.
768: * <p>
769: * This method blocks until the four bytes are read, the end of the
770: * stream is detected, or an exception is thrown.
771: *
772: * @return the next four bytes of this stream, interpreted as a
773: * <code>float</code>.
774: * @exception EOFException if this stream reaches the end before reading
775: * four bytes.
776: * @exception IOException if an I/O error occurs.
777: */
778: public final float readFloat() throws IOException {
779: return Float.intBitsToFloat(readInt());
780: }
781:
782: /**
783: * Reads a <code>float</code> from this stream in little-endian order.
784: * This method reads an
785: * <code>int</code> value, starting at the current stream pointer,
786: * as if by the <code>readInt</code> method
787: * and then converts that <code>int</code> to a <code>float</code>
788: * using the <code>intBitsToFloat</code> method in class
789: * <code>Float</code>.
790: * <p>
791: * This method blocks until the four bytes are read, the end of the
792: * stream is detected, or an exception is thrown.
793: *
794: * @return the next four bytes of this stream, interpreted as a
795: * <code>float</code>.
796: * @exception EOFException if this stream reaches the end before reading
797: * four bytes.
798: * @exception IOException if an I/O error occurs.
799: */
800: public final float readFloatLE() throws IOException {
801: return Float.intBitsToFloat(readIntLE());
802: }
803:
804: /**
805: * Reads a <code>double</code> from this stream. This method reads a
806: * <code>long</code> value, starting at the current stream pointer,
807: * as if by the <code>readLong</code> method
808: * and then converts that <code>long</code> to a <code>double</code>
809: * using the <code>longBitsToDouble</code> method in
810: * class <code>Double</code>.
811: * <p>
812: * This method blocks until the eight bytes are read, the end of the
813: * stream is detected, or an exception is thrown.
814: *
815: * @return the next eight bytes of this stream, interpreted as a
816: * <code>double</code>.
817: * @exception EOFException if this stream reaches the end before reading
818: * eight bytes.
819: * @exception IOException if an I/O error occurs.
820: */
821: public final double readDouble() throws IOException {
822: return Double.longBitsToDouble(readLong());
823: }
824:
825: /**
826: * Reads a <code>double</code> from this stream in little-endian order.
827: * This method reads a
828: * <code>long</code> value, starting at the current stream pointer,
829: * as if by the <code>readLong</code> method
830: * and then converts that <code>long</code> to a <code>double</code>
831: * using the <code>longBitsToDouble</code> method in
832: * class <code>Double</code>.
833: * <p>
834: * This method blocks until the eight bytes are read, the end of the
835: * stream is detected, or an exception is thrown.
836: *
837: * @return the next eight bytes of this stream, interpreted as a
838: * <code>double</code>.
839: * @exception EOFException if this stream reaches the end before reading
840: * eight bytes.
841: * @exception IOException if an I/O error occurs.
842: */
843: public final double readDoubleLE() throws IOException {
844: return Double.longBitsToDouble(readLongLE());
845: }
846:
847: /**
848: * Reads the next line of text from this stream. This method successively
849: * reads bytes from the stream, starting at the current stream pointer,
850: * until it reaches a line terminator or the end
851: * of the stream. Each byte is converted into a character by taking the
852: * byte's value for the lower eight bits of the character and setting the
853: * high eight bits of the character to zero. This method does not,
854: * therefore, support the full Unicode character set.
855: *
856: * <p> A line of text is terminated by a carriage-return character
857: * (<code>'\r'</code>), a newline character (<code>'\n'</code>), a
858: * carriage-return character immediately followed by a newline character,
859: * or the end of the stream. Line-terminating characters are discarded and
860: * are not included as part of the string returned.
861: *
862: * <p> This method blocks until a newline character is read, a carriage
863: * return and the byte following it are read (to see if it is a newline),
864: * the end of the stream is reached, or an exception is thrown.
865: *
866: * @return the next line of text from this stream, or null if end
867: * of stream is encountered before even one byte is read.
868: * @exception IOException if an I/O error occurs.
869: */
870: public final String readLine() throws IOException {
871: StringBuffer input = new StringBuffer();
872: int c = -1;
873: boolean eol = false;
874:
875: while (!eol) {
876: switch (c = read()) {
877: case -1:
878: case '\n':
879: eol = true;
880: break;
881: case '\r':
882: eol = true;
883: long cur = getFilePointer();
884: if ((read()) != '\n') {
885: seek(cur);
886: }
887: break;
888: default:
889: input.append((char) c);
890: break;
891: }
892: }
893:
894: if ((c == -1) && (input.length() == 0)) {
895: return null;
896: }
897: return input.toString();
898: }
899:
900: /**
901: * Reads in a string from this stream. The string has been encoded
902: * using a modified UTF-8 format.
903: * <p>
904: * The first two bytes are read, starting from the current stream
905: * pointer, as if by
906: * <code>readUnsignedShort</code>. This value gives the number of
907: * following bytes that are in the encoded string, not
908: * the length of the resulting string. The following bytes are then
909: * interpreted as bytes encoding characters in the UTF-8 format
910: * and are converted into characters.
911: * <p>
912: * This method blocks until all the bytes are read, the end of the
913: * stream is detected, or an exception is thrown.
914: *
915: * @return a Unicode string.
916: * @exception EOFException if this stream reaches the end before
917: * reading all the bytes.
918: * @exception IOException if an I/O error occurs.
919: * @exception UTFDataFormatException if the bytes do not represent
920: * valid UTF-8 encoding of a Unicode string.
921: */
922: public final String readUTF() throws IOException {
923: return DataInputStream.readUTF(this );
924: }
925:
926: /**
927: * Releases any system resources associated with this stream
928: * by calling the <code>close()</code> method.
929: */
930: protected void finalize() throws Throwable {
931: super.finalize();
932: close();
933: }
934: }
|