~ubuntu-branches/debian/sid/gsmartcontrol/sid

« back to all changes in this revision

Viewing changes to .pc/03_gcc4.4.patch/src/libdebug/dstream.h

  • Committer: Bazaar Package Importer
  • Author(s): Giuseppe Iuculano
  • Date: 2011-07-15 14:59:29 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20110715145929-2o1o4phm5w1rwttz
Tags: 0.8.6-1
* [dbb993d] Updated my email address and removed DM-Upload-Allowed
  control field
* [b681b5b] Imported Upstream version 0.8.6
* [ab9bb7a] Refreshed patches
* [a909506] Bump to Standards-Version 3.9.2, no changes needed
* [48dd13d] Switch to dpkg-source 3.0 (quilt) format

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**************************************************************************
 
2
 Copyright:
 
3
      (C) 2008 - 2011  Alexander Shaduri <ashaduri 'at' gmail.com>
 
4
 License: See LICENSE_zlib.txt file
 
5
***************************************************************************/
 
6
 
 
7
#ifndef LIBDEBUG_DSTREAM_H
 
8
#define LIBDEBUG_DSTREAM_H
 
9
 
 
10
#include <ostream>  // std::ostream definition
 
11
#include <streambuf>  // std::streambuf definition
 
12
#include <string>
 
13
#include <sstream>
 
14
#include <vector>
 
15
 
 
16
#include "hz/intrusive_ptr.h"
 
17
#include "hz/tls.h"
 
18
 
 
19
#include "dflags.h"
 
20
#include "dchannel.h"
 
21
 
 
22
 
 
23
 
 
24
namespace debug_internal {
 
25
 
 
26
 
 
27
        std::streambuf& get_null_streambuf();
 
28
 
 
29
        std::ostream& get_null_stream();
 
30
 
 
31
 
 
32
        // state.h includes us, so we need these forward declarations
 
33
//      class DebugState;
 
34
//      DebugState& get_debug_state();
 
35
 
 
36
 
 
37
 
 
38
        class DebugOutStream;
 
39
 
 
40
 
 
41
        class DebugStreamBuf : public std::streambuf {
 
42
                public:
 
43
 
 
44
                        DebugStreamBuf(DebugOutStream* dos) : dos_(dos)
 
45
                        {
 
46
                                // in case of overflow for output, overflow() will be called to _output_ the data.
 
47
 
 
48
                                // no buffers here - we process it char-by-char. Apart from practical reasons,
 
49
                                // this is also needed to ensure that the state of the object (buffer) doesn't
 
50
                                // change during calls to methods - to ensure read-only thread-safety.
 
51
                                int buf_size = 0;
 
52
                                if (buf_size) {
 
53
                                        char* buf = new char[buf_size];  // further accessible through pbase().
 
54
                                        setp(buf, buf + buf_size);  // Set output sequence pointers, aka output buffer
 
55
                                } else {
 
56
                                        setp(NULL, NULL);
 
57
                                }
 
58
 
 
59
                                setg(NULL, NULL, NULL);  // Set input sequence pointers; not relevant in this class.
 
60
                        }
 
61
 
 
62
 
 
63
                        virtual ~DebugStreamBuf()
 
64
                        {
 
65
                                sync();
 
66
                                delete[] pbase();  // delete the buffer
 
67
                        }
 
68
 
 
69
 
 
70
                        // Force output of the stringstream's contents to the channels.
 
71
                        // This is function thread-safe as long as state is not modified.
 
72
                        void force_output()
 
73
                        {
 
74
                                flush_to_channel();
 
75
                        }
 
76
 
 
77
 
 
78
                protected:
 
79
 
 
80
                        // overflow happens when a new character is to be written at the put
 
81
                        // pointer pptr position, but this has reached the end pointer epptr.
 
82
                        virtual int overflow(int c)  // overridden from parent
 
83
                        {
 
84
                                sync();  // write the buffer contents if available
 
85
                                if (c != traits_type::eof()) {
 
86
                                        if (pbase() == epptr()) {  // no buffer, write it char-by-char (epptr() - buffer end pointer)
 
87
        //                                      std::string tmp;
 
88
        //                                      tmp += char(c);
 
89
        //                                      write_out(tmp);
 
90
                                                write_char(char(c));
 
91
                                        } else {  // we have a buffer
 
92
                                                // put c into buffer (the overflowed char); the rest is written in sync() earlier.
 
93
                                                sputc(static_cast<char>(c));
 
94
                                        }
 
95
                                }
 
96
                                return 0;
 
97
                        }
 
98
 
 
99
 
 
100
                        // sort-of flush the buffer. only makes sense if there is a buffer.
 
101
                        virtual int sync()  // overridden from parent
 
102
                        {
 
103
                                if (pbase() != pptr()) {  // pptr() - current position; condition is true only if there is something in the buffer.
 
104
        //                              write_out(std::string(pbase(), pptr() - pbase()));
 
105
                                        for (char* pos = pbase(); pos != pptr(); ++pos)
 
106
                                                write_char(*pos);
 
107
                                        setp(pbase(), epptr());  // reset the buffer's current pointer (?)
 
108
                                }
 
109
                                return 0;
 
110
                        }
 
111
 
 
112
 
 
113
                        // custom function. write contents if necessary.
 
114
        //              void write_out(const std::string& str)  // str may be one char, or entire buffer, or in between.
 
115
        //              {
 
116
        //              }
 
117
 
 
118
 
 
119
                        // custom function. write contents if necessary.
 
120
                        void write_char(char c)
 
121
                        {
 
122
                                if (!oss_.get())
 
123
                                        oss_.reset(new std::ostringstream());
 
124
 
 
125
                                *oss_ << c;
 
126
                                if (c == '\n')  // send to channels on newline
 
127
                                        flush_to_channel();
 
128
                        }
 
129
 
 
130
 
 
131
                        // This is function thread-safe as long as state is not modified.
 
132
                        void flush_to_channel();
 
133
 
 
134
 
 
135
                private:
 
136
                        DebugOutStream* dos_;
 
137
 
 
138
                        // It's thread-local because it is not shared between different flows.
 
139
                        // we can't provide any manual cleanup, because the only one we can do it
 
140
                        // is in main thread, and it's already being done with the destructor.
 
141
                        hz::thread_local_ptr<std::ostringstream> oss_;
 
142
 
 
143
                        DebugStreamBuf(const DebugStreamBuf& from);
 
144
        };
 
145
 
 
146
 
 
147
 
 
148
 
 
149
        typedef std::vector<debug_channel_base_ptr> channel_list_t;
 
150
 
 
151
 
 
152
 
 
153
        // This is returned by debug_out()
 
154
        class DebugOutStream : public std::ostream, public hz::intrusive_ptr_referenced {
 
155
                public:
 
156
 
 
157
                        friend class DebugStreamBuf;
 
158
 
 
159
                        DebugOutStream(debug_level::flag level, const std::string& domain, const debug_format::type& format_flags)
 
160
                                        : std::ostream(NULL), level_(level), domain_(domain), format_(format_flags), buf_(this)
 
161
                        {
 
162
                                set_enabled(true);  // sets ostream's rdbuf
 
163
                        }
 
164
 
 
165
//                      DebugOutStream() : std::ostream(NULL), buf_(this)
 
166
//                      {
 
167
//                              set_enabled(false);
 
168
//                      }
 
169
 
 
170
                        DebugOutStream(const DebugOutStream& other, const std::string& domain)
 
171
                                        : std::ostream(NULL), level_(other.level_), domain_(domain), format_(other.format_), buf_(this)
 
172
                        {
 
173
                                set_enabled(other.get_enabled());  // sets ostream's rdbuf
 
174
                                for (channel_list_t::const_iterator iter = other.channels_.begin(); iter != other.channels_.end(); ++iter) {
 
175
                                        // we let the object dictate the copy rules because really copying it
 
176
                                        // may harm the underlying locking mechanism
 
177
                                        channels_.push_back((*iter)->clone_ptr());
 
178
                                }
 
179
                        }
 
180
 
 
181
/*
 
182
                        void set_level(debug_level::flag level)
 
183
                        {
 
184
                                level_ = level;
 
185
                        }
 
186
 
 
187
                        void set_domain(const std::string& domain)
 
188
                        {
 
189
                                domain_ = domain;
 
190
                        }
 
191
*/
 
192
 
 
193
                        void set_format(const debug_format::type& format_flags)
 
194
                        {
 
195
                                format_ = format_flags;
 
196
                        }
 
197
 
 
198
                        debug_format::type get_format() const
 
199
                        {
 
200
                                return format_;
 
201
                        }
 
202
 
 
203
 
 
204
                        void set_enabled(bool enabled)
 
205
                        {
 
206
                                if (enabled)
 
207
                                        rdbuf(&buf_);
 
208
                                else
 
209
                                        rdbuf(&get_null_streambuf());
 
210
                        }
 
211
 
 
212
                        bool get_enabled() const
 
213
                        {
 
214
                                return (rdbuf() == &buf_);
 
215
                        }
 
216
 
 
217
 
 
218
                        void set_channels(const channel_list_t& channels)
 
219
                        {
 
220
                                channels_ = channels;
 
221
                        }
 
222
 
 
223
                        channel_list_t& get_channels()
 
224
                        {
 
225
                                return channels_;
 
226
                        }
 
227
 
 
228
                        // this will claim the ownership of the passed parameter
 
229
                        void add_channel(debug_channel_base_ptr channel)
 
230
                        {
 
231
                                channels_.push_back(channel);
 
232
                        }
 
233
 
 
234
 
 
235
                        bool get_is_first_line()
 
236
                        {
 
237
                                if (!is_first_line_.get())
 
238
                                        is_first_line_.reset(new bool(true));
 
239
                                return *is_first_line_;
 
240
                        }
 
241
 
 
242
                        void set_is_first_line(bool b)
 
243
                        {
 
244
                                if (!is_first_line_.get()) {
 
245
                                        is_first_line_.reset(new bool(b));
 
246
                                } else {
 
247
                                        *is_first_line_ = b;
 
248
                                }
 
249
                        }
 
250
 
 
251
 
 
252
                        // Force output of buf_'s contents to the channels.
 
253
                        // This also outputs a prefix if needed.
 
254
                        // This is function thread-safe in read-only context.
 
255
                        std::ostream& force_output()
 
256
                        {
 
257
                                buf_.force_output();
 
258
                                return *this;
 
259
                        }
 
260
 
 
261
 
 
262
                private:
 
263
                        debug_level::flag level_;
 
264
                        std::string domain_;
 
265
                        debug_format::type format_;
 
266
 
 
267
                        // It's thread-local because it is not shared between different flows.
 
268
                        // we can't provide any manual cleanup, because the only one we can do
 
269
                        // is in main thread, and it's already being done with the destructor.
 
270
                        hz::thread_local_ptr<bool> is_first_line_;
 
271
 
 
272
                        channel_list_t channels_;
 
273
 
 
274
                        DebugStreamBuf buf_;  // not thread-local, but its buffer is.
 
275
        };
 
276
 
 
277
 
 
278
 
 
279
 
 
280
 
 
281
}  // ns debug_internal
 
282
 
 
283
 
 
284
 
 
285
 
 
286
 
 
287
 
 
288
 
 
289
#endif