14fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy/* 24fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * Licensed to the Apache Software Foundation (ASF) under one or more 34fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * contributor license agreements. See the NOTICE file distributed with 44fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * this work for additional information regarding copyright ownership. 54fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * The ASF licenses this file to You under the Apache License, Version 2.0 64fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * (the "License"); you may not use this file except in compliance with 74fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * the License. You may obtain a copy of the License at 84fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 94fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * http://www.apache.org/licenses/LICENSE-2.0 104fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 114fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * Unless required by applicable law or agreed to in writing, software 124fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * distributed under the License is distributed on an "AS IS" BASIS, 134fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 144fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * See the License for the specific language governing permissions and 154fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * limitations under the License. 164fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy */ 174fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedypackage org.apache.commons.io.input; 184fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy 194fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedyimport java.io.IOException; 204fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedyimport java.io.InputStream; 214fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedyimport java.io.OutputStream; 224fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy 234fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy/** 244fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * InputStream proxy that transparently writes a copy of all bytes read 254fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * from the proxied stream to a given OutputStream. Using {@link #skip(long)} 264fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * or {@link #mark(int)}/{@link #reset()} on the stream will result on some 274fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * bytes from the input stream being skipped or duplicated in the output 284fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * stream. 294fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <p> 304fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * The proxied input stream is closed when the {@link #close()} method is 314fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * called on this proxy. It is configurable whether the associated output 324fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * stream will also closed. 334fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 344fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @version $Id: TeeInputStream.java 587913 2007-10-24 15:47:30Z niallp $ 354fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @since Commons IO 1.4 364fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy */ 374fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedypublic class TeeInputStream extends ProxyInputStream { 384fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy 394fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy /** 404fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * The output stream that will receive a copy of all bytes read from the 414fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * proxied input stream. 424fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy */ 434fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy private final OutputStream branch; 444fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy 454fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy /** 464fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * Flag for closing also the associated output stream when this 474fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * stream is closed. 484fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy */ 494fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy private final boolean closeBranch; 504fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy 514fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy /** 524fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * Creates a TeeInputStream that proxies the given {@link InputStream} 534fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * and copies all read bytes to the given {@link OutputStream}. The given 544fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * output stream will not be closed when this stream gets closed. 554fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 564fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param input input stream to be proxied 574fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param branch output stream that will receive a copy of all bytes read 584fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy */ 594fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy public TeeInputStream(InputStream input, OutputStream branch) { 604fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy this(input, branch, false); 614fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } 624fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy 634fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy /** 644fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * Creates a TeeInputStream that proxies the given {@link InputStream} 654fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * and copies all read bytes to the given {@link OutputStream}. The given 664fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * output stream will be closed when this stream gets closed if the 674fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * closeBranch parameter is <code>true</code>. 684fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 694fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param input input stream to be proxied 704fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param branch output stream that will receive a copy of all bytes read 714fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param closeBranch flag for closing also the output stream when this 724fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * stream is closed 734fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy */ 744fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy public TeeInputStream( 754fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy InputStream input, OutputStream branch, boolean closeBranch) { 764fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy super(input); 774fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy this.branch = branch; 784fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy this.closeBranch = closeBranch; 794fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } 804fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy 814fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy /** 824fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * Closes the proxied input stream and, if so configured, the associated 834fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * output stream. An exception thrown from one stream will not prevent 844fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * closing of the other stream. 854fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 864fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @throws IOException if either of the streams could not be closed 874fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy */ 884fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy public void close() throws IOException { 894fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy try { 904fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy super.close(); 914fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } finally { 924fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy if (closeBranch) { 934fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy branch.close(); 944fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } 954fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } 964fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } 974fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy 984fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy /** 994fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * Reads a single byte from the proxied input stream and writes it to 1004fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * the associated output stream. 1014fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 1024fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @return next byte from the stream, or -1 if the stream has ended 1034fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @throws IOException if the stream could not be read (or written) 1044fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy */ 1054fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy public int read() throws IOException { 1064fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy int ch = super.read(); 1074fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy if (ch != -1) { 1084fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy branch.write(ch); 1094fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } 1104fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy return ch; 1114fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } 1124fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy 1134fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy /** 1144fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * Reads bytes from the proxied input stream and writes the read bytes 1154fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * to the associated output stream. 1164fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 1174fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param bts byte buffer 1184fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param st start offset within the buffer 1194fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param end maximum number of bytes to read 1204fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @return number of bytes read, or -1 if the stream has ended 1214fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @throws IOException if the stream could not be read (or written) 1224fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy */ 1234fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy public int read(byte[] bts, int st, int end) throws IOException { 1244fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy int n = super.read(bts, st, end); 1254fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy if (n != -1) { 1264fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy branch.write(bts, st, n); 1274fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } 1284fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy return n; 1294fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } 1304fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy 1314fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy /** 1324fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * Reads bytes from the proxied input stream and writes the read bytes 1334fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * to the associated output stream. 1344fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 1354fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param bts byte buffer 1364fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @return number of bytes read, or -1 if the stream has ended 1374fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @throws IOException if the stream could not be read (or written) 1384fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy */ 1394fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy public int read(byte[] bts) throws IOException { 1404fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy int n = super.read(bts); 1414fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy if (n != -1) { 1424fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy branch.write(bts, 0, n); 1434fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } 1444fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy return n; 1454fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } 1464fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy 1474fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy} 148