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.
 
filebuf fbuf; // 1
fbuf.open("UnicodeCharacterFilteredWrite.dat", ios::in |
ios::binary);
RWByteInputStream binInputStream =
RWByteFromStreambufInputStreamImp::make(fbuf); // 2
 
RWByteInputStream bufferedBinInputStream=
RWBufferedByteInputStreamImp::make(binInputStream,1024); // 3
 
RWUCharInputStream UTF8InputStream=
RWUCharFromUTF8ByteInputStreamImp::make(bufferedBinInputStream);// 4
 
try {
RWSize i;
RWUChar theUChar; // 5
 
for(i=0; i<17; i++) {
UTF8InputStream >> theUChar; // 6
// do something with the UTF-16 character read
}
 
for(i=0; i<17; i++) {
theUChar= UTF8InputStream.read(); // 7
// do something with the value read
}
 
RWUChar array[17];
RWSize read_= UTF8InputStream.read(array,17); // 8
cout << "The number of Unicode character(s) read is: "
<< read_ << endl;
// do something with the array of UTF-16 characters
 
RWUChar until_= 0x0F7F;
 
read_= UTF8InputStream.readUntil(array,17,until_); // 9
if(UTF8InputStream.isGood()) //10
cout << "The operation succeeded\n";
cout << "The number of Unicode character(s) stored is: "
<< read_ << endl;
// do something with the array of UTF-16 character(s)
 
if (UTF8InputStream.isGood()) //10
cout << "The stream is in a valid state" << endl;
else
cout << "The stream is in error state" << endl;
 
if(UTF8InputStream.isEof()) //11
cout << "There is no more data available for reading"
<< endl;
else {
while(!UTF8InputStream.isEof()) //11
theUChar= UTF8InputStream.read();
// do something with the UTF-16 Character
} //end else
} // end try
catch(const RWExternalStreamException& e) { //12
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 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 Error Handling.