StringBufferInputStream.java revision 8cfafd33742282beb20c6971aafc1feb35e3fa5e
1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18package java.io;
19
20/**
21 * A specialized {@link InputStream} that reads bytes from a {@code String} in
22 * a sequential manner.
23 *
24 * @deprecated Use {@link StringReader}
25 */
26@Deprecated
27public class StringBufferInputStream extends InputStream {
28    /**
29     * The source string containing the data to read.
30     */
31    protected String buffer;
32
33    /**
34     * The total number of characters in the source string.
35     */
36    protected int count;
37
38    /**
39     * The current position within the source string.
40     */
41    protected int pos;
42
43    /**
44     * Construct a new {@code StringBufferInputStream} with {@code str} as
45     * source. The size of the stream is set to the {@code length()} of the
46     * string.
47     *
48     * @param str
49     *            the source string for this stream.
50     * @throws NullPointerException
51     *             if {@code str} is {@code null}.
52     */
53    public StringBufferInputStream(String str) {
54        if (str == null) {
55            throw new NullPointerException();
56        }
57        buffer = str;
58        count = str.length();
59    }
60
61    @Override
62    public synchronized int available() {
63        return count - pos;
64    }
65
66    /**
67     * Reads a single byte from the source string and returns it as an integer
68     * in the range from 0 to 255. Returns -1 if the end of the source string
69     * has been reached.
70     *
71     * @return the byte read or -1 if the end of the source string has been
72     *         reached.
73     */
74    @Override
75    public synchronized int read() {
76        return pos < count ? buffer.charAt(pos++) & 0xFF : -1;
77    }
78
79    /**
80     * Reads at most {@code length} bytes from the source string and stores them
81     * in the byte array {@code b} starting at {@code offset}.
82     *
83     * @param buffer
84     *            the byte array in which to store the bytes read.
85     * @param offset
86     *            the initial position in {@code b} to store the bytes read from
87     *            this stream.
88     * @param length
89     *            the maximum number of bytes to store in {@code b}.
90     * @return the number of bytes actually read or -1 if the end of the source
91     *         string has been reached.
92     * @throws IndexOutOfBoundsException
93     *             if {@code offset < 0} or {@code length < 0}, or if
94     *             {@code offset + length} is greater than the length of
95     *             {@code b}.
96     * @throws NullPointerException
97     *             if {@code b} is {@code null}.
98     */
99    @Override
100    public synchronized int read(byte[] buffer, int offset, int length) {
101        if (buffer == null) {
102            throw new NullPointerException("buffer == null");
103        }
104        // avoid int overflow
105        if (offset < 0 || offset > buffer.length) {
106            throw new ArrayIndexOutOfBoundsException("Offset out of bounds: " + offset);
107        }
108        if (length < 0 || length > buffer.length - offset) {
109            throw new ArrayIndexOutOfBoundsException("Length out of bounds: " + length);
110        }
111
112        if (length == 0) {
113            return 0;
114        }
115
116        int copylen = count - pos < length ? count - pos : length;
117        for (int i = 0; i < copylen; i++) {
118            buffer[offset + i] = (byte) this.buffer.charAt(pos + i);
119        }
120        pos += copylen;
121        return copylen;
122    }
123
124    /**
125     * Resets this stream to the beginning of the source string.
126     */
127    @Override
128    public synchronized void reset() {
129        pos = 0;
130    }
131
132    /**
133     * Skips {@code n} characters in the source string. It does nothing and
134     * returns 0 if {@code n} is negative. Less than {@code n} characters are
135     * skipped if the end of the source string is reached before the operation
136     * completes.
137     *
138     * @param n
139     *            the number of characters to skip.
140     * @return the number of characters actually skipped.
141     */
142    @Override
143    public synchronized long skip(long n) {
144        if (n <= 0) {
145            return 0;
146        }
147
148        int numskipped;
149        if (this.count - pos < n) {
150            numskipped = this.count - pos;
151            pos = this.count;
152        } else {
153            numskipped = (int) n;
154            pos += n;
155        }
156        return numskipped;
157    }
158}
159