SourcePro : Advanced Tools Module User’s Guide : PART II Advanced Tools Module Packages : Using Streams : Examples : Creating and Using Streams With Only One Streaming Element
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.
 
filebuf fbuf; // 1
fbuf.open("binaryTerminalWrite.dat",ios::out | ios::binary);
 
RWByteOutputStream binOutputStream =
RWByteToStreambufOutputStreamImp::make(fbuf); // 2
 
RWByte array_[10]; // 3
 
unsigned char i;
for(i=0; i<10; i++);
array_[i]= i+64;
// fill up the array with values
 
try {
 
for(i=0; i<10; i++)
binOutputStream << array_[i]; // 4
 
for(i=0; i<10; i++)
binOutputStream.write(array_[i]); // 5
 
binOutputStream.write(array_,10); // 6
}
catch(const RWIncompleteStreamOperation& e) { // 7
cout << e.why() << endl;
cout << e.elementsProcessed() << endl;
}
catch(const RWExternalStreamException& e) {
cout << e.why() << endl;
}
//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 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.
 
filebuf fbuf; // 1
fbuf.open("binaryTerminalWrite.dat", ios::in | ios::binary);
 
RWByteInputStream binInputStream =
RWByteFromStreambufInputStreamImp::make(fbuf); // 2
 
try {
 
RWSize i;
RWByte theByte; // 3
 
for(i=0; i<10; i++) {
binInputStream >> theByte; // 4
// do something with the value read
}
 
for(i=0; i<10; i++) {
theByte= binInputStream.read(); // 5
// do something with the value read
}
 
RWByte array_[10];
 
RWSize read_= binInputStream.read(array_,10); // 6
// do something with the array of bytes
 
RWByte until_= 69;
 
read_= binInputStream.readUntil(array_,10,until_); // 7
if(binInputStream.isGood()) // 8
cout << "The operation succeeded\n";
cout << "The number of byte(s) stored is: " << read_ << endl;
// do something with the bytes stored
 
if (binInputStream.isGood()) // 8
cout << "The stream is in a valid state" << endl;
else
cout << "The stream is in error state" << endl;
 
if(binInputStream.isEof()) // 9
cout << "There is no more data available for reading"
<< endl;
else {
cout << "More data is available for reading" << endl;
while(!binInputStream.isEof()) // 9
theByte= binInputStream.read();
// do something with the byte value
} //end else
} // end try
catch(const RWExternalStreamException& e) { // 10
cout << e.why() << endl;
}
//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 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.