StringBufferInputStream.java revision dd828f42a5c83b4270d4fbf6fce2da1878f1e84a
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 20import org.apache.harmony.luni.util.Msg; 21 22/** 23 * A specialized {@link InputStream} that reads bytes from a {@code String} in 24 * a sequential manner. 25 * 26 * @deprecated Use {@link StringReader} 27 * 28 * @since Android 1.0 29 */ 30@Deprecated 31public class StringBufferInputStream extends InputStream { 32 /** 33 * The source string containing the data to read. 34 * 35 * @since Android 1.0 36 */ 37 protected String buffer; 38 39 /** 40 * The total number of characters in the source string. 41 * 42 * @since Android 1.0 43 */ 44 protected int count; 45 46 /** 47 * The current position within the source string. 48 * 49 * @since Android 1.0 50 */ 51 protected int pos; 52 53 /** 54 * Construct a new {@code StringBufferInputStream} with {@code str} as 55 * source. The size of the stream is set to the {@code length()} of the 56 * string. 57 * 58 * @param str 59 * the source string for this stream. 60 * @throws NullPointerException 61 * if {@code str} is {@code null}. 62 * @since Android 1.0 63 */ 64 public StringBufferInputStream(String str) { 65 if (str == null) { 66 throw new NullPointerException(); 67 } 68 buffer = str; 69 count = str.length(); 70 } 71 72 /** 73 * Returns the number of bytes that are available before this stream will 74 * block. 75 * 76 * @return the number of bytes available before blocking. 77 * @since Android 1.0 78 */ 79 @Override 80 public synchronized int available() { 81 return count - pos; 82 } 83 84 /** 85 * Reads a single byte from the source string and returns it as an integer 86 * in the range from 0 to 255. Returns -1 if the end of the source string 87 * has been reached. 88 * 89 * @return the byte read or -1 if the end of the source string has been 90 * reached. 91 * @since Android 1.0 92 */ 93 @Override 94 public synchronized int read() { 95 return pos < count ? buffer.charAt(pos++) & 0xFF : -1; 96 } 97 98 /** 99 * Reads at most {@code length} bytes from the source string and stores them 100 * in the byte array {@code b} starting at {@code offset}. 101 * 102 * @param b 103 * the byte array in which to store the bytes read. 104 * @param offset 105 * the initial position in {@code b} to store the bytes read from 106 * this stream. 107 * @param length 108 * the maximum number of bytes to store in {@code b}. 109 * @return the number of bytes actually read or -1 if the end of the source 110 * string has been reached. 111 * @throws ArrayIndexOutOfBoundsException 112 * if {@code offset < 0} or {@code length < 0}, or if 113 * {@code offset + length} is greater than the length of 114 * {@code b}. 115 * @throws NullPointerException 116 * if {@code b} is {@code null}. 117 * @since Android 1.0 118 */ 119 @Override 120 public synchronized int read(byte[] b, int offset, int length) { 121 // BEGIN android-note 122 // changed array notation to be consistent with the rest of harmony 123 // END android-note 124 // According to 22.7.6 should return -1 before checking other 125 // parameters. 126 if (pos >= count) { 127 return -1; 128 } 129 if (b == null) { 130 throw new NullPointerException(Msg.getString("K0047")); //$NON-NLS-1$ 131 } 132 // avoid int overflow 133 // BEGIN android-changed 134 // Exception priorities (in case of multiple errors) differ from 135 // RI, but are spec-compliant. 136 // removed redundant check, used (offset | length) < 0 137 // instead of (offset < 0) || (length < 0) to safe one operation 138 if ((offset | length) < 0 || length > b.length - offset) { 139 throw new ArrayIndexOutOfBoundsException(Msg.getString("K002f")); //$NON-NLS-1$ 140 } 141 // END android-changed 142 if (length == 0) { 143 return 0; 144 } 145 146 int copylen = count - pos < length ? count - pos : length; 147 for (int i = 0; i < copylen; i++) { 148 b[offset + i] = (byte) buffer.charAt(pos + i); 149 } 150 pos += copylen; 151 return copylen; 152 } 153 154 /** 155 * Resets this stream to the beginning of the source string. 156 * 157 * @since Android 1.0 158 */ 159 @Override 160 public synchronized void reset() { 161 pos = 0; 162 } 163 164 /** 165 * Skips {@code n} characters in the source string. It does nothing and 166 * returns 0 if {@code n} is negative. Less than {@code n} characters are 167 * skipped if the end of the source string is reached before the operation 168 * completes. 169 * 170 * @param n 171 * the number of characters to skip. 172 * @return the number of characters actually skipped. 173 * @since Android 1.0 174 */ 175 @Override 176 public synchronized long skip(long n) { 177 if (n <= 0) { 178 return 0; 179 } 180 181 int numskipped; 182 if (this.count - pos < n) { 183 numskipped = this.count - pos; 184 pos = this.count; 185 } else { 186 numskipped = (int) n; 187 pos += n; 188 } 189 return numskipped; 190 } 191} 192