cisst-saw
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
osaThreadedLogFile.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): Anton Deguet
7  Created on: 2008-01-04
8 
9  (C) Copyright 2002-2008 Johns Hopkins University (JHU), All Rights
10  Reserved.
11 
12 --- begin cisst license - do not edit ---
13 
14 This software is provided "as is" under an open source license, with
15 no warranty. The complete license can be found in license.txt and
16 http://www.cisst.org/cisst/license.txt.
17 
18 --- end cisst license ---
19 
20 */
21 
22 
27 #ifndef _osaThreadedLogFile_h
28 #define _osaThreadedLogFile_h
29 
33 
34 #include <list>
35 #include <algorithm>
36 #include <iostream>
37 #include <sstream>
38 #include <fstream>
39 
40 
45 template<class _element, class _trait = std::char_traits<_element> >
46 class osaThreadedLogFileStreambuf: public std::basic_streambuf<_element, _trait>
47 {
48 public:
49 
50  typedef std::basic_streambuf<_element, _trait> BaseClassType;
51 
52  typedef std::basic_streambuf<_element, _trait> ChannelType;
53 
54  typedef std::pair<osaThreadId, ChannelType *> ElementType;
55 
57  typedef std::list<ElementType> ChannelContainerType;
58  typedef typename ChannelContainerType::iterator iterator;
59  typedef typename ChannelContainerType::const_iterator const_iterator;
60 
64  osaThreadedLogFileStreambuf(const std::string & filePrefix):
65  FilePrefix(filePrefix),
66  Mutex()
67  {}
68 
70  ChannelType * AddChannelForThread(const osaThreadId & threadId);
71 
72 
73 // Here we provide basic_streambuf namesame methods for multiplexing.
74 // This part is declared 'protected' following the declarations of
75 // basic_streambuf. See basic_streambuf documentation for more
76 // details.
77 protected:
78  typedef typename std::basic_streambuf<_element, _trait>::int_type int_type;
79 
82  virtual int sync();
83 
86  virtual std::streamsize xsputn(const _element *s, std::streamsize n);
87 
93  virtual int_type overflow(int_type c = _trait::eof());
94 
95 private:
97  std::string FilePrefix;
98 
100  osaMutex Mutex;
101 
103  ChannelContainerType ChannelContainer;
104 
108  iterator FindChannel(const osaThreadId & threadId);
109 };
110 
111 
112 
113 template<class _element, class _trait>
115 {
116  const osaThreadId threadId = osaGetCurrentThreadId();
117  Mutex.Lock();
118  iterator it = FindChannel(threadId);
119  if (it != ChannelContainer.end()) {
120  Mutex.Unlock();
121  return it->second->pubsync();
122  }
123  ChannelType * channel = AddChannelForThread(threadId);
124  Mutex.Unlock();
125  return channel->pubsync();
126 }
127 
128 
129 template<class _element, class _trait>
130 std::streamsize
131 osaThreadedLogFileStreambuf<_element, _trait>::xsputn(const _element *s, std::streamsize n)
132 {
133  const osaThreadId threadId = osaGetCurrentThreadId();
134  Mutex.Lock();
135  const iterator it = FindChannel(threadId);
136  if (it != ChannelContainer.end()) {
137  Mutex.Unlock();
138  return it->second->sputn(s, n);
139  }
140  ChannelType * channel = AddChannelForThread(threadId);
141  Mutex.Unlock();
142  return channel->sputn(s, n);
143 }
144 
145 
146 template<class _element, class _trait>
149 {
150  // follow the basic_streambuf standard
151  if (_trait::eq_int_type(_trait::eof(), c))
152  return (_trait::not_eof(c));
153 
154  const osaThreadId threadId = osaGetCurrentThreadId();
155  Mutex.Lock();
156  const iterator it = FindChannel(threadId);
157  if (it != ChannelContainer.end()) {
158  Mutex.Unlock();
159  return it->second->sputc( _trait::to_char_type(c) );
160  }
161  ChannelType * channel = AddChannelForThread(threadId);
162  Mutex.Unlock();
163  return channel->sputc( _trait::to_char_type(c) );
164 }
165 
166 
167 template<class _element, class _trait>
170 {
171  iterator it = ChannelContainer.begin();
172  while (it != ChannelContainer.end()) {
173  if ((*it).first == threadId)
174  break;
175  ++it;
176  }
177  return it;
178 }
179 
180 
181 template<class _element, class _trait>
184 {
185  std::stringstream fileName;
186  fileName << this->FilePrefix << this->ChannelContainer.size() << ".txt";
187  std::ofstream * newFile = new std::ofstream(fileName.str().c_str());
188  ChannelContainer.push_back(ElementType(threadId, newFile->rdbuf()));
189  return newFile->rdbuf();
190 }
191 
192 
193 
194 
195 class osaThreadedLogFile: public std::ostream
196 {
197 private:
199 
200 public:
201  osaThreadedLogFile(const std::string & filePrefix):
202  std::ostream(&Streambuf),
203  Streambuf(filePrefix)
204  {}
205 
206  virtual std::basic_streambuf<char> * rdbuf(void) {
207  return &Streambuf;
208  }
209 };
210 
211 
212 #endif
213 
virtual int_type overflow(int_type c=_trait::eof())
Definition: osaThreadedLogFile.h:148
std::pair< osaThreadId, ChannelType * > ElementType
Definition: osaThreadedLogFile.h:54
Declaration of osaMutex.
Define a Mutex object.
Definition: osaMutex.h:48
Portability across compilers and operating systems tools.
Definition: osaThreadedLogFile.h:46
Definition: osaThreadedLogFile.h:195
ChannelContainerType::iterator iterator
Definition: osaThreadedLogFile.h:58
std::basic_streambuf< _element, _trait > ChannelType
Definition: osaThreadedLogFile.h:52
std::basic_streambuf< _element, _trait > BaseClassType
Definition: osaThreadedLogFile.h:50
std::basic_streambuf< _element, _trait >::int_type int_type
Definition: osaThreadedLogFile.h:78
osaThreadedLogFileStreambuf(const std::string &filePrefix)
Definition: osaThreadedLogFile.h:64
std::list< ElementType > ChannelContainerType
Definition: osaThreadedLogFile.h:57
Declaration of osaThread.
virtual int sync()
Definition: osaThreadedLogFile.h:114
osaThreadedLogFile(const std::string &filePrefix)
Definition: osaThreadedLogFile.h:201
CISST_EXPORT osaThreadId osaGetCurrentThreadId(void)
ChannelType * AddChannelForThread(const osaThreadId &threadId)
Definition: osaThreadedLogFile.h:183
ThreadId type.
Definition: osaThread.h:77
virtual std::streamsize xsputn(const _element *s, std::streamsize n)
Definition: osaThreadedLogFile.h:131
ChannelContainerType::const_iterator const_iterator
Definition: osaThreadedLogFile.h:59
virtual std::basic_streambuf< char > * rdbuf(void)
Definition: osaThreadedLogFile.h:206