Source Code Cross Referenced for ImageInputStreamImpl.java in  » 6.0-JDK-Core » image » javax » imageio » stream » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » image » javax.imageio.stream 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001        /*
002         * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004         *
005         * This code is free software; you can redistribute it and/or modify it
006         * under the terms of the GNU General Public License version 2 only, as
007         * published by the Free Software Foundation.  Sun designates this
008         * particular file as subject to the "Classpath" exception as provided
009         * by Sun in the LICENSE file that accompanied this code.
010         *
011         * This code is distributed in the hope that it will be useful, but WITHOUT
012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014         * version 2 for more details (a copy is included in the LICENSE file that
015         * accompanied this code).
016         *
017         * You should have received a copy of the GNU General Public License version
018         * 2 along with this work; if not, write to the Free Software Foundation,
019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020         *
021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022         * CA 95054 USA or visit www.sun.com if you need additional information or
023         * have any questions.
024         */
025
026        package javax.imageio.stream;
027
028        import java.io.DataInput;
029        import java.io.DataInputStream;
030        import java.io.EOFException;
031        import java.io.File;
032        import java.io.FileNotFoundException;
033        import java.io.IOException;
034        import java.io.RandomAccessFile;
035        import java.nio.ByteOrder;
036        import java.util.Stack;
037        import javax.imageio.IIOException;
038
039        /**
040         * An abstract class implementing the <code>ImageInputStream</code> interface.
041         * This class is designed to reduce the number of methods that must
042         * be implemented by subclasses.
043         *
044         * <p> In particular, this class handles most or all of the details of
045         * byte order interpretation, buffering, mark/reset, discarding,
046         * closing, and disposing.
047         */
048        public abstract class ImageInputStreamImpl implements  ImageInputStream {
049
050            private Stack markByteStack = new Stack();
051
052            private Stack markBitStack = new Stack();
053
054            private boolean isClosed = false;
055
056            // Length of the buffer used for readFully(type[], int, int)
057            private static final int BYTE_BUF_LENGTH = 8192;
058
059            /**
060             * Byte buffer used for readFully(type[], int, int).  Note that this
061             * array is also used for bulk reads in readShort(), readInt(), etc, so
062             * it should be large enough to hold a primitive value (i.e. >= 8 bytes).
063             * Also note that this array is package protected, so that it can be
064             * used by ImageOutputStreamImpl in a similar manner.
065             */
066            byte[] byteBuf = new byte[BYTE_BUF_LENGTH];
067
068            /**
069             * The byte order of the stream as an instance of the enumeration
070             * class <code>java.nio.ByteOrder</code>, where
071             * <code>ByteOrder.BIG_ENDIAN</code> indicates network byte order
072             * and <code>ByteOrder.LITTLE_ENDIAN</code> indicates the reverse
073             * order.  By default, the value is
074             * <code>ByteOrder.BIG_ENDIAN</code>.
075             */
076            protected ByteOrder byteOrder = ByteOrder.BIG_ENDIAN;
077
078            /**
079             * The current read position within the stream.  Subclasses are
080             * responsible for keeping this value current from any method they
081             * override that alters the read position.
082             */
083            protected long streamPos;
084
085            /**
086             * The current bit offset within the stream.  Subclasses are
087             * responsible for keeping this value current from any method they
088             * override that alters the bit offset.
089             */
090            protected int bitOffset;
091
092            /**
093             * The position prior to which data may be discarded.  Seeking
094             * to a smaller position is not allowed.  <code>flushedPos</code>
095             * will always be >= 0.
096             */
097            protected long flushedPos = 0;
098
099            /**
100             * Constructs an <code>ImageInputStreamImpl</code>.
101             */
102            public ImageInputStreamImpl() {
103            }
104
105            /**
106             * Throws an <code>IOException</code> if the stream has been closed.
107             * Subclasses may call this method from any of their methods that
108             * require the stream not to be closed.
109             *
110             * @exception IOException if the stream is closed.
111             */
112            protected final void checkClosed() throws IOException {
113                if (isClosed) {
114                    throw new IOException("closed");
115                }
116            }
117
118            public void setByteOrder(ByteOrder byteOrder) {
119                this .byteOrder = byteOrder;
120            }
121
122            public ByteOrder getByteOrder() {
123                return byteOrder;
124            }
125
126            /**
127             * Reads a single byte from the stream and returns it as an
128             * <code>int</code> between 0 and 255.  If EOF is reached, 
129             * <code>-1</code> is returned.
130             *
131             * <p> Subclasses must provide an implementation for this method.
132             * The subclass implementation should update the stream position
133             * before exiting.
134             *
135             * <p> The bit offset within the stream must be reset to zero before
136             * the read occurs.
137             *
138             * @return the value of the next byte in the stream, or <code>-1</code>
139             * if EOF is reached.
140             *
141             * @exception IOException if the stream has been closed.
142             */
143            public abstract int read() throws IOException;
144
145            /**
146             * A convenience method that calls <code>read(b, 0, b.length)</code>.
147             *
148             * <p> The bit offset within the stream is reset to zero before
149             * the read occurs.
150             *
151             * @return the number of bytes actually read, or <code>-1</code>
152             * to indicate EOF.
153             *
154             * @exception NullPointerException if <code>b</code> is
155             * <code>null</code>.
156             * @exception IOException if an I/O error occurs.
157             */
158            public int read(byte[] b) throws IOException {
159                return read(b, 0, b.length);
160            }
161
162            /**
163             * Reads up to <code>len</code> bytes from the stream, and stores
164             * them into <code>b</code> starting at index <code>off</code>.
165             * If no bytes can be read because the end of the stream has been
166             * reached, <code>-1</code> is returned.
167             *
168             * <p> The bit offset within the stream must be reset to zero before
169             * the read occurs.
170             *
171             * <p> Subclasses must provide an implementation for this method.
172             * The subclass implementation should update the stream position
173             * before exiting. 
174             *
175             * @param b an array of bytes to be written to.
176             * @param off the starting position within <code>b</code> to write to.
177             * @param len the maximum number of bytes to read.
178             *
179             * @return the number of bytes actually read, or <code>-1</code>
180             * to indicate EOF.
181             *
182             * @exception IndexOutOfBoundsException if <code>off</code> is
183             * negative, <code>len</code> is negative, or <code>off +
184             * len</code> is greater than <code>b.length</code>.
185             * @exception NullPointerException if <code>b</code> is
186             * <code>null</code>.
187             * @exception IOException if an I/O error occurs.
188             */
189            public abstract int read(byte[] b, int off, int len)
190                    throws IOException;
191
192            public void readBytes(IIOByteBuffer buf, int len)
193                    throws IOException {
194                if (len < 0) {
195                    throw new IndexOutOfBoundsException("len < 0!");
196                }
197                if (buf == null) {
198                    throw new NullPointerException("buf == null!");
199                }
200
201                byte[] data = new byte[len];
202                len = read(data, 0, len);
203
204                buf.setData(data);
205                buf.setOffset(0);
206                buf.setLength(len);
207            }
208
209            public boolean readBoolean() throws IOException {
210                int ch = this .read();
211                if (ch < 0) {
212                    throw new EOFException();
213                }
214                return (ch != 0);
215            }
216
217            public byte readByte() throws IOException {
218                int ch = this .read();
219                if (ch < 0) {
220                    throw new EOFException();
221                }
222                return (byte) ch;
223            }
224
225            public int readUnsignedByte() throws IOException {
226                int ch = this .read();
227                if (ch < 0) {
228                    throw new EOFException();
229                }
230                return ch;
231            }
232
233            public short readShort() throws IOException {
234                if (read(byteBuf, 0, 2) < 0) {
235                    throw new EOFException();
236                }
237
238                if (byteOrder == ByteOrder.BIG_ENDIAN) {
239                    return (short) (((byteBuf[0] & 0xff) << 8) | ((byteBuf[1] & 0xff) << 0));
240                } else {
241                    return (short) (((byteBuf[1] & 0xff) << 8) | ((byteBuf[0] & 0xff) << 0));
242                }
243            }
244
245            public int readUnsignedShort() throws IOException {
246                return ((int) readShort()) & 0xffff;
247            }
248
249            public char readChar() throws IOException {
250                return (char) readShort();
251            }
252
253            public int readInt() throws IOException {
254                if (read(byteBuf, 0, 4) < 0) {
255                    throw new EOFException();
256                }
257
258                if (byteOrder == ByteOrder.BIG_ENDIAN) {
259                    return (((byteBuf[0] & 0xff) << 24)
260                            | ((byteBuf[1] & 0xff) << 16)
261                            | ((byteBuf[2] & 0xff) << 8) | ((byteBuf[3] & 0xff) << 0));
262                } else {
263                    return (((byteBuf[3] & 0xff) << 24)
264                            | ((byteBuf[2] & 0xff) << 16)
265                            | ((byteBuf[1] & 0xff) << 8) | ((byteBuf[0] & 0xff) << 0));
266                }
267            }
268
269            public long readUnsignedInt() throws IOException {
270                return ((long) readInt()) & 0xffffffffL;
271            }
272
273            public long readLong() throws IOException {
274                // REMIND: Once 6277756 is fixed, we should do a bulk read of all 8
275                // bytes here as we do in readShort() and readInt() for even better
276                // performance (see 6347575 for details).
277                int i1 = readInt();
278                int i2 = readInt();
279
280                if (byteOrder == ByteOrder.BIG_ENDIAN) {
281                    return ((long) i1 << 32) + (i2 & 0xFFFFFFFFL);
282                } else {
283                    return ((long) i2 << 32) + (i1 & 0xFFFFFFFFL);
284                }
285            }
286
287            public float readFloat() throws IOException {
288                return Float.intBitsToFloat(readInt());
289            }
290
291            public double readDouble() throws IOException {
292                return Double.longBitsToDouble(readLong());
293            }
294
295            public String readLine() throws IOException {
296                StringBuffer input = new StringBuffer();
297                int c = -1;
298                boolean eol = false;
299
300                while (!eol) {
301                    switch (c = read()) {
302                    case -1:
303                    case '\n':
304                        eol = true;
305                        break;
306                    case '\r':
307                        eol = true;
308                        long cur = getStreamPosition();
309                        if ((read()) != '\n') {
310                            seek(cur);
311                        }
312                        break;
313                    default:
314                        input.append((char) c);
315                        break;
316                    }
317                }
318
319                if ((c == -1) && (input.length() == 0)) {
320                    return null;
321                }
322                return input.toString();
323            }
324
325            public String readUTF() throws IOException {
326                this .bitOffset = 0;
327
328                // Fix 4494369: method ImageInputStreamImpl.readUTF()
329                // does not work as specified (it should always assume
330                // network byte order).
331                ByteOrder oldByteOrder = getByteOrder();
332                setByteOrder(ByteOrder.BIG_ENDIAN);
333
334                String ret;
335                try {
336                    ret = DataInputStream.readUTF(this );
337                } catch (IOException e) {
338                    // Restore the old byte order even if an exception occurs
339                    setByteOrder(oldByteOrder);
340                    throw e;
341                }
342
343                setByteOrder(oldByteOrder);
344                return ret;
345            }
346
347            public void readFully(byte[] b, int off, int len)
348                    throws IOException {
349                // Fix 4430357 - if off + len < 0, overflow occurred
350                if (off < 0 || len < 0 || off + len > b.length || off + len < 0) {
351                    throw new IndexOutOfBoundsException(
352                            "off < 0 || len < 0 || off + len > b.length!");
353                }
354
355                while (len > 0) {
356                    int nbytes = read(b, off, len);
357                    if (nbytes == -1) {
358                        throw new EOFException();
359                    }
360                    off += nbytes;
361                    len -= nbytes;
362                }
363            }
364
365            public void readFully(byte[] b) throws IOException {
366                readFully(b, 0, b.length);
367            }
368
369            public void readFully(short[] s, int off, int len)
370                    throws IOException {
371                // Fix 4430357 - if off + len < 0, overflow occurred
372                if (off < 0 || len < 0 || off + len > s.length || off + len < 0) {
373                    throw new IndexOutOfBoundsException(
374                            "off < 0 || len < 0 || off + len > s.length!");
375                }
376
377                while (len > 0) {
378                    int nelts = Math.min(len, byteBuf.length / 2);
379                    readFully(byteBuf, 0, nelts * 2);
380                    toShorts(byteBuf, s, off, nelts);
381                    off += nelts;
382                    len -= nelts;
383                }
384            }
385
386            public void readFully(char[] c, int off, int len)
387                    throws IOException {
388                // Fix 4430357 - if off + len < 0, overflow occurred
389                if (off < 0 || len < 0 || off + len > c.length || off + len < 0) {
390                    throw new IndexOutOfBoundsException(
391                            "off < 0 || len < 0 || off + len > c.length!");
392                }
393
394                while (len > 0) {
395                    int nelts = Math.min(len, byteBuf.length / 2);
396                    readFully(byteBuf, 0, nelts * 2);
397                    toChars(byteBuf, c, off, nelts);
398                    off += nelts;
399                    len -= nelts;
400                }
401            }
402
403            public void readFully(int[] i, int off, int len) throws IOException {
404                // Fix 4430357 - if off + len < 0, overflow occurred
405                if (off < 0 || len < 0 || off + len > i.length || off + len < 0) {
406                    throw new IndexOutOfBoundsException(
407                            "off < 0 || len < 0 || off + len > i.length!");
408                }
409
410                while (len > 0) {
411                    int nelts = Math.min(len, byteBuf.length / 4);
412                    readFully(byteBuf, 0, nelts * 4);
413                    toInts(byteBuf, i, off, nelts);
414                    off += nelts;
415                    len -= nelts;
416                }
417            }
418
419            public void readFully(long[] l, int off, int len)
420                    throws IOException {
421                // Fix 4430357 - if off + len < 0, overflow occurred
422                if (off < 0 || len < 0 || off + len > l.length || off + len < 0) {
423                    throw new IndexOutOfBoundsException(
424                            "off < 0 || len < 0 || off + len > l.length!");
425                }
426
427                while (len > 0) {
428                    int nelts = Math.min(len, byteBuf.length / 8);
429                    readFully(byteBuf, 0, nelts * 8);
430                    toLongs(byteBuf, l, off, nelts);
431                    off += nelts;
432                    len -= nelts;
433                }
434            }
435
436            public void readFully(float[] f, int off, int len)
437                    throws IOException {
438                // Fix 4430357 - if off + len < 0, overflow occurred
439                if (off < 0 || len < 0 || off + len > f.length || off + len < 0) {
440                    throw new IndexOutOfBoundsException(
441                            "off < 0 || len < 0 || off + len > f.length!");
442                }
443
444                while (len > 0) {
445                    int nelts = Math.min(len, byteBuf.length / 4);
446                    readFully(byteBuf, 0, nelts * 4);
447                    toFloats(byteBuf, f, off, nelts);
448                    off += nelts;
449                    len -= nelts;
450                }
451            }
452
453            public void readFully(double[] d, int off, int len)
454                    throws IOException {
455                // Fix 4430357 - if off + len < 0, overflow occurred
456                if (off < 0 || len < 0 || off + len > d.length || off + len < 0) {
457                    throw new IndexOutOfBoundsException(
458                            "off < 0 || len < 0 || off + len > d.length!");
459                }
460
461                while (len > 0) {
462                    int nelts = Math.min(len, byteBuf.length / 8);
463                    readFully(byteBuf, 0, nelts * 8);
464                    toDoubles(byteBuf, d, off, nelts);
465                    off += nelts;
466                    len -= nelts;
467                }
468            }
469
470            private void toShorts(byte[] b, short[] s, int off, int len) {
471                int boff = 0;
472                if (byteOrder == ByteOrder.BIG_ENDIAN) {
473                    for (int j = 0; j < len; j++) {
474                        int b0 = b[boff];
475                        int b1 = b[boff + 1] & 0xff;
476                        s[off + j] = (short) ((b0 << 8) | b1);
477                        boff += 2;
478                    }
479                } else {
480                    for (int j = 0; j < len; j++) {
481                        int b0 = b[boff + 1];
482                        int b1 = b[boff] & 0xff;
483                        s[off + j] = (short) ((b0 << 8) | b1);
484                        boff += 2;
485                    }
486                }
487            }
488
489            private void toChars(byte[] b, char[] c, int off, int len) {
490                int boff = 0;
491                if (byteOrder == ByteOrder.BIG_ENDIAN) {
492                    for (int j = 0; j < len; j++) {
493                        int b0 = b[boff];
494                        int b1 = b[boff + 1] & 0xff;
495                        c[off + j] = (char) ((b0 << 8) | b1);
496                        boff += 2;
497                    }
498                } else {
499                    for (int j = 0; j < len; j++) {
500                        int b0 = b[boff + 1];
501                        int b1 = b[boff] & 0xff;
502                        c[off + j] = (char) ((b0 << 8) | b1);
503                        boff += 2;
504                    }
505                }
506            }
507
508            private void toInts(byte[] b, int[] i, int off, int len) {
509                int boff = 0;
510                if (byteOrder == ByteOrder.BIG_ENDIAN) {
511                    for (int j = 0; j < len; j++) {
512                        int b0 = b[boff];
513                        int b1 = b[boff + 1] & 0xff;
514                        int b2 = b[boff + 2] & 0xff;
515                        int b3 = b[boff + 3] & 0xff;
516                        i[off + j] = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
517                        boff += 4;
518                    }
519                } else {
520                    for (int j = 0; j < len; j++) {
521                        int b0 = b[boff + 3];
522                        int b1 = b[boff + 2] & 0xff;
523                        int b2 = b[boff + 1] & 0xff;
524                        int b3 = b[boff] & 0xff;
525                        i[off + j] = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
526                        boff += 4;
527                    }
528                }
529            }
530
531            private void toLongs(byte[] b, long[] l, int off, int len) {
532                int boff = 0;
533                if (byteOrder == ByteOrder.BIG_ENDIAN) {
534                    for (int j = 0; j < len; j++) {
535                        int b0 = b[boff];
536                        int b1 = b[boff + 1] & 0xff;
537                        int b2 = b[boff + 2] & 0xff;
538                        int b3 = b[boff + 3] & 0xff;
539                        int b4 = b[boff + 4];
540                        int b5 = b[boff + 5] & 0xff;
541                        int b6 = b[boff + 6] & 0xff;
542                        int b7 = b[boff + 7] & 0xff;
543
544                        int i0 = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
545                        int i1 = (b4 << 24) | (b5 << 16) | (b6 << 8) | b7;
546
547                        l[off + j] = ((long) i0 << 32) | (i1 & 0xffffffffL);
548                        boff += 8;
549                    }
550                } else {
551                    for (int j = 0; j < len; j++) {
552                        int b0 = b[boff + 7];
553                        int b1 = b[boff + 6] & 0xff;
554                        int b2 = b[boff + 5] & 0xff;
555                        int b3 = b[boff + 4] & 0xff;
556                        int b4 = b[boff + 3];
557                        int b5 = b[boff + 2] & 0xff;
558                        int b6 = b[boff + 1] & 0xff;
559                        int b7 = b[boff] & 0xff;
560
561                        int i0 = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
562                        int i1 = (b4 << 24) | (b5 << 16) | (b6 << 8) | b7;
563
564                        l[off + j] = ((long) i0 << 32) | (i1 & 0xffffffffL);
565                        boff += 8;
566                    }
567                }
568            }
569
570            private void toFloats(byte[] b, float[] f, int off, int len) {
571                int boff = 0;
572                if (byteOrder == ByteOrder.BIG_ENDIAN) {
573                    for (int j = 0; j < len; j++) {
574                        int b0 = b[boff];
575                        int b1 = b[boff + 1] & 0xff;
576                        int b2 = b[boff + 2] & 0xff;
577                        int b3 = b[boff + 3] & 0xff;
578                        int i = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
579                        f[off + j] = Float.intBitsToFloat(i);
580                        boff += 4;
581                    }
582                } else {
583                    for (int j = 0; j < len; j++) {
584                        int b0 = b[boff + 3];
585                        int b1 = b[boff + 2] & 0xff;
586                        int b2 = b[boff + 1] & 0xff;
587                        int b3 = b[boff + 0] & 0xff;
588                        int i = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
589                        f[off + j] = Float.intBitsToFloat(i);
590                        boff += 4;
591                    }
592                }
593            }
594
595            private void toDoubles(byte[] b, double[] d, int off, int len) {
596                int boff = 0;
597                if (byteOrder == ByteOrder.BIG_ENDIAN) {
598                    for (int j = 0; j < len; j++) {
599                        int b0 = b[boff];
600                        int b1 = b[boff + 1] & 0xff;
601                        int b2 = b[boff + 2] & 0xff;
602                        int b3 = b[boff + 3] & 0xff;
603                        int b4 = b[boff + 4];
604                        int b5 = b[boff + 5] & 0xff;
605                        int b6 = b[boff + 6] & 0xff;
606                        int b7 = b[boff + 7] & 0xff;
607
608                        int i0 = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
609                        int i1 = (b4 << 24) | (b5 << 16) | (b6 << 8) | b7;
610                        long l = ((long) i0 << 32) | (i1 & 0xffffffffL);
611
612                        d[off + j] = Double.longBitsToDouble(l);
613                        boff += 8;
614                    }
615                } else {
616                    for (int j = 0; j < len; j++) {
617                        int b0 = b[boff + 7];
618                        int b1 = b[boff + 6] & 0xff;
619                        int b2 = b[boff + 5] & 0xff;
620                        int b3 = b[boff + 4] & 0xff;
621                        int b4 = b[boff + 3];
622                        int b5 = b[boff + 2] & 0xff;
623                        int b6 = b[boff + 1] & 0xff;
624                        int b7 = b[boff] & 0xff;
625
626                        int i0 = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
627                        int i1 = (b4 << 24) | (b5 << 16) | (b6 << 8) | b7;
628                        long l = ((long) i0 << 32) | (i1 & 0xffffffffL);
629
630                        d[off + j] = Double.longBitsToDouble(l);
631                        boff += 8;
632                    }
633                }
634            }
635
636            public long getStreamPosition() throws IOException {
637                checkClosed();
638                return streamPos;
639            }
640
641            public int getBitOffset() throws IOException {
642                checkClosed();
643                return bitOffset;
644            }
645
646            public void setBitOffset(int bitOffset) throws IOException {
647                checkClosed();
648                if (bitOffset < 0 || bitOffset > 7) {
649                    throw new IllegalArgumentException(
650                            "bitOffset must be betwwen 0 and 7!");
651                }
652                this .bitOffset = bitOffset;
653            }
654
655            public int readBit() throws IOException {
656                checkClosed();
657
658                // Compute final bit offset before we call read() and seek()
659                int newBitOffset = (this .bitOffset + 1) & 0x7;
660
661                int val = read();
662                if (val == -1) {
663                    throw new EOFException();
664                }
665
666                if (newBitOffset != 0) {
667                    // Move byte position back if in the middle of a byte
668                    seek(getStreamPosition() - 1);
669                    // Shift the bit to be read to the rightmost position
670                    val >>= 8 - newBitOffset;
671                }
672                this .bitOffset = newBitOffset;
673
674                return val & 0x1;
675            }
676
677            public long readBits(int numBits) throws IOException {
678                checkClosed();
679
680                if (numBits < 0 || numBits > 64) {
681                    throw new IllegalArgumentException();
682                }
683                if (numBits == 0) {
684                    return 0L;
685                }
686
687                // Have to read additional bits on the left equal to the bit offset
688                int bitsToRead = numBits + bitOffset;
689
690                // Compute final bit offset before we call read() and seek()
691                int newBitOffset = (this .bitOffset + numBits) & 0x7;
692
693                // Read a byte at a time, accumulate
694                long accum = 0L;
695                while (bitsToRead > 0) {
696                    int val = read();
697                    if (val == -1) {
698                        throw new EOFException();
699                    }
700
701                    accum <<= 8;
702                    accum |= val;
703                    bitsToRead -= 8;
704                }
705
706                // Move byte position back if in the middle of a byte
707                if (newBitOffset != 0) {
708                    seek(getStreamPosition() - 1);
709                }
710                this .bitOffset = newBitOffset;
711
712                // Shift away unwanted bits on the right.
713                accum >>>= (-bitsToRead); // Negative of bitsToRead == extra bits read
714
715                // Mask out unwanted bits on the left
716                accum &= (-1L >>> (64 - numBits));
717
718                return accum;
719            }
720
721            /**
722             * Returns <code>-1L</code> to indicate that the stream has unknown
723             * length.  Subclasses must override this method to provide actual
724             * length information.
725             *
726             * @return -1L to indicate unknown length.
727             */
728            public long length() {
729                return -1L;
730            }
731
732            /**
733             * Advances the current stream position by calling
734             * <code>seek(getStreamPosition() + n)</code>.
735             *
736             * <p> The bit offset is reset to zero.
737             *
738             * @param n the number of bytes to seek forward.
739             *
740             * @return an <code>int</code> representing the number of bytes
741             * skipped.
742             *
743             * @exception IOException if <code>getStreamPosition</code>
744             * throws an <code>IOException</code> when computing either
745             * the starting or ending position.
746             */
747            public int skipBytes(int n) throws IOException {
748                long pos = getStreamPosition();
749                seek(pos + n);
750                return (int) (getStreamPosition() - pos);
751            }
752
753            /**
754             * Advances the current stream position by calling
755             * <code>seek(getStreamPosition() + n)</code>.
756             *
757             * <p> The bit offset is reset to zero.
758             *
759             * @param n the number of bytes to seek forward.
760             *
761             * @return a <code>long</code> representing the number of bytes
762             * skipped.
763             *
764             * @exception IOException if <code>getStreamPosition</code>
765             * throws an <code>IOException</code> when computing either
766             * the starting or ending position.
767             */
768            public long skipBytes(long n) throws IOException {
769                long pos = getStreamPosition();
770                seek(pos + n);
771                return getStreamPosition() - pos;
772            }
773
774            public void seek(long pos) throws IOException {
775                checkClosed();
776
777                // This test also covers pos < 0
778                if (pos < flushedPos) {
779                    throw new IndexOutOfBoundsException("pos < flushedPos!");
780                }
781
782                this .streamPos = pos;
783                this .bitOffset = 0;
784            }
785
786            /**
787             * Pushes the current stream position onto a stack of marked
788             * positions.
789             */
790            public void mark() {
791                try {
792                    markByteStack.push(new Long(getStreamPosition()));
793                    markBitStack.push(new Integer(getBitOffset()));
794                } catch (IOException e) {
795                }
796            }
797
798            /**
799             * Resets the current stream byte and bit positions from the stack
800             * of marked positions.
801             *
802             * <p> An <code>IOException</code> will be thrown if the previous
803             * marked position lies in the discarded portion of the stream.
804             *
805             * @exception IOException if an I/O error occurs.
806             */
807            public void reset() throws IOException {
808                if (markByteStack.empty()) {
809                    return;
810                }
811
812                long pos = ((Long) markByteStack.pop()).longValue();
813                if (pos < flushedPos) {
814                    throw new IIOException(
815                            "Previous marked position has been discarded!");
816                }
817                seek(pos);
818
819                int offset = ((Integer) markBitStack.pop()).intValue();
820                setBitOffset(offset);
821            }
822
823            public void flushBefore(long pos) throws IOException {
824                checkClosed();
825                if (pos < flushedPos) {
826                    throw new IndexOutOfBoundsException("pos < flushedPos!");
827                }
828                if (pos > getStreamPosition()) {
829                    throw new IndexOutOfBoundsException(
830                            "pos > getStreamPosition()!");
831                }
832                // Invariant: flushedPos >= 0
833                flushedPos = pos;
834            }
835
836            public void flush() throws IOException {
837                flushBefore(getStreamPosition());
838            }
839
840            public long getFlushedPosition() {
841                return flushedPos;
842            }
843
844            /** 
845             * Default implementation returns false.  Subclasses should
846             * override this if they cache data.
847             */
848            public boolean isCached() {
849                return false;
850            }
851
852            /** 
853             * Default implementation returns false.  Subclasses should
854             * override this if they cache data in main memory.
855             */
856            public boolean isCachedMemory() {
857                return false;
858            }
859
860            /** 
861             * Default implementation returns false.  Subclasses should
862             * override this if they cache data in a temporary file.
863             */
864            public boolean isCachedFile() {
865                return false;
866            }
867
868            public void close() throws IOException {
869                checkClosed();
870
871                isClosed = true;
872            }
873
874            /**
875             * Finalizes this object prior to garbage collection.  The
876             * <code>close</code> method is called to close any open input
877             * source.  This method should not be called from application
878             * code.
879             *
880             * @exception Throwable if an error occurs during superclass
881             * finalization.
882             */
883            protected void finalize() throws Throwable {
884                if (!isClosed) {
885                    try {
886                        close();
887                    } catch (IOException e) {
888                    }
889                }
890                super.finalize();
891            }
892        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.