Filters are used to modified character sequences. For example, you might use a filter to replace all instances of one word with another, to convert all alphabetic characters to lower case or to encrypt a document. Sometimes the filter is a mere observer; in this case the filtered character sequence if the same as the unfiltered sequence. For example, you might use a filter to count the number of occurences of a given word.
The Iostreams library supports two basic categories of Filters InputFilters and OutputFilters. InputFilters represent a “pull” model of filtering: a source of unfilitered data is provided — represented as a Source — and the Filter is expected to generate a certain number characters of the filtered sequence. The filtered sequence is generated incrementally, meaning that to filter a given character sequence the Filter typically must be invoked several times. OutputFilters represent a “push” model of filtering: a sequence of unfiltered characters and a Sink are provided, and the Filter is expected to filter the characters and write them to the Sink. Like InputFilters, OutputFilters also process data incrementally.
The simplest InputFilters and OutputFilters process characters one at a time. This type of Filter is easy to write, but is less efficient than Filters that process several characters at a time. Filters which process several characters at a time are called Multi-Character fiters.
The Iostreams library provides several utilities to make Filter writing easier:
aggregate_filterallows a programmer to define a Filter by reading unfilitered data from one
std::vectorand writing filtered data to another
stdio_filterallows a programmer to define a Filter by reading unfilitered data from standard input and writing filtered data to standard output.
symmetric_filterallows a programmer to define a Filter by reading unfilitered data from one array and writing filtered data to another array.
finite_state_filterallows a programmer to define a Filter as a finite state machine. This component is included with the example filters; it is not currently an official part of the library.
Suppose you need to write a Filter to perform a given filtering task. How do you decide whether to write an InputFilters or OutputFilters, or to use one of the Filter helpers? The first two Filter helpers mentioned above,
stdio_filter, have high-memory usage and only work with character sequences that have a well-defined end. They allow filtering algorithms to be expressed in a very straightforward way, however, and so provide a good introduction to filtering. The third Filter helper,
symmetric_filter, is useful for defining filter based on C-language API such as zlib, libbz2 or OpenSSL. If none of the Filter helpers are appropriate, you should generally write an InputFilter if you plan to use the filter for reading and an OutputFilter if you plan to use it for writing. In some cases, however, it is much easier to express an algorithm as an InputFilter than as an OutputFilter, or vice versa. In such cases, you can write the filter whichever way is easier, and use the class template
inverse or the function template
invert to turn an InputFilter into an OutputFilter or vice versa.
In all but the last of the filtering examples below, I will first show how to implement an algorithm using
stdio_filter before implementing it from scratch as an InputFilter or OutputFilter.
Revised 20 May, 2004
© Copyright Jonathan Turkanis, 2004
Use, modification, and distribution are subject to the Boost Software License, Version 2.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)