1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 package org.apache.commons.crypto.stream.input; 19 20 import static org.apache.commons.crypto.stream.CryptoInputStream.EOS; 21 22 import java.io.IOException; 23 import java.io.InputStream; 24 import java.nio.ByteBuffer; 25 26 import org.apache.commons.crypto.stream.CryptoInputStream; 27 28 /** 29 * The StreamInput class takes a {@link InputStream} object and wraps it as 30 * {@link Input} object acceptable by {@link CryptoInputStream}. 31 */ 32 public class StreamInput implements Input { 33 34 private final byte[] buf; 35 private final int bufferSize; 36 final InputStream in; 37 38 /** 39 * Constructs a {@link org.apache.commons.crypto.stream.input.StreamInput}. 40 * 41 * @param inputStream the InputStream object. 42 * @param bufferSize the buffer size. 43 */ 44 public StreamInput(final InputStream inputStream, final int bufferSize) { 45 this.in = inputStream; 46 this.bufferSize = bufferSize; 47 this.buf = new byte[bufferSize]; 48 } 49 50 /** 51 * Overrides the {@link Input#available()}. Returns an estimate of the 52 * number of bytes that can be read (or skipped over) from this input stream 53 * without blocking by the next invocation of a method for this input 54 * stream. The next invocation might be the same thread or another thread. A 55 * single read or skip of this many bytes will not block, but may read or 56 * skip fewer bytes. 57 * 58 * @return an estimate of the number of bytes that can be read (or skipped 59 * over) from this input stream without blocking or {@code 0} when 60 * it reaches the end of the input stream. 61 * @throws IOException if an I/O error occurs. 62 */ 63 @Override 64 public int available() throws IOException { 65 return in.available(); 66 } 67 68 /** 69 * Overrides the 70 * {@link org.apache.commons.crypto.stream.input.Input#seek(long)}. Closes 71 * this input and releases any system resources associated with the under 72 * layer input. 73 * 74 * @throws IOException if an I/O error occurs. 75 */ 76 @Override 77 public void close() throws IOException { 78 in.close(); 79 } 80 81 /** 82 * Overrides the 83 * {@link org.apache.commons.crypto.stream.input.Input#read(ByteBuffer)}. 84 * Reads a sequence of bytes from input into the given buffer. 85 * 86 * @param dst The buffer into which bytes are to be transferred. 87 * 88 * @return the total number of bytes read into the buffer, or 89 * {@code EOS (-1)} if there is no more data because the end of the 90 * stream has been reached. 91 * @throws IOException if an I/O error occurs. 92 */ 93 @Override 94 public int read(final ByteBuffer dst) throws IOException { 95 int remaining = dst.remaining(); 96 int read = 0; 97 while (remaining > 0) { 98 final int n = in.read(buf, 0, Math.min(remaining, bufferSize)); 99 if (n == EOS) { 100 if (read == 0) { 101 read = EOS; 102 } 103 break; 104 } 105 if (n > 0) { 106 dst.put(buf, 0, n); 107 read += n; 108 remaining -= n; 109 } 110 } 111 return read; 112 } 113 114 /** 115 * Overrides the 116 * {@link org.apache.commons.crypto.stream.input.Input#read(long, byte[], int, int)} 117 * . Reads up to {@code len} bytes of data from the input stream into 118 * an array of bytes. An attempt is made to read as many as {@code len} 119 * bytes, but a smaller number may be read. The number of bytes actually 120 * read is returned as an integer. 121 * 122 * @param position the given position within a stream. 123 * @param buffer the buffer into which the data is read. 124 * @param offset the start offset in array buffer. 125 * @param length the maximum number of bytes to read. 126 * @return the total number of bytes read into the buffer, or 127 * {@code EOS (-1)} if there is no more data because the end of the 128 * stream has been reached. 129 * @throws IOException if an I/O error occurs. 130 */ 131 @Override 132 public int read(final long position, final byte[] buffer, final int offset, final int length) throws IOException { 133 throw new UnsupportedOperationException("Positioned read is not supported by this implementation"); 134 } 135 136 /** 137 * Overrides the 138 * {@link org.apache.commons.crypto.stream.input.Input#seek(long)}. Seeks to 139 * the given offset from the start of the stream. The next read() will be 140 * from that location. 141 * 142 * @param position the offset from the start of the stream. 143 * @throws IOException if an I/O error occurs. 144 */ 145 @Override 146 public void seek(final long position) throws IOException { 147 throw new UnsupportedOperationException("Seek is not supported by this implementation"); 148 } 149 150 /** 151 * Overrides the 152 * {@link org.apache.commons.crypto.stream.input.Input#skip(long)}. Skips 153 * over and discards {@code n} bytes of data from this input stream. 154 * 155 * @param n the number of bytes to be skipped. 156 * @return the actual number of bytes skipped. 157 * @throws IOException if an I/O error occurs. 158 */ 159 @Override 160 public long skip(final long n) throws IOException { 161 return in.skip(n); 162 } 163 }