001: // You can redistribute this software and/or modify it under the terms of
002: // the Ozone Library License version 1 published by ozone-db.org.
003: //
004: // The original code and portions created by SMB are
005: // Copyright (C) 1997-@year@ by SMB GmbH. All rights reserved.
006: //
007: // $Id: ChunkInputStream.java,v 1.1 2001/12/18 10:31:31 per_nyfelt Exp $
008:
009: package org.ozoneDB.xml.util;
010:
011: import java.io.InputStream;
012: import java.io.IOException;
013: import java.io.Serializable;
014:
015: /**
016: */
017: public final class ChunkInputStream extends InputStream implements
018: Serializable {
019:
020: /**
021: * The internal buffer array where the data is stored. When necessary,
022: * it may be replaced by another array of
023: * a different size.
024: */
025: protected byte[] buf;
026:
027: /**
028: * The current position in the buffer. This is the index of the next
029: * character to be read from the <code>buf</code> array.
030: * <p>
031: * This value is always in the range <code>0</code>
032: * through <code>count</code>. If it is less
033: * than <code>count</code>, then <code>buf[pos]</code>
034: * is the next byte to be supplied as input;
035: * if it is equal to <code>count</code>, then
036: * the next <code>read</code> or <code>skip</code>
037: * operation will require more bytes to be
038: * read from the contained input stream.
039: *
040: * @see java.io.BufferedInputStream#buf
041: */
042: protected int pos;
043:
044: /**
045: * Creates a <code>BufferedInputStream</code>
046: * and saves its argument, the input stream
047: * <code>in</code>, for later use. An internal
048: * buffer array is created and stored in <code>buf</code>.
049: *
050: * @param in the underlying input stream.
051: */
052: public ChunkInputStream(byte[] data) {
053: this .buf = data;
054: this .pos = 0;
055: }
056:
057: /**
058: * See
059: * the general contract of the <code>read</code>
060: * method of <code>InputStream</code>.
061: *
062: * @return the next byte of data, or <code>-1</code> if the end of the
063: * stream is reached.
064: * @exception IOException if an I/O error occurs.
065: * @see java.io.FilterInputStream#in
066: */
067: public synchronized int read() throws IOException {
068: if (this .pos >= this .buf.length) {
069: return -1;
070: }
071:
072: return this .buf[this .pos++] & 0xff;
073: }
074:
075: /**
076: * Reads bytes from this byte-input stream into the specified byte array,
077: * starting at the given offset.
078: *
079: * @param b destination buffer.
080: * @param off offset at which to start storing bytes.
081: * @param len maximum number of bytes to read.
082: * @return the number of bytes read, or <code>-1</code> if the end of
083: * the stream has been reached.
084: * @exception IOException if an I/O error occurs.
085: */
086: public synchronized final int read(byte[] b, int off, int len)
087: throws IOException {
088: if (this .pos >= this .buf.length) {
089: return -1;
090: }
091:
092: if (off < 0 || off > b.length || len < 0
093: || off + len > b.length || off + len < 0) {
094: throw new IndexOutOfBoundsException();
095: } else {
096: if (len == 0) {
097: return 0;
098: }
099: }
100:
101: int toRead = this .buf.length - this .pos;
102: len = toRead <= len ? toRead : len;
103: System.arraycopy(this .buf, this .pos, b, off, len);
104:
105: this .pos += len;
106:
107: return len;
108: }
109:
110: /**
111: * See the general contract of the <code>skip</code>
112: * method of <code>InputStream</code>.
113: *
114: * @param n the number of bytes to be skipped.
115: * @return the actual number of bytes skipped.
116: * @exception IOException if an I/O error occurs.
117: */
118: public synchronized final long skip(long n) throws IOException {
119: int toRead = this .buf.length - this .pos;
120: n = toRead <= n ? toRead : n;
121: pos += n;
122: return n;
123: }
124:
125: /**
126: * Returns the number of bytes that can be read from this input
127: * stream without blocking.
128: *
129: * @return the number of bytes that can be read from this input
130: * stream without blocking.
131: * @exception IOException if an I/O error occurs.
132: */
133: public synchronized final int available() throws IOException {
134: return this .buf.length - pos;
135: }
136:
137: /**
138: * Tests if this input stream supports the <code>mark</code>
139: * and <code>reset</code> methods. The <code>markSupported</code>
140: * method of <code>ChunkInputStream</code> returns <code>false</code>.
141: *
142: * @return a <code>boolean</code> indicating if this stream type supports
143: * the <code>mark</code> and <code>reset</code> methods.
144: */
145: public final boolean markSupported() {
146: return false;
147: }
148:
149: /**
150: * Closes this input stream and releases any system resources
151: * associated with the stream.
152: *
153: * @exception IOException if an I/O error occurs.
154: */
155: public synchronized final void close() throws IOException {
156: this .buf = null;
157: }
158:
159: /**
160: * Set a new buffer for this input stream.
161: * @param buffer the data buffer
162: */
163: public final void setBuffer(byte[] buffer) {
164: this .buf = buffer;
165: this .pos = 0;
166: }
167:
168: }
|