1 /*
2 * Copyright 2004-2025 the original author or authors.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 /**
17 * Java Network Programming, Second Edition Merlin Hughes, Michael Shoffner, Derek Hamner Manning Publications Company;
18 * ISBN 188477749X
19 *
20 * http://nitric.com/jnp/
21 *
22 * Copyright (c) 1997-1999 Merlin Hughes, Michael Shoffner, Derek Hamner; all rights reserved.
23 *
24 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
25 * following conditions are met:
26 *
27 * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
28 * disclaimer.
29 *
30 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
31 * following disclaimer in the documentation and/or other materials provided with the distribution.
32 *
33 * THIS SOFTWARE IS PROVIDED BY THE ABOVE NAMED AUTHORS "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
34 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
35 * EVENT SHALL THE AUTHORS, THEIR PUBLISHER OR THEIR EMPLOYERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
36 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
37 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
38 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
39 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 */
41 package com.ibatis.common.io;
42
43 import java.io.ByteArrayOutputStream;
44 import java.io.IOException;
45 import java.io.InputStream;
46 import java.io.OutputStreamWriter;
47 import java.io.Reader;
48 import java.io.UnsupportedEncodingException;
49 import java.io.Writer;
50 import java.nio.charset.Charset;
51
52 /**
53 * An InputStream backed by a Reader.
54 */
55 public class ReaderInputStream extends InputStream {
56
57 /** The reader. */
58 protected Reader reader;
59
60 /** The byte array out. */
61 protected ByteArrayOutputStream byteArrayOut;
62
63 /** The writer. */
64 protected Writer writer;
65
66 /** The chars. */
67 protected char[] chars;
68
69 /** The buffer. */
70 protected byte[] buffer;
71
72 /** The length. */
73 protected int index, length;
74
75 /**
76 * Constructor to supply a Reader.
77 *
78 * @param reader
79 * - the Reader used by the InputStream
80 */
81 public ReaderInputStream(Reader reader) {
82 this.reader = reader;
83 byteArrayOut = new ByteArrayOutputStream();
84 writer = new OutputStreamWriter(byteArrayOut);
85 chars = new char[1024];
86 }
87
88 /**
89 * Constructor to supply a Reader and an encoding.
90 *
91 * @param reader
92 * - the Reader used by the InputStream
93 * @param encoding
94 * - the encoding to use for the InputStream
95 *
96 * @throws UnsupportedEncodingException
97 * if the encoding is not supported
98 */
99 public ReaderInputStream(Reader reader, String encoding) throws UnsupportedEncodingException {
100 this.reader = reader;
101 byteArrayOut = new ByteArrayOutputStream();
102 writer = new OutputStreamWriter(byteArrayOut, Charset.forName(encoding));
103 chars = new char[1024];
104 }
105
106 /**
107 * @see java.io.InputStream#read()
108 */
109 @Override
110 public int read() throws IOException {
111 if (index >= length) {
112 fillBuffer();
113 }
114 if (index >= length) {
115 return -1;
116 }
117 return 0xff & buffer[index++];
118 }
119
120 /**
121 * Fill buffer.
122 *
123 * @throws IOException
124 * Signals that an I/O exception has occurred.
125 */
126 protected void fillBuffer() throws IOException {
127 if (length < 0) {
128 return;
129 }
130 int numChars = reader.read(chars);
131 if (numChars < 0) {
132 length = -1;
133 } else {
134 byteArrayOut.reset();
135 writer.write(chars, 0, numChars);
136 writer.flush();
137 buffer = byteArrayOut.toByteArray();
138 length = buffer.length;
139 index = 0;
140 }
141 }
142
143 /**
144 * @see java.io.InputStream#read(byte[], int, int)
145 */
146 @Override
147 public int read(byte[] data, int off, int len) throws IOException {
148 if (index >= length) {
149 fillBuffer();
150 }
151 if (index >= length) {
152 return -1;
153 }
154 int amount = Math.min(len, length - index);
155 System.arraycopy(buffer, index, data, off, amount);
156 index += amount;
157 return amount;
158 }
159
160 /**
161 * @see java.io.InputStream#available()
162 */
163 @Override
164 public int available() throws IOException {
165 return index < length ? length - index : length >= 0 && reader.ready() ? 1 : 0;
166 }
167
168 /**
169 * @see java.io.InputStream#close()
170 */
171 @Override
172 public void close() throws IOException {
173 reader.close();
174 }
175 }