001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.commons.crypto.stream.input; 019 020import static org.apache.commons.crypto.stream.CryptoInputStream.EOS; 021 022import java.io.IOException; 023import java.io.InputStream; 024import java.nio.ByteBuffer; 025 026import org.apache.commons.crypto.stream.CryptoInputStream; 027 028 /** 029 * The StreamInput class takes a {@link InputStream} object and wraps it as 030 * {@link Input} object acceptable by {@link CryptoInputStream}. 031 */ 032public class StreamInput implements Input { 033 034 private final byte[] buf; 035 private final int bufferSize; 036 final InputStream in; 037 038 /** 039 * Constructs a {@link org.apache.commons.crypto.stream.input.StreamInput}. 040 * 041 * @param inputStream the InputStream object. 042 * @param bufferSize the buffer size. 043 */ 044 public StreamInput(final InputStream inputStream, final int bufferSize) { 045 this.in = inputStream; 046 this.bufferSize = bufferSize; 047 this.buf = new byte[bufferSize]; 048 } 049 050 /** 051 * Overrides the {@link Input#available()}. Returns an estimate of the 052 * number of bytes that can be read (or skipped over) from this input stream 053 * without blocking by the next invocation of a method for this input 054 * stream. The next invocation might be the same thread or another thread. A 055 * single read or skip of this many bytes will not block, but may read or 056 * skip fewer bytes. 057 * 058 * @return an estimate of the number of bytes that can be read (or skipped 059 * over) from this input stream without blocking or {@code 0} when 060 * it reaches the end of the input stream. 061 * @throws IOException if an I/O error occurs. 062 */ 063 @Override 064 public int available() throws IOException { 065 return in.available(); 066 } 067 068 /** 069 * Overrides the 070 * {@link org.apache.commons.crypto.stream.input.Input#seek(long)}. Closes 071 * this input and releases any system resources associated with the under 072 * layer input. 073 * 074 * @throws IOException if an I/O error occurs. 075 */ 076 @Override 077 public void close() throws IOException { 078 in.close(); 079 } 080 081 /** 082 * Overrides the 083 * {@link org.apache.commons.crypto.stream.input.Input#read(ByteBuffer)}. 084 * Reads a sequence of bytes from input into the given buffer. 085 * 086 * @param dst The buffer into which bytes are to be transferred. 087 * 088 * @return the total number of bytes read into the buffer, or 089 * {@code EOS (-1)} if there is no more data because the end of the 090 * stream has been reached. 091 * @throws IOException if an I/O error occurs. 092 */ 093 @Override 094 public int read(final ByteBuffer dst) throws IOException { 095 int remaining = dst.remaining(); 096 int read = 0; 097 while (remaining > 0) { 098 final int n = in.read(buf, 0, Math.min(remaining, bufferSize)); 099 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}