Rogue Wave banner
Previous fileTop of DocumentContentsIndex pageNext file
Advanced Tools Module User's Guide
Rogue Wave web site:  Home Page  |  Main Documentation Page

4.2 Examples

This section explains the basics about using the Streams package and uses examples to introduce concepts and classes.

4.2.1 Creating and Using Streams with Only One Streaming Element

The first example shows how to create and use a single streaming element. It creates an instance of class RWByteToStreambufOutputStreamImp, which uses an instance of the iostreams class filebuf to write to a file. The complete example is located in directory ...\examples\stream in the file binaryTerminalWrite.cpp. Only part of the code is presented below.

//1

Creates an iostreams file buffer, and opens it in output mode. If the code is compiled on a PC platform, the file buffer needs to be opened in binary mode by specifying the flag ios::binary. If you built the Advanced Tools Module with the Standard iostreams library, you need to qualify filebuf and other iostreams elements with std::, or you need to include using declarations. The complete example uses macros defined by the Essential Tools Module in order to support both the classic and Standard iostreams.

//2

Creates a concrete instance of class RWByteToStreambufOutputStreamImp. The class is created by calling its static member function make(), which creates an instance of self and returns it as a binary output stream handle. The concrete stream classes, except for the adapter classes, follow the same creation pattern. They are created using a public static member function called make(), which returns a handle of the stream corresponding family type. The concrete stream constructors are protected, which prevents direct construction. In this example, the make() function takes a reference to an iostreams streambuf object that is used as the sink of bytes.

//3

Declares an array of bytes. RWByte is a typedef for unsigned char and is used to represent bytes.

//4

Inserts single byte elements into the stream. Insertion operations can be cascaded as in the following example which inserts the array's first three bytes into the stream, and then the manipulator rwFlush triggers the stream flushing:

    binOutputStream << array_[0] << array_[1] << array_[2] 
      << rwFlush;
    
//5

Inserts single byte elements into the stream.

//6

Inserts an array of byte elements into the stream.

//7

Catches exceptions potentially thrown by the stream. The Streams package defines two exception classes: RWExternalStreamException and RWIncompleteStreamOperation. Class RWExternalStreamException returns an error message and an error code. Class RWIncompleteStreamOperation inherits from class RWExternalStreamException and is thrown when an operation partially succeeds. In the example, writing an array of bytes might fail after writing only a few bytes. You can query an instance of class RWIncompleteStreamOperation for the number of elements successfully written. For more information, see Section 4.3, "Error Handling."

The next example implements the previous example's corresponding input operation. It creates an instance of class RWByteFromStreambufInputStreamImp, which uses an instance of the iostreams class filebuf to read from the file written in the previous example. The complete example is located in directory ...\examples\stream in the file binaryTerminalRead.cpp. Only part of the code is presented below.

//1

Creates an iostreams file buffer, and opens it in input mode. If the code is compiled on a PC platform, the file buffer needs to be opened in binary mode by specifying the flag ios::binary. If you built the Advanced Tools Module with the Standard iostreams library, you need to qualify filebuf and other iostreams elements with std::, or you need to include using declarations. The complete example code makes use of macros defined by the Essential Tools Module in order to support both the classic and Standard iostreams.

//2

Creates a concrete instance of class RWByteFromStreambufInputStreamImp. The class is created by calling its static member function make(), which creates an instance of self and returns it as a binary input stream handle. In this example, the make() function takes a reference to an iostreams streambuf object that is used as the source of bytes.

//3

Declares a single byte variable. RWByte is a typedef for unsigned char and is used by the Streams package to represent bytes.

//4

Extracts single byte elements from the stream. Extraction operations can be cascaded as in the following example which extracts three bytes from the stream. If the stream cannot provide enough bytes, then an RWExternalStreamException is thrown.

    RWByte value1, value2, value3;
    binInputStream >> value1 >> value2  >> value3;
    
//5

Extracts single byte elements from the stream.

//6

Reads an array of byte elements from the stream. The number of actual bytes extracted is returned, and if this number differs from the number requested, then the input stream member function isFail() returns true.

//7

Reads bytes from the stream until a certain value is read or a maximum number of bytes is read. If the byte value requested is read, it is removed from the stream, but not inserted in the result array. The readUntil() function returns the number of elements inserted in the result array. If the function fails to read the requested byte value, then the input stream member function isFail() returns true.

//8

Checks the stream status.

//9

Checks for more bytes in the stream.

//10

Catches exceptions potentially thrown by the stream. Class RWExternalStreamException is the base class for all the exceptions thrown by the Streams package. It returns an error message and an error code. For more information on exceptions, see Section 4.3, "Error Handling."

Two more examples demonstrating how to create and use single streaming element can be found in directory examples\stream in the files narrowCharacterTerminalWrite.cpp and narrowCharacterTerminalRead.cpp. The first example creates an instance of class RWCharToStreambufOutputStreamImp, which uses an instance of the -iostreams class filebuf to write to a file. The second example creates an instance of class RWCharFromStreambufInputStreamImp, which uses an instance of the -iostreams class filebuf to read from the file written in the previous example.

4.2.2 Creating and Using Chains of Streaming Elements

A chain of streaming elements is the composition of a single terminal streaming element with one or more filtered stream elements. The terminal streaming element is constructed first and then passed to a filtered stream constructor, which in turn can be passed to another filtered stream constructor. Each streaming element is responsible for a particular task and is independent of the task performed by other streaming elements. The filtered stream elements are not aware of the real type of the streaming element that is used internally. They are linked to it by a handle instance.

4.2.2.1 Output Example

The first example shows how to create and use a chain of streaming elements. It creates a Unicode character output stream that encodes UTF-16 characters using the UCS Transformation Format 8-bit form (UTF-8). The UTF-8 Unicode stream is connected to a buffered binary output stream that sends the transformed bytes to a file:

Figure 13 is a representation of the chain of streaming elements used in this example.

Figure 13: Streaming elements—output stream

The complete example is located in directory ...\examples\stream in the file UnicodeCharacterFilteredWrite.cpp. Only part of the code is presented below.

//1

Stores UTF-16 characters using type RWUChar, which is a typedef for unsigned short. In this example, 17 UTF-16 characters, which are part of the Tibetan Unicode character set, are stored.

//2

Creates an iostreams file buffer, and opens it in output mode. If the code is compiled on a PC platform, the file buffer needs to be opened in binary mode by specifying the flag ios::binary. If you built the Advanced Tools Module with the Standard iostreams library, you need to qualify filebuf and other iostreams elements with std::, or you need to include using declarations. The complete example code makes use of macros defined by the Essential Tools Module in order to support both the classic and Standard iostreams.

//3

Creates a concrete instance of class RWByteToStreambufOutputStreamImp. The class is created by calling its static member function make(), which creates an instance of self and returns it as a binary output stream handle. In this example, the make() function takes a reference to an iostreams streambuf object that is used as the sink of bytes.

//4

Creates a concrete instance of class RWBufferedByteOutputStreamImp. The class is created by calling one of its static member functions make(), which creates an instance of self and returns it as a binary output stream handle. Several static make() functions are available to construct an instance of class RWBufferedByteOutputStreamImp. All take a handle to the next streaming element, which must be of type RWByteOutputStream. The static make() function in this example takes a second parameter that specifies the size of the buffer to be allocated.

//5

Creates a concrete instance of class RWUCharToUTF8ByteOutputStreamImp. The class is created by calling its static member function make(), which creates an instance of self and returns it as a UTF-16 output stream handle. The make() function takes a handle to the next streaming element, which must be of type RWByteOutputStream. It is used as a sink for the bytes generated when converting UTF-16 characters to the UTF-8 form.

//6

Inserts single UTF-16 characters into the stream. Insertion operations can be cascaded as in the following example which inserts the array's first three UTF-16 characters into the stream, and then the manipulator rwFlush triggers the stream flushing.

    UTF8OutputStream << array[0] << array[1] << array[2] << rwFlush;
    
//7

Inserts single UTF-16 characters into the stream.

//8

Inserts an array of UTF-16 characters into the stream.

//9

Catches exceptions potentially thrown by the stream. The Streams package defines two exception classes: RWExternalStreamException and RWIncompleteStreamOperation.

Class RWExternalStreamException returns an error message and an error code. Class RWIncompleteStreamOperation inherits from class RWExternalStreamException and is thrown when an operation partially succeeds. In the above example, writing an array of UTF-16 characters might fail after writing some of the characters. An instance of class RWIncompleteStreamOperation can be queried for the number of elements successfully written. For more information on exceptions, see Section 4.3, "Error Handling."

4.2.2.2 Input Example

The next example implements the previous example's corresponding input operation. It creates a UTF-16 character input stream that decodes UTF-16 characters using the UTF-8 form. The UTF-8 Unicode stream is connected to a buffered binary input stream that gets bytes from the file created in the previous example. The class RWUCharFromUTF8ByteInputStreamImp converts the bytes into UTF-16 characters. The class RWBufferedByteInputStreamImp is connected to class RWByteFromStreambufInputStreamImp to provide the buffered byte input stream.

Figure 14 is a representation of the chain of streaming elements used in this example.

Figure 14: Streaming elements—input stream

The complete example is located in directory ...\examples\stream in the file UnicodeCharacterFilteredRead.cpp. Only part of the code is presented below.

//1

Creates an iostreams file buffer, and opens it in input mode. If the code is compiled on a PC platform, the file buffer needs to be opened in binary mode by specifying the flag ios::binary. If you built the Advanced Tools Module with the Standard iostreams library, you need to qualify filebuf and other iostreams elements with std::, or you need to include using declarations. The complete code makes use of macros defined by the Essential Tools Module in order to support both the classic and Standard iostreams.

//2

Creates a concrete instance of class RWByteFromStreambufInputStreamImp. The class is created by calling its static member function make(), which creates an instance of self and returns it as a binary input stream handle. In this example the make() function takes a reference to an iostreams streambuf object that is used as the source of bytes.

//3

Creates a concrete instance of class RWBufferedByteInputStreamImp. The class is created by calling one of its static member functions make(), which creates an instance of self and returns it as a binary input stream handle. Several static make() functions are available to construct an instance of class RWBufferedByteInputStreamImp. All take a handle to the next streaming element, which must be of type RWByteInputStream. The static make() function used in this example takes a second parameter that specifies the size of the buffer to be allocated.

//4

Creates a concrete instance of class RWUCharFromUTF8ByteInputStreamImp. The class is created by calling its static member function make(), which creates an instance of self and returns it as a UTF-16 input stream handle. The make() function takes a handle to the next streaming element, which must be of type RWByteInputStream. It is used as the source of bytes.

//5

Declares a single UTF-16 character variable. RWUChar is a typedef for unsigned short and is used by the Streams package to represent UTF-16 characters.

//6

Extracts single UTF-16 characters from the stream. Extraction operations can be cascaded as in the following example which extracts three UTF-16 characters from the stream. If the stream cannot provide enough UTF-16 characters, then a RWExternalStreamException is thrown.

    RWUChar value1, value2, value3;
    UTF8InputStream >> value1 >> value2  >> value3;
    
//7

Extracts single UTF-16 characters from the stream.

//8

Reads an array of UTF-16 characters from the stream. The number of actual characters extracted is returned, and if this number differs from the number requested, then the input stream member function isFail() returns true.

//9

Read UTF-16 characters from the stream until a certain value is read or a maximum number of characters is read. If the UTF-16 character value requested is read, it is removed from the stream, but not inserted in the result array. The readUntil function returns the number of elements inserted in the result array. If the function fails to read the requested UTF-16 character value, then the input stream member function isFail() returns true.

//10

Checks the stream status.

//11

Checks for more UTF-16 characters in the stream.

//12

Catches exceptions potentially thrown by the stream. Class RWExternalStreamException is the base class for all exceptions thrown by the Streams package. It returns an error message and an error code. For more information on exceptions, see Section 4.3, "Error Handling."

4.2.3 Creating and Using Thread-safe Chains of Streaming Elements

A thread-safe chain of streaming elements is a composition of streaming elements in which one of the streaming elements is a synchronized filtered stream. Synchronized filtered streams ensure that each operation carried out on a stream is executed atomically in a multithreaded environment. Synchronized filtered streams can also be used in conjunction with guarded filtered streams to ensure that a group of operations are executed atomically in a multithreaded environment. For more information on the synchronized and guarded filtered streams, see Section 3.4.3.2, "Synchronized Streams," and Section 3.4.3.3, "Guarded Streams."

4.2.3.1 Creating a Synchronized Data Output Stream

The first example demonstrates how to create and use a thread-safe chain of streaming elements. It creates a synchronized data output stream (RWSynchronizedDataOutputStreamImp) that connects to a RWNativeDataToByteOutputStreamImp stream, which encodes C++ base types as a sequence of bytes using their native binary representation.

The RWNativeDataToByteOutputStreamImp stream is in turn connected to a buffered binary output stream that sends the transformed bytes to a file. The class RWBufferedByteOutputStreamImp is connected to class RWByteToStreambufOutputStreamImp to provide the buffered byte output stream. This example requires the Streams package, as well as the Execution Tracing, Thread-compatible Exception, Synchronization, Smart Pointer, Threading, Functor, and Interthread Communication packages from the Threads Module.

Figure 15 is a representation of the chain of streaming elements used in this example.

Figure 15: Thread-safe chain of streaming elements

The complete source for the examples in Section 4.2.3.2 and Section 4.2.3.3 is located in examples\stream\dataFilteredWrite.cpp. Only part of the code is presented here.

4.2.3.2 Creating and Managing Threads Using Active Objects

The example uses active objects to carry out asynchronous operations on a unique thread-safe data stream. Active objects execute in their own thread. They start their execution upon construction and wait for their processing to terminate upon destruction, if necessary. This example uses two different kinds of active objects. The first one writes ten elements of one of the C++ base types to a data output stream, ensuring that the ten elements are written in one synchronized operation. The second type of active object writes twenty elements to a data output stream, ensuring that each individual operation on the data output stream is synchronized. The code for both active object classes is presented below.

//1

The active object's constructor takes a handle to the data output stream that is used internally as the sink of data. The handle points to the thread-safe chain of streaming elements. If the first element of the chain of streaming elements pointed to by the data output stream handle is not of type RWSynchronizedDataOutputStreamImp, then the active object does not enforce proper thread synchronization. The second parameter is the C++ base type's value that is inserted ten times into the data output stream.

//2

Creates and starts a thread that executes the member function func().

//3

Upon destruction the active object waits for its thread to terminate execution and re-throws any exception raised while executing.

//4

Creates a temporary guarded output stream. All the operations carried out on the guarded output stream until its destruction are synchronized. The guarded output stream uses the internal lock provided by the synchronized data output stream class to which it is attached to enforce synchronization. The guarded output stream acquires the synchronized data output stream lock in its constructor and releases it in its destructor. Once the guarded output stream is constructed, any other threads accessing the guarded output stream's synchronized data output stream are blocked.

//5

Inserts the C++ base type's value provided at construction time into the temporary guarded data output stream.

The code for the second active object is similar to the code presented above with the exception of the func() function, which enforces synchronization at the operation level.

//1

Inserts the C++ base type's value provided at construction time into the data output stream. After each insertion, the active object's thread yields execution to any other thread candidate for execution. Therefore, only individual insertions are guaranteed to be synchronized because a synchronized data output stream is used as the sink of data.

4.2.3.3 Creating and Sharing a Synchronized Data Output Stream Among Several Active Objects

The following code constructs the thread-safe chain of streaming elements, and then constructs several active objects that use the same chain of streaming elements as the sink of data.

//1

Creates an iostreams file buffer, and opens it in output mode. If the code is compiled on a PC platform, the file buffer needs to be opened in binary mode by specifying the flag ios::binary. If you built the Advanced Tools Module with the Standard iostreams library, you need to qualify filebuf and other iostreams elements with std::, or you need to include using declarations. The complete example makes use of macros defined by the Essential Tools Module in order to support both the classic and Standard iostreams.

//2

Creates an instance of class RWByteToStreambufOutputStreamImp. The class is created by calling its static member function make(), which creates an instance of self and returns it as a binary output stream handle. In this example, the make() function takes a reference to an iostreams streambuf object that is used as the sink of bytes.

//3

Creates an instance of class RWBufferedByteOutputStreamImp. The class is created by calling one of its static member functions make(), which creates an instance of self and returns it as a binary output stream handle. Several static make() functions are available to construct an instance of class RWBufferedByteOutputStreamImp. All take a handle to the next streaming element, which must be of type RWByteOutputStream. The static make() function used in this example takes a second parameter that specifies the size of the buffer to be allocated.

//4

Creates an instance of class RWNativeDataToByteOutputStreamImp. The class is created by calling its static member function make(), which creates an instance of self and returns it as a data output stream handle. The make() function takes a handle to the next streaming element, which must be of type RWByteOutputStream. It is used as the sink for the bytes generated when converting C++ base types to their binary representation.

//5

Creates an instance of class RWSynchronizedDataOutputStreamImp. The class is created by calling its static member function make(), which creates an instance of self and returns it as a data output stream handle. The make() function takes a handle to the next streaming element, which must be of type RWDataOutputStream. Each operation executed on this stream is guaranteed to be synchronized in a multithreaded environment.

//6

Creates the active objects. They are passed the same synchronized data output stream at construction time. First, an active object writes the same element twenty times. Then, two active objects write the same element ten times in a single synchronized operation. The twenty elements written by the first active object are not necessarily written consecutively into the stream, but each element is written atomically. The elements of the other two active objects are written consecutively into the stream. For example, one element of the first active object might be written into the stream, then the ten elements of the second active object, then the second element of the first active object, then the ten elements of the third active object, and finally the eighteen remaining elements of the first active object.

//7

Each active object waits for its thread to finish execution before being destroyed.

//8

Catches exceptions potentially thrown by the stream. The Streams package defines two exception classes: RWExternalStreamException and RWIncompleteStreamOperation. Class RWExternalStreamException returns an error message and an error code. Class RWIncompleteStreamOperation inherits from class RWExternalStreamException and is thrown when an operation partially succeeds. For more information on exceptions, see Section 4.3, "Error Handling."

4.2.3.4 Active Objects and Data Input Streams

The example in this section implements the previous example's corresponding input operation. It creates a synchronized data input streamRWSynchronizedDataInputStreamImp that connects to an RWNativeDataFromByteInputStreamImp stream, which restores C++ base types from a sequences of bytes. The RWNativeDataFromByteInputStreamImp stream is then connected to a buffered binary input stream that reads bytes from the file created in the previous example. The class RWBufferedByteInputStreamImp is connected to class RWByteFromStreambufInputStreamImp to provide the buffered byte input stream.

This example requires the Streams package, as well as the Execution Tracing, Thread-compatible Exception, Synchronization, Smart Pointer, Threading, Functor, and Interthread Communication packages from the Threads Module.

Figure 16 is a representation of the chain of streaming elements used in this example.

Figure 16: Streaming with active objects

As in the previous example, this example uses active objects to carry out asynchronous operations on a unique thread-safe data stream. Only one type of active object is used. Its purpose is to read ten elements of one of the C++ base types from a data input stream, ensuring that the ten elements are read in one synchronized operation.

The complete example is located in directory ...\examples\stream in the file dataFilteredRead.cpp. The code for the active object class is presented below:

//1

The active object's constructor takes a handle to the data input stream that is used internally as the source of data. The handle points to the thread-safe chain of streaming elements. If the first element of the chain of streaming elements pointed to by the data input stream handle is not of type RWSynchronizedDataInputStreamImp, then the active object does not enforce proper thread synchronization.

//2

Creates and starts a thread that executes the member function func().

//3

Upon destruction the active object waits for its thread to terminate execution and re-throws any exception raised while executing.

//4

Creates a temporary guarded input stream. All operations carried out on the guarded input stream are synchronized until its destruction. The guarded input stream uses the internal lock provided by the synchronized data input stream class to which it is attached to enforce synchronization. The guarded input stream acquires the synchronized data input stream lock in its constructor and releases it in its destructor. Once the guarded input stream is constructed, any other threads accessing the guarded input stream's synchronized data input stream are blocked.

//5

Extracts the C++ base type from the temporary guarded data output stream and sends it to the standard output.

4.2.3.5 Creating and Sharing a Synchronized Data Input Stream Among Several Active Objects

The following code constructs the thread-safe chain of streaming elements, and then constructs several active objects that use the same chain of streaming elements as the source of data.

//1

Creates an iostreams file buffer, and opens it in input mode. If the code is compiled on a PC platform, the file buffer needs to be opened in binary mode by specifying the flag ios::binary. If you built the Advanced Tools Module with the Standard iostreams library, you need to qualify filebuf and other iostreams elements with std::, or you need to include using declarations. The complete example code makes use of macros defined by the Essential Tools Module in order to support both the classic and Standard iostreams.

//2

Creates an instance of class RWByteFromStreambufInputStreamImp. The class is created by calling its static member function make(), which creates an instance of self and returns it as a binary input stream handle. In this example, the make() function takes a reference to an iostreams streambuf object that is used as the source of bytes.

//3

Creates an instance of class RWBufferedByteInputStreamImp. The class is created by calling one of its static member functions make(), which creates an instance of self and returns it as a binary input stream handle. Several static make() functions are available to construct an instance of class RWBufferedByteInputStreamImp. All of them take a handle to the next streaming element, which must be of type RWByteInputStream. The static make() function used in this example takes a second parameter that specifies the size of the buffer to be allocated.

//4

Creates an instance of class RWNativeDataFromByteInputStreamImp. The class is created by calling its static member function make(), which creates an instance of self and returns it as a data input stream handle. The make() function takes a handle to the next streaming element, which must be of type RWByteInputStream. It is used as the source of bytes.

//5

Creates an instance of class RWSynchronizedDataInputStreamImp. The class is created by calling its static member function make(), which creates an instance of self and returns it as a data input stream handle. The make() function takes a handle to the next streaming element, which must be of type RWDataInputStream. Each operation executed on this stream is guaranteed to be synchronized in a multithreaded environment.

//6

Creates four active objects. They are passed the same synchronized data input stream at construction time. Each active object reads ten consecutive elements from the stream, and sends them to the standard output.

//7

Each active object waits for its thread to finish execution before being destroyed.

//8

Catches exceptions potentially thrown by the stream. Class RWExternalStreamException is the base class for all the exceptions thrown by the Streams package. It returns an error message and an error code. For more information on exceptions, see Section 4.3, "Error Handling."

4.2.4 Creating and Using Stream Adapter Classes in the Advanced Tools Module

The stream adapter classes adapt other streaming interfaces to the Advanced Tools Module streaming interface. This means that an application designed to use a streaming library such as iostreams can instantly use the Advanced Tools Module Streams package by using an adapter class as the first streaming element.

The Streams package contains adapter classes for both the iostreams library and the Essential Tools Module virtual streams.

4.2.4.1 The iostreams Adapter Classes

The Streams package has four adapter classes that implement the iostreams streambuf interface:

The iostreams adapter classes support both the Standard (as described in the C++ standard) and classic iostreams libraries.

4.2.4.2 Virtual Streams Adapter Classes in the Essential Tools Module

The Streams package has two adapter classes that implement the Essential Tools Module virtual input/output stream interface:

4.2.4.3 Architecture of the Adapter Classes

The main architectural difference between the stream adapter classes and the other stream concrete classes is that the adapter classes are not constructed using a public static make() function, and they are not manipulated using a handle class. The adapter classes provide a public constructor that takes a handle to the stream element to which they forward a request.

4.2.4.4 Using the Adapter Classes for Output

The first example of the Streams package's adapter classes creates a RWStreambufToCharOutputStream object that connects to an instance of class RWCharToStreambufOutputStreamImp, which in turn uses an iostreams filebuf as a sink of narrow characters. The instance of the adapter class RWStreambufToCharOutputStream is used to construct an iostreams object of type ostream, which is used as the sink of data in the rest of the example.

Figure 17 is a representation of the chain of streaming elements used in this example.

Figure 17: Streaming with adapter classes—output

The complete example is located in directory ...\examples\stream in the file adapterWrite.cpp. Only part of the code is presented below.

//1

Creates an iostreams file buffer, and opens it in output mode. If you built the Advanced Tools Module with the Standard iostreams library, you need to qualify filebuf and other iostreams elements with std::, or you need to include using declarations. The complete example code makes use of macros defined by the Essential Tools Module in order to support both the classic and Standard iostreams.

//2

Creates an instance of class RWCharToStreambufOutputStreamImp. The class is created by calling its static member function make(), which creates an instance of self and returns it as a narrow character output stream handle. In this example the make() function takes a reference to an iostreams streambuf object that is used as the sink of bytes.

//3

Creates the adapter class that implements the iostreams streambuf interface and forwards request to an Advanced Tools Module narrow character output stream.

//4

Creates an iostreams ostream object that uses the previously created adapter class as the sink of narrow characters.

//5

Uses the ostream object.

//6

Catches exceptions potentially thrown by the stream. The Streams package defines two exception classes: RWExternalStreamException and RWIncompleteStreamOperation. Class RWExternalStreamException returns an error message and an error code. Class RWIncompleteStreamOperation inherits from class RWExternalStreamException, and is thrown when an operation partially succeeds. An instance of class RWIncompleteStreamOperation can be queried for the number of elements successfully written. For more information on exceptions, see Section 4.3, "Error Handling."

4.2.4.5 Using the Adapter Classes for Input

The following example implements the previous example's corresponding input operation. It creates a RWStreambufFromCharInputStream object that connects to an instance of class RWCharFromStreambufInputStreamImp, which in turn uses an iostreams filebuf as a source of narrow characters. The instance of the adapter class RWStreambufFromCharInputStream is used to construct an iostreams object of type istream, which is used as the source of data in the rest of the example.

Figure 18 is a representation of the chain of streaming elements used in this example.

Figure 18: Streaming with adapter classes—input

The complete example is located in directory ...\examples\stream in the file adapterRead.cpp. Only part of the code is presented below.

//1

Creates an iostreams file buffer, and opens it in input mode. If you built the Advanced Tools Module with the Standard iostreams library, you need to qualify filebuf and other iostreams elements with std::, or you need to include using declarations. The complete example makes use of macros defined by the Essential Tools Module in order to support both the classic and Standard iostreams.

//2

Creates an instance of class RWCharFromStreambufInputStreamImp. The class is created by calling its static member function make(), which creates an instance of self and returns it as a narrow character input stream handle. In this example the make() function takes a reference to an iostreams streambuf object that is used as the source of narrow characters.

//3

Creates the adapter class that implement the iostreams streambuf interface and forwards a request to an Advanced Tools Module narrow character input stream.

//4

Creates an iostreams istream object that uses the previously created adapter class as the source of narrow characters.

//5

Uses the istream object.

//6

Catches exceptions potentially thrown by the stream. The Streams package defines two exception classes: RWExternalStreamException and RWIncompleteStreamOperation. Class RWExternalStreamException returns an error message and an error code. Class RWIncompleteStreamOperation inherits from class RWExternalStreamException and is thrown when an operation partially succeeds. An instance of class RWIncompleteStreamOperation can be queried for the number of elements successfully read. For more information on exceptions, see Section 4.3, "Error Handling."



Previous fileTop of DocumentContentsNo linkNext file

Copyright © Rogue Wave Software, Inc. All Rights Reserved.

The Rogue Wave name and logo, and SourcePro, are registered trademarks of Rogue Wave Software. All other trademarks are the property of their respective owners.
Provide feedback to Rogue Wave about its documentation.