| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 | /*Copyright 2010 Beman DawesCopyright 2019-2020 Glen Joseph Fernandes(glenjofe@gmail.com)Distributed under the Boost Software License, Version 1.0.(http://www.boost.org/LICENSE_1_0.txt)*/#ifndef BOOST_IO_QUOTED_HPP#define BOOST_IO_QUOTED_HPP#include <boost/io/detail/buffer_fill.hpp>#include <boost/io/detail/ostream_guard.hpp>#include <boost/io/ios_state.hpp>namespace boost {namespace io {namespace detail {template<class String, class Char>struct quoted_proxy {    String string;    Char escape;    Char delim;};template<class Char>struct quoted_state {    const Char* string;    std::size_t size;    std::size_t count;};template<class Char>inline quoted_state<Char>quoted_start(const Char* string, Char escape, Char delim){    const Char* end = string;    std::size_t count = 2;    for (Char ch; (ch = *end) != 0; ++end) {        count += 1 + (ch == escape || ch == delim);    }    quoted_state<Char> state = { string,        static_cast<std::size_t>(end - string), count };    return state;}template<class Char, class String>inline quoted_state<Char>quoted_start(const String* string, Char escape, Char delim){    const Char* begin = string->data();    std::size_t size = string->size();    std::size_t count = 2;    for (const Char *it = begin, *end = begin + size; it != end; ++it) {        Char ch = *it;        count += 1 + (ch == escape || ch == delim);    }    quoted_state<Char> state = { begin, size, count };    return state;}template<class Char, class Traits>inline boolquoted_put(std::basic_streambuf<Char, Traits>& buf, const Char* string,    std::size_t size, std::size_t count, Char escape, Char delim){    if (buf.sputc(delim) == Traits::eof()) {        return false;    }    if (size == count) {        if (static_cast<std::size_t>(buf.sputn(string, size)) != size) {            return false;        }    } else {        for (const Char* end = string + size; string != end; ++string) {            Char ch = *string;            if ((ch == escape || ch == delim) &&                buf.sputc(escape) == Traits::eof()) {                return false;            }            if (buf.sputc(ch) == Traits::eof()) {                return false;            }        }    }    return buf.sputc(delim) != Traits::eof();}template<class Char, class Traits, class String>inline std::basic_ostream<Char, Traits>"ed_out(std::basic_ostream<Char, Traits>& os, String* string, Char escape,    Char delim){    typedef std::basic_ostream<Char, Traits> stream;    ostream_guard<Char, Traits> guard(os);    typename stream::sentry entry(os);    if (entry) {        quoted_state<Char> state = boost::io::detail::quoted_start(string,            escape, delim);        std::basic_streambuf<Char, Traits>& buf = *os.rdbuf();        std::size_t width = static_cast<std::size_t>(os.width());        if (width <= state.count) {            if (!boost::io::detail::quoted_put(buf, state.string, state.size,                state.count, escape, delim)) {                return os;            }        } else if ((os.flags() & stream::adjustfield) == stream::left) {            if (!boost::io::detail::quoted_put(buf, state.string, state.size,                    state.count, escape, delim) ||                !boost::io::detail::buffer_fill(buf, os.fill(),                    width - state.count)) {                return os;            }        } else if (!boost::io::detail::buffer_fill(buf, os.fill(),                width - state.count) ||            !boost::io::detail::quoted_put(buf, state.string, state.size,                state.count, escape, delim)) {            return os;        }        os.width(0);    }    guard.release();    return os;}template<class Char, class Traits>inline std::basic_ostream<Char, Traits>&operator<<(std::basic_ostream<Char, Traits>& os,    const quoted_proxy<const Char*, Char>& proxy){    return boost::io::detail::quoted_out(os, proxy.string, proxy.escape,        proxy.delim);}template <class Char, class Traits, class Alloc>inline std::basic_ostream<Char, Traits>&operator<<(std::basic_ostream<Char, Traits>& os,    const quoted_proxy<const std::basic_string<Char, Traits, Alloc>*,        Char>& proxy){    return boost::io::detail::quoted_out(os, proxy.string, proxy.escape,        proxy.delim);}template<class Char, class Traits, class Alloc>inline std::basic_ostream<Char, Traits>&operator<<(std::basic_ostream<Char, Traits>& os,    const quoted_proxy<std::basic_string<Char, Traits, Alloc>*, Char>& proxy){    return boost::io::detail::quoted_out(os, proxy.string, proxy.escape,        proxy.delim);}template<class Char, class Traits, class Alloc>inline std::basic_istream<Char, Traits>&operator>>(std::basic_istream<Char, Traits>& is,    const quoted_proxy<std::basic_string<Char, Traits, Alloc>*, Char>& proxy){    Char ch;    if (!(is >> ch)) {        return is;    }    if (ch != proxy.delim) {        is.unget();        return is >> *proxy.string;    }    {        boost::io::ios_flags_saver ifs(is);        std::noskipws(is);        proxy.string->clear();        while ((is >> ch) && ch != proxy.delim) {            if (ch == proxy.escape && !(is >> ch)) {                break;            }            proxy.string->push_back(ch);        }    }    return is;}} /* detail */template<class Char, class Traits, class Alloc>inline detail::quoted_proxy<const std::basic_string<Char, Traits, Alloc>*,    Char>quoted(const std::basic_string<Char, Traits, Alloc>& s, Char escape='\\',    Char delim='\"'){    detail::quoted_proxy<const std::basic_string<Char, Traits, Alloc>*,        Char> proxy = { &s, escape, delim };    return proxy;}template<class Char, class Traits, class Alloc>inline detail::quoted_proxy<std::basic_string<Char, Traits, Alloc>*, Char>quoted(std::basic_string<Char, Traits, Alloc>& s, Char escape='\\',    Char delim='\"'){    detail::quoted_proxy<std::basic_string<Char, Traits, Alloc>*,        Char> proxy = { &s, escape, delim };    return proxy;}template<class Char>inline detail::quoted_proxy<const Char*, Char>quoted(const Char* s, Char escape='\\', Char delim='\"'){    detail::quoted_proxy<const Char*, Char> proxy = { s, escape, delim };    return proxy;}} /* io */} /* boost */#endif
 |