util::format

This module provides classes for formatting text strings from data. These classes simplify printing textual data to output streams.

Example

The util::stream::IOutputStream object is not suitable for printing formatted text, as it processes characters as unformatted (raw) bytes. To write readable text to the output stream, a util::format::StringWriter object can be instantiated. This object wraps the stream and provides printing functions:

void ptintInteger(::util::stream::IOutputStream& outputStream, int int32Value)
{
    ::util::format::StringWriter writer(outputStream);
    writer.printf("This is a formatted int value: %d", int32Value).endl();
}

Features

StringWriter

The util::format::StringWriter encapsulates most of the functionality of this submodule. It provides methods for formatting data using a format string and data arguments in a platform-independent manner. For a detailed description of format strings, refer to util::format::PrintfFormatter.

SharedStringWriter

util::format::SharedStringWriter is a class that implements the RAII idiom. A local object of this type is created immediately before outputting data to the terminal, typically within the same visibility scope, such as a function or block.

An object of this type shares a pointer to the stream, which may also be used by other terminal clients. Upon creation, it checks if the stream is in use, forces it to finish, and captures the stream for its own use. The stream is released when the object is destroyed.

util::format::Vt100AttributedStringFormatter

On small devices, the simplest output stream is typically the stdout console stream. While supported by terminal programs, it can be useful to decorate text data by applying VT100 text attributes to certain parts. The util::format::Vt100AttributedStringFormatter class writes VT100 format strings to toggle attributes on or off and tracks all attributes applied to a stream. A VT100 formatter object can be instantiated and used to apply attributes to text, as shown:

void printText(::util::stream::IOutputStream& stream)
{
    ::util::format::StringWriter writer(stream);
    ::util::format::Vt100AttributedStringFormatter vt100;

    writer.printf("This is a formatted and attributed int value: ")
        .apply(vt100.attr(::util::format::RED))
        .printf("%d", int32Value)
        .apply(vt100.reset())
        .endl();
}

Variadic parameters

The printf() function of util::format::StringWriter is a typical variadic function, meaning it accepts any number of arguments (variadic parameters). The format string is expected to be the first argument in such a call. Subsequent arguments must match the placeholders (% symbols) in the format string.

The types of the arguments are restricted to standard (primitive) C types: integral types, pointers, and characters. Integral types may be prefixed with characters specifying their numeral system (decimal, octal, or hexadecimal).

The following classes are responsible for correctly handling variadic arguments:

  • util::format::PrintfFormatScanner

  • util::format::PrintfFormatter

  • util::format::PrintfArgumentReader

These classes handle parsing the variadic arguments, converting integral types to their corresponding character representations, and printing the resulting bytes into the stream. They can be used independently or through the util::format::StringWriter class (refer to the printf() example above).

void printText(::util::stream::IOutputStream& stream)
{
    PrintfFormatter formatter(stream);
    formatter.format("%d %s", 17, "abc"); // expected "17 abc"
    formatter.format("%+012d", 47); // expected "+00000000047"
    formatter.format("%hx", 0x23c5); // expected "23c5"
}