#include <map>
#include <string>
namespace boost { namespace iostreams { namespace example {
class dictionary {
public:
void add(std::string key, const std::string& value);
void replace(std::string& key);
/* ... */
};
} } } // End namespace boost::iostreams:example
#include <cstdio> // EOF
#include <iostream> // cin, cout
#include <boost/iostreams/filter/stdio.hpp>
namespace boost { namespace iostreams { namespace example {
class dictionary_stdio_filter : public stdio_filter {
public:
dictionary_stdio_filter(dictionary& d) : dictionary_(d) { }
private:
void do_filter()
{
using namespace std;
while (true) {
int c = std::cin.get();
if (c == EOF || !std::isalpha((unsigned char) c)) {
dictionary_.replace(current_word_);
cout.write( current_word_.data(),
static_cast<streamsize>(current_word_.size()) );
current_word_.erase();
if (c == EOF)
break;
cout.put(c);
} else {
current_word_ += c;
}
}
}
dictionary& dictionary_;
std::string current_word_;
};
} } } // End namespace boost::iostreams:example
#include <boost/iostreams/char_traits.hpp> // EOF, WOULD_BLOCK
#include <boost/iostreams/concepts.hpp> // input_filter
#include <boost/iostreams/operations.hpp> // get
namespace boost { namespace iostreams { namespace example {
class dictionary_input_filter : public input_filter {
public:
dictionary_input_filter(dictionary& d)
: dictionary_(d), off_(std::string::npos), eof_(false)
{ }
template<typename Source>
int get(Source& src);
template<typename Source>
void close(Source&);
private:
dictionary& dictionary_;
std::string current_word_;
std::string::size_type off_;
bool eof_;
};
} } } // End namespace boost::iostreams:example
template<typename Source>
int get(Source& src)
{
// Handle unfinished business.
if (off_ != std::string::npos && off_ < current_word_.size())
return current_word_[off_++];
if (off_ == current_word_.size()) {
current_word_.erase();
off_ = std::string::npos;
}
if (eof_)
return EOF;
// Compute curent word.
while (true) {
int c;
if ((c = iostreams::get(src)) == WOULD_BLOCK)
return WOULD_BLOCK;
if (c == EOF || !std::isalpha((unsigned char) c)) {
dictionary_.replace(current_word_);
off_ = 0;
if (c == EOF)
eof_ = true;
else
current_word_ += c;
break;
} else {
current_word_ += c;
}
}
return this->get(src); // Note: current_word_ is not empty.
}
template<typename Source>
void close(Source&)
{
current_word_.erase();
off_ = std::string::npos;
eof_ = false;
}
#include <algorithm> // swap
#include <boost/iostreams/concepts.hpp> // output_filter
#include <boost/iostreams/operations.hpp> // write
namespace boost { namespace iostreams { namespace example {
class dictionary_output_filter : public output_filter {
public:
typedef std::map<std::string, std::string> map_type;
dictionary_output_filter(dictionary& d)
: dictionary_(d), off_(std::string::npos)
{ }
template<typename Sink>
bool put(Sink& dest, int c);
template<typename Sink>
void close(Sink& dest);
private:
template<typename Sink>
bool write_current_word(Sink& dest);
dictionary& dictionary_;
std::string current_word_;
std::string::size_type off_;
bool initialized_;
};
} } } // End namespace boost::iostreams:example
template<typename Sink>
bool write_current_word(Sink& dest)
{
using namespace std;
streamsize amt = static_cast<streamsize>(current_word_.size() - off_);
streamsize result =
iostreams::write(dest, current_word_.data() + off_, amt);
if (result == amt) {
current_word_.erase();
off_ = string::npos;
return true;
} else {
off_ += result;
return false;
}
}
template<typename Sink>
bool put(Sink& dest, int c)
{
if (off_ != std::string::npos && !write_current_word(dest))
return false;
if (!std::isalpha((unsigned char) c)) {
dictionary_.replace(current_word_);
off_ = 0;
}
current_word_ += c;
return true;
}
template<typename Sink>
void close(Sink& dest)
{
// Reset current_word_ and off_, saving old values.
std::string current_word;
std::string::size_type off = 0;
current_word.swap(current_word_);
std::swap(off, off_);
// Write remaining characters to dest.
if (off == std::string::npos) {
dictionary_.replace(current_word);
off = 0;
}
if (!current_word.empty())
iostreams::write(
dest,
current_word.data() + off,
static_cast<std::streamsize>(current_word.size() - off)
);
}
#include <cstdio> // EOF
#include <iostream> // cin, cout
#include <boost/iostreams/filter/stdio.hpp>
namespace boost { namespace iostreams { namespace example {
class unix2dos_stdio_filter : public stdio_filter {
private:
void do_filter()
{
int c;
while ((c = std::cin.get()) != EOF) {
if (c == ' ')
std::cout.put(' ');
std::cout.put(c);
}
}
};
} } } // End namespace boost::iostreams:example
#include <boost/iostreams/categories.hpp> // input_filter_tag
#include <boost/iostreams/operations.hpp> // get
namespace boost { namespace iostreams { namespace example {
class unix2dos_input_filter {
public:
typedef char char_type;
typedef input_filter_tag category;
unix2dos_input_filter() : has_linefeed_(false) { }
template<typename Source>
int get(Source& src)
{
// Handle unfinished business
if (has_linefeed_) {
has_linefeed_ = false;
return ' ';
}
// Forward all characters except ' '
int c;
if ((c = iostreams::get(src)) == ' ') {
has_linefeed_ = true;
return ' ';
}
return c;
}
template<typename Source>
void close(Source&);
private:
bool has_linefeed_;
};
} } } // End namespace boost::iostreams:example
template<typename Source>
void close(Source&) { skip_ = false; }
#include <boost/iostreams/concepts.hpp> // output_filter
#include <boost/iostreams/operations.hpp> // put
namespace boost { namespace iostreams { namespace example {
class unix2dos_output_filter : public output_filter {
public:
unix2dos_output_filter() : has_linefeed_(false) { }
template<typename Sink>
bool put(Sink& dest, int c);
template<typename Sink>
void close(Sink&) { has_linefeed_ = false; }
private:
template<typename Sink>
bool put_char(Sink& dest, int c);
bool has_linefeed_;
};
} } } // End namespace boost::iostreams:example
template<typename Sink>
bool put_char(Sink& dest, int c)
{
bool result;
if ((result = iostreams::put(dest, c)) == true) {
has_linefeed_ =
c == ' ' ?
true :
c == ' ' ?
false :
has_linefeed_;
}
return result;
}
bool put(Sink& dest, int c)
{
if (c == ' ')
return has_linefeed_ ?
put_char(dest, ' ') :
put_char(dest, ' ') ?
this->put(dest, ' ') :
false;
return iostreams::put(dest, c);
}
#include <boost/iostreams/invert.hpp> // inverse 
namespace io = boost::iostreams;
namespace ex = boost::iostreams::example;
typedef io::inverse<ex::unix2dos_input_filter> unix2dos_output_filter;发表于 @ 2007年05月10日 13:03:00 | 评论( loading... ) | 举报| 收藏