Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/iostreams/example/tab_expanding_filter.hpp @ 29

Last change on this file since 29 was 29, checked in by landauf, 16 years ago

updated boost from 1_33_1 to 1_34_1

File size: 3.6 KB
Line 
1// (C) Copyright Jonathan Turkanis 2005.
2// Distributed under the Boost Software License, Version 1.0. (See accompanying
3// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
4
5// See http://www.boost.org/libs/iostreams for documentation.
6
7// Adapted from an example of James Kanze, with suggestions from Rob Stewart.
8// See http://www.gabi-soft.fr/codebase-en.html.
9
10#ifndef BOOST_IOSTREAMS_TAB_EXPANDING_FILTER_HPP_INCLUDED
11#define BOOST_IOSTREAMS_TAB_EXPANDING_FILTER_HPP_INCLUDED
12
13#include <cassert>
14#include <cstdio>    // EOF.
15#include <iostream>  // cin, cout.
16#include <boost/iostreams/concepts.hpp>
17#include <boost/iostreams/filter/stdio.hpp>
18#include <boost/iostreams/operations.hpp>
19
20namespace boost { namespace iostreams { namespace example {
21
22class tab_expanding_stdio_filter : public stdio_filter {
23public:
24    explicit tab_expanding_stdio_filter(int tab_size = 8)
25        : tab_size_(tab_size), col_no_(0)
26    {
27        assert(tab_size > 0);
28    }
29private:
30    void do_filter()
31    {
32        int c;
33        while ((c = std::cin.get()) != EOF) {
34            if (c == '\t') {
35                int spaces = tab_size_ - (col_no_ % tab_size_);
36                for (; spaces > 0; --spaces)
37                    put_char(' ');
38            } else {
39                put_char(c);
40            }
41        }
42    }
43    void do_close() { col_no_ = 0; }
44    void put_char(int c)
45    {
46        std::cout.put(c);
47        if (c == '\n') {
48            col_no_ = 0;
49        } else {
50            ++col_no_;
51        }
52    }
53    int  tab_size_;
54    int  col_no_;
55};
56
57class tab_expanding_input_filter : public input_filter {
58public:
59    explicit tab_expanding_input_filter(int tab_size = 8)
60        : tab_size_(tab_size), col_no_(0), spaces_(0)
61    {
62        assert(tab_size > 0);
63    }
64
65    template<typename Source>
66    int get(Source& src)
67    {
68        if (spaces_ > 0) {
69            --spaces_;
70            return get_char(' ');
71        }
72
73        int c;
74        if ((c = iostreams::get(src)) == EOF || c == WOULD_BLOCK)
75            return c;
76
77        if (c != '\t')
78            return get_char(c);
79
80        // Found a tab. Call this filter recursively.
81        spaces_ = tab_size_ - (col_no_ % tab_size_);
82        return this->get(src);
83    }
84
85    template<typename Source>
86    void close(Source&)
87    {
88        col_no_ = 0;
89        spaces_ = 0;
90    }
91private:
92    int get_char(int c)
93    {
94        if (c == '\n') {
95            col_no_ = 0;
96        } else {
97            ++col_no_;
98        }
99        return c;
100    }
101    int   tab_size_;
102    int   col_no_;
103    int   spaces_;
104};
105
106class tab_expanding_output_filter : public output_filter {
107public:
108    explicit tab_expanding_output_filter(int tab_size = 8)
109        : tab_size_(tab_size), col_no_(0), spaces_(0)
110    {
111        assert(tab_size > 0);
112    }
113
114    template<typename Sink>
115    bool put(Sink& dest, int c)
116    {
117        for (; spaces_ > 0; --spaces_)
118            if (!put_char(dest, ' '))
119                return false;
120
121        if (c == '\t') {
122            spaces_ = tab_size_ - (col_no_ % tab_size_) - 1;
123            return this->put(dest, ' ');
124        }
125
126        return put_char(dest, c);
127    }
128
129    template<typename Sink>
130    void close(Sink&)
131    {
132        col_no_ = 0;
133        spaces_ = 0;
134    }
135private:
136    template<typename Sink>
137    bool put_char(Sink& dest, int c)
138    {
139        if (!iostreams::put(dest, c))
140            return false;
141        if (c != '\n')
142            ++col_no_;
143        else
144            col_no_ = 0;
145        return true;
146    }
147    int  tab_size_;
148    int  col_no_;
149    int  spaces_;
150};
151
152} } } // End namespaces example, iostreams, boost.
153
154#endif // #ifndef BOOST_IOSTREAMS_TAB_EXPANDING_FILTER_HPP_INCLUDED
Note: See TracBrowser for help on using the repository browser.