| 1 | // (C) Copyright Jonathan Turkanis 2003. | 
|---|
| 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 | // Inspired by fdstream.hpp, (C) Copyright Nicolai M. Josuttis 2001, | 
|---|
| 8 | // available at http://www.josuttis.com/cppcode/fdstream.html. | 
|---|
| 9 |  | 
|---|
| 10 | #ifndef BOOST_IOSTREAMS_FILE_DESCRIPTOR_HPP_INCLUDED | 
|---|
| 11 | #define BOOST_IOSTREAMS_FILE_DESCRIPTOR_HPP_INCLUDED | 
|---|
| 12 |  | 
|---|
| 13 | #if defined(_MSC_VER) && (_MSC_VER >= 1020) | 
|---|
| 14 | # pragma once | 
|---|
| 15 | #endif | 
|---|
| 16 |  | 
|---|
| 17 | #include <string>                          // file pathnames. | 
|---|
| 18 | #include <boost/cstdint.hpp>               // intmax_t. | 
|---|
| 19 | #include <boost/iostreams/categories.hpp>  // tags. | 
|---|
| 20 | #include <boost/iostreams/detail/config/auto_link.hpp> | 
|---|
| 21 | #include <boost/iostreams/detail/config/dyn_link.hpp> | 
|---|
| 22 | #include <boost/iostreams/detail/config/windows_posix.hpp> | 
|---|
| 23 | #include <boost/iostreams/detail/ios.hpp>  // openmode, seekdir, int types. | 
|---|
| 24 | #include <boost/iostreams/positioning.hpp> | 
|---|
| 25 | #include <boost/shared_ptr.hpp> | 
|---|
| 26 |  | 
|---|
| 27 | // Must come last. | 
|---|
| 28 | #include <boost/config/abi_prefix.hpp> | 
|---|
| 29 |  | 
|---|
| 30 | namespace boost { namespace iostreams { | 
|---|
| 31 |  | 
|---|
| 32 | class BOOST_IOSTREAMS_DECL file_descriptor { | 
|---|
| 33 | public: | 
|---|
| 34 | #ifdef BOOST_IOSTREAMS_WINDOWS | 
|---|
| 35 |     typedef void*  handle_type; | 
|---|
| 36 | #endif | 
|---|
| 37 |     typedef char   char_type; | 
|---|
| 38 |     struct category | 
|---|
| 39 |         : seekable_device_tag, | 
|---|
| 40 |           closable_tag | 
|---|
| 41 |         { }; | 
|---|
| 42 |     file_descriptor() : pimpl_(new impl) { } | 
|---|
| 43 |     explicit file_descriptor(int fd, bool close_on_exit = false) | 
|---|
| 44 |         : pimpl_(new impl(fd, close_on_exit)) | 
|---|
| 45 |         { } | 
|---|
| 46 | #ifdef BOOST_IOSTREAMS_WINDOWS | 
|---|
| 47 |     explicit file_descriptor(handle_type handle, bool close_on_exit = false) | 
|---|
| 48 |         : pimpl_(new impl(handle, close_on_exit)) | 
|---|
| 49 |         { } | 
|---|
| 50 | #endif | 
|---|
| 51 |     explicit file_descriptor( const std::string& path, | 
|---|
| 52 |                               BOOST_IOS::openmode mode = | 
|---|
| 53 |                                   BOOST_IOS::in | BOOST_IOS::out, | 
|---|
| 54 |                               BOOST_IOS::openmode base_mode = | 
|---|
| 55 |                                   BOOST_IOS::in | BOOST_IOS::out ) | 
|---|
| 56 |         : pimpl_(new impl) | 
|---|
| 57 |     { open(path, mode, base_mode); } | 
|---|
| 58 |     void open( const std::string& path, | 
|---|
| 59 |                BOOST_IOS::openmode = | 
|---|
| 60 |                    BOOST_IOS::in | BOOST_IOS::out, | 
|---|
| 61 |                BOOST_IOS::openmode base_mode = | 
|---|
| 62 |                    BOOST_IOS::in | BOOST_IOS::out ); | 
|---|
| 63 |     bool is_open() const { return pimpl_->flags_ != 0; } | 
|---|
| 64 |     std::streamsize read(char_type* s, std::streamsize n); | 
|---|
| 65 |     std::streamsize write(const char_type* s, std::streamsize n); | 
|---|
| 66 |     std::streampos seek(stream_offset off, BOOST_IOS::seekdir way); | 
|---|
| 67 |     void close(); | 
|---|
| 68 | private: | 
|---|
| 69 |     struct impl { | 
|---|
| 70 |         impl() : fd_(-1), flags_(0) { } | 
|---|
| 71 |         impl(int fd, bool close_on_exit) | 
|---|
| 72 |             : fd_(fd), flags_(0) | 
|---|
| 73 |         { if (close_on_exit) flags_ |= impl::close_on_exit; } | 
|---|
| 74 |     #ifdef BOOST_IOSTREAMS_WINDOWS | 
|---|
| 75 |         impl(handle_type handle, bool close_on_exit) | 
|---|
| 76 |             : handle_(handle), flags_(has_handle) | 
|---|
| 77 |         { if (close_on_exit) flags_ |= impl::close_on_exit; } | 
|---|
| 78 |     #endif | 
|---|
| 79 |         ~impl() { | 
|---|
| 80 |             if (flags_ & close_on_exit) close_impl(*this); | 
|---|
| 81 |         } | 
|---|
| 82 |         enum flags { | 
|---|
| 83 |             close_on_exit = 1, | 
|---|
| 84 |             has_handle = 2, | 
|---|
| 85 |             append = 4 | 
|---|
| 86 |         }; | 
|---|
| 87 |         int          fd_; | 
|---|
| 88 |     #ifdef BOOST_IOSTREAMS_WINDOWS | 
|---|
| 89 |         handle_type  handle_; | 
|---|
| 90 |     #endif | 
|---|
| 91 |         int          flags_; | 
|---|
| 92 |     }; | 
|---|
| 93 |     friend struct impl; | 
|---|
| 94 |  | 
|---|
| 95 |     static void close_impl(impl&); | 
|---|
| 96 |  | 
|---|
| 97 |     shared_ptr<impl> pimpl_; | 
|---|
| 98 | }; | 
|---|
| 99 |  | 
|---|
| 100 | struct file_descriptor_source : private file_descriptor { | 
|---|
| 101 | #ifdef BOOST_IOSTREAMS_WINDOWS | 
|---|
| 102 |     typedef void*  handle_type; | 
|---|
| 103 | #endif | 
|---|
| 104 |     typedef char   char_type; | 
|---|
| 105 |     struct category : public source_tag, closable_tag { }; | 
|---|
| 106 |     using file_descriptor::read; | 
|---|
| 107 |     using file_descriptor::open; | 
|---|
| 108 |     using file_descriptor::is_open; | 
|---|
| 109 |     using file_descriptor::close; | 
|---|
| 110 |     file_descriptor_source() { } | 
|---|
| 111 |     explicit file_descriptor_source(int fd, bool close_on_exit = false) | 
|---|
| 112 |         : file_descriptor(fd, close_on_exit) | 
|---|
| 113 |         { } | 
|---|
| 114 | #ifdef BOOST_IOSTREAMS_WINDOWS | 
|---|
| 115 |     explicit file_descriptor_source( handle_type handle, | 
|---|
| 116 |                                      bool close_on_exit = false ) | 
|---|
| 117 |         : file_descriptor(handle, close_on_exit) | 
|---|
| 118 |         { } | 
|---|
| 119 | #endif | 
|---|
| 120 |     explicit file_descriptor_source( const std::string& path, | 
|---|
| 121 |                                      BOOST_IOS::openmode m = BOOST_IOS::in ) | 
|---|
| 122 |         : file_descriptor(path, m & ~BOOST_IOS::out, BOOST_IOS::in) | 
|---|
| 123 |         { } | 
|---|
| 124 | }; | 
|---|
| 125 |  | 
|---|
| 126 | struct file_descriptor_sink : private file_descriptor { | 
|---|
| 127 | #ifdef BOOST_IOSTREAMS_WINDOWS | 
|---|
| 128 |     typedef void*  handle_type; | 
|---|
| 129 | #endif | 
|---|
| 130 |     typedef char   char_type; | 
|---|
| 131 |     struct category : public sink_tag, closable_tag { }; | 
|---|
| 132 |     using file_descriptor::write; | 
|---|
| 133 |     using file_descriptor::open; | 
|---|
| 134 |     using file_descriptor::is_open; | 
|---|
| 135 |     using file_descriptor::close; | 
|---|
| 136 |     file_descriptor_sink() { } | 
|---|
| 137 |     explicit file_descriptor_sink(int fd, bool close_on_exit = false) | 
|---|
| 138 |         : file_descriptor(fd, close_on_exit) | 
|---|
| 139 |         { } | 
|---|
| 140 | #ifdef BOOST_IOSTREAMS_WINDOWS | 
|---|
| 141 |     explicit file_descriptor_sink( handle_type handle, | 
|---|
| 142 |                                    bool close_on_exit = false ) | 
|---|
| 143 |         : file_descriptor(handle, close_on_exit) | 
|---|
| 144 |         { } | 
|---|
| 145 | #endif | 
|---|
| 146 |     explicit file_descriptor_sink( const std::string& path, | 
|---|
| 147 |                                    BOOST_IOS::openmode m = BOOST_IOS::out ) | 
|---|
| 148 |         : file_descriptor(path, m & ~BOOST_IOS::in, BOOST_IOS::out) | 
|---|
| 149 |         { } | 
|---|
| 150 | }; | 
|---|
| 151 |  | 
|---|
| 152 | } } // End namespaces iostreams, boost. | 
|---|
| 153 |  | 
|---|
| 154 | #include <boost/config/abi_suffix.hpp> // pops abi_suffix.hpp pragmas | 
|---|
| 155 |  | 
|---|
| 156 | #endif // #ifndef BOOST_IOSTREAMS_FILE_DESCRIPTOR_HPP_INCLUDED | 
|---|