1 /*
2 * Copyright 2004-2022 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.*;
44 import java.nio.charset.Charset;
45
46 /**
47 * An InputStream backed by a Reader.
48 */
49 public class ReaderInputStream extends InputStream {
50
51 /** The reader. */
52 protected Reader reader;
53
54 /** The byte array out. */
55 protected ByteArrayOutputStream byteArrayOut;
56
57 /** The writer. */
58 protected Writer writer;
59
60 /** The chars. */
61 protected char[] chars;
62
63 /** The buffer. */
64 protected byte[] buffer;
65
66 /** The length. */
67 protected int index, length;
68
69 /**
70 * Constructor to supply a Reader.
71 *
72 * @param reader
73 * - the Reader used by the InputStream
74 */
75 public ReaderInputStream(Reader reader) {
76 this.reader = reader;
77 byteArrayOut = new ByteArrayOutputStream();
78 writer = new OutputStreamWriter(byteArrayOut);
79 chars = new char[1024];
80 }
81
82 /**
83 * Constructor to supply a Reader and an encoding.
84 *
85 * @param reader
86 * - the Reader used by the InputStream
87 * @param encoding
88 * - the encoding to use for the InputStream
89 *
90 * @throws UnsupportedEncodingException
91 * if the encoding is not supported
92 */
93 public ReaderInputStream(Reader reader, String encoding) throws UnsupportedEncodingException {
94 this.reader = reader;
95 byteArrayOut = new ByteArrayOutputStream();
96 writer = new OutputStreamWriter(byteArrayOut, Charset.forName(encoding));
97 chars = new char[1024];
98 }
99
100 /**
101 * @see java.io.InputStream#read()
102 */
103 @Override
104 public int read() throws IOException {
105 if (index >= length)
106 fillBuffer();
107 if (index >= length)
108 return -1;
109 return 0xff & buffer[index++];
110 }
111
112 /**
113 * Fill buffer.
114 *
115 * @throws IOException
116 * Signals that an I/O exception has occurred.
117 */
118 protected void fillBuffer() throws IOException {
119 if (length < 0)
120 return;
121 int numChars = reader.read(chars);
122 if (numChars < 0) {
123 length = -1;
124 } else {
125 byteArrayOut.reset();
126 writer.write(chars, 0, numChars);
127 writer.flush();
128 buffer = byteArrayOut.toByteArray();
129 length = buffer.length;
130 index = 0;
131 }
132 }
133
134 /**
135 * @see java.io.InputStream#read(byte[], int, int)
136 */
137 @Override
138 public int read(byte[] data, int off, int len) throws IOException {
139 if (index >= length)
140 fillBuffer();
141 if (index >= length)
142 return -1;
143 int amount = Math.min(len, length - index);
144 System.arraycopy(buffer, index, data, off, amount);
145 index += amount;
146 return amount;
147 }
148
149 /**
150 * @see java.io.InputStream#available()
151 */
152 @Override
153 public int available() throws IOException {
154 return (index < length) ? length - index : ((length >= 0) && reader.ready()) ? 1 : 0;
155 }
156
157 /**
158 * @see java.io.InputStream#close()
159 */
160 @Override
161 public void close() throws IOException {
162 reader.close();
163 }
164 }