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