Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
Разработка программного обеспечения

Tutorial

Boost , ,

Tutorial

2.2.8. Multi-Character Filters

Все фильтры, которые вы видели до сих пор — за исключением тех, которые происходят от<stdio_filter>— обрабатывают символы по одному за раз. Если вы обрабатываете несколько символов одновременно, вы часто можете уменьшить количество вызовов функций, необходимых для фильтрации последовательности символов, что приводит к более эффективному коду. Вот что такоемногофакторные фильтрыВы можете это сделать.

Multi-Character InputFilters

Типичный узкий персонажМногохарактерныйФильтр вводавыглядит так:

<

#include<iosfwd>                        // streamsize
#include<boost/iostreams/categories.hpp>// tags

classmy_input_filter {
public:
   typedefcharchar_type;
   structcategory 
        : input_filter_tag,
          multichar_tag
        { };
   template<typenameSource>
    std::streamsize read(Source& src,char* s, std::streamsize n)
    {
       // Read up to n filtered characters into the buffer s,
       // returning the number of characters read or -1 for EOF.
       // Use src to access the unfiltered character sequence
    }
   /* Other members */
};
>

Обратите внимание, что категория типа участника является<struct>конвертируемой в<input_filter_tag>и в<multichar_tag>. Это говорит библиотеке Iostream, что<my_input_filter>являетсямногохарактерным фильтромиInputFilter.. Вы могли бы достичь того же эффекта несколькими способами.Например,,

    struct category 
        : input,
          filter_tag,
          multichar_tag
        { };
        /* or */
    typedef multichar_input_filter_tag category;

(Подробнее см.)Теги режимаиТеги категории.

Вы также можете написать приведенный выше пример следующим образом:

#include <iosfwd>                       // streamsize
#include <boost/iostreams/concepts.hpp> // multichar_input_filter
class my_input_filter : public multichar_input_filter {
public:
    template<typename Source>
    std::streamsize read(char* s, std::streamsize n);
    /* Other members */
};

Здесь<multichar_input_filter>является базовым классом удобства, который обеспечивает типы членов<char_type>и<category>, а также не-оп реализации функций членов<close>и<imbue>.

<shell_comments_multichar_input_filter>

Вы можете выражатькомментарии оболочки Фильтрв видеМультихарактерВходящий фильтрследующим образом:

#include <boost/iostreams/char_traits.hpp> // EOF, WOULD_BLOCK
#include <boost/iostreams/concepts.hpp>    // multichar_input_filter
#include <boost/iostreams/operations.hpp>  // get
namespace boost { namespace iostreams { namespace example {
class shell_comments_multichar_input_filter : public multichar_input_filter {
public:
    explicit shell_comments_multichar_input_filter(char comment_char = '#')
        : comment_char_(comment_char), skip_(false)
        { }
    template<typename Source>
    std::streamsize read(Source& src, char* s, std::streamsize n)
    {
        for (std::streamsize z = 0; z < n; ++z) {
            int c;
            while (true) {
                if ((c = boost::iostreams::get(src)) == EOF)
                    return z != 0 ? z : -1;
                else if (c == WOULD_BLOCK)
                    return z;
                skip_ = c == comment_char_ ?
                    true :
                    c == '\n' ?
                        false :
                        skip_;
                if (!skip_)
                    break;
            }
            s[z] = c;
        }
        return n;
    }
    template<typename Source>
    void close(Source&) { skip_ = false; }
private:
    char comment_char_;
    bool skip_;
};
} } } // End namespace boost::iostreams:example

Обратите внимание, что реализация<read>очень похожа на то, что вы получите, если поместите реализацию<shell_comments_input_filter::get>внутри<for>петли, итерирующейся от<0>до<n>. Вводные фильтры, которые называют себя рекурсивно, такие как<tab_expanding_input_filter>, гораздо труднее преобразовать в многохарактерные фильтры.

Multi-Character OutputFilters

Типичный узкохарактерныйМультихарактерOutputFilterвыглядит следующим образом:

<

#include<iosfwd>                        // streamsize
#include<boost/iostreams/categories.hpp>// tags

classmy_output_filter {
public:
   typedefcharchar_type;
   structcategory 
        : output_filter_tag,
          multichar_tag
        { };
   template<typenameSink>
    std::streamsize write(Sink& dest,constchar* s, std::streamsize n)
    {
       // Consume up to n filtered characters from the buffer s,
       // writing filtered characters to dest. Return the number
       // of characters consumed.
    }
   /* Other members */
};
>

Обратите внимание, что категория типа участника является<struct>конвертируемой в<keyword>и в<multichar_tag>. Это говорит библиотеке Iostream, что<my_output_filter>являетсямногохарактерным фильтромивыходным фильтром. Как и в случае сMulti-CharacterInputFilters, вы могли бы достичь того же эффекта несколькими различными способами.Например,,

    struct category 
        : output,
          filter_tag,
          multichar_tag
        { };
        /* or */
    typedef multichar_output_filter_tag category;

(Подробнее см.)Теги режимаиТеги категории.

Вы также можете написать приведенный выше пример следующим образом:

#include <iosfwd>                       // streamsize
#include <boost/iostreams/concepts.hpp> // multichar_output_filter
class my_output_filter : public multichar_output_filter {
public:
    template<typename Sink>
    std::streamsize write(Sink& dest, const char* s, std::streamsize n);
    /* Other members */
};

Здесь<multichar_output_filter>является базовым классом удобства, который предоставляет типы членов<char_type>и<category>, а также не-оп реализации функций членов<close>и<imbue>.

<shell_comments_multichar_output_filter>

Вы можете выражатькомментарий оболочки ФильтркакМультихарактерФильтр выводаследующим образом:

#include <boost/iostreams/char_traits.hpp> // EOF, WOULD_BLOCK
#include <boost/iostreams/concepts.hpp>    // multichar_output_filter
#include <boost/iostreams/operations.hpp>  // get
namespace boost { namespace iostreams { namespace example {
class shell_comments_multichar_output_filter : public multichar_output_filter {
public:
    explicit shell_comments_multichar_output_filter(char comment_char = '#')
        : comment_char_(comment_char), skip_(false)
        { }
    template<typename Sink>
    std::streamsize write(Sink& dest, const char* s, std::streamsize n)
    {
        std::streamsize z;
        for (z = 0; z < n; ++z) {
            int c = s[z];
            skip_ = c == comment_char_ ?
                true :
                c == '\n' ?
                    false :
                    skip_;
            if (skip_)
                continue;
            if (!iostreams::put(dest, c))
                break;
        }
        return z;
    }
    template<typename Source>
    void close(Source&) { skip_ = false; }
private:
    char comment_char_;
    bool skip_;
};
} } } // End namespace boost::iostreams:example

Обратите внимание, что реализация<write>очень похожа на то, что вы получите, если поместите реализацию<shell_comments_output_filter::put>внутри<for>петли, итерирующейся от<0>до<n>. Фильтры вывода, которые называют себя рекурсивными, такие как<unix2dos_output_filter>, гораздо труднее преобразовать в многохарактерные фильтры.


Статья Tutorial раздела может быть полезна для разработчиков на c++ и boost.




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.



:: Главная :: ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-30 11:47:00
2025-07-05 05:20:45/0.0040040016174316/0