Stream States


Streams and Recursion Software I/O objects maintain state information that can be used to determine whether the stream or device is ready for a read or write. Binary streams respond to the following messages.

eof bool eof() const
Returns true if the device attached to the stream is at end-of-input.
good bool good() const
Returns true if both the device attached to the stream and the stream are ready for a read or write; that is, the stream has not failed, the device has not failed, and the device is not at end-of-input.
clear void clear() const
Clears both the stream and the device from a failed state, returning the stream to a good() state. Clearing may or may not allow a successful read or write, depending on the reason for the failure.

The most basic stream state is end-of-input, which is used even in situations of no error occurrence. The following example shows a simple case to illustrate the end-of-input state. In this example, the last read does not change the value of result from its initial value of -1 , because an os_bstream read that results in end-of-input or failure does not modify the result.

Example <ospace/stream/examples/state1.cpp>
#include <fstream>
#include <ospace/stream.h>

void
write()
  {
  fstream file( "state1.bin", ios::binary | ios::out | ios::trunc );
  os_bstream stream( os_adapter_for( file ) );
  for (int i = 0; i < 3; i++)
    stream << i;
  }

void
read()
  {
  fstream file( "state1.bin", ios::binary | ios::in );
  os_bstream stream( os_adapter_for( file ) );

  while ( stream.good() )
    {
    int result = -1;
    stream >> result;
    cout << "eof() = " << stream.eof();
    cout << "    good() = " << stream.good();
    cout << "    result =  " << result << endl;
    }
  }

void
main()
  {
  os_streaming_toolkit initialize;
  write();
  read();
  }

eof() = 0    good() = 1    result =  0
eof() = 0    good() = 1    result =  1
eof() = 0    good() = 1    result =  2
eof() = 1    good() = 0    result =  -1

The following example shows how the good() state of an os_bstream changes when an error occurs in the stream. Refer to the "Exception Handling" section of Introduction to Communications for more information on exceptions.

Example <ospace/stream/examples/state2.cpp>
#include <fstream>
#include <ospace/stream.h>
#include <ospace/time.h>
#include <ospace/uss/time.h>

void
write()
  {
  fstream file( "state2.bin",  ios::binary | ios::out | ios::trunc );
  os_bstream stream( os_adapter_for( file ) );
  os_time time = os_time::now();
  cout << "Writing: " << time << endl;
  stream << time;
  }

void
read()
  {
  fstream file( "state2.bin",  ios::binary | ios::in );
  os_bstream stream( os_adapter_for( file ) );
  os_date date;
  cout << "stream.good() before = " << stream.good() << endl;
  cout << "Reading os_date to cause a stream type error." << endl;
  stream >> date;
  cout << endl << "stream.good() after = " << stream.good() << endl;
  }
void
main()
  {
  os_streaming_toolkit init_streaming;
  os_time_toolkit init_time;

  try
    {
    write();
    read();
     }
  catch ( os_streaming_toolkit_error& error )
    {
    cout << "Caught os_streaming_toolkit_error:" << endl;
    cout << "\t" << error.what() << endl;
    cout << "\t" << error.description( error.code() ) << endl;
    }
}

Writing: 16:22:39.648328
stream.good() before = 1
Reading os_date to cause a stream type error.
Caught os_streaming_toolkit_error :
        type_mismatch: Tried to read os_date but got os_time             [bstream.cpp:1295]
        Attempted to read wrong type.
	

When reading and writing with an os_bstream , only the stream throws exceptions. Exceptions raised by the underlying device are handled by the device adapter. For example, if you read from an unopened os_file using os_bstream , no exception is thrown; however, the return value for the stream's good() state changes to reflect the error. The following example shows this case.

Example <ospace/stream/examples/state3.cpp>
#include <iostream>
#include <ospace/file.h>
#include <ospace/stream.h>

void
main()
  {
  os_file_toolkit init_file;
  os_streaming_toolkit init_stream;

  os_file file
    (
    "state3.bin",
    os_open_control::create_new,
    os_io_control::write_only_access
    );
  os_bstream stream( os_adapter_for( file ) );

  cout << "stream.good() before = " << stream.good() << endl;
  try
    {
     cout << "Reading int from write-only file." << endl;
    int value;
     stream >> value;
    }
  catch ( os_streaming_toolkit_error& )
    {
     cout << "Never executes." << end1;
    }
  cout << "stream.good() after = " << stream.good() << endl;
  }

stream.good() before = 1
Reading int from write-only file.
stream.good() after = 0

When using device adapters, the device error is not lost in the event of an error. Each device adapter caches its specific error. Refer to Streaming Text Streams for an example that shows the retrieval of device adapter error results.


Copyright©1994-2026 Recursion Software LLC
All Rights Reserved - For use by licensed users only.