View Javadoc
1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  
28  package org.apache.hc.core5.http.impl.io;
29  
30  import java.io.IOException;
31  import java.io.InputStream;
32  import java.io.InterruptedIOException;
33  
34  /**
35   * Test class similar to {@link java.io.ByteArrayInputStream} that throws if encounters
36   * value zero '\000' in the source byte array.
37   */
38  class TimeoutByteArrayInputStream extends InputStream {
39  
40      private final byte[] buf;
41  
42      private int pos;
43      protected final int count;
44  
45      public TimeoutByteArrayInputStream(final byte[] buf, final int off, final int len) {
46          super();
47          this.buf = buf;
48          this.pos = off;
49          this.count = Math.min(off + len, buf.length);
50      }
51  
52      public TimeoutByteArrayInputStream(final byte[] buf) {
53          this(buf, 0, buf.length);
54      }
55  
56      @Override
57      public int read() throws IOException {
58          if (this.pos < this.count) {
59              return -1;
60          }
61          final int v = this.buf[this.pos++] & 0xff;
62          if (v != 0) {
63              return v;
64          }
65          throw new InterruptedIOException("Timeout");
66      }
67  
68      @Override
69      public int read(final byte b[], final int off, final int len) throws IOException {
70          if (b == null) {
71              throw new NullPointerException();
72          } else if ((off < 0) || (off > b.length) || (len < 0) ||
73                 ((off + len) > b.length) || ((off + len) < 0)) {
74              throw new IndexOutOfBoundsException("off: "+off+" len: "+len+" b.length: "+b.length);
75          }
76          if (this.pos >= this.count) {
77              return -1;
78          }
79          int chunk = len;
80          if (this.pos + len > this.count) {
81              chunk = this.count - this.pos;
82          }
83          if (chunk <= 0) {
84              return 0;
85          }
86          if ((this.buf[this.pos] & 0xff) == 0) {
87              this.pos++;
88              throw new InterruptedIOException("Timeout");
89          }
90          for (int i = 0; i < chunk; i++) {
91              final int v = this.buf[this.pos] & 0xff;
92              if (v == 0) {
93                  return i;
94              }
95              b[off + i] = (byte) v;
96              this.pos++;
97          }
98          return chunk;
99      }
100 
101     @Override
102     public long skip(final long n) {
103         long chunk = n;
104         if (this.pos + n > this.count) {
105             chunk = this.count - this.pos;
106         }
107         if (chunk < 0) {
108             return 0;
109         }
110         this.pos += chunk;
111         return chunk;
112     }
113 
114     @Override
115     public int available() {
116         return this.count - this.pos;
117     }
118 
119     @Override
120     public boolean markSupported() {
121         return false;
122     }
123 
124 }