Jeff Thompson | 86b6d64 | 2013-10-17 15:01:56 -0700 | [diff] [blame] | 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 | #ifndef NDNBOOST_IOSTREAMS_FILE_HPP_INCLUDED |
| 9 | #define NDNBOOST_IOSTREAMS_FILE_HPP_INCLUDED |
| 10 | |
| 11 | #if defined(_MSC_VER) && (_MSC_VER >= 1020) |
| 12 | # pragma once |
| 13 | #endif |
| 14 | |
| 15 | #include <ndnboost/iostreams/detail/config/wide_streams.hpp> |
| 16 | #ifndef NDNBOOST_IOSTREAMS_NO_LOCALE |
| 17 | # include <locale> |
| 18 | #endif |
| 19 | #include <string> // pathnames, char_traits. |
| 20 | #include <ndnboost/iostreams/categories.hpp> |
| 21 | #include <ndnboost/iostreams/detail/ios.hpp> // openmode, seekdir, int types. |
| 22 | #include <ndnboost/iostreams/detail/fstream.hpp> |
| 23 | #include <ndnboost/iostreams/operations.hpp> // seek. |
| 24 | #include <ndnboost/shared_ptr.hpp> |
| 25 | |
| 26 | // Must come last. |
| 27 | #include <ndnboost/iostreams/detail/config/disable_warnings.hpp> // MSVC. |
| 28 | |
| 29 | namespace ndnboost { namespace iostreams { |
| 30 | |
| 31 | template<typename Ch> |
| 32 | class basic_file { |
| 33 | public: |
| 34 | typedef Ch char_type; |
| 35 | struct category |
| 36 | : public seekable_device_tag, |
| 37 | public closable_tag, |
| 38 | public localizable_tag, |
| 39 | public flushable_tag |
| 40 | { }; |
| 41 | basic_file( const std::string& path, |
| 42 | NDNBOOST_IOS::openmode mode = |
| 43 | NDNBOOST_IOS::in | NDNBOOST_IOS::out, |
| 44 | NDNBOOST_IOS::openmode base_mode = |
| 45 | NDNBOOST_IOS::in | NDNBOOST_IOS::out ); |
| 46 | std::streamsize read(char_type* s, std::streamsize n); |
| 47 | bool putback(char_type c); |
| 48 | std::streamsize write(const char_type* s, std::streamsize n); |
| 49 | std::streampos seek( stream_offset off, NDNBOOST_IOS::seekdir way, |
| 50 | NDNBOOST_IOS::openmode which = |
| 51 | NDNBOOST_IOS::in | NDNBOOST_IOS::out ); |
| 52 | void open( const std::string& path, |
| 53 | NDNBOOST_IOS::openmode mode = |
| 54 | NDNBOOST_IOS::in | NDNBOOST_IOS::out, |
| 55 | NDNBOOST_IOS::openmode base_mode = |
| 56 | NDNBOOST_IOS::in | NDNBOOST_IOS::out ); |
| 57 | bool is_open() const; |
| 58 | void close(); |
| 59 | bool flush(); |
| 60 | #ifndef NDNBOOST_IOSTREAMS_NO_LOCALE |
| 61 | void imbue(const std::locale& loc) { pimpl_->file_.pubimbue(loc); } |
| 62 | #endif |
| 63 | private: |
| 64 | struct impl { |
| 65 | impl(const std::string& path, NDNBOOST_IOS::openmode mode) |
| 66 | { file_.open(path.c_str(), mode); } |
| 67 | ~impl() { if (file_.is_open()) file_.close(); } |
| 68 | NDNBOOST_IOSTREAMS_BASIC_FILEBUF(Ch) file_; |
| 69 | }; |
| 70 | shared_ptr<impl> pimpl_; |
| 71 | }; |
| 72 | |
| 73 | typedef basic_file<char> file; |
| 74 | typedef basic_file<wchar_t> wfile; |
| 75 | |
| 76 | template<typename Ch> |
| 77 | struct basic_file_source : private basic_file<Ch> { |
| 78 | typedef Ch char_type; |
| 79 | struct category |
| 80 | : input_seekable, |
| 81 | device_tag, |
| 82 | closable_tag |
| 83 | { }; |
| 84 | using basic_file<Ch>::read; |
| 85 | using basic_file<Ch>::putback; |
| 86 | using basic_file<Ch>::seek; |
| 87 | using basic_file<Ch>::is_open; |
| 88 | using basic_file<Ch>::close; |
| 89 | basic_file_source( const std::string& path, |
| 90 | NDNBOOST_IOS::openmode mode = |
| 91 | NDNBOOST_IOS::in ) |
| 92 | : basic_file<Ch>(path, mode & ~NDNBOOST_IOS::out, NDNBOOST_IOS::in) |
| 93 | { } |
| 94 | void open( const std::string& path, |
| 95 | NDNBOOST_IOS::openmode mode = NDNBOOST_IOS::in ) |
| 96 | { |
| 97 | basic_file<Ch>::open(path, mode & ~NDNBOOST_IOS::out, NDNBOOST_IOS::in); |
| 98 | } |
| 99 | }; |
| 100 | |
| 101 | typedef basic_file_source<char> file_source; |
| 102 | typedef basic_file_source<wchar_t> wfile_source; |
| 103 | |
| 104 | template<typename Ch> |
| 105 | struct basic_file_sink : private basic_file<Ch> { |
| 106 | typedef Ch char_type; |
| 107 | struct category |
| 108 | : output_seekable, |
| 109 | device_tag, |
| 110 | closable_tag, |
| 111 | flushable_tag |
| 112 | { }; |
| 113 | using basic_file<Ch>::write; |
| 114 | using basic_file<Ch>::seek; |
| 115 | using basic_file<Ch>::is_open; |
| 116 | using basic_file<Ch>::close; |
| 117 | using basic_file<Ch>::flush; |
| 118 | basic_file_sink( const std::string& path, |
| 119 | NDNBOOST_IOS::openmode mode = NDNBOOST_IOS::out ) |
| 120 | : basic_file<Ch>(path, mode & ~NDNBOOST_IOS::in, NDNBOOST_IOS::out) |
| 121 | { } |
| 122 | void open( const std::string& path, |
| 123 | NDNBOOST_IOS::openmode mode = NDNBOOST_IOS::out ) |
| 124 | { |
| 125 | basic_file<Ch>::open(path, mode & ~NDNBOOST_IOS::in, NDNBOOST_IOS::out); |
| 126 | } |
| 127 | }; |
| 128 | |
| 129 | typedef basic_file_sink<char> file_sink; |
| 130 | typedef basic_file_sink<wchar_t> wfile_sink; |
| 131 | |
| 132 | //------------------Implementation of basic_file------------------------------// |
| 133 | |
| 134 | template<typename Ch> |
| 135 | basic_file<Ch>::basic_file |
| 136 | ( const std::string& path, NDNBOOST_IOS::openmode mode, |
| 137 | NDNBOOST_IOS::openmode base_mode ) |
| 138 | { |
| 139 | open(path, mode, base_mode); |
| 140 | } |
| 141 | |
| 142 | template<typename Ch> |
| 143 | inline std::streamsize basic_file<Ch>::read |
| 144 | (char_type* s, std::streamsize n) |
| 145 | { |
| 146 | std::streamsize result = pimpl_->file_.sgetn(s, n); |
| 147 | return result != 0 ? result : -1; |
| 148 | } |
| 149 | |
| 150 | template<typename Ch> |
| 151 | inline bool basic_file<Ch>::putback(char_type c) |
| 152 | { |
| 153 | return !!pimpl_->file_.sputbackc(c); |
| 154 | } |
| 155 | |
| 156 | template<typename Ch> |
| 157 | inline std::streamsize basic_file<Ch>::write |
| 158 | (const char_type* s, std::streamsize n) |
| 159 | { return pimpl_->file_.sputn(s, n); } |
| 160 | |
| 161 | template<typename Ch> |
| 162 | std::streampos basic_file<Ch>::seek |
| 163 | ( stream_offset off, NDNBOOST_IOS::seekdir way, |
| 164 | NDNBOOST_IOS::openmode ) |
| 165 | { return iostreams::seek(pimpl_->file_, off, way); } |
| 166 | |
| 167 | template<typename Ch> |
| 168 | void basic_file<Ch>::open |
| 169 | ( const std::string& path, NDNBOOST_IOS::openmode mode, |
| 170 | NDNBOOST_IOS::openmode base_mode ) |
| 171 | { |
| 172 | pimpl_.reset(new impl(path, mode | base_mode)); |
| 173 | } |
| 174 | |
| 175 | template<typename Ch> |
| 176 | bool basic_file<Ch>::is_open() const { return pimpl_->file_.is_open(); } |
| 177 | |
| 178 | template<typename Ch> |
| 179 | void basic_file<Ch>::close() { pimpl_->file_.close(); } |
| 180 | |
| 181 | template<typename Ch> |
| 182 | bool basic_file<Ch>::flush() |
| 183 | { return pimpl_->file_.NDNBOOST_IOSTREAMS_PUBSYNC() == 0; } |
| 184 | |
| 185 | //----------------------------------------------------------------------------// |
| 186 | |
| 187 | } } // End namespaces iostreams, boost. |
| 188 | |
| 189 | #include <ndnboost/iostreams/detail/config/enable_warnings.hpp> // MSVC |
| 190 | |
| 191 | #endif // #ifndef NDNBOOST_IOSTREAMS_FILE_HPP_INCLUDED |