nlib
nn::nlib::InputStream Class Referenceabstract

The base class for input streams. This class cannot be instantiated. More...

#include "nn/nlib/InputStream.h"

+ Inheritance diagram for nn::nlib::InputStream:

Public Member Functions

errno_t GetErrorValue () const noexcept
 Gets the error value. More...
 
size_t Pos () const noexcept
 Returns the current position in the stream. More...
 
uint64_t Pos64 () const noexcept
 Returns the current position in the stream as a 64-bit value. More...
 
bool IsEos () noexcept
 Returns true if the stream is finished being read through to the end. If the stream has not been read through to the end, or if an error occurs, the function returns false. More...
 
int Read () noexcept
 Reads one byte of data from the stream. More...
 
NLIB_CHECK_RESULT int Peek () noexcept
 Reads the next byte without consuming the stream. More...
 
size_t Skip (size_t nbytes) noexcept
 Skips over the number of bytes specified by nBytes. More...
 
size_t Read (void *ptr, size_t nbytes) noexcept
 Reads the number of bytes of data specified by nBytes into the memory region specified by ptr. More...
 
bool Close () noexcept
 Closes the stream. Returns true if successful. More...
 
 operator bool () const
 Returns true if no internal error has occurred.
 
Basic Member Functions
constexpr InputStream () noexcept
 Instantiates the object. This function is called from the derived class.
 
virtual ~InputStream () noexcept
 Destructor. This function is called from the derived class.
 

Protected Member Functions

Functions Used From Derived Classes
void ResetBuffer (void *p, size_t nbytes) noexcept
 Sets the buffer held by InputStream. More...
 
void SetError (errno_t e) const noexcept
 Sets an error to InputStream. More...
 

Detailed Description

The base class for input streams. This class cannot be instantiated.

Description
It is the base class for input streams with a synchronous and sequential access interface. The place into which the data is read is defined by the derived class.
To read data one byte at a time, use code like the following.
InputStream& is = .... the derived class object ....;
int c;
while ((c = is.Read()) >= 0) {
// A process that used the bytes read into c.
}
if (nlib_is_error(is)) {
// An error occurred while reading.
}
To prepare a buffer and read a collection of a certain number of bytes, use code like the following.
InputStream& is = .... the derived class object ....;
uint8_t* buf = ... N bytes of memory ...;
size n = is.Read(buf, N);
if (n == 0 && nlib_is_error(is)) {
// An error occurred while reading.
}
To read UTF-8 text data, use a TextReader object. Normalize newlines and check for UTF-8, and then convert it into UTF-32 and pass it to the user.
InputStream& is = .... the derived class object ....;
TextReader r;
if (nlib_is_error(r.Init(&is))) { Error; }
int c;
while ((c = is.Read()) >= 0) {
// A process that used the code points (UTF-32) read into c.
}
if (nlib_is_error(r)) {
// An error occurred while reading.
}

Information for Implementing Derived Classes

The specifications of the InputStream class may change without notice. You can lower your risk by implementing derived classes independently whenever possible. However, if necessary, you can define derived classes by overriding the following virtual function.
size_t FillBuffer_(void* p, size_t nbytes)
p is the pointer to the data to set, and nBytes is the size. The function is called when the user attempts to read data but there is no data inside the InputStream internal buffer. The p parameter holds the pointer to the internal buffer or to a user-specified buffer.
The value that is returned is the amount of data that was actually set. It is a value equal to or less than nBytes. The function only returns 0 if there was an error or if it was the end of the data. The function must block if the data is not available yet.
If the buffer has not yet been configured by the GetWorkBuffer_ function (described below), you can call this function with NULL specified for the p parameter. If you do that, you must call the ResetBuffer function and reset the InputStream internal buffer.
In the case of errors, deal with them as shown in the examples below.
  • If there is no compatible device (for example, the handle is invalid), set EBADF and return 0.
  • If there is a confirmed failure while reading, set an error (for example, EIO) and return 0.
Note that 0 must be returned if there is an error and also if data has been partially read.
bool Close_()
Closes internal handles and the like. No matter how you implement this function, you must free all associated resources that are being held internally. Also be careful not to call the Close_ function from the base class destructor.
In the case of errors, deal with them as shown in the examples below.
  • If there is no compatible device (for example, the handle is invalid), set EBADF and return false.
  • If the process fails during closing, set some error (for example, EIO) and return false.
Note that even if an error occurs, you must make sure that the handle and other internal resources are freed.
void* GetWorkBuffer_(size_t* nbytes)
If is_buf_ is NULL, InputStream calls this function to try to get a buffer. The return value is the pointer to the buffer. The size gets set in nBytes. The buffer itself is owned by the derived class, so the freeing of the buffer must be coded in the derived class.
If memory fails to be allocated and no buffer is passed, you must return NULL and set nBytes to 0.
If you do not override this function, it returns NULL and -1 is substituted for the value in nBytes. In that case, InputStream uses the FillBuffer_ function to try to get a buffer.

Notes About the Configuration of InputStream

When you read data with the InputStream class, the data is invariably cached in a buffer. The purpose of this cache is not to collect the read operations from a device, but rather to limit the calls to virtual functions.
When designing InputSrteam, using an interface class as listed below as the base class makes the design simple.
class InputStream {
public:
virtual int Read()=0;
virtual int Peek()=0;
...
};
This approach, however, is impractical because calling data on a byte basis causes significant overhead of the virtual functions.

Definition at line 29 of file InputStream.h.

Member Function Documentation

◆ Close()

nn::nlib::InputStream::Close ( )
noexcept

Closes the stream. Returns true if successful.

Returns
Returns true when successful.
Description
If the function returns false, a process failed. Even if a process failed, you do not need to close again.

◆ GetErrorValue()

nn::nlib::InputStream::GetErrorValue ( ) const
inlinenoexcept

Gets the error value.

Returns
Returns the error value.
Description
Any value other than 0 indicates an error. The error values generally depend on the implementation.

Definition at line 44 of file InputStream.h.

◆ IsEos()

nn::nlib::InputStream::IsEos ( )
inlinenoexcept

Returns true if the stream is finished being read through to the end. If the stream has not been read through to the end, or if an error occurs, the function returns false.

Returns
Returns true if the end of the stream has been reached.

Definition at line 48 of file InputStream.h.

◆ Peek()

nn::nlib::InputStream::Peek ( )
inlinenoexcept

Reads the next byte without consuming the stream.

Returns
Returns the read data, or -1.
Description
Returns the data that was read. If the function fails or the stream is finished being read through to the end, the function returns -1.

Definition at line 64 of file InputStream.h.

◆ Pos()

nn::nlib::InputStream::Pos ( ) const
inlinenoexcept

Returns the current position in the stream.

Returns
The current position in the stream (the number of bytes that have been read).
Description
Note that if you use this member function after the stream has been closed, it does not get a correct value.

Definition at line 46 of file InputStream.h.

◆ Pos64()

nn::nlib::InputStream::Pos64 ( ) const
inlinenoexcept

Returns the current position in the stream as a 64-bit value.

Returns
The current position in the stream (the number of bytes that have been read).

Definition at line 47 of file InputStream.h.

◆ Read() [1/2]

nn::nlib::InputStream::Read ( )
inlinenoexcept

Reads one byte of data from the stream.

Returns
Returns the read data, or -1.
Description
Returns the data that was read. If the function fails or the stream is finished being read through to the end, the function returns -1.
Consequently, if -1 is read, you must determine whether an error occurred or the end of the stream was reached.
InputStream& is = ....;
c = is.Read();
if (c < 0) {
if (nlib_is_error(is)) {
// An error has occurred.
} else {
// The end of the stream has been reached.
}
}

Definition at line 56 of file InputStream.h.

◆ Read() [2/2]

nn::nlib::InputStream::Read ( void *  ptr,
size_t  nbytes 
)
inlinenoexcept

Reads the number of bytes of data specified by nBytes into the memory region specified by ptr.

Parameters
[in,out]ptrThe location in memory used to store the read data.
[in]nbytesThe number of bytes to be read.
Returns
Returns the number of bytes actually read.
Description
If the number of bytes read is specified as 0, either there was an error or the stream is over. The stream might also be over if some other value smaller than nBytes is returned.

Definition at line 73 of file InputStream.h.

◆ ResetBuffer()

nn::nlib::InputStream::ResetBuffer ( void *  p,
size_t  nbytes 
)
inlineprotectednoexcept

Sets the buffer held by InputStream.

Parameters
[in]pPointer to the buffer.
[in]nbytesBuffer size.

Definition at line 95 of file InputStream.h.

◆ SetError()

nn::nlib::InputStream::SetError ( errno_t  e) const
inlineprotectednoexcept

Sets an error to InputStream.

Parameters
[in]eAn error value.
Description
If a non-zero error has been set already, that error value is not overwritten.

Definition at line 99 of file InputStream.h.

◆ Skip()

nn::nlib::InputStream::Skip ( size_t  nbytes)
noexcept

Skips over the number of bytes specified by nBytes.

Parameters
[in]nbytesThe number of bytes to skip.
Returns
Returns the number of bytes actually skipped.
Description
Skipping data can be more efficient than reading and discarding data using the Read function.

The documentation for this class was generated from the following files: