blob: 533491deb022f5533cedcc6b511bf20b7fdfcd47 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _DECAF_IO_INPUTSTREAM_H_
#define _DECAF_IO_INPUTSTREAM_H_
#include <decaf/io/IOException.h>
#include <decaf/io/Closeable.h>
#include <decaf/util/concurrent/Synchronizable.h>
#include <decaf/util/concurrent/Mutex.h>
#include <decaf/lang/exceptions/UnsupportedOperationException.h>
#include <decaf/lang/exceptions/NullPointerException.h>
#include <decaf/lang/exceptions/IndexOutOfBoundsException.h>
#include <decaf/util/Config.h>
namespace decaf{
namespace io{
/**
* A base class that must be implemented by all classes wishing to provide a
* class that reads in a stream of bytes
*
* @since 1.0
*/
class DECAF_API InputStream: public Closeable, virtual public util::concurrent::Synchronizable {
private:
// Synchronization object.
util::concurrent::Mutex mutex;
private:
InputStream(const InputStream&);
InputStream& operator=(const InputStream&);
public:
InputStream();
virtual ~InputStream();
/**
* Closes the InputStream freeing any resources that might have been acquired
* during the lifetime of this stream.
*
* The default implementation of this method does nothing.
*
* @throws IOException if an I/O error occurs while closing the InputStream.
*/
virtual void close();
/**
* Marks the current position in the stream A subsequent call to the
* reset method repositions this stream at the last marked position so
* that subsequent reads re-read the same bytes.
*
* If a stream instance reports that marks are supported then the stream
* will ensure that the same bytes can be read again after the reset method
* is called so long the readLimit is not reached.
*
* Calling mark on a closed stream instance should have no effect.
*
* The default implementation of this method does nothing.
*
* @param readLimit
* The max bytes read before marked position is invalid.
*/
virtual void mark(int readLimit);
/**
* Repositions this stream to the position at the time the mark method was
* last called on this input stream.
*
* If the method markSupported returns true, then:
* * If the method mark has not been called since the stream was created,
* or the number of bytes read from the stream since mark was last called
* is larger than the argument to mark at that last call, then an
* IOException might be thrown.
* * If such an IOException is not thrown, then the stream is reset to a
* state such that all the bytes read since the most recent call to mark
* (or since the start of the file, if mark has not been called) will be
* resupplied to subsequent callers of the read method, followed by any
* bytes that otherwise would have been the next input data as of the
* time of the call to reset.
*
* If the method markSupported returns false, then:
* * The call to reset may throw an IOException.
* * If an IOException is not thrown, then the stream is reset to a fixed
* state that depends on the particular type of the input stream and how
* it was created. The bytes that will be supplied to subsequent callers
* of the read method depend on the particular type of the input stream.
*
* The default implementation of this method throws an IOException.
*
* @throws IOException if an I/O error occurs.
*/
virtual void reset();
/**
* Determines if this input stream supports the mark and reset methods.
* Whether or not mark and reset are supported is an invariant property of
* a particular input stream instance.
*
* The default implementation of this method returns false.
*
* @return true if this stream instance supports marks
*/
virtual bool markSupported() const {
return false;
}
/**
* Indicates the number of bytes available. The default implementation of this
* methods returns 0. Classes that override this method may return the total
* number of bytes that are currently available for reading and others may simply
* return a value of one indicating that there is some data avaiable. The caller
* should view the result of this method as an absolute.
*
* The default implementation of this method returns zero.
*
* @return the number of bytes available on this input stream.
*
* @throws IOException if an I/O error occurs.
*/
virtual int available() const {
return 0;
}
/**
* Reads a single byte from the buffer. The value byte is returned as an int in the
* range 0 to 255. If no byte is available because the end of the stream has been reached,
* the value -1 is returned. This method blocks until input data is available, the end of
* the stream is detected, or an exception is thrown.
*
* The default implementation of this method calls the internal virtual method doReadByte
* which is a pure virtual method and must be overridden by all subclasses.
*
* @return The next byte or -1 if the end of stream is reached.
*
* @throws IOException if an I/O error occurs.
*/
virtual int read();
/**
* Reads up to size bytes of data from the input stream into an array of bytes. An
* attempt is made to read as many as size bytes, but a smaller number may be read.
* The number of bytes actually read is returned as an integer.
*
* This method blocks until input data is available, end of file is detected, or
* an exception is thrown.
*
* If size is zero, then no bytes are read and 0 is returned; otherwise, there is an
* attempt to read at least one byte. If no byte is available because the stream is
* at end of file, the value -1 is returned; otherwise, at least one byte is read and
* stored into b.
*
* This method called the protected virtual method doReadArray which by default is the
* same as calling read( buffer, size, 0, size ). Subclasses can customize the behavior
* of this method by overriding the doReadArray method to provide a better performing
* read operation.
*
* @param buffer
* The target buffer to write the read in data to.
* @param size
* The size in bytes of the target buffer.
*
* @return The number of bytes read or -1 if EOF is detected
*
* @throws IOException if an I/O error occurs.
* @throws NullPointerException if buffer passed is NULL.
*/
virtual int read(unsigned char* buffer, int size);
/**
* Reads up to length bytes of data from the input stream into an array of bytes. An
* attempt is made to read as many as length bytes, but a smaller number may be read.
* The number of bytes actually read is returned as an integer.
*
* This method blocks until input data is available, end of file is detected, or
* an exception is thrown.
*
* If length is zero, then no bytes are read and 0 is returned; otherwise, there is an
* attempt to read at least one byte. If no byte is available because the stream is
* at end of file, the value -1 is returned; otherwise, at least one byte is read and
* stored into b.
*
* The first byte read is stored into element b[off], the next one into b[off+1], and
* so on. The number of bytes read is, at most, equal to length. Let k be the number of
* bytes actually read; these bytes will be stored in elements b[off] through b[off+k-1],
* leaving elements b[offset+k] through b[offset+length-1] unaffected.
*
* In every case, elements b[0] through b[offset] and elements b[offset+length] through
* b[b.length-1] are unaffected.
*
* This method called the protected virtual method doReadArrayBounded which simply
* calls the method doReadByte() repeatedly. If the first such call results in an IOException,
* that exception is returned. If any subsequent call to doReadByte() results in a IOException,
* the exception is caught and treated as if it were end of file; the bytes read up to that
* point are stored into the buffer and the number of bytes read before the exception occurred
* is returned. The default implementation of this method blocks until the requested amount of
* input data has been read, end of file is detected, or an exception is thrown. Subclasses
* are encouraged to provide a more efficient implementation of this method.
*
* @param buffer
* The target buffer to write the read in data to.
* @param size
* The size in bytes of the target buffer.
* @param offset
* The position in the buffer to start inserting the read in data.
* @param length
* The maximum number of bytes that should be read into buffer.
*
* @return The number of bytes read or -1 if EOF is detected
*
* @throws IOException if an I/O error occurs.
* @throws NullPointerException if buffer passed is NULL.
* @throws IndexOutOfBoundsException if length > size - offset.
*/
virtual int read(unsigned char* buffer, int size, int offset, int length);
/**
* Skips over and discards n bytes of data from this input stream. The skip
* method may, for a variety of reasons, end up skipping over some smaller
* number of bytes, possibly 0. This may result from any of a number of
* conditions; reaching end of file before n bytes have been skipped is
* only one possibility. The actual number of bytes skipped is returned.
*
* The skip method of InputStream creates a byte array and then repeatedly
* reads into it until num bytes have been read or the end of the stream has
* been reached. Subclasses are encouraged to provide a more efficient
* implementation of this method.
*
* @param num
* The number of bytes to skip.
*
* @return total bytes skipped
*
* @throws IOException if an I/O error occurs.
* @throws UnsupportedOperationException if the concrete stream class does
* not support skipping bytes.
*/
virtual long long skip(long long num);
/**
* Output a String representation of this object.
*
* The default version of this method just prints the Class Name.
*
* @return a string representation of the object.
*/
virtual std::string toString() const;
protected: // Virtual doRead methods that can be overridden to customize subclasses.
virtual int doReadByte() = 0;
virtual int doReadArray(unsigned char* buffer, int size);
virtual int doReadArrayBounded(unsigned char* buffer, int size, int offset, int length);
public: // Synchronizable
virtual void lock() {
mutex.lock();
}
virtual bool tryLock() {
return mutex.tryLock();
}
virtual void unlock() {
mutex.unlock();
}
virtual void wait() {
mutex.wait();
}
virtual void wait(long long millisecs) {
mutex.wait(millisecs);
}
virtual void wait(long long millisecs, int nanos) {
mutex.wait(millisecs, nanos);
}
virtual void notify() {
mutex.notify();
}
virtual void notifyAll() {
mutex.notifyAll();
}
};
}}
#endif /*_DECAF_IO_INPUTSTREAM_H_*/