Coverage Report - org.apache.commons.flatfile.util.RepeatingInputStream
 
Classes in this File Line Coverage Branch Coverage Complexity
RepeatingInputStream
76%
16/21
75%
6/8
1.889
RepeatingInputStream$1
N/A
N/A
1.889
RepeatingInputStream$LimitedOutput
100%
14/14
100%
4/4
1.889
RepeatingInputStream$RepeatArray
0%
0/12
0%
0/4
1.889
RepeatingInputStream$RepeatOneByte
100%
9/9
N/A
1.889
 
 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one or more
 3  
  * contributor license agreements.  See the NOTICE file distributed with
 4  
  * this work for additional information regarding copyright ownership.
 5  
  * The ASF licenses this file to You under the Apache License, Version 2.0
 6  
  * (the "License"); you may not use this file except in compliance with
 7  
  * the License.  You may obtain a copy of the License at
 8  
  *
 9  
  *      http://www.apache.org/licenses/LICENSE-2.0
 10  
  *
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 package org.apache.commons.flatfile.util;
 18  
 
 19  
 import java.io.IOException;
 20  
 import java.io.InputStream;
 21  
 
 22  
 import org.apache.commons.lang3.Validate;
 23  
 
 24  
 /**
 25  
  * Provides factory methods to return InputStreams that return a repeating
 26  
  * ordered sequence of bytes, optionally limiting output to some maximum total
 27  
  * size.
 28  
  *
 29  
  * @version $Revision: 1301242 $ $Date: 2009-03-24 16:09:19 -0500 (Tue, 24 Mar
 30  
  *          2009) $
 31  
  */
 32  
 public abstract class RepeatingInputStream {
 33  0
     /**
 34  0
      * Construct a new {@link RepeatingInputStream} instance.
 35  
      */
 36  0
     private RepeatingInputStream() {
 37  0
     }
 38  
 
 39  18
     /**
 40  
      * An InputStream that repeats a single byte forever.
 41  
      */
 42  9
     private static class RepeatOneByte extends InputStream {
 43  
         private final byte b;
 44  
 
 45  
         /**
 46  
          * Create a new RepeatOneByte instance.
 47  
          *
 48  18
          * @param b byte to repeat
 49  18
          */
 50  81
         private RepeatOneByte(byte b) {
 51  36
             this.b = b;
 52  36
         }
 53  
 
 54  
         /**
 55  
          * {@inheritDoc}
 56  1354
          */
 57  
         public int read() throws IOException {
 58  2708
             return b;
 59  
         }
 60  
     }
 61  
 
 62  
     /**
 63  0
      * An InputStream that repeats a byte[] forever.
 64  
      */
 65  0
     private static class RepeatArray extends InputStream {
 66  
         private final byte[] b;
 67  
         private int pos;
 68  
 
 69  
         /**
 70  
          * Create a new RepeatArray instance.
 71  
          *
 72  
          * @param b byte[] to repeat
 73  0
          */
 74  0
         private RepeatArray(byte[] b) {
 75  0
             this.b = b;
 76  0
         }
 77  
 
 78  
         /**
 79  
          * {@inheritDoc}
 80  
          */
 81  
         public synchronized int read() throws IOException {
 82  0
             try {
 83  0
                 return b[pos++];
 84  0
             } finally {
 85  0
                 if (pos == b.length) {
 86  0
                     pos = 0;
 87  
                 }
 88  0
             }
 89  
         }
 90  
     }
 91  
 
 92  
     /**
 93  
      * InputStream that limits the content of another InputStream.
 94  42
      */
 95  21
     private static class LimitedOutput extends InputStream {
 96  
         private static final int EOF = -1;
 97  
 
 98  
         private final InputStream source;
 99  
         private final int bytesToReturn;
 100  
         private int bytesReturned;
 101  
 
 102  
         /**
 103  
          * Create a new LimitedOutput instance.
 104  
          *
 105  
          * @param source wrapped InputStream
 106  
          * @param bytesToReturn int max
 107  
          */
 108  147
         private LimitedOutput(InputStream source, int bytesToReturn) {
 109  126
             this.source = source;
 110  126
             this.bytesToReturn = bytesToReturn;
 111  126
         }
 112  42
 
 113  
         /**
 114  
          * {@inheritDoc}
 115  
          */
 116  
         public int read() throws IOException {
 117  220
             if (bytesReturned == bytesToReturn) {
 118  162
                 return EOF;
 119  26
             }
 120  
             try {
 121  294
                 return source.read();
 122  84
             } finally {
 123  168
                 bytesReturned++;
 124  84
             }
 125  
         }
 126  
     }
 127  
 
 128  
     /**
 129  
      * Holds cached instances of single-byte RepeatingInputStreams, with enough
 130  
      * space for every unique byte value.
 131  
      */
 132  4
     private static final InputStream[] REPEAT_BYTE = new InputStream[(int) Math.pow(2, Byte.SIZE)];
 133  2
 
 134  
     /**
 135  
      * Get an InputStream that will return the specified byte[] forever.
 136  
      *
 137  
      * @param b byte[] to repeat
 138  
      * @return {@link InputStream}
 139  
      * @throws NullPointerException if {@code b} is {@code null}
 140  
      */
 141  
     public static InputStream of(byte... b) {
 142  136
         Validate.notNull(b);
 143  136
         if (b.length == 1) {
 144  136
             final int index = 0 | b[0];
 145  136
             InputStream result = REPEAT_BYTE[index];
 146  204
             if (result == null) {
 147  104
                 result = new RepeatOneByte(b[0]);
 148  104
                 REPEAT_BYTE[index] = result;
 149  68
             }
 150  204
             return result;
 151  18
         }
 152  18
         return new RepeatArray(b);
 153  
     }
 154  68
 
 155  
     /**
 156  0
      * Get an InputStream that will return the specified byte sequence until a
 157  
      * total of {@code limit} bytes have been returned.
 158  
      *
 159  
      * @param limit int
 160  
      * @param b byte[] to repeat
 161  
      * @return {@link InputStream}
 162  
      * @throws NullPointerException if {@code b} is {@code null}
 163  
      */
 164  
     public static synchronized InputStream withLimit(int limit, byte... b) {
 165  84
         return new LimitedOutput(of(b), limit);
 166  
     }
 167  
 
 168  
 }