StringSource

From Crypto++ Wiki
Jump to navigation Jump to search
StringSource
Documentation
#include <cryptopp/filters.h>

A StringSource is a source for byte arrays, C-strings and C++ strings.

The StringSource takes a pointer to a BufferedTransformation. Because a pointer is taken, the StringSource owns the attached transformation, and therefore will destroy it. See ownership for more details.

Sources, filters and sinks are discussed at Pipelining. The pipeline article explains the design and shows you how to use them.

Constructors

StringSource (BufferedTransformation *attachment=NULL)

StringSource (const char *zstring,
              bool pumpAll,
              BufferedTransformation *attachment=NULL)

StringSource (const std::string &string,
              bool pumpAll,
              BufferedTransformation *attachment=NULL)

StringSource (const byte *bstring,
              size_t length,
              bool pumpAll,
              BufferedTransformation *attachment=NULL)

zstring is a NULL terminated C-string.

string is a C++ string.

bstring is a byte array.

length is the length of the byte array.

pumpAll is a boolean value indicating if the StringSource should pump all of the data immediately to its attached transformation.

attachment is a BufferedTransformation, such as another filter or sink.

Examples

The following examples demonstrate creation of a StringSource.

StringSource ss( "Hello World" );
string data;
StringSource ss( data );

The following example demonstrates writing a string to a file.

string data;
StringSource ss( data, true /*pumpAll*/, new FileSink( "test.txt" ) );

The following example performs the same operation as above, but without the variable s.

string data;
StringSource ss( data, true /*pumpAll*/, new FileSink( "test.txt" ) );

The following example uses a byte array rather than a string. Note an alternate constructor is used in this case.

const byte arr[] = {0, 2, 4, 6, 8};
StringSource ss( arr, 5, true /*pumpAll*/, new FileSink( "test.txt" ) );

A slightly more complicated example of pipelining is below. Before the string is written to the file, it is HexEncoded.

string s;
StringSource ss( s, true /*pumpAll*/, new HexEncoder( new FileSink( "test.txt" ) ) );

Sometimes the pipeline will be coded over multiple lines to aid in readability. The following is equivalent to the previous.

string s;
StringSource ss( s, true /*pumpAll*/,
    new HexEncoder(
        new FileSink( "test.txt" )
    ) // HexEncoder
); // StringSource

Note that the HexEncoder and FileSink created with new do not require explicit destruction - the StringSource will call delete on the HexEncoder, which in turns calls delete on the FileSink when it (the StringSource) is destroyed.

Missing Data

Its not uncommon to experience Missing Data in a pipeline. A source will send data through a pipeline but have nothing in the sink. This is usually due to the compiler matching the wrong function. For example:

string source = "FF 88 00", destination;
StringSink ss(source,
    new HexDecoder(
        new StringSink(destination)
    ) // HexDecoder
); // StringSink

After the above code executes, destination will likely be empty because the compiler coerces the HexDecoder (the pointer) 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 = "FF 88 00", destination;
StringSink ss(source, true /*pumpAll*/,
    new HexDecoder(
        new StringSink(destination)
    ) // HexDecoder
); // StringSink

Another way data ends up missing is failing to call MessageEnd() when pumping data. For example, the following may not produce expected results:

// The 4-bit nibble will be buffered waiting for another nibble
string source = "FF 88 0", destination;

HexDecoder decoder(new StringSink(destination));
decoder.Put(source.data(), source.size());

// Do something with destination

Be sure to call MessageEnd() when data comes up missing:

string source = "FF 88 0", destination;

HexDecoder decoder(new StringSink(destination));
decoder.Put(source.data(), source.size());
decoder.MessageEnd();

// Do something with destination