1 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
6 # define _MSGSTREAM_H
\r
9 # include "stringtool.h"
\r
10 # include "multithread.h"
\r
13 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
18 <p>Before writing to omsgstream, you must acquire lock by calling
\r
19 <code>acquire()</code>. Then after completion of writing, you
\r
20 must call <code>release()</code>.</p>
\r
22 <p>Omsgbuf calls <code>PostMessage(hwnd, messageid, 0,
\r
23 (LPARAM)omsgbuf)</code> to notify that string is ready to get.
\r
24 When the window (<code>hwnd</code>) get the message, you can get
\r
25 the string containd in the omsgbuf by calling
\r
26 <code>acquireString()</code>. After calling
\r
27 <code>acquireString()</code>, you must / call releaseString().</p>
\r
31 template<class T, size_t SIZE = 1024,
\r
32 class TR = std::char_traits<T>, class A = std::allocator<T> >
\r
33 class basic_msgbuf : public std::basic_streambuf<T, TR>, public SyncObject
\r
36 typedef std::basic_string<T, TR, A> String; ///
\r
37 typedef std::basic_streambuf<T, TR> Super; ///
\r
40 HWND m_hwnd; /** window handle for
\r
42 UINT m_messageId; /// messageid for notification
\r
43 T *m_buf; /// for streambuf
\r
44 String m_str; /// for notification
\r
45 CriticalSection m_cs; /// lock
\r
46 A m_allocator; /// allocator
\r
49 if ( m_msgDebugLevel <= m_debugLevel ), message is displayed
\r
52 int m_msgDebugLevel; ///
\r
55 basic_msgbuf(const basic_msgbuf &); /// disable copy constructor
\r
59 basic_msgbuf(UINT i_messageId, HWND i_hwnd = 0)
\r
61 m_messageId(i_messageId),
\r
62 m_buf(m_allocator.allocate(SIZE, 0)),
\r
67 setp(m_buf, m_buf + SIZE);
\r
74 m_allocator.deallocate(m_buf, SIZE);
\r
77 /// attach/detach a window
\r
78 basic_msgbuf* attach(HWND i_hwnd)
\r
81 ASSERT( !m_hwnd && i_hwnd );
\r
84 PostMessage(m_hwnd, m_messageId, 0, (LPARAM)this);
\r
89 basic_msgbuf* detach()
\r
97 /// get window handle
\r
98 HWND getHwnd() const { return m_hwnd; }
\r
100 /// is a window attached ?
\r
101 int is_open() const { return !!m_hwnd; }
\r
103 /// acquire string and release the string
\r
104 const String &acquireString()
\r
111 void releaseString()
\r
117 /// set debug level
\r
118 void setDebugLevel(int i_debugLevel)
\r
120 m_debugLevel = i_debugLevel;
\r
124 int getDebugLevel() const { return m_debugLevel; }
\r
127 typename Super::int_type overflow(typename Super::int_type i_c = TR::eof())
\r
129 if (sync() == TR::eof()) // sync before new buffer created below
\r
132 if (i_c != TR::eof())
\r
134 *pptr() = TR::to_char_type(i_c);
\r
138 return TR::not_eof(i_c); // return something other than EOF if successful
\r
144 T *begin = pbase();
\r
147 for (i = begin; i < end; ++ i)
\r
152 if (m_msgDebugLevel <= m_debugLevel)
\r
153 m_str += String(begin, end - begin);
\r
154 setp(m_buf, m_buf + SIZE);
\r
158 if (m_msgDebugLevel <= m_debugLevel)
\r
159 m_str += String(begin, end - begin - 1);
\r
160 m_buf[0] = end[-1];
\r
161 setp(m_buf, m_buf + SIZE);
\r
164 return TR::not_eof(0);
\r
170 virtual void acquire()
\r
176 virtual void acquire(int i_msgDebugLevel)
\r
179 m_msgDebugLevel = i_msgDebugLevel;
\r
183 virtual void release()
\r
185 if (!m_str.empty())
\r
186 PostMessage(m_hwnd, m_messageId, 0, reinterpret_cast<LPARAM>(this));
\r
187 m_msgDebugLevel = m_debugLevel;
\r
194 template<class T, size_t SIZE = 1024,
\r
195 class TR = std::char_traits<T>, class A = std::allocator<T> >
\r
196 class basic_omsgstream : public std::basic_ostream<T, TR>, public SyncObject
\r
199 typedef std::basic_ostream<T, TR> Super; ///
\r
200 typedef basic_msgbuf<T, SIZE, TR, A> StreamBuf; ///
\r
201 typedef std::basic_string<T, TR, A> String; ///
\r
204 StreamBuf m_streamBuf; ///
\r
208 explicit basic_omsgstream(UINT i_messageId, HWND i_hwnd = 0)
\r
209 : Super(&m_streamBuf), m_streamBuf(i_messageId, i_hwnd)
\r
214 virtual ~basic_omsgstream()
\r
219 StreamBuf *rdbuf() const
\r
221 return const_cast<StreamBuf *>(&m_streamBuf);
\r
224 /// attach a msg control
\r
225 void attach(HWND i_hwnd)
\r
227 m_streamBuf.attach(i_hwnd);
\r
230 /// detach a msg control
\r
233 m_streamBuf.detach();
\r
236 /// get window handle of the msg control
\r
237 HWND getHwnd() const
\r
239 return m_streamBuf.getHwnd();
\r
242 /// is the msg control attached ?
\r
243 int is_open() const
\r
245 return m_streamBuf.is_open();
\r
248 /// set debug level
\r
249 void setDebugLevel(int i_debugLevel)
\r
251 m_streamBuf.setDebugLevel(i_debugLevel);
\r
255 int getDebugLevel() const
\r
257 return m_streamBuf.getDebugLevel();
\r
260 /// acquire string and release the string
\r
261 const String &acquireString()
\r
263 return m_streamBuf.acquireString();
\r
267 void releaseString()
\r
269 m_streamBuf->releaseString();
\r
275 virtual void acquire()
\r
277 m_streamBuf.acquire();
\r
281 virtual void acquire(int i_msgDebugLevel)
\r
283 m_streamBuf.acquire(i_msgDebugLevel);
\r
287 virtual void release()
\r
289 m_streamBuf.release();
\r
294 typedef basic_omsgstream<_TCHAR> tomsgstream;
\r
297 #endif // !_MSGSTREAM_H
\r