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