InputFilter

Definition
Description
Examples
Detailed Specification

Definition

An InputFilter is a Filter whose mode_of refines input.

Description

An InputFilter operates on the character sequence controlled by a Source, providing access to a filtered sequence having the same character type. It may expose the filtered sequence in two ways:

  1. by defining a member function get
  2. by defining a member function read
The second alternative is provided for enhanced performance. InputFilters implementing this alternative are referred to as Multi-Character. (See Multi-Character Filter.)

Examples

I. Ordinary InputFilter

The following example shows an InputFilter which removes all non-alphabetic characters from a sequence.

    #include <ctype.h>                 // isalpha
    #include <cstdio.h>                // EOF
    #include <boost/iostreams/categories.hpp> // input_filter_tag
    #include <boost/iostreams/operations.hpp> // get, WOULD_BLOCK

    using namespace std;
    using namespace boost::iostreams;

    struct alphabetic_input_filter {
        typedef char              char_type;
        typedef input_filter_tag  category;

        template<typename Source>
        int get(Source& src)
        {
            int c;
            while ( (c = boost::iostreams::get(src)) != EOF &&
                     c != WOULD_BLOCK &&
                    !isalpha((unsigned char) c) )
                ;
            return c;
        }
    };

Here char_type is the character type of the Filter, input_filter_tag is a category tag identifying the Filter as a model of InputFilter, and the function boost::iostreams::get reads a character from an arbitrary Source.[1] The constant WOULD_BLOCK, defined in the header <boost/iostreams/char_traits.hpp>, is used to indicate that input is temporarily unavilable.

The Iostreams library defines two convenience classes, input_filter and input_wfilter, which provide member typedefs char_type and category as well as default implementations of several member functions. When defining a new model of InputFilter, it is often sufficient to derive from input_filter or input_wfilter and to define a member function get.

II. Multi-Character InputFilter

The following example shows a Multi-Character InputFilter which performs the same filtering operation as the Filter in Example I.

    #include <ctype.h>                 // isalpha
    #include <cstdio.h>                // EOF
    #include <boost/iostreams/categories.hpp> // input_filter_tag
    #include <boost/iostreams/operations.hpp> // get

    using namespace std;
    using namespace boost::io;

    struct alphabetic_input_filter {
        typedef char                       char_type;
        typedef multichar_input_filter_tag  category;

        template<typename Source>
        streamsize read(Source& src, char* s, streamsize n)
            {
                int   c;
                char* first = s;
                char* last  = s + n;
                while ( first != last &&
                        (c = boost::iostreams::get(src)) != EOF &&
                         c != WOULD_BLOCK &&
                        isalpha((unsigned char) c) )
                {
                    *first++ = c;
                }
                streamsize result = static_cast<streamsize>(first - s);
                return result == 0 && c != WOULD_BLOCK ?
                    -1 :
                    result;
            }
    };

Here multichar_input_filter_tag is a category tag identifying the Filter as a Multi-Character InputFilter.

The Iostreams library defines two convenience classes, multichar_input_filter and multichar_input_wfilter, which provide the member typedefs char_type and category as well as default implementations of several member functions. When defining a new Multi-Character InputFilter, it is often sufficient to derive from multichar_input_filter or multichar_input_wfilter and to define a member function read.

Refinement of

Filter.

Associated Types

Character typeThe type of the characters in the filtered sequences
Category A type convertible to filter_tag and to input
Mode The unique most-derived mode tag to which Category is convertible

Notation

F- A type which is a model of InputFilter
D- A type which is a model of Device, with the same character type as F and with mode refining the mode of F
Ch- The character type of F
Tr- boost::iostreams::char_traits<Ch>
f- Object of type F
d- Object of type D
s- Object of type Ch*
n- Object of type std::streamsize
io- Alias for namespace boost::iostreams

Valid Expressions / Semantics

ExpressionExpression TypeCategory PreconditionSemantics
typename char_type_of<F>::type
typename of the character type --
typename category_of<F>::type
typename of the category --
f.get(d)
Tr::int_type Convertible to input but not to multichar_tag Returns the next character in the input sequence controlled by f, Tr::eof() if the end of the sequence has been reached or Tr::would_block() if input is temporarily unavilable because a call to d has produced fewer characters than requested. The input sequence controlled by d may be accessed using io::get, io::read and io::putback.
f.read(d, s, n)
std::streamsize
Convertible to input and to multichar_tag Reads up to n characters from the input sequence controlled by f into the buffer s, returning the number of characters read or -1 to indicate end-of-sequence. A value less than n may be returned only at end-of-sequence or if input is temporarily unavilable because a call to d has produced fewer characters than requested. The input sequence controlled by d may be accessed using io::get, io::read and io::putback.

Exceptions

Errors which occur during the execution of get and read are indicated by throwing exceptions. Reaching the end of the sequence is not an error.

After an exception is thrown, an InputFilter must be in a consistent state; further i/o operations may throw exceptions but must have well-defined behaviour. Furthermore, unless it is Closable, it must be ready to begin processing a new character sequence.

Models

Acknowledgments

The concept InputFilter was inspired by the extractors of [Kanze].


[1]Technically, boost::iostreams::get requires that a Source be indirect.