BufferedTransformation

From Crypto++ Wiki
Jump to: navigation, search

Transformation.png

An object which derives from BufferedTransformation can participate in Pipelining. Pipelining is a paradigm in Crypto++ which allows data to flow from a Source to a Sink. Each BufferedTransformation in the pipeline transforms the data in some way in the in route to the Sink.

Taking from the Crypto++ Source Code comments:

BufferedTransformation is a generalization of BlockTransformation, StreamTransformation, and HashTransformation.
A buffered transformation is an object that takes a stream of bytes as input (this may be done in stages), does some computation on them, and then places the result into an internal buffer for later retrieval. Any partial result already in the output buffer is not modified by further input.
If a method takes a "blocking" parameter, and you pass "false" for it, the method will return before all input has been processed if the input cannot be processed without waiting (for network buffers to become available, for example). In this case the method will return true or a non-zero integer value. When this happens you must continue to call the method with the same parameters until it returns false or zero, before calling any other method on it or attached BufferedTransformation. The integer return value in this case is approximately the number of bytes left to be processed, and can be used to implement a progress bar.
For functions that take a "propagation" parameter, propagation != 0 means pass on the signal to attached BufferedTransformation objects, with propagation decremented at each step until it reaches 0. -1 means unlimited propagation.

To distinguish between a Filter and a BufferedTransformation, call, its Attachable method. If the object is a Filter, the method will return true; if it is a BufferedTransformation, it will return false.

Missing Data

Its not uncommon to send data through a pipeline and then have nothing in the sink. This is usually due to the compiler matching the wrong function. For example:

string source = "ABCD...WXYZ", destination;
StringSink ss(source,
    new HexEncoder(
        new StringSink(destination)
    ) // HexEncoder
); // StringSink

After the above code executes, destination is likely to be empty because the compiler coerces the HexEncoder to a bool (the pumpAll parameter), which leaves the StringSource's attached transformation NULL. The compiler will do so without warning, even with -Wall -Wextra -Wconversion. To resolve the issue, explicitly specify the pumpAll parameter:

string source = "ABCD...WXYZ", destination;
StringSink ss(source, true /*pumpAll*/
    new HexEncoder(
        new StringSink(destination)
    ) // HexEncoder
); // StringSink