/*
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.facebook.stetho.server;
import javax.annotation.concurrent.NotThreadSafe;
import java.io.IOException;
import java.io.InputStream;
import com.facebook.stetho.common.LogUtil;
@NotThreadSafe
public class CompositeInputStream extends InputStream {
private final InputStream[] mStreams;
private int mCurrentIndex;
public CompositeInputStream(InputStream[] streams) {
if (streams == null || streams.length < 2) {
throw new IllegalArgumentException("Streams must be non-null and have more than 1 entry");
}
mStreams = streams;
mCurrentIndex = 0;
}
@Override
public int available() throws IOException {
return mStreams[mCurrentIndex].available();
}
@Override
public void close() throws IOException {
closeAll(mCurrentIndex);
}
private void closeAll(int mostImportantIndex) throws IOException {
IOException exceptionToThrow = null;
for (int i = 0; i < mStreams.length; i++) {
try {
mStreams[i].close();
} catch (IOException e) {
IOException previousException = exceptionToThrow;
if (i == mostImportantIndex || exceptionToThrow == null) {
exceptionToThrow = e;
}
if (previousException != null && previousException != exceptionToThrow) {
LogUtil.w(previousException, "Suppressing exception");
}
}
}
}
@Override
public void mark(int readlimit) {
throw new UnsupportedOperationException();
}
@Override
public boolean markSupported() {
return false;
}
@Override
public void reset() throws IOException {
throw new UnsupportedOperationException();
}
@Override
public int read(byte[] buffer) throws IOException {
return read(buffer, 0, buffer.length);
}
@Override
public int read(byte[] buffer, int byteOffset, int byteCount) throws IOException {
int n;
while ((n = mStreams[mCurrentIndex].read(buffer, byteOffset, byteCount)) == -1) {
if (!tryMoveToNextStream()) {
break;
}
}
return n;
}
@Override
public int read() throws IOException {
int b;
while ((b = mStreams[mCurrentIndex].read()) == -1) {
if (!tryMoveToNextStream()) {
break;
}
}
return b;
}
private boolean tryMoveToNextStream() {
if (mCurrentIndex + 1 < mStreams.length) {
mCurrentIndex++;
return true;
}
return false;
}
@Override
public long skip(long byteCount) throws IOException {
byte[] buf = new byte[(int)byteCount];
int n = read(buf);
return n >= 0 ? n : -1;
}
}