001: /*_############################################################################
002: _##
003: _## SNMP4J - BERInputStream.java
004: _##
005: _## Copyright (C) 2003-2008 Frank Fock and Jochen Katz (SNMP4J.org)
006: _##
007: _## Licensed under the Apache License, Version 2.0 (the "License");
008: _## you may not use this file except in compliance with the License.
009: _## You may obtain a copy of the License at
010: _##
011: _## http://www.apache.org/licenses/LICENSE-2.0
012: _##
013: _## Unless required by applicable law or agreed to in writing, software
014: _## distributed under the License is distributed on an "AS IS" BASIS,
015: _## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016: _## See the License for the specific language governing permissions and
017: _## limitations under the License.
018: _##
019: _##########################################################################*/
020:
021: package org.snmp4j.asn1;
022:
023: import java.io.*;
024: import java.nio.ByteBuffer;
025: import java.nio.BufferUnderflowException;
026:
027: /**
028: * The <code>BERInputStream</code> class wraps a <code>ByteBuffer</code> and
029: * implements the <code>InputStream</code> abstract class.
030: * positions in the input stream.
031: *
032: * @author Frank Fock
033: * @version 1.6.1
034: */
035:
036: public class BERInputStream extends InputStream {
037:
038: private ByteBuffer buffer;
039:
040: public BERInputStream(ByteBuffer buffer) {
041: this .buffer = buffer;
042: buffer.mark();
043: }
044:
045: public ByteBuffer getBuffer() {
046: return buffer;
047: }
048:
049: public void setBuffer(ByteBuffer buf) {
050: this .buffer = buf;
051: }
052:
053: public int read() throws java.io.IOException {
054: try {
055: return (buffer.get() & 0xFF);
056: } catch (BufferUnderflowException ex) {
057: throw new IOException(
058: "Unexpected end of input stream at position "
059: + getPosition());
060: }
061: }
062:
063: /**
064: * Returns the number of bytes that can be read (or skipped over) from this
065: * input stream without blocking by the next caller of a method for this input
066: * stream.
067: *
068: * @return the number of bytes that can be read from this input stream without
069: * blocking.
070: * @throws IOException if an I/O error occurs.
071: */
072: public int available() throws IOException {
073: return buffer.remaining();
074: }
075:
076: /**
077: * Closes this input stream and releases any system resources associated with
078: * the stream.
079: *
080: * @throws IOException if an I/O error occurs.
081: */
082: public void close() throws IOException {
083: }
084:
085: /**
086: * Marks the current position in this input stream.
087: *
088: * @param readlimit the maximum limit of bytes that can be read before the
089: * mark position becomes invalid.
090: */
091: public synchronized void mark(int readlimit) {
092: buffer.mark();
093: }
094:
095: /**
096: * Tests if this input stream supports the <code>mark</code> and
097: * <code>reset</code> methods.
098: *
099: * @return <code>true</code> if this stream instance supports the mark and
100: * reset methods; <code>false</code> otherwise.
101: */
102: public boolean markSupported() {
103: return true;
104: }
105:
106: /**
107: * Reads some number of bytes from the input stream and stores them into the
108: * buffer array <code>b</code>.
109: *
110: * @param b the buffer into which the data is read.
111: * @return the total number of bytes read into the buffer, or <code>-1</code>
112: * is there is no more data because the end of the stream has been reached.
113: * @throws IOException if an I/O error occurs.
114: */
115: public int read(byte[] b) throws IOException {
116: if (buffer.remaining() <= 0) {
117: return -1;
118: }
119: int read = Math.min(buffer.remaining(), b.length);
120: buffer.get(b, 0, read);
121: return read;
122: }
123:
124: /**
125: * Reads up to <code>len</code> bytes of data from the input stream into an
126: * array of bytes.
127: *
128: * @param b the buffer into which the data is read.
129: * @param off the start offset in array <code>b</code> at which the data is
130: * written.
131: * @param len the maximum number of bytes to read.
132: * @return the total number of bytes read into the buffer, or <code>-1</code>
133: * if there is no more data because the end of the stream has been reached.
134: * @throws IOException if an I/O error occurs.
135: */
136: public int read(byte[] b, int off, int len) throws IOException {
137: if (buffer.remaining() <= 0) {
138: return -1;
139: }
140: int read = Math.min(buffer.remaining(), b.length);
141: buffer.get(b, off, len);
142: return read;
143: }
144:
145: /**
146: * Repositions this stream to the position at the time the <code>mark</code>
147: * method was last called on this input stream.
148: *
149: * @throws IOException if this stream has not been marked or if the mark has
150: * been invalidated.
151: */
152: public synchronized void reset() throws IOException {
153: buffer.reset();
154: }
155:
156: /**
157: * Skips over and discards <code>n</code> bytes of data from this input stream.
158: *
159: * @param n the number of bytes to be skipped.
160: * @return the actual number of bytes skipped.
161: * @throws IOException if an I/O error occurs.
162: */
163: public long skip(long n) throws IOException {
164: long skipped = Math.min(buffer.remaining(), n);
165: buffer.position((int) (buffer.position() + skipped));
166: return skipped;
167: }
168:
169: /**
170: * Gets the current position in the underlying <code>buffer</code>.
171: * @return
172: * <code>buffer.position()</code>.
173: */
174: public long getPosition() {
175: return buffer.position();
176: }
177:
178: /**
179: * Checks whether a mark has been set on the input stream. This can be used
180: * to determine whether the value returned by {@link #available()} is limited
181: * by a readlimit set when the mark has been set.
182: * @return
183: * always <code>true</code>. If no mark has been set explicitly, the mark
184: * is set to the initial position (i.e. zero).
185: */
186: public boolean isMarked() {
187: return true;
188: }
189:
190: /**
191: * Gets the total number of bytes that can be read from this input stream.
192: * @return
193: * the number of bytes that can be read from this stream.
194: */
195: public int getAvailableBytes() {
196: return buffer.limit();
197: }
198:
199: }
|