Creating and Using Stream Adapter Classes
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.
The iostreams Adapter Classes
The Streams package has four adapter classes that implement the iostreams streambuf interface:
• RWStreambufToByteOutputStream, which implements the iostreams
streambuf interface and forwards to an Advanced Tools Module binary output stream
• RWStreambufToCharOutputStream, which implements the iostreams
streambuf interface and forwards to an Advanced Tools Module narrow character output stream
• RWStreambufFromCharInputStream, which implements the iostreams
streambuf interface and forwards to an Advanced Tools Module narrow character input stream
The iostreams adapter classes support both the Standard (as described in the C++ standard) and classic iostreams libraries.
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:
• RWvostreamToDataOutputStream, which implements the Essential Tools Module
vostream interface and forwards to an Advanced Tools Module data output stream
• RWvistreamFromDataInputStream, which implements the Essential Tools Module
vistream interface and forwards to an Advanced Tools Module data input stream
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.
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.
The complete example is located in directory ...\examples\stream in the file adapterWrite.cpp. Only part of the code is presented below.
filebuf fbuf; // 1
fbuf.open("adaptorWrite.dat", ios::out);
RWCharOutputStream charOutputStream =
RWCharToStreambufOutputStreamImp::make(fbuf); // 2
RWStreambufToCharOutputStream streambufAdaptor(charOutputStream);// 3
ostream os(&streambufAdaptor); // 4
try {
double f= 3.14159;
int i= 567;
char* text="Wagabunga";
// insert a bunch of things
os << f << ' ' << i << ' ' << text; // 5
}
catch(const RWIncompleteStreamOperation& e) { // 6
cout << e.why() << endl;
cout << e.elementsProcessed() << endl;
}
catch(const RWExternalStreamException& e) {
cout << e.why() << endl;
}
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.
The complete example is located in directory ...\examples\stream in the file adapterRead.cpp. Only part of the code is presented below.
filebuf fbuf; // 1
fbuf.open("adaptorWrite.dat", ios::in);
RWCharInputStream charInputStream =
RWCharFromStreambufInputStreamImp::make(fbuf); // 2
RWStreambufFromCharInputStream streambufAdaptor(charInputStream);// 3
istream is(&streambufAdaptor); // 4
try {
double f;
int i;
char text[40];
// extract a bunch of things
is >> f >> i >> text; // 5
cout << '\n' << f << '\n' << i << '\n' << text << '\n' << endl;
}
catch(const RWIncompleteStreamOperation& e) { // 6
cout << e.why() << endl;
cout << e.elementsProcessed() << endl;
}
catch(const RWExternalStreamException& e) {
cout << e.why() << endl;
}