11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/*
21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2007 The Guava Authors
31d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
41d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License");
51d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * you may not use this file except in compliance with the License.
61d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * You may obtain a copy of the License at
71d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
81d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * http://www.apache.org/licenses/LICENSE-2.0
91d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unless required by applicable law or agreed to in writing, software
111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS,
121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * See the License for the specific language governing permissions and
141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * limitations under the License.
151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpackage com.google.common.io;
181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.Lists;
201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.ByteArrayInputStream;
221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.FilterInputStream;
231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.IOException;
241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.InputStream;
251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Collections;
261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.List;
271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/**
291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Test class for {@link MultiInputStream}.
301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Chris Nokleberg
321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic class MultiInputStreamTest extends IoTestCase {
341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testJoin() throws Exception {
361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    joinHelper(0);
371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    joinHelper(1);
381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    joinHelper(0, 0, 0);
391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    joinHelper(10, 20);
401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    joinHelper(10, 0, 20);
411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    joinHelper(0, 10, 20);
421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    joinHelper(10, 20, 0);
431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    joinHelper(10, 20, 1);
441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    joinHelper(1, 1, 1, 1, 1, 1, 1, 1);
451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    joinHelper(1, 0, 1, 0, 1, 0, 1, 0);
461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testOnlyOneOpen() throws Exception {
491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final InputSupplier<InputStream> supplier = newByteSupplier(0, 50);
501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final int[] counter = new int[1];
511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    InputSupplier<InputStream> checker = new InputSupplier<InputStream>() {
521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override
531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      public InputStream getInput() throws IOException {
541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        if (counter[0]++ != 0) {
551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          throw new IllegalStateException("More than one supplier open");
561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return new FilterInputStream(supplier.getInput()) {
581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          @Override public void close() throws IOException {
591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            super.close();
601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            counter[0]--;
611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        };
631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    };
651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @SuppressWarnings("unchecked")
661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    byte[] result = ByteStreams.toByteArray(
671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        ByteStreams.join(checker, checker, checker));
681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(150, result.length);
691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private void joinHelper(Integer... spans) throws Exception {
721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    List<InputSupplier<InputStream>> suppliers = Lists.newArrayList();
731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    int start = 0;
741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (Integer span : spans) {
751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      suppliers.add(newByteSupplier(start, span));
761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      start += span;
771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    InputSupplier<InputStream> joined = ByteStreams.join(suppliers);
791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(ByteStreams.equal(newByteSupplier(0, start), joined));
801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testReadSingleByte() throws Exception {
831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    InputSupplier<InputStream> supplier = newByteSupplier(0, 10);
841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @SuppressWarnings("unchecked")
851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    InputSupplier<InputStream> joined = ByteStreams.join(supplier, supplier);
861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(20, ByteStreams.length(joined));
871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    InputStream in = joined.getInput();
881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(in.markSupported());
891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(10, in.available());
901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    int total = 0;
911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    while (in.read() != -1) {
921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      total++;
931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(0, in.available());
951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(20, total);
961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSkip() throws Exception {
991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    MultiInputStream multi = new MultiInputStream(
1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Collections.singleton(new InputSupplier<InputStream>() {
1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          @Override
1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          public InputStream getInput() {
1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            return new ByteArrayInputStream(newPreFilledByteArray(0, 50)) {
1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              @Override public long skip(long n) {
1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                return 0;
1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              }
1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            };
1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }).iterator());
1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    multi.skip(-1);
1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    multi.skip(-1);
1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    multi.skip(0);
1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    ByteStreams.skipFully(multi, 20);
1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(20, multi.read());
1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static InputSupplier<InputStream> newByteSupplier(final int start, final int size) {
1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new InputSupplier<InputStream>() {
1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override
1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      public InputStream getInput() {
1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return new ByteArrayInputStream(newPreFilledByteArray(start, size));
1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    };
1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert}
126