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 java.io.IOException; 021import java.nio.ByteBuffer; 022import java.nio.channels.ReadableByteChannel; 023 024/** 025 * The ChannelInput class takes a {@code ReadableByteChannel} object and 026 * wraps it as {@code Input} object acceptable by 027 * {@code CryptoInputStream}. 028 */ 029public class ChannelInput implements Input { 030 private static final int SKIP_BUFFER_SIZE = 2048; 031 032 private ByteBuffer buf; 033 private final ReadableByteChannel channel; 034 035 /** 036 * Constructs the 037 * {@link org.apache.commons.crypto.stream.input.ChannelInput}. 038 * 039 * @param channel the ReadableByteChannel object. 040 */ 041 public ChannelInput(final ReadableByteChannel channel) { 042 this.channel = channel; 043 } 044 045 /** 046 * Overrides the 047 * {@link org.apache.commons.crypto.stream.input.Input#read(ByteBuffer)}. 048 * Reads a sequence of bytes from input into the given buffer. 049 * 050 * @param dst The buffer into which bytes are to be transferred. 051 * @return the total number of bytes read into the buffer, or 052 * {@code -1} if there is no more data because the end of the 053 * stream has been reached. 054 * @throws IOException if an I/O error occurs. 055 */ 056 @Override 057 public int read(final ByteBuffer dst) throws IOException { 058 return channel.read(dst); 059 } 060 061 /** 062 * Overrides the 063 * {@link org.apache.commons.crypto.stream.input.Input#skip(long)}. Skips 064 * over and discards {@code n} bytes of data from this input stream. 065 * 066 * @param n the number of bytes to be skipped. 067 * @return the actual number of bytes skipped. 068 * @throws IOException if an I/O error occurs. 069 */ 070 @Override 071 public long skip(final long n) throws IOException { 072 long remaining = n; 073 int nr; 074 075 if (n <= 0) { 076 return 0; 077 } 078 079 final int size = (int) Math.min(SKIP_BUFFER_SIZE, remaining); 080 final ByteBuffer skipBuffer = getSkipBuf(); 081 while (remaining > 0) { 082 skipBuffer.clear(); 083 skipBuffer.limit((int) Math.min(size, remaining)); 084 nr = read(skipBuffer); 085 if (nr < 0) { 086 break; 087 } 088 remaining -= nr; 089 } 090 091 return n - remaining; 092 } 093 094 /** 095 * Overrides the {@link Input#available()}. Returns an estimate of the 096 * number of bytes that can be read (or skipped over) from this input stream 097 * without blocking by the next invocation of a method for this input 098 * stream. The next invocation might be the same thread or another thread. A 099 * single read or skip of this many bytes will not block, but may read or 100 * skip fewer bytes. 101 * 102 * @return an estimate of the number of bytes that can be read (or skipped 103 * over) from this input stream without blocking or {@code 0} when 104 * it reaches the end of the input stream. 105 * @throws IOException if an I/O error occurs. 106 */ 107 @Override 108 public int available() throws IOException { 109 return 0; 110 } 111 112 /** 113 * Overrides the 114 * {@link org.apache.commons.crypto.stream.input.Input#read(long, byte[], int, int)} 115 * . Reads up to {@code len} bytes of data from the input stream into 116 * an array of bytes. An attempt is made to read as many as {@code len} 117 * bytes, but a smaller number may be read. The number of bytes actually 118 * read is returned as an integer. 119 * 120 * @param position the given position within a stream. 121 * @param buffer the buffer into which the data is read. 122 * @param offset the start offset in array buffer. 123 * @param length the maximum number of bytes to read. 124 * @return the total number of bytes read into the buffer, or 125 * {@code -1} if there is no more data because the end of the 126 * stream has been reached. 127 * @throws IOException if an I/O error occurs. 128 */ 129 @Override 130 public int read(final long position, final byte[] buffer, final int offset, final int length) 131 throws IOException { 132 throw new UnsupportedOperationException( 133 "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( 148 "Seek is not supported by this implementation"); 149 } 150 151 /** 152 * Overrides the 153 * {@link org.apache.commons.crypto.stream.input.Input#seek(long)}. Closes 154 * this input and releases any system resources associated with the under 155 * layer input. 156 * 157 * @throws IOException if an I/O error occurs. 158 */ 159 @Override 160 public void close() throws IOException { 161 channel.close(); 162 } 163 164 /** 165 * Gets the skip buffer. 166 * 167 * @return the buffer. 168 */ 169 private ByteBuffer getSkipBuf() { 170 if (buf == null) { 171 buf = ByteBuffer.allocate(SKIP_BUFFER_SIZE); 172 } 173 return buf; 174 } 175}