BVB Source Codes

mars Show symmetric.hpp Source code

Return Download mars: download symmetric.hpp Source code - Download mars Source code - Type:.hpp
  1. // (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
  2. // (C) Copyright 2003-2007 Jonathan Turkanis
  3. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
  5.  
  6. // See http://www.boost.org/libs/iostreams for documentation.
  7.  
  8. // Contains the definitions of the class templates symmetric_filter,
  9. // which models DualUseFilter based on a model of the Symmetric Filter.
  10.  
  11. //
  12. // Roughly, a Symmetric Filter is a class type with the following interface:
  13. //
  14. //   struct symmetric_filter {
  15. //       typedef xxx char_type;
  16. //
  17. //       bool filter( const char*& begin_in, const char* end_in,
  18. //                    char*& begin_out, char* end_out, bool flush )
  19. //       {
  20. //          // Consume as many characters as possible from the interval
  21. //          // [begin_in, end_in), without exhausting the output range
  22. //          // [begin_out, end_out). If flush is true, write as mush output
  23. //          // as possible.
  24. //          // A return value of true indicates that filter should be called
  25. //          // again. More precisely, if flush is false, a return value of
  26. //          // false indicates that the natural end of stream has been reached
  27. //          // and that all filtered data has been forwarded; if flush is
  28. //          // true, a return value of false indicates that all filtered data
  29. //          // has been forwarded.
  30. //       }
  31. //       void close() { /* Reset filter's state. */ }
  32. //   };
  33. //
  34. // Symmetric Filter filters need not be CopyConstructable.
  35. //
  36.  
  37. #ifndef BOOST_IOSTREAMS_SYMMETRIC_FILTER_HPP_INCLUDED
  38. #define BOOST_IOSTREAMS_SYMMETRIC_FILTER_HPP_INCLUDED
  39.  
  40. #if defined(_MSC_VER) && (_MSC_VER >= 1020)
  41. # pragma once
  42. #endif
  43.  
  44. #include <boost/assert.hpp>
  45. #include <memory>                               // allocator, auto_ptr.
  46. #include <boost/config.hpp>                     // BOOST_DEDUCED_TYPENAME.
  47. #include <boost/iostreams/char_traits.hpp>
  48. #include <boost/iostreams/constants.hpp>        // buffer size.
  49. #include <boost/iostreams/detail/buffer.hpp>
  50. #include <boost/iostreams/detail/char_traits.hpp>
  51. #include <boost/iostreams/detail/config/limits.hpp>
  52. #include <boost/iostreams/detail/template_params.hpp>
  53. #include <boost/iostreams/traits.hpp>
  54. #include <boost/iostreams/operations.hpp>       // read, write.
  55. #include <boost/iostreams/pipeline.hpp>
  56. #include <boost/preprocessor/iteration/local.hpp>
  57. #include <boost/preprocessor/punctuation/comma_if.hpp>
  58. #include <boost/preprocessor/repetition/enum_binary_params.hpp>
  59. #include <boost/preprocessor/repetition/enum_params.hpp>
  60. #include <boost/shared_ptr.hpp>
  61.  
  62. // Must come last.
  63. #include <boost/iostreams/detail/config/disable_warnings.hpp>  // MSVC.
  64.  
  65. namespace mars_boost {} namespace boost = mars_boost; namespace mars_boost { namespace iostreams {
  66.  
  67. template< typename SymmetricFilter,
  68.           typename Alloc =
  69.               std::allocator<
  70.                   BOOST_DEDUCED_TYPENAME char_type_of<SymmetricFilter>::type
  71.               > >
  72. class symmetric_filter {
  73. public:
  74.     typedef typename char_type_of<SymmetricFilter>::type      char_type;
  75.     typedef BOOST_IOSTREAMS_CHAR_TRAITS(char_type)            traits_type;
  76.     typedef std::basic_string<char_type, traits_type, Alloc>  string_type;
  77.     struct category
  78.         : dual_use,
  79.           filter_tag,
  80.           multichar_tag,
  81.           closable_tag
  82.         { };
  83.  
  84.     // Expands to a sequence of ctors which forward to impl.
  85.     #define BOOST_PP_LOCAL_MACRO(n) \
  86.         BOOST_IOSTREAMS_TEMPLATE_PARAMS(n, T) \
  87.         explicit symmetric_filter( \
  88.               int buffer_size BOOST_PP_COMMA_IF(n) \
  89.               BOOST_PP_ENUM_BINARY_PARAMS(n, const T, &t) ) \
  90.             : pimpl_(new impl(buffer_size BOOST_PP_COMMA_IF(n) \
  91.                      BOOST_PP_ENUM_PARAMS(n, t))) \
  92.             { BOOST_ASSERT(buffer_size > 0); } \
  93.         /**/
  94.     #define BOOST_PP_LOCAL_LIMITS (0, BOOST_IOSTREAMS_MAX_FORWARDING_ARITY)
  95.     #include BOOST_PP_LOCAL_ITERATE()
  96.     #undef BOOST_PP_LOCAL_MACRO
  97.  
  98.     template<typename Source>
  99.     std::streamsize read(Source& src, char_type* s, std::streamsize n)
  100.     {
  101.         using namespace std;
  102.         if (!(state() & f_read))
  103.             begin_read();
  104.  
  105.         buffer_type&  buf = pimpl_->buf_;
  106.         int           status = (state() & f_eof) != 0 ? f_eof : f_good;
  107.         char_type    *next_s = s,
  108.                      *end_s = s + n;
  109.         while (true)
  110.         {
  111.             // Invoke filter if there are unconsumed characters in buffer or if
  112.             // filter must be flushed.
  113.             bool flush = status == f_eof;
  114.             if (buf.ptr() != buf.eptr() || flush) {
  115.                 const char_type* next = buf.ptr();
  116.                 bool done =
  117.                     !filter().filter(next, buf.eptr(), next_s, end_s, flush);
  118.                 buf.ptr() = buf.data() + (next - buf.data());
  119.                 if (done)
  120.                     return detail::check_eof(
  121.                                static_cast<std::streamsize>(next_s - s)
  122.                            );
  123.             }
  124.  
  125.             // If no more characters are available without blocking, or
  126.             // if read request has been satisfied, return.
  127.             if ( (status == f_would_block && buf.ptr() == buf.eptr()) ||
  128.                  next_s == end_s )
  129.             {
  130.                 return static_cast<std::streamsize>(next_s - s);
  131.             }
  132.  
  133.             // Fill buffer.
  134.             if (status == f_good)
  135.                 status = fill(src);
  136.         }
  137.     }
  138.  
  139.     template<typename Sink>
  140.     std::streamsize write(Sink& snk, const char_type* s, std::streamsize n)
  141.     {
  142.         if (!(state() & f_write))
  143.             begin_write();
  144.  
  145.         buffer_type&     buf = pimpl_->buf_;
  146.         const char_type *next_s, *end_s;
  147.         for (next_s = s, end_s = s + n; next_s != end_s; ) {
  148.             if (buf.ptr() == buf.eptr() && !flush(snk))
  149.                 break;
  150.             if(!filter().filter(next_s, end_s, buf.ptr(), buf.eptr(), false)) {
  151.                 flush(snk);
  152.                 break;
  153.             }
  154.         }
  155.         return static_cast<std::streamsize>(next_s - s);
  156.     }
  157.  
  158.     template<typename Sink>
  159.     void close(Sink& snk, BOOST_IOS::openmode mode)
  160.     {
  161.         if (mode == BOOST_IOS::out) {
  162.  
  163.             if (!(state() & f_write))
  164.                 begin_write();
  165.  
  166.             // Repeatedly invoke filter() with no input.
  167.              BOOST_TRY {
  168.                 buffer_type&     buf = pimpl_->buf_;
  169.                 char_type        dummy;
  170.                 const char_type* end = &dummy;
  171.                 bool             again = true;
  172.                 while (again) {
  173.                     if (buf.ptr() != buf.eptr())
  174.                         again = filter().filter( end, end, buf.ptr(),
  175.                                                  buf.eptr(), true );
  176.                     flush(snk);
  177.                 }
  178.             } BOOST_CATCH (...) {
  179.                 BOOST_TRY { close_impl(); } BOOST_CATCH (...) { } BOOST_CATCH_END
  180.                 BOOST_RETHROW;
  181.             } BOOST_CATCH_END}
  182.             close_impl();
  183.         } else {
  184.             close_impl();
  185.         }
  186.     }
  187.     SymmetricFilter& filter() { return *pimpl_; }
  188.     string_type unconsumed_input() const;
  189.  
  190. // Give impl access to buffer_type on Tru64
  191. #if !BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042))
  192.     private:
  193. #endif
  194.     typedef detail::buffer<char_type, Alloc> buffer_type;
  195. private:
  196.     buffer_type& buf() { return pimpl_->buf_; }
  197.     const buffer_type& buf() const { return pimpl_->buf_; }
  198.     int& state() { return pimpl_->state_; }
  199.     void begin_read();
  200.     void begin_write();
  201.  
  202.     template<typename Source>
  203.     int fill(Source& src)
  204.     {
  205.         std::streamsize amt = iostreams::read(src, buf().data(), buf().size());
  206.         if (amt == -1) {
  207.             state() |= f_eof;
  208.             return f_eof;
  209.         }
  210.         buf().set(0, amt);
  211.         return amt != 0 ? f_good : f_would_block;
  212.     }
  213.  
  214.     // Attempts to write the contents of the buffer the given Sink.
  215.     // Returns true if at least on character was written.
  216.     template<typename Sink>
  217.     bool flush(Sink& snk)
  218.     {
  219.         typedef typename iostreams::category_of<Sink>::type  category;
  220.         typedef is_convertible<category, output>             can_write;
  221.         return flush(snk, can_write());
  222.     }
  223.  
  224.     template<typename Sink>
  225.     bool flush(Sink& snk, mpl::true_)
  226.     {
  227.         std::streamsize amt =
  228.             static_cast<std::streamsize>(buf().ptr() - buf().data());
  229.         std::streamsize result =
  230.             mars_boost::iostreams::write(snk, buf().data(), amt);
  231.         if (result < amt && result > 0)
  232.             traits_type::move(buf().data(), buf().data() + result, amt - result);
  233.         buf().set(amt - result, buf().size());
  234.         return result != 0;
  235.     }
  236.  
  237.     template<typename Sink>
  238.     bool flush(Sink&, mpl::false_) { return true;}
  239.  
  240.     void close_impl();
  241.  
  242.     enum flag_type {
  243.         f_read   = 1,
  244.         f_write  = f_read << 1,
  245.         f_eof    = f_write << 1,
  246.         f_good,
  247.         f_would_block
  248.     };
  249.  
  250.     struct impl : SymmetricFilter {
  251.  
  252.     // Expands to a sequence of ctors which forward to SymmetricFilter.
  253.     #define BOOST_PP_LOCAL_MACRO(n) \
  254.         BOOST_IOSTREAMS_TEMPLATE_PARAMS(n, T) \
  255.         impl( int buffer_size BOOST_PP_COMMA_IF(n) \
  256.               BOOST_PP_ENUM_BINARY_PARAMS(n, const T, &t) ) \
  257.             : SymmetricFilter(BOOST_PP_ENUM_PARAMS(n, t)), \
  258.               buf_(buffer_size), state_(0) \
  259.             { } \
  260.         /**/
  261.     #define BOOST_PP_LOCAL_LIMITS (0, BOOST_IOSTREAMS_MAX_FORWARDING_ARITY)
  262.     #include BOOST_PP_LOCAL_ITERATE()
  263.     #undef BOOST_PP_LOCAL_MACRO
  264.  
  265.         buffer_type  buf_;
  266.         int          state_;
  267.     };
  268.  
  269.     shared_ptr<impl> pimpl_;
  270. };
  271. BOOST_IOSTREAMS_PIPABLE(symmetric_filter, 2)
  272.  
  273. //------------------Implementation of symmetric_filter----------------//
  274.  
  275. template<typename SymmetricFilter, typename Alloc>
  276. void symmetric_filter<SymmetricFilter, Alloc>::begin_read()
  277. {
  278.     BOOST_ASSERT(!(state() & f_write));
  279.     state() |= f_read;
  280.     buf().set(0, 0);
  281. }
  282.  
  283. template<typename SymmetricFilter, typename Alloc>
  284. void symmetric_filter<SymmetricFilter, Alloc>::begin_write()
  285. {
  286.     BOOST_ASSERT(!(state() & f_read));
  287.     state() |= f_write;
  288.     buf().set(0, buf().size());
  289. }
  290.  
  291. template<typename SymmetricFilter, typename Alloc>
  292. void symmetric_filter<SymmetricFilter, Alloc>::close_impl()
  293. {
  294.     state() = 0;
  295.     buf().set(0, 0);
  296.     filter().close();
  297. }
  298.  
  299. template<typename SymmetricFilter, typename Alloc>
  300. typename symmetric_filter<SymmetricFilter, Alloc>::string_type
  301. symmetric_filter<SymmetricFilter, Alloc>::unconsumed_input() const
  302. { return string_type(buf().ptr(), buf().eptr()); }
  303.  
  304. //----------------------------------------------------------------------------//
  305.  
  306. } } // End namespaces iostreams, boost.
  307.  
  308. #include <boost/iostreams/detail/config/enable_warnings.hpp>  // MSVC.
  309.  
  310. #endif // #ifndef BOOST_IOSTREAMS_SYMMETRIC_FILTER_HPP_INCLUDED
  311.  
downloadsymmetric.hpp Source code - Download mars Source code
Related Source Codes/Software:
Hero - Elegant transition library for iOS & tvOS 2017-06-09
deep-photo-styletransfer - Code and data for paper "Deep Photo Style Transfer... 2017-06-09
mastodon - A GNU Social-compatible microblogging server ... 2017-06-09
plyr - A simple HTML5, YouTube and Vimeo player ... 2017-06-08
prepack - Prepack is a partial evaluator for JavaScript. Pre... 2017-06-08
Public-APIs - 2017-06-09
lottie-ios - An iOS library to natively render After Effects ve... 2017-06-09
Awesome-Hacking - A collection of various awesome lists for hackers,... 2017-06-09
algorithms - Minimal examples of data structures and algorithms... 2017-06-10
lectures - Oxford Deep NLP 2017 course 2017-06-10
CRYENGINE - CRYENGINE is a powerful real-time game development... 2017-06-11
postal - 2017-06-11
reactide - Reactide is the first dedicated IDE for React web ... 2017-06-11
rkt - rkt is a pod-native container engine for Linux. It... 2017-06-11
uWebSockets - Tiny WebSockets https://for... 2017-06-11
realworld - TodoMVC for the RealWorld - Exemplary fullstack Me... 2017-06-11
goreplay - GoReplay is an open-source tool for capturing and ... 2017-06-10
pyenv - Simple Python version management 2017-06-10
redux-saga - An alternative side effect model for Redux apps ... 2017-06-10
angular-starter - 2017-06-10

 Back to top