1 /* cclive 2 * Copyright (C) 2010-2013 Toni Gundogdu <legatvs@gmail.com> 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #ifndef cclive_log_h 19 #define cclive_log_h 20 21 #include <iostream> 22 #include <fstream> 23 24 #include <boost/iostreams/filtering_stream.hpp> 25 26 #define cc_debug(...)\ 27 do { cc::_debug(__BASE_FILE__, __func__, __LINE__, __VA_ARGS__); } while (0) 28 29 namespace cc 30 { 31 32 void _debug(const std::string&, const std::string&, 33 const int, const char*, ...); 34 35 extern boost::iostreams::filtering_ostream log; 36 37 struct omit_sink : public boost::iostreams::sink 38 { writeomit_sink39 inline std::streamsize write(const char *s, std::streamsize n) 40 { 41 if (!_omit) std::clog.write(s,n); 42 return n; 43 } _omitomit_sink44 inline explicit omit_sink(bool b=false): _omit(b) { } 45 private: 46 bool _omit; 47 }; 48 49 struct flushable_file_sink 50 { 51 typedef char char_type; 52 53 struct category : 54 boost::iostreams::output_seekable, 55 boost::iostreams::device_tag, 56 boost::iostreams::closable_tag, 57 boost::iostreams::flushable_tag {}; 58 59 inline flushable_file_sink( 60 const std::string& fpath, 61 const std::ios_base::openmode mode = std::ios::trunc|std::ios::out) _modeflushable_file_sink62 : _mode(mode), _fpath(fpath) 63 { 64 _open(); 65 } 66 flushable_file_sinkflushable_file_sink67 inline flushable_file_sink(const flushable_file_sink& f) { _swap(f); } 68 69 inline flushable_file_sink& operator=(const flushable_file_sink& f) 70 { 71 if (this != &f) _swap(f); 72 return *this; 73 } 74 seekflushable_file_sink75 inline std::streampos seek(std::streamoff o, std::ios_base::seekdir d) 76 { 77 _f.seekp(o,d); 78 _f.seekg(o,d); 79 return o; 80 } 81 writeflushable_file_sink82 inline std::streamsize write(const char *s, std::streamsize n) 83 { 84 _f.write(s,n); 85 return n; 86 } 87 readflushable_file_sink88 inline std::streamsize read(char_type *t, std::streamsize n) 89 { 90 _f.read(t,n); 91 return n; 92 } 93 is_openflushable_file_sink94 inline bool is_open() const { return _f.is_open(); } 95 flushflushable_file_sink96 inline bool flush() 97 { 98 _f.flush(); 99 return true; 100 } 101 closeflushable_file_sink102 inline void close() 103 { 104 flush(); 105 _f.close(); 106 } 107 private: _swapflushable_file_sink108 inline void _swap(const flushable_file_sink& f) 109 { 110 close(); 111 _fpath = f._fpath; 112 _mode = f._mode; 113 _open(); 114 } 115 void _open(); 116 private: 117 std::ios_base::openmode _mode; 118 mutable std::fstream _f; 119 std::string _fpath; 120 }; 121 122 } // namespace cc 123 124 #endif // cclive_log_h 125 126 // vim: set ts=2 sw=2 tw=72 expandtab: 127