1 /*=============================================================================
2     Copyright (c) 2001-2011 Hartmut Kaiser
3 
4     Distributed under the Boost Software License, Version 1.0. (See accompanying
5     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 ==============================================================================*/
7 #if !defined(BOOST_SPIRIT_ITERATOR_ISTREAM_MAY_05_2007_0110PM)
8 #define BOOST_SPIRIT_ITERATOR_ISTREAM_MAY_05_2007_0110PM
9 
10 #if defined(_MSC_VER)
11 #pragma once
12 #endif
13 
14 #include <boost/iostreams/stream.hpp>
15 #include <boost/detail/iterator.hpp>
16 
17 ///////////////////////////////////////////////////////////////////////////////
18 namespace boost { namespace spirit { namespace qi { namespace detail
19 {
20     ///////////////////////////////////////////////////////////////////////////
21     template <typename Iterator>
22     struct iterator_source
23     {
24         typedef typename
25             boost::detail::iterator_traits<Iterator>::value_type
26         char_type;
27         typedef boost::iostreams::seekable_device_tag category;
28 
iterator_sourceboost::spirit::qi::detail::iterator_source29         iterator_source (Iterator const& first_, Iterator const& last_)
30           : first(first_), last(last_), pos(0)
31         {}
32 
33         // Read up to n characters from the input sequence into the buffer s,
34         // returning the number of characters read, or -1 to indicate
35         // end-of-sequence.
readboost::spirit::qi::detail::iterator_source36         std::streamsize read (char_type* s, std::streamsize n)
37         {
38             if (first == last)
39                 return -1;
40 
41             std::streamsize bytes_read = 0;
42             while (n--) {
43                 *s = *first;
44                 ++s; ++bytes_read;
45                 if (++first == last)
46                     break;
47             }
48 
49             pos += bytes_read;
50             return bytes_read;
51         }
52 
53         // Write is implemented only to satisfy the requirements of a
54         // boost::iostreams::seekable_device. We need to have see support to
55         // be able to figure out how many characters have been actually
56         // consumed by the stream.
writeboost::spirit::qi::detail::iterator_source57         std::streamsize write(const char_type*, std::streamsize)
58         {
59             BOOST_ASSERT(false);    // not supported
60             return -1;
61         }
62 
seekboost::spirit::qi::detail::iterator_source63         std::streampos seek(boost::iostreams::stream_offset, std::ios_base::seekdir way)
64         {
65             BOOST_ASSERT(way == std::ios_base::cur);    // only support queries
66             return pos;                              // return current position
67         }
68 
69         Iterator first;
70         Iterator const& last;
71         std::streamsize pos;
72 
73     private:
74         // silence MSVC warning C4512: assignment operator could not be generated
75         iterator_source& operator= (iterator_source const&);
76     };
77 
78 }}}}
79 
80 #endif
81