    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: Digging a Ditch</title>
        <link>https://members.accu.org/index.php/articles/264</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>




<div class="xar-mod-head"><span class="xar-mod-title">Programming Topics + Overload Journal #66 - Apr 2005</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c65/">Programming</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c78/">Overload</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c146/">66</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/c65-146/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/articles/c65+146/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;Digging a Ditch</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 12 April 2005 18:05:25 +01:00 or Tue, 12 April 2005 18:05:25 +01:00</p>
<p><strong>Summary:</strong>&nbsp;</p>
<p><strong>Body:</strong>&nbsp;<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e20" id="d0e20"></a></h2>
</div>
<p>Writing a custom stream is easy! Most people are now entirely
comfortable using <tt class="classname">std::vector</tt> and
<tt class="classname">std::list</tt>, and know the difference
between a <tt class="classname">std::map</tt> and a <tt class=
"classname">std::set</tt>. However, the use and extension of the
C++ standard library's streams is still considered difficult.</p>
<p>In this article I am going to look at writing a logging stream.
A logging stream inserts the current date and time at the beginning
of a buffer full of characters when it is flushed. The buffer is
flushed to another stream which can modify the characters further
or write them, for example, to the console (<tt class=
"classname">std::cout</tt>) or to a file (<tt class=
"classname">std::ofstream</tt>).</p>
<p>In section 13.13.3 of The C++ Standard Library [<a href=
"#Josuttis">Josuttis</a>] Nico Josuttis discusses how to write a
custom stream in a fair amount of detail. Even though the book is
widespread among developers, the section on streams does not appear
to be widely read. Therefore in this article I am going to follow
reasonably closely the line that Josuttis takes, but will cut out a
lot of the unnecessary background which may scare the people who,
wrongly, feel it must be read and understood before embarking on a
custom stream. I will also discuss and resolve a potential
initialisation problem not explored by Josuttis.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e49" id="d0e49"></a>Stream
Buffer</h2>
</div>
<p>The heart of a stream is its buffer. Buffer is a misnomer as it
does not have to buffer at all and can, if it so chooses, process
the characters immediately.</p>
<p>Along with buffering, if required, the stream buffer does all
the reading and writing of characters for the stream. The standard
library provides <tt class="classname">std::basic_streambuf</tt> as
a base class for stream buffers. Listing 1 shows a stream buffer
that converts all the characters streamed to it to upper case and
writes them with <tt class="function">putchar</tt>:</p>
<pre class="programlisting">
#include &lt;streambuf&gt;
#include &lt;locale&gt;
#include &lt;cstdio&gt;

template&lt;class charT,
         class traits = std::char_traits&lt;charT&gt; &gt;
class outbuf
     : public std::basic_streambuf&lt;charT, traits&gt; {
private:
  typedef typename std::basic_streambuf&lt;charT,
                        traits&gt;::int_type int_type;

  // Central output function.
  // - print characters in uppercase.
  virtual int_type overflow(int_type c) {

    // Check character is not EOF
    if(!traits::eq_int_type(c, traits::eof())) {

      // Convert character to uppercase.
      c = std::toupper&lt;charT&gt;(c,
                        std::basic_streambuf&lt;charT,
                                traits&gt;::getloc());
      // Write character to standard output
      if(putchar(c) == EOF) {
        return traits::eof();
      }
    }

    return traits::not_eof(c);
  }
};
</pre>
<p><span class="bold"><b>Listing 1: Example stream
buffer</b></span></p>
<p>The overflow member function of <tt class=
"classname">std::basic_streambuf</tt> is called for each character
that is sent to the stream buffer. Overriding it allows the
behaviour to be modified. The example in Listing 1 above performs
the following for each character sent to overflow:</p>
<div class="orderedlist">
<ol type="1">
<li>
<p>The character is tested to make sure it is not an indication of
the end of a file or an error.</p>
</li>
<li>
<p>The character is converted to uppercase.</p>
</li>
<li>
<p>The character is written to standard out. If an error occurs
while writing the character this is indicated by returning
<tt class="methodname">traits::eof()</tt>.</p>
</li>
<li>
<p>An indication of whether or not the character represents the end
of a file or an error is returned.</p>
</li>
</ol>
</div>
<p>Traits are used throughout Listing 1 to ensure that EOF is
detected and handled correctly. Streams can be used with any
character type that has a corresponding set of character traits. A
detailed knowledge of character traits is not required when using
the built in character types char and <tt class="type">wchar_t</tt>
as their traits are already part of the standard library. Character
traits are discussed in 14.1.2 of Josuttis.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e93" id="d0e93"></a>Output
Stream</h2>
</div>
<p>The easiest way to use a stream buffer is to pass it to an
output stream as shown in Listing 2 below:</p>
<pre class="programlisting">
#include &lt;streambuf&gt;
#include &lt;ostream&gt;
#include &lt;locale&gt;
#include &lt;cstdio&gt;

template&lt;class charT,
         class traits = std::char_traits&lt;charT&gt; &gt;
class outbuf : public std::basic_streambuf&lt;charT,
                                          traits&gt; {
private:
  typedef typename std::basic_streambuf&lt;charT,
                        traits&gt;::int_type int_type;

  // Central output function.
  // - print characters in uppercase.
  virtual int_type overflow(int_type c) {
    // Check character is not EOF
    if(!traits::eq_int_type(c, traits::eof())) {
      // Convert character to uppercase.
      c = std::toupper&lt;charT&gt;(c,
                        std::basic_streambuf&lt;charT,
                                traits&gt;::getloc());
      // Write character to standard output
      if(putchar(c) == EOF) {
        return traits::eof();
      }
    }

    return traits::not_eof(c);
  }
};

int main() {
  outbuf&lt;char&gt; ob;
  std::basic_ostream&lt;char&gt; out(&amp;ob);
  out &lt;&lt; &quot;31 hexadecimal: &quot;
      &lt;&lt; std::hex
      &lt;&lt; 31 &lt;&lt; std::endl;
  return 0;
}
</pre>
<p><span class="bold"><b>Listing 2: Passing a stream buffer to an
output stream</b></span></p>
<p>The output from the example in Listing 2 is:</p>
<pre class="screen">
31 HEXADECIMAL: 1F
</pre>
<p>The example in Listing 2 demonstrates a working stream, but is
not an ideal solution as the stream buffer must be declared
separately from the stream itself. A common solution is to create a
subclass of std::basic_ostream with the stream buffer as a member
which can be passed to the <tt class=
"classname">std::basic_ostream</tt> constructor as shown in Listing
3:</p>
<pre class="programlisting">
template&lt;class charT,
         class traits = std::char_traits&lt;charT&gt; &gt;
class ostream
       : public std::basic_ostream&lt;charT, traits&gt; {
private:
  outbuf&lt;charT, traits&gt; buf_;

public:
  ostream() : std::basic_ostream&lt;charT,
                          traits&gt;(&amp;buf_), buf_() {}
};
</pre>
<p><span class="bold"><b>Listing 3: Subclass of <tt class=
"classname">std::basic_ostream</tt></b></span></p>
<p>Having the stream buffer as a member introduces a potential
initialisation problem. The solution to the problem introduces a
further problem hidden deep within the C++ standard [<a href=
"#Standard">Standard</a>]. However, this second problem is also
easily fixed.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e124" id="d0e124"></a>Problem
1</h2>
</div>
<p>If the stream buffer is dereferenced in <tt class=
"classname">std::basic_ostream</tt>'s constructor or in its
destructor, undefined behaviour can occur as the stream buffer will
not have been initialised. At least one well known and widely used
standard library implementation does nothing to avoid this and does
not need to. Library implementers know their stream implementations
and whether or not protection is needed. We, as stream extenders
writing for potentially any number of different stream
implementations, do not. There is no guarantee in the C++ standard
to fall back on either.</p>
<p>Josuttis places the buffer before <tt class=
"classname">std::basic_ostream</tt>'s constructor in the
initialisation list, which makes no difference at all as stated in
12.6.2/5 of the C++ standard:</p>
<div class="blockquote">
<blockquote class="blockquote">
<p>Initialization shall proceed in the following order:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>First, and only for the constructor of the most derived class as
described below, virtual base classes shall be initialized in the
order they appear on a depth-first left-to-right traversal of the
directed acyclic graph of base classes, where &quot;left-to-right&quot; is
the order of appearance of the base class names in the derived
class base-specifier-list.</p>
</li>
<li>
<p>Then, direct base classes shall be initialized in declaration
order as they appear in the base-specifier-list (regardless of the
order of the mem-initializers).</p>
</li>
<li>
<p>Then, nonstatic data members shall be initialized in the order
they were declared in the class definition (again regardless of the
order of the mem-initializers).</p>
</li>
<li>
<p>Finally, the body of the constructor is executed.</p>
</li>
</ul>
</div>
<p>Note: the declaration order is mandated to ensure that base and
member subobjects are destroyed in the reverse order of
initialization.</p>
</blockquote>
</div>
<p>The fact that the stream buffer is not initialised before it is
passed to <tt class="classname">std::basic_ostream</tt>'s
constructor may not cause a problem with your compiler and library,
but why risk it when there is a simple and straightforward
solution? On the other hand, it may fail in a screaming fit
immediately. Moving the stream buffer to a private base class which
is initialised before <tt class="classname">std::basic_ostream</tt>
solves the problem nicely. The initialisation order of base classes
is specified as stated in 12.6.2/5 above. Listing 4 shows the base
class which is used to initialise the stream buffer and how to use
it with the output stream.</p>
<pre class="programlisting">
template&lt;class charT,
         class traits = std::char_traits&lt;charT&gt; &gt;
struct outbuf_init {

private:
  outbuf&lt;charT, traits&gt; buf_;

public:
  outbuf&lt;charT, traits&gt;* buf() {
    return &amp;buf_;
  }
};

template&lt;class charT,
         class traits = std::char_traits&lt;charT&gt; &gt;
class ostream : private outbuf_init&lt;charT, traits&gt;, 
         public std::basic_ostream&lt;charT, traits&gt; {

private:
  typedef outbuf_init&lt;charT, traits&gt; outbuf_init;

public:
    ostream() : outbuf_init(),
      std::basic_ostream&lt;charT,
                     traits&gt;(outbuf_init::buf()) {}
};
</pre>
<p><span class="bold"><b>Listing 4: Initialising the stream
buffer</b></span></p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e168" id="d0e168"></a>Problem
2</h2>
</div>
<p><tt class="classname">basic_ios</tt> is a virtual base class of
<tt class="classname">basic_ostream</tt>. The C++ standard
(27.4.4/2) describes its constructor as follows:</p>
<div class="blockquote">
<blockquote class="blockquote">
<p><span class="bold"><b>Effects:</b></span> Constructs an object
of class <tt class="classname">basic_ios</tt> (27.4.2.7) leaving
its member objects uninitialized. The object must be initialized by
calling its <tt class="methodname">init</tt> member function. If it
is destroyed before it has been initialized the behavior is
undefined.</p>
</blockquote>
</div>
<p><tt class="methodname">basic_ios::init</tt> is called from
within <tt class="classname">basic_ostream</tt>'s constructor. This
is where things get complicated. As <tt class=
"classname">basic_ios</tt> is a virtual base class of <tt class=
"classname">basic_ostream</tt>, the objects which make up an
<tt class="classname">ostream</tt> object are initialised in the
following order (see 12.6.2/5):</p>
<pre class="programlisting">
...
basic_ios
outbuf
outbuf_init
basic_ostream
ostream
</pre>
<p>Therefore the constructors of <tt class=
"classname">basic_ios</tt> and outbuf are both called before the
constructor of <tt class="classname">basic_ostream</tt> and
therefore before <tt class="methodname">basic_ios::init</tt> is
called. This means that if the <tt class="varname">outbuf</tt>
constructor throws an exception, <tt class=
"classname">basic_ios</tt>'s destructor will be called before
<tt class="methodname">basic_ios::init</tt>; resulting in the
undefined behaviour described in 27.4.4/2.</p>
<p>The answer to this problem is contained within 12.6.2/5 and is
very simple. Making <tt class="classname">ostream</tt> inherit
virtually, as well as privately, from <tt class=
"methodname">outbuf_init</tt> causes it to be constructed before
anything else:</p>
<pre class="programlisting">
template&lt;class charT,
         class traits = std::char_traits&lt;charT&gt; &gt;
class ostream
      : private virtual outbuf_init&lt;charT, traits&gt;, 
        public std::basic_ostream&lt;charT, traits&gt; {

private:
  typedef outbuf_init&lt;charT, traits&gt; outbuf_init;

public:
  ostream()
      : outbuf_init(),
       std::basic_ostream&lt;charT,
                    traits&gt;(outbuf_init::buf()) {}
};
</pre>
<p>The initialisation order then becomes:</p>
<pre class="programlisting">
outbuf
outbuf_init
...
basic_ios
basic_ostream
ostream
</pre>
<p>Now, if <tt class="varname">output_buf</tt> does throw an
exception there is no undefined behaviour as the <tt class=
"classname">basic_ios</tt> has not yet been created.</p>
<p><tt class="classname">ostream</tt> can be made easier to use by
introducing a couple of simple <tt class="literal">typedef</tt>s
for common character types:</p>
<pre class="programlisting">
typedef ostream&lt;char&gt; costream;
typedef ostream&lt;wchar_t&gt; wostream;

int main() {
  costream out;
  out &lt;&lt; &quot;31 HEXADECIMAL: &quot; &lt;&lt; std::hex
      &lt;&lt; 31 &lt;&lt; std::endl;
  return 0;
}
</pre>
<p><span class="bold"><b>Listing 5: Typedefs for using <tt class=
"classname">ostream</tt></b></span></p>
<p>That completes the implementation for the simplest possible
custom stream.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e265" id="d0e265"></a>Logging
Stream Buffer</h2>
</div>
<p>The previous example of a stream buffer was very basic,
potentially inefficient and didn't actually buffer the characters
streamed to it. The logging stream mentioned at the start of this
article requires the characters to be buffered. When the buffer is
flushed the time and date are prepended before it is passed on to
the next stream.</p>
<p>Josuttis also has an example of a buffered stream buffer.
However, his example uses a fixed array for a buffer that gets
flushed when it is full. The logging stream should only flush the
buffer when instructed to do so, with a <tt class=
"classname">std::endl</tt> or a call to <tt class=
"methodname">flush</tt>. To accomplish this, the fixed array can be
replaced with a <tt class="classname">std::vector</tt>.</p>
<p>As already mentioned the logging stream simply buffers the
characters streamed to it and passes them on to another stream,
preceded by a time and date, when flushed. Therefore the stream
buffer must contain some form of reference to the other stream.</p>
<p>Listing 6 shows a basic implementation for the logging stream
buffer. A <tt class="classname">std::vector</tt> based buffer has
been introduced and overflow modified to check for EOF before
inserting its character into the buffer.</p>
<pre class="programlisting">
#include &lt;streambuf&gt;
#include &lt;vector&gt;

template&lt;class charT,
         class traits = std::char_traits&lt;charT&gt; &gt;
class logoutbuf
     : public std::basic_streambuf&lt;charT, traits&gt; {
private:
  typedef typename std::basic_streambuf&lt;charT,
                        traits&gt;::int_type int_type;
  typedef std::vector&lt;charT&gt; buffer_type;
  buffer_type buffer_;

  virtual int_type overflow(int_type c) {
    if(!traits::eq_int_type(c, traits::eof())) {
      buffer_.push_back(c);
    }
    return traits::not_eof(c);
  }
};
</pre>
<p><span class="bold"><b>Listing 6: Basic implementation of logging
stream buffer</b></span></p>
<p>As it stands the stream buffer in Listing 6 only buffers
characters. It never flushes them. A pointer to an output stream
buffer, that the characters can be flushed to, is required. The
initialisation and undefined behaviour fixes described in the
previous section have the side effect that <tt class=
"classname">logoutbuf</tt> will be a member of a virtual base class
and therefore should have a default constructor. A virtual base
class constructor must be called explicitly or implicitly from the
constructor of the most derived class (12.6.2/6). A default
constructor eliminates the need for explicit constructor calling.
This in turn means that a reference to an output stream cannot be
passed in through the constructor and therefore a pointer to the
output stream buffer must be stored instead and initialised by way
of an initialisation function. This is not ideal, but a trade-off
to guarantee safety elsewhere. The initialisation function is also
in keeping with the buffer initialisation in <tt class=
"classname">basic_ios</tt>.</p>
<pre class="programlisting">
template&lt;class charT,
         class traits = std::char_traits&lt;charT&gt; &gt;
class logoutbuf
     : public std::basic_streambuf&lt;charT, traits&gt; {
private:
  typedef typename std::basic_streambuf&lt;charT,
                        traits&gt;::int_type int_type;

  typedef std::vector&lt;charT&gt; buffer_type;

  std::basic_streambuf&lt;charT, traits&gt;* out_;
  buffer_type buffer_;

public:
  logoutbuf() : out_(0), buffer_() {}
  void init(std::basic_ostream&lt;charT,
                               traits&gt;* out) {
    out_ = out;
  }
  ...
}; 
</pre>
<p><span class="bold"><b>Listing 7: Initialising the output stream
buffer</b></span></p>
<p>Listing 7 shows the <tt class="classname">logoutbuf</tt> stream
buffer with the output stream buffer pointer and initialisation
function. A constructor has also been added to make sure that the
output stream buffer pointer is initialised to 0, so that it can be
reliably checked before characters are sent to it.</p>
<p>When <tt class="methodname">basic_ostream::flush</tt> is called,
either directly or via <tt class="classname">std::endl</tt>, it
starts a chain of function calls that finally results in <tt class=
"methodname">basic_streambuf::sync</tt> being called. This is where
the buffer should be flushed. The buffer should also be flushed
when a <tt class="varname">logoutbuf</tt> object is destroyed, so
<tt class="methodname">sync</tt> should also be called from the
<tt class="varname">logoutbuf</tt> destructor.</p>
<pre class="programlisting">
template&lt;class charT,
         class traits = std::char_traits&lt;charT&gt; &gt;
class logoutbuf
     : public std::basic_streambuf&lt;charT, traits&gt; {
  ...
public:
  ...
  ~logoutbuf() {
    sync();
  }
  ...

private:
  ...
  virtual int sync() {
    if(!buffer_.empty() &amp;&amp; out_) {
      out_-&gt;sputn(&amp;buffer_[0],
                  static_cast&lt;std::streamsize&gt;
                                 (buffer_.size()));
      buffer_.clear();
    }
    return 0;
  }
}; 
</pre>
<p><span class="bold"><b>Listing 8: Synchronising the
buffer</b></span></p>
<p>Listing 8 shows the implementation of the <tt class=
"methodname">sync</tt> function. It checks the buffer to make sure
there is something in it to flush and then checks the output stream
buffer pointer to make sure the pointer is valid. The contents of
the buffer are then sent to the output stream buffer, via its
<tt class="methodname">sputn</tt> function, and then cleared.</p>
<p><tt class="classname">basic_streambuf</tt>'s <tt class=
"methodname">sputn</tt> function takes an array of characters as
its first parameter and the number of characters in the array as
its second parameter. <tt class="classname">std::vector</tt> stores
its elements contiguously in memory, like an array, so the address
of the first element in the buffer can be passed as <tt class=
"methodname">sputn</tt>'s first parameter. <tt class=
"classname">std::vector</tt>'s size function is used to determine
the number of elements in the buffer and can therefore be used as
<tt class="methodname">sputn</tt>'s second parameter. The type of
<tt class="methodname">sputn</tt>'s second argument is the
implementation defined typedef <tt class=
"classname">std::streamsize</tt>. As the return type of <tt class=
"methodname">std::vector::size</tt> is also implementation defined
(and not necessarily the same type), <tt class=
"methodname">sputn</tt>'s second parameter must be cast to avoid
warnings from compilers such as Microsoft Visual C++. There is a
possibility that the number of characters stored in the buffer will
be greater than <tt class="classname">std::streamsize</tt> can
hold, but this is highly unlikely.</p>
<p><tt class="classname">logoutbuf</tt> is now a fully functioning,
buffered output stream buffer and can be plugged into a <tt class=
"classname">basic_ostream</tt> object and tested.</p>
<pre class="programlisting">
...
int main() {
  logoutbuf&lt;char&gt; ob;
  ob.init(std::cout.rdbuf());

  // Flush to std::cout
  std::basic_ostream&lt;char&gt; out(&amp;ob);
  out &lt;&lt; &quot;31 hexadecimal: &quot; &lt;&lt; std::hex
      &lt;&lt; 31 &lt;&lt; std::endl;
  return 0;
}
</pre>
<p><span class="bold"><b>Listing 9: Using <tt class=
"classname">logoutbuf</tt></b></span></p>
<p>Listing 9 creates a <tt class="classname">logoutbuf</tt> object,
sets <tt class="classname">std::cout</tt>'s stream buffer as its
output stream buffer and then passes it to a <tt class=
"classname">basic_ostream</tt> object, which then has character
streamed to it. The output from the example in Listing 9 is:</p>
<pre class="screen">
31 hexadecimal: 1f
</pre>
<p>The next step is to generate the time and date that will be
flushed to the output stream buffer prior to the contents of the
<tt class="classname">logoutbuf</tt> buffer. The different ways of
generating a date and time string are beyond the scope of this
article so I am providing the following implementation, which will
handle both <tt class="type">char</tt> and <tt class=
"type">wchar_t</tt> character types, without any explanation beyond
the comments in the code:</p>
<pre class="programlisting">
#include &lt;streambuf&gt;
#include &lt;vector&gt;
#include &lt;ctime&gt;
#include &lt;string&gt;
#include &lt;sstream&gt;

...

template&lt;class charT,
         class traits = std::char_traits&lt;charT&gt; &gt;
class logoutbuf
     : public std::basic_streambuf&lt;charT, traits&gt; {
  ...
private:
  std::basic_string&lt;charT, traits&gt; format_time() {
    // Get current time and date
    time_t ltime;
    time(&amp;ltime);

    // Convert time and date to string
    std::basic_stringstream&lt;charT, traits&gt; time;
    time &lt;&lt; asctime(gmtime(&amp;ltime));

    // Remove LF from time date string and
    // add separator
    std::basic_stringstream&lt;char_type&gt; result;
    result &lt;&lt; time.str().erase(
                 time.str().length() - 1) &lt;&lt; &quot; - &quot;;

    return result.str();
  }
  ...

  virtual int sync() {
    if(!buffer_.empty() &amp;&amp; out_) {
      const std::basic_string&lt;charT, traits&gt; time
                                   = format_time();
      out_-&gt;sputn(time.c_str(),
                  static_cast&lt;std::streamsize&gt;
                                  (time.length()));
      out_-&gt;sputn(&amp;buffer_[0],
                   static_cast&lt;std::streamsize&gt;
                                 (buffer_.size()));
      buffer_.clear();            
    }
    return 0;
  }
  ...   
};
</pre>
<p><span class="bold"><b>Listing 10: Adding date and
time</b></span></p>
<p>The <tt class="methodname">sync</tt> function in Listing 10 now
sends a date and time string (plus the separator) to the output
stream buffer before flushing the <tt class=
"classname">logoutbuf</tt> buffer. The result of running the
example from Listing 9 is now:</p>
<pre class="screen">
Fri Apr 20 16:00:00 2005 - 31 hexadecimal: 1f
</pre>
<p><tt class="classname">logoutbuf</tt> is now fully functional,
but there is a further modification that can be made for the sake
of efficiency. Currently <tt class="methodname">overflow</tt> is
called for <span class="emphasis"><em>every single
character</em></span> streamed to the stream buffer. This means
that to stream the <tt class="literal">31 hexadecimal:</tt> string
literal to the stream buffer involves <span class=
"emphasis"><em>16</em></span> separate function calls. This can be
reduced to a single function call by overriding <tt class=
"methodname">xsputn</tt>.</p>
<pre class="programlisting">
...
#include &lt;algorithm&gt;

template&lt;class charT,
         class traits = std::char_traits&lt;charT&gt; &gt;
class logoutbuf
     : public std::basic_streambuf&lt;charT, traits&gt; {
  ...
private:
  ...
  virtual std::streamsize xsputn(const char_type* s,
                             std::streamsize num) {
    std::copy(s, s + num,
         std::back_inserter&lt;buffer_type&gt;(buffer_));
    return num;
  }
  ...
};
</pre>
<p>Listing 11: Overriding <tt class="methodname">xsputn</tt></p>
<p><tt class="methodname">xsputn</tt> takes the same parameters as
<tt class="methodname">basic_streambuf::sputn</tt> and uses the
<tt class="function">std::copy</tt> algorithm together with
<tt class="classname">std::back_inserter</tt> to insert the
characters from the array into the buffer. <tt class=
"classname">logoutbuf</tt> is now complete.</p>
<p><tt class="classname">logoutbuf</tt> does of course require its
own <tt class="classname">logoutbuf_init</tt> class and <tt class=
"classname">basic_ostream</tt> subclass, with a few
modifications:</p>
<pre class="programlisting">
template&lt;class charT,
         class traits = std::char_traits&lt;charT&gt; &gt;
class logoutbuf_init {
private:
  logoutbuf&lt;charT, traits&gt; buf_;

public:
  logoutbuf&lt;charT, traits&gt;* buf() {
    return &amp;buf_;
  }
};

template&lt;class charT,
         class traits = std::char_traits&lt;charT&gt; &gt;
class logostream
       : private virtual logoutbuf_init&lt;charT,
                                        traits&gt;,
         public std::basic_ostream&lt;charT, traits&gt; {
private:
  typedef logoutbuf_init&lt;charT, traits&gt;
                                    logoutbuf_init;
public:
  logostream(std::basic_ostream&lt;charT,
                                traits&gt;&amp; out)
      : logoutbuf_init(),
        std::basic_ostream&lt;charT,
                   traits&gt;(logoutbuf_init::buf()) {
    logoutbuf_init::buf()-&gt;init(out.rdbuf());
  }
};

typedef logostream&lt;char&gt; clogostream;
typedef logostream&lt;wchar_t&gt; wlogostream; 
</pre>
<p><span class="bold"><b>Listing 12: <tt class=
"classname">logoutbuf_init</tt> class and <tt class=
"classname">basic_ostream</tt> subclass</b></span></p>
<p>The <tt class="classname">logoutbuf_init</tt> class is actually
the same as the one form the previous section; it's the <tt class=
"classname">logostream</tt> that is slightly different. The
constructor takes a single parameter which is the output stream and
its body passes its stream buffer to <tt class=
"classname">logoutbuf</tt> via <tt class="methodname">init</tt>
(suddenly the trade off doesn't seem so bad).</p>
<p>The final test example is shown in Listing 13:</p>
<pre class="programlisting">
...
int main() {
  costream out(std::cout);
  out &lt;&lt; &quot;31 hexadecimal: &quot; &lt;&lt; std::hex
      &lt;&lt; 31 &lt;&lt; std::endl;
  return 0;
}
</pre>
<p><span class="bold"><b>Listing 13: Using the
stream</b></span></p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e514" id=
"d0e514"></a>Conclusion</h2>
</div>
<p>The stream buffer is clearly the heart of an output stream. The
potential for a stream buffer being accessed before it is
initialised is easily avoided, as is the possibility of undefined
behaviour, with the minimal of tradeoffs.</p>
<p>The buffering of characters streamed to a stream buffer is
easily handled by a <tt class="classname">std::vector</tt> with no
need for extra memory handling. Multiple characters can be added to
a <tt class="classname">std::vector</tt> just as easily as single
characters and the contiguous memory elements make it easy to flush
to an output stream.</p>
<p>Writing a custom stream is easy! I believe this article shows
just how easy it is, even with a minimum of background
knowledge.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e529" id=
"d0e529"></a>Acknowledgments</h2>
</div>
<p>Alisdair Meredith, Alan Stokes, Jez Higgins, Alan Griffiths,
Thaddaeus Frogley.</p>
</div>
<div class="bibliography">
<div class="titlepage">
<h2><a name="d0e534" id="d0e534"></a>References</h2>
</div>
<div class="bibliomixed"><a name="Josuttis" id="Josuttis"></a>
<p class="bibliomixed">[Josuttis] Nicolai M. Josuttis, <span class=
"citetitle"><i class="citetitle">The C++ Standard
Library</i></span>, Addison-Wesley, ISBN: 0-201-37926-0.</p>
</div>
<div class="bibliomixed"><a name="Standard" id="Standard"></a>
<p class="bibliomixed">[Standard] <span class="citetitle"><i class=
"citetitle">The C++ Standard</i></span>, John Wiley and Sons Ltd,
ISBN: 0-470-84674-7</p>
</div>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
