cisst-saw
Loading...
Searching...
No Matches
cmnLODMultiplexerStreambuf.h
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/* ex: set filetype=cpp softtabstop=4 shiftwidth=4 tabstop=4 cindent expandtab: */
3
4/*
5
6 Author(s): Ofri Sadowsky
7 Created on: 2002-05-17
8
9 (C) Copyright 2002-2007 Johns Hopkins University (JHU), All Rights
10 Reserved.
11
12--- begin cisst license - do not edit ---
13
14This software is provided "as is" under an open source license, with
15no warranty. The complete license can be found in license.txt and
16http://www.cisst.org/cisst/license.txt.
17
18--- end cisst license ---
19
20*/
21
22
26#pragma once
27
28#ifndef _cmnLODMultiplexerStreambuf_h
29#define _cmnLODMultiplexerStreambuf_h
30
34
35
36#include <list>
37#include <algorithm>
38#include <fstream>
39
107template <class _element, class _trait = std::char_traits<_element> >
108class cmnLODMultiplexerStreambuf : public std::basic_streambuf<_element, _trait>
109{
110 friend class cmnMultiplexerStreambufProxy<_element, _trait>;
111
112public:
113
115 typedef std::basic_streambuf<_element, _trait> BaseClassType;
116 typedef std::basic_streambuf<_element, _trait> ChannelType;
117
118 typedef std::pair<ChannelType *, cmnLogMask> ElementType;
119
124 typedef std::list<ElementType> ChannelContainerType;
125 typedef typename ChannelContainerType::iterator IteratorType;
126 typedef typename ChannelContainerType::const_iterator ConstIteratorType;
127
128 typedef std::list<ThisType *> MultiplexerContainerType;
129 typedef typename MultiplexerContainerType::iterator MultiplexerIteratorType;
130 typedef typename MultiplexerContainerType::const_iterator MultiplexerConstIteratorType;
131
136 cmnLODMultiplexerStreambuf(std::ofstream & fileStream) {
137 this->AddChannel(fileStream.rdbuf(), CMN_LOG_ALLOW_ALL);
138 }
139
145
146
153 bool AddChannel(ChannelType * channel, cmnLogMask mask);
154
155
163 inline bool AddChannel(std::ostream & outstream, cmnLogMask mask) {
164 return AddChannel(outstream.rdbuf(), mask);
165 }
166
167
168 bool AddMultiplexer(ThisType * multiplexer);
169
170
178 void RemoveChannel(ChannelType * channel);
179
180
181 void RemoveMultiplexer(ThisType * multiplexer);
182
183
190 inline void RemoveChannel(std::ostream & outstream) {
191 RemoveChannel(outstream.rdbuf());
192 }
193
194
197
198
206 bool SetChannelMask(ChannelType * channel, cmnLogMask mask);
207
208
216 bool GetChannelMask(const ChannelType * channel, cmnLogMask & mask) const;
217
226 const ChannelContainerType & GetChannels(void) const {
227 return Channels;
228 }
229
230 // Here we provide basic_streambuf namesame methods for multiplexing.
231 // This part is declared 'protected' following the declarations of
232 // basic_streambuf. See basic_streambuf documentation for more
233 // details.
234protected:
235 typedef typename std::basic_streambuf<_element, _trait>::int_type int_type;
236
240 virtual std::streamsize xsputn(const _element * s, std::streamsize n, cmnLogLevel level);
241
245 virtual int sync();
246
253
256 virtual std::streamsize xsputn(const _element *s, std::streamsize n);
257
262 virtual int_type overflow(int_type c = _trait::eof());
263
264//private:
268
273
278
282
287
292};
293
294
295
296//********************************
297// Template method implementation
298//********************************
299
300
301template <class _element, class _trait>
303{
304 IteratorType it = FindChannel(channel);
305
306 if (it == Channels.end()) {
307 Channels.insert(it, ElementType(channel, mask));
308 return true;
309 }
310 return false;
311}
312
313
314template <class _element, class _trait>
316{
318
319 if (it == Multiplexers.end()) {
320 Multiplexers.insert(it, multiplexer);
321 return true;
322 }
323 return false;
324}
325
326
327template <class _element, class _trait>
329{
330 IteratorType it = FindChannel(channel);
331
332 if (it != Channels.end()) {
333 Channels.erase(it);
334 }
335}
336
337
338template <class _element, class _trait>
340{
342
343 if (it != Multiplexers.end()) {
344 Multiplexers.erase(it);
345 }
346}
347
348
349template <class _element, class _trait>
355
356
357template <class _element, class _trait>
359{
360 IteratorType it = FindChannel(channel);
361 if (it != Channels.end()) {
362 (*it).second = mask;
363 return true;
364 }
365 return false;
366}
367
368
369template <class _element, class _trait>
371{
372 ConstIteratorType it = FindChannel(channel);
373 if (it != Channels.end()) {
374 mask = (*it).second;
375 return true;
376 }
377 return false;
378}
379
380
381template <class _element, class _trait>
382std::streamsize cmnLODMultiplexerStreambuf<_element, _trait>::xsputn(const _element * s, std::streamsize n, cmnLogLevel level)
383{
384 // for channels, compare to channel's mask
385 std::streamsize ssize(0);
386 IteratorType channelIt;
387 const IteratorType channelEnd = Channels.end();
388 for (channelIt = Channels.begin();
389 channelIt != channelEnd;
390 ++channelIt) {
391 if (level & ((*channelIt).second)) {
392 ssize = ((*channelIt).first)->sputn(s, n);
393 }
394 }
395 // for multiplexers, just send message along with log level
396 MultiplexerIteratorType multiplexerIt;
397 const MultiplexerIteratorType multiplexerEnd = Multiplexers.end();
398 for (multiplexerIt = Multiplexers.begin();
399 multiplexerIt != multiplexerEnd;
400 ++multiplexerIt) {
401 ssize = (*multiplexerIt)->xsputn(s, n, level);
402 }
403 return ssize;
404}
405
406
407template <class _element, class _trait>
409{
410 IteratorType channelIt;
411 // synchronize all channels
412 const IteratorType channelEnd = Channels.end();
413 for (channelIt = Channels.begin();
414 channelIt != channelEnd;
415 ++channelIt) {
416 ((*channelIt).first)->pubsync();
417 }
418 // synchronize all multiplexers
419 MultiplexerIteratorType multiplexerIt;
420 const MultiplexerIteratorType multiplexerEnd = Multiplexers.end();
421 for (multiplexerIt = Multiplexers.begin();
422 multiplexerIt != multiplexerEnd;
423 ++multiplexerIt) {
424 (*multiplexerIt)->sync();
425 }
426 return 0;
427}
428
429
430template <class _element, class _trait>
433{
434 // follow the basic_streambuf standard
435 if (_trait::eq_int_type(_trait::eof(), c)) {
436 return (_trait::not_eof(c));
437 }
438
439 // multiplexing
440 IteratorType channelIt;
441 const IteratorType channelEnd = Channels.end();
442 for (channelIt = Channels.begin();
443 channelIt != channelEnd;
444 ++channelIt) {
445 if (level & ((*channelIt).second)) {
446 ((*channelIt).first)->sputc(_trait::to_char_type(c));
447 }
448 }
449 // for multiplexers, just send message along with log level
450 MultiplexerIteratorType multiplexerIt;
451 const MultiplexerIteratorType multiplexerEnd = Multiplexers.end();
452 for (multiplexerIt = Multiplexers.begin();
453 multiplexerIt != multiplexerEnd;
454 ++multiplexerIt) {
455 (*multiplexerIt)->overflow(c, level);
456 }
457 // follow the basic_streambuf standard
458 return _trait::not_eof(c);
459}
460
461
462template <class _element, class _trait>
463std::streamsize cmnLODMultiplexerStreambuf<_element, _trait>::xsputn(const _element *s, std::streamsize n)
464{
465 std::streamsize ssize(0);
466 // channels
467 IteratorType channelIt;
468 const IteratorType channelEnd = Channels.end();
469 for (channelIt = Channels.begin();
470 channelIt != channelEnd;
471 ++channelIt) {
472 ssize = ((*channelIt).first)->sputn(s, n);
473 }
474 // for multiplexers, just send message along
475 MultiplexerIteratorType multiplexerIt;
476 const MultiplexerIteratorType multiplexerEnd = Multiplexers.end();
477 for (multiplexerIt = Multiplexers.begin();
478 multiplexerIt != multiplexerEnd;
479 ++multiplexerIt) {
480 ssize = (*multiplexerIt)->xsputn(s, n);
481 }
482 return ssize;
483}
484
485
486template <class _element, class _trait>
489{
490 // follow the basic_streambuf standard
491 if (_trait::eq_int_type(_trait::eof(), c)) {
492 return (_trait::not_eof(c));
493 }
494
495 // channels
496 IteratorType channelIt;
497 const IteratorType channelEnd = Channels.end();
498 for (channelIt = Channels.begin();
499 channelIt != channelEnd;
500 ++channelIt) {
501 ((*channelIt).first)->sputc(_trait::to_char_type(c));
502 }
503 // for multiplexers, just send message along
504 MultiplexerIteratorType multiplexerIt;
505 const MultiplexerIteratorType multiplexerEnd = Multiplexers.end();
506 for (multiplexerIt = Multiplexers.begin();
507 multiplexerIt != multiplexerEnd;
508 ++multiplexerIt) {
509 (*multiplexerIt)->overflow(c);
510 }
511
512 // follow the basic_streambuf standard
513 return _trait::not_eof(c);
514}
515
516
517template <class _element, class _trait>
520{
521 IteratorType it = Channels.begin();
522 while (it != Channels.end()) {
523 if ((*it).first == channel) {
524 break;
525 }
526 ++it;
527 }
528 return it;
529}
530
531
532template <class _element, class _trait>
535{
536 ConstIteratorType it = Channels.begin();
537 while (it != Channels.end()) {
538 if ((*it).first == channel) {
539 break;
540 }
541 ++it;
542 }
543 return it;
544}
545
546
547template <class _element, class _trait>
550{
552 while (it != Multiplexers.end()) {
553 if ((*it) == multiplexer) {
554 break;
555 }
556 ++it;
557 }
558 return it;
559}
560
561
562template <class _element, class _trait>
565{
567 while (it != Multiplexers.end()) {
568 if ((*it) == multiplexer) {
569 break;
570 }
571 ++it;
572 }
573 return it;
574}
575
576
577#endif
MultiplexerConstIteratorType FindMultiplexer(const ThisType *multiplexer) const
Definition cmnLODMultiplexerStreambuf.h:564
cmnLODMultiplexerStreambuf()
Definition cmnLODMultiplexerStreambuf.h:143
bool AddChannel(ChannelType *channel, cmnLogMask mask)
virtual std::streamsize xsputn(const _element *s, std::streamsize n)
Definition cmnLODMultiplexerStreambuf.h:463
ChannelContainerType Channels
Definition cmnLODMultiplexerStreambuf.h:267
bool GetChannelMask(const ChannelType *channel, cmnLogMask &mask) const
Definition cmnLODMultiplexerStreambuf.h:370
std::list< ElementType > ChannelContainerType
Definition cmnLODMultiplexerStreambuf.h:124
ChannelContainerType::iterator IteratorType
Definition cmnLODMultiplexerStreambuf.h:125
IteratorType FindChannel(const ChannelType *channel)
Definition cmnLODMultiplexerStreambuf.h:519
std::basic_streambuf< _element, _trait >::int_type int_type
Definition cmnLODMultiplexerStreambuf.h:235
bool AddMultiplexer(ThisType *multiplexer)
Definition cmnLODMultiplexerStreambuf.h:315
void RemoveAllChannels(void)
Definition cmnLODMultiplexerStreambuf.h:350
MultiplexerContainerType Multiplexers
Definition cmnLODMultiplexerStreambuf.h:281
bool AddChannel(std::ostream &outstream, cmnLogMask mask)
Definition cmnLODMultiplexerStreambuf.h:163
MultiplexerContainerType::const_iterator MultiplexerConstIteratorType
Definition cmnLODMultiplexerStreambuf.h:130
virtual int_type overflow(int_type c, cmnLogLevel level)
Definition cmnLODMultiplexerStreambuf.h:432
bool SetChannelMask(ChannelType *channel, cmnLogMask mask)
Definition cmnLODMultiplexerStreambuf.h:358
MultiplexerIteratorType FindMultiplexer(const ThisType *multiplexer)
Definition cmnLODMultiplexerStreambuf.h:549
virtual int_type overflow(int_type c=_trait::eof())
Definition cmnLODMultiplexerStreambuf.h:488
cmnLODMultiplexerStreambuf(std::ofstream &fileStream)
Definition cmnLODMultiplexerStreambuf.h:136
std::basic_streambuf< _element, _trait > ChannelType
Definition cmnLODMultiplexerStreambuf.h:116
cmnLODMultiplexerStreambuf< _element, _trait > ThisType
Definition cmnLODMultiplexerStreambuf.h:114
virtual int sync()
Definition cmnLODMultiplexerStreambuf.h:408
void RemoveChannel(ChannelType *channel)
Definition cmnLODMultiplexerStreambuf.h:328
std::list< ThisType * > MultiplexerContainerType
Definition cmnLODMultiplexerStreambuf.h:128
const ChannelContainerType & GetChannels(void) const
Definition cmnLODMultiplexerStreambuf.h:226
std::pair< ChannelType *, cmnLogMask > ElementType
Definition cmnLODMultiplexerStreambuf.h:118
std::basic_streambuf< _element, _trait > BaseClassType
Definition cmnLODMultiplexerStreambuf.h:115
void RemoveChannel(std::ostream &outstream)
Definition cmnLODMultiplexerStreambuf.h:190
ConstIteratorType FindChannel(const ChannelType *channel) const
Definition cmnLODMultiplexerStreambuf.h:534
ChannelContainerType::const_iterator ConstIteratorType
Definition cmnLODMultiplexerStreambuf.h:126
void RemoveMultiplexer(ThisType *multiplexer)
Definition cmnLODMultiplexerStreambuf.h:339
MultiplexerContainerType::iterator MultiplexerIteratorType
Definition cmnLODMultiplexerStreambuf.h:129
virtual std::streamsize xsputn(const _element *s, std::streamsize n, cmnLogLevel level)
Definition cmnLODMultiplexerStreambuf.h:382
Types for dynamic control of output messages.
Definition cmnMultiplexerStreambufProxy.h:88
Declaration of Levels of Detail for cmnLogger (human readable logging).
short cmnLogMask
Definition cmnLogLoD.h:67
short cmnLogLevel
Definition cmnLogLoD.h:55
#define CMN_LOG_ALLOW_ALL
Definition cmnLogLoD.h:75
Portability across compilers and operating systems tools.