1 /* 2 * Copyright (C) 2007 The Guava 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 * http://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 package com.google.common.io; 18 19 import com.google.common.collect.Lists; 20 import java.io.ByteArrayInputStream; 21 import java.io.FilterInputStream; 22 import java.io.IOException; 23 import java.io.InputStream; 24 import java.util.Collections; 25 import java.util.List; 26 27 /** 28 * Test class for {@link MultiInputStream}. 29 * 30 * @author Chris Nokleberg 31 */ 32 public class MultiInputStreamTest extends IoTestCase { 33 testJoin()34 public void testJoin() throws Exception { 35 joinHelper(0); 36 joinHelper(1); 37 joinHelper(0, 0, 0); 38 joinHelper(10, 20); 39 joinHelper(10, 0, 20); 40 joinHelper(0, 10, 20); 41 joinHelper(10, 20, 0); 42 joinHelper(10, 20, 1); 43 joinHelper(1, 1, 1, 1, 1, 1, 1, 1); 44 joinHelper(1, 0, 1, 0, 1, 0, 1, 0); 45 } 46 testOnlyOneOpen()47 public void testOnlyOneOpen() throws Exception { 48 final ByteSource source = newByteSource(0, 50); 49 final int[] counter = new int[1]; 50 ByteSource checker = 51 new ByteSource() { 52 @Override 53 public InputStream openStream() throws IOException { 54 if (counter[0]++ != 0) { 55 throw new IllegalStateException("More than one source open"); 56 } 57 return new FilterInputStream(source.openStream()) { 58 @Override 59 public void close() throws IOException { 60 super.close(); 61 counter[0]--; 62 } 63 }; 64 } 65 }; 66 byte[] result = ByteSource.concat(checker, checker, checker).read(); 67 assertEquals(150, result.length); 68 } 69 joinHelper(Integer... spans)70 private void joinHelper(Integer... spans) throws Exception { 71 List<ByteSource> sources = Lists.newArrayList(); 72 int start = 0; 73 for (Integer span : spans) { 74 sources.add(newByteSource(start, span)); 75 start += span; 76 } 77 ByteSource joined = ByteSource.concat(sources); 78 assertTrue(newByteSource(0, start).contentEquals(joined)); 79 } 80 testReadSingleByte()81 public void testReadSingleByte() throws Exception { 82 ByteSource source = newByteSource(0, 10); 83 ByteSource joined = ByteSource.concat(source, source); 84 assertEquals(20, joined.size()); 85 InputStream in = joined.openStream(); 86 assertFalse(in.markSupported()); 87 assertEquals(10, in.available()); 88 int total = 0; 89 while (in.read() != -1) { 90 total++; 91 } 92 assertEquals(0, in.available()); 93 assertEquals(20, total); 94 } 95 96 @SuppressWarnings("CheckReturnValue") // these calls to skip always return 0 testSkip()97 public void testSkip() throws Exception { 98 MultiInputStream multi = 99 new MultiInputStream( 100 Collections.singleton( 101 new ByteSource() { 102 @Override 103 public InputStream openStream() { 104 return new ByteArrayInputStream(newPreFilledByteArray(0, 50)) { 105 @Override 106 public long skip(long n) { 107 return 0; 108 } 109 }; 110 } 111 }) 112 .iterator()); 113 assertEquals(0, multi.skip(-1)); 114 assertEquals(0, multi.skip(-1)); 115 assertEquals(0, multi.skip(0)); 116 ByteStreams.skipFully(multi, 20); 117 assertEquals(20, multi.read()); 118 } 119 testReadSingle_noStackOverflow()120 public void testReadSingle_noStackOverflow() throws IOException { 121 // https://github.com/google/guava/issues/2996 122 // no data, just testing that there's no StackOverflowException 123 assertEquals(-1, tenMillionEmptySources().read()); 124 } 125 testReadArray_noStackOverflow()126 public void testReadArray_noStackOverflow() throws IOException { 127 // https://github.com/google/guava/issues/2996 128 // no data, just testing that there's no StackOverflowException 129 assertEquals(-1, tenMillionEmptySources().read(new byte[1])); 130 } 131 tenMillionEmptySources()132 private static MultiInputStream tenMillionEmptySources() throws IOException { 133 return new MultiInputStream(Collections.nCopies(10_000_000, ByteSource.empty()).iterator()); 134 } 135 newByteSource(final int start, final int size)136 private static ByteSource newByteSource(final int start, final int size) { 137 return new ByteSource() { 138 @Override 139 public InputStream openStream() { 140 return new ByteArrayInputStream(newPreFilledByteArray(start, size)); 141 } 142 }; 143 } 144 } 145