c++-gtk-utils
gstream.h
Go to the documentation of this file.
00001 /* Copyright (C) 2010 and 2011 Chris Vine
00002 
00003 
00004 The library comprised in this file or of which this file is part is
00005 distributed by Chris Vine under the GNU Lesser General Public
00006 License as follows:
00007 
00008    This library is free software; you can redistribute it and/or
00009    modify it under the terms of the GNU Lesser General Public License
00010    as published by the Free Software Foundation; either version 2.1 of
00011    the License, or (at your option) any later version.
00012 
00013    This library is distributed in the hope that it will be useful, but
00014    WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016    Lesser General Public License for more details.
00017 
00018    You should have received a copy of the GNU Lesser General Public
00019    License, version 2.1, along with this library (see the file LGPL.TXT
00020    which came with this source code package in the c++-gtk-utils
00021    sub-directory); if not, write to the Free Software Foundation, Inc.,
00022    59 Temple Place - Suite 330, Boston, MA, 02111-1307, USA.
00023 
00024 However, it is not intended that the object code of a program whose
00025 source code instantiates a template from this file or uses macros or
00026 inline functions (of any length) should by reason only of that
00027 instantiation or use be subject to the restrictions of use in the GNU
00028 Lesser General Public License.  With that in mind, the words "and
00029 macros, inline functions and instantiations of templates (of any
00030 length)" shall be treated as substituted for the words "and small
00031 macros and small inline functions (ten lines or less in length)" in
00032 the fourth paragraph of section 5 of that licence.  This does not
00033 affect any other reason why object code may be subject to the
00034 restrictions in that licence (nor for the avoidance of doubt does it
00035 affect the application of section 2 of that licence to modifications
00036 of the source code in this file).
00037 */
00038 
00039 /**
00040  * @defgroup gstreams gstreams
00041  *
00042  * \#include <c++-gtk-utils/gstream.h>
00043  *
00044  * The c++-gtk-utils library contains C++ classes providing a
00045  * streambuffer and stream objects interfacing with GIO streams.
00046  *
00047  * Normally 'true' would be passed as the second (manage) argument of
00048  * the gostream/gistream/giostream constructors or of the attach()
00049  * methods, so that the destructors of these classes close the GIO
00050  * streams concerned, which helps exception safety (the attach()
00051  * method will also close any previous GIO stream).  If this behaviour
00052  * is not wanted, pass 'false' instead to that argument.
00053  *
00054  * C++ stream objects are not suitable for asynchronous input and
00055  * output.  On sockets and pipes or other special devices, they may
00056  * block on a read or write until the read or write request has been
00057  * satisfied.  In circumstances where asynchronous input and output is
00058  * wanted, it will be necessary to start a new thread in which to
00059  * carry out the input and output operations (which is what GIO does
00060  * behind the scenes on its asynchronous operations) or use the GIO
00061  * interfaces directly.
00062  *
00063  * Here are some examples of use:
00064  *
00065  * @code
00066  *   // open file for input, another for output, and make the
00067  *   // output file a gzipped copy of the input (gzipping a
00068  *   // file doesn't get much easier than this)
00069  *   Cgu::gistream input;
00070  *   Cgu::gostream output;
00071  *   Cgu::GobjHandle<GFile> file_in(g_file_new_for_path("filename"));
00072  *   GFileInputStream* is = g_file_read(file_in, 0, 0);
00073  *   if (is) 
00074  *     input.attach(Cgu::GobjHandle<GInputStream>(G_INPUT_STREAM(is)), // takes ownership of 'is'
00075  *                  true);
00076  *   else {
00077  *     std::cerr << "Can't open file 'filename'" << std::endl;
00078  *     return;
00079  *   }
00080  *   Cgu::GobjHandle<GFile> file_out(g_file_new_for_path("filename.gz"));
00081  *   GFileOutputStream* os = g_file_replace(file_out, 0, false,
00082  *                                          G_FILE_CREATE_REPLACE_DESTINATION,
00083  *                                          0, 0);
00084  *   if (os) {
00085  *      output.attach(Cgu::GobjHandle<GOutputStream>(G_OUTPUT_STREAM(os)), // takes ownership of 'os'
00086  *                    true,
00087  *                    Cgu::GobjHandle<GConverter>(
00088  *                      G_CONVERTER(g_zlib_compressor_new(G_ZLIB_COMPRESSOR_FORMAT_GZIP, -1)))
00089  *                    );
00090  *   }
00091  *   else {
00092  *     std::cerr << "Can't create file 'filename.gz'" << std::endl;
00093  *     return;
00094  *   }
00095  *   // this does the copying, and is shorthand for creating your own buffer
00096  *   // and calling std::istream::read() and std::ostream::write() on it
00097  *   fileout << filein.rdbuf();
00098  *
00099  *   --------------------------------------------------------------------
00100  *
00101  *   // establish a TCP socket on localhost, listen for connections on port
00102  *   // 1200 and receive whitespace-separated words for processing
00103  *   using Cgu::GobjHandle;
00104  *   GobjHandle<GInetAddress> i(g_inet_address_new_loopback(G_SOCKET_FAMILY_IPV4));
00105  *   GobjHandle<GSocketAddress> a(g_inet_socket_address_new(i, 1200));
00106  *   GobjHandle<GSocketListener> l(g_socket_listener_new());
00107  *
00108  *   gboolean success = g_socket_listener_add_address(l,
00109  *                                                    a,
00110  *                                                    G_SOCKET_TYPE_STREAM,
00111  *                                                    G_SOCKET_PROTOCOL_TCP,
00112  *                                                    0, 0, 0);
00113  *   if (!success) {
00114  *     std::cerr << "Can't bind socket on localhost" << std::endl;
00115  *     return;
00116  *   }
00117  *
00118  *   GSocketConnection* c = g_socket_listener_accept(l, 0, 0, 0);
00119  *   if (!c) {
00120  *    std::cerr << "Can't listen on localhost" << std::endl;
00121  *    return;
00122  *   }
00123  *
00124  *   Cgu::giostream sock_strm(GobjHandle<GIOStream>(G_IO_STREAM(c)), true); // takes ownership of c
00125  *   sock_strm.set_output_buffered(false);
00126  *   std::cout << "Connection accepted" << std::endl;
00127  *
00128  *   std::string str;
00129  *   while (sock_strm >> str) {
00130  *     [ ... do something with the word in str ... ]
00131  *     // acknowledge the client
00132  *     sock_strm << "ACK\n";
00133  *   }
00134  *
00135  *   --------------------------------------------------------------------
00136  *
00137  *   // read line delimited text from a pipe until it is closed by the
00138  *   // writer: assume 'fd' is the read file descriptor of the pipe
00139  *   // (in real life you would probably want to use a Cgu::fdistream
00140  *   // object in this usage and bypass GIO)
00141  *   Cgu::gistream istrm(Cgu::GobjHandle<GInputStream>(g_unix_input_stream_new(fd, true)), true);
00142  *   if (!istrm.get_gio_stream().get()) {
00143  *     std::cerr << "Can't create gio file-descriptor input stream" << std::endl;
00144  *     return;
00145  *   }
00146  *   std::string line;
00147  *   while (std::getline(istrm, line)) {
00148  *     [ ... do something with the read text ... ]
00149  *   }
00150  * @endcode
00151  *
00152  *
00153  * @note 1. Users cannot (except by derivation) use the virtual
00154  * protected methods of the streambuffer classes, including xsgetn()
00155  * and xsputn().  Instead, if they want direct access to the
00156  * streambuffer other than through the gostream/gistream/giostream
00157  * methods (or their wide stream equivalents), they should use the
00158  * public forwarding functions provided by std::streambuf base class.
00159  * @note 2. These streambuffers and stream objects are not copiable.
00160  * @note 3. The base glib requirement for the c++-gtk-utils library is
00161  * glib >= 2.10.0, but the gstreams component will only be available
00162  * if glib >= 2.16.0 is installed.
00163  *
00164  * @b Buffering
00165  *
00166  * The classes implement buffering on input streams and (unless output
00167  * buffering is switched off) on output streams.  They implement the
00168  * buffering internally and do not use GBufferedInputStream and
00169  * GBufferedOutputStream.  This has a number of efficiency advantages
00170  * and also retains random access, on devices that support it, for
00171  * buffered streams (GBufferedInputStream and GBufferedOutputStream do
00172  * not do so).  So far as concerns random access on GIOStream objects,
00173  * which are opened for both read and write, see
00174  * @ref GioRandomAccessAnchor "giostream and random access"
00175  *
00176  * The streambuf class provides a block read and write in xsgetn() and
00177  * xsputn(), which will be called by the read() and write() methods
00178  * (and some other output operators) inherited by (w)gistream,
00179  * (w)gostream and (w)giostream from std::basic_istream and
00180  * std::basic_ostream.  They operate (after appropriately vacating and
00181  * resetting the buffers) by doing a block read and write directly to
00182  * and from the target, and are very efficient for large block reads
00183  * (those significantly exceeding the buffer size).  If users want all
00184  * reads and writes to go through the buffers, by using
00185  * std::basic_streambuf<>::xsputn() and
00186  * std::basic_streambuf<>::xsgetn() then the symbol
00187  * CGU_GSTREAM_USE_STD_N_READ_WRITE can be defined for the purpose
00188  * before gstream.h is \#include'd.  (libstdc++-3 provides efficient
00189  * inbuilt versions of these std::basic_streambuf functions for block
00190  * reads not significantly larger than the buffer size, provided
00191  * output buffering has not been turned off by the
00192  * set_output_buffered() method of these classes.)
00193  *
00194  * One possible case for defining that symbol is where the user wants
00195  * to use the tie() method of (w)gistream or (w)giostream (inherited
00196  * from std::basic_ios) to procure flushing of an output stream before
00197  * extraction from an input stream is made by (w)gistream::read() or
00198  * (w)giostream::read().  Such flushing might not occur where a call
00199  * to read() is made unless CGU_GSTREAM_USE_STD_N_READ_WRITE is
00200  * defined, because an implementation is permitted to defer such
00201  * flushing until underflow() occurs, and the block read by read(), as
00202  * forwarded to xsgetn(), will never invoke underflow() if that symbol
00203  * is not defined.  (Having said that, any basic_istream
00204  * implementation which does defer output flushing until underflow()
00205  * is called makes tie() unusable anyway for a number of purposes,
00206  * because the time of flushing would become dependent on whether a
00207  * read request can be satisfied by what is already in the buffers.)
00208  *
00209  * 4 characters are stored and available for putback.  However, if the
00210  * symbol CGU_GSTREAM_USE_STD_N_READ_WRITE is not defined, then a call
00211  * to (w)gstreambuf::xsgetn() via (w)gistream::read() or
00212  * (w)giostream::read() with a request for less than 4 characters will
00213  * result in less than 4 characters available for putback (if these
00214  * block read methods obtain some characters but less than 4, only the
00215  * number of characters obtained by them is guaranteed to be available
00216  * for putback).
00217  *
00218  * @anchor GioRandomAccessAnchor
00219  * @b giostream @b and @b random @b access
00220  *
00221  * For GIO objects which implement GSeekable (which are GFileIOStream,
00222  * GFileInputStream, GFileOutputStream, GMemoryInputStream and
00223  * GMemoryOutputStream), the classes in this c++-gtk-utils library
00224  * implement the tellg(), tellp(), seekg() and seekp() random access
00225  * methods.
00226  *
00227  * This presents complications if the giostream or wgiostream classes
00228  * are used with a GFIleIOStream object (GFileIOStream objects are
00229  * opened for both read and write).  Because the classes employ
00230  * buffering of input, and optional buffering of output, the logical
00231  * file position (the file position expected by the user from the
00232  * reads and writes she has made) will usually differ from the actual
00233  * file position seen by the underlying operating system.  The
00234  * gstreambuf class provided by this library implements intelligent
00235  * tying between input and output streams for GFileIOStream objects
00236  * which means that if output has been made unbuffered by a call to
00237  * set_output_buffered(false) and no converter has been attached, all
00238  * reads and writes onto the file system from the same giostream
00239  * object will be made at the expected logical position.
00240  *
00241  * This cannot be done by the gstreambuf class where the output stream
00242  * is set as buffered (the default).  In that case, if the last
00243  * operation on a giostream or wgiostream object 'strm' was a read,
00244  * before the first write operation thereafter is made on it, the user
00245  * should call strm.seekg(strm.tellg()) or strm.seekp(strm.tellp())
00246  * (the two have the same effect), in order to synchronise the logical
00247  * and actual file positions, or if the user does not want to maintain
00248  * the current logical file position, make some other call to seekg()
00249  * or seekp() which does not comprise only seekg(0,
00250  * std::ios_base::cur) or seekp(0, std::ios_base::cur).  Many
00251  * std::basic_iostream implementations, as inherited by
00252  * Cgu::giostream, will synchronise positions automatically on
00253  * seekable streams via their sentry objects in order to provide
00254  * support for buffered random access on their std::basic_fstream
00255  * class (gcc's libstdc++ library does this, for example), making
00256  * these steps unnecessary, but following these steps will provide
00257  * maximum portability.  The same applies to the equivalent wide
00258  * stream classes.
00259  *
00260  * If a GFileIOStream object attached to a giostream or wgiostream
00261  * object is not seekable (that is, can_seek() returns false), say
00262  * because an input or output converter has been attached or the
00263  * filesystem is a network file system, no random access may be
00264  * attempted.  In particular, the tellg(), tellp(), seekg() and
00265  * seekp() methods will not work (they will return
00266  * pos_type(off_type(-1))).  Furthermore, if a giostream or wgiostream
00267  * object which manages a GFileIOStream object (as opposed to a
00268  * socket) has a converter attached or is not seekable for some other
00269  * reason, then after a read has been made no further write may be
00270  * made using the same GFileIOStream object, so the use of converters
00271  * with giostream or wgiostream objects should generally be restricted
00272  * to use with sockets (GSocketConnection objects) only.  Where
00273  * converters are used with files on a filesystem, it is best to use
00274  * the gostream and gistream classes (or their wide stream
00275  * equivalents), and to close one stream before opening the other
00276  * where they address the same file.
00277  *
00278  * None of these restrictions applies to GSocketConnection objects
00279  * obtained by a call to g_socket_listener_accept() or
00280  * g_socket_client_connect(), or obtained in some other way, as these
00281  * do not maintain file pointers.  They can be attached to a giostream
00282  * or wgiostream object (with or without a converter) without any
00283  * special precautions being taken, other than the normal step of
00284  * calling giostream::flush() (or using the std::flush manipulator) to
00285  * flush the output buffer to the socket if the user needs to know
00286  * that that has happened (or setting output buffering off with the
00287  * set_output_buffered() method).  In summary, on a socket, a read
00288  * does not automatically flush the output buffer: it is for the user
00289  * to do that.
00290  *
00291  * @b Wide @b streams @b and @b endianness
00292  *
00293  * This library provides typedef'ed instances of the template classes
00294  * for wchar_t, char16_t and char32_t characters.  Unless a converter
00295  * is attached (for, say, UTF-32LE to UTF-32BE, or vice versa), with
00296  * these wide character classes wide characters are written out in the
00297  * native endian format of the writing machine.  Whether or not a
00298  * converter from one endianness to another is attached, special steps
00299  * need to be taken if the text which is sent for output might be read
00300  * by machines of unknown endianness.
00301  *
00302  * No such special steps are required where the wide character classes
00303  * are used with temporary files, pipes, fifos, unix domain sockets
00304  * and network sockets on localhost, because in those cases they will
00305  * be read by the same machine that writes; but they are required
00306  * where sockets communicate with other computers over a network or
00307  * when writing to files which may be distributed to and read by other
00308  * computers with different endianness.
00309  *
00310  * Where wide characters are to be exported to other machines, one
00311  * useful approach is to convert to and from UTF-8 with
00312  * Utf8::uniwide_from_utf8(), Utf8::uniwide_to_utf8(),
00313  * Utf8::wide_from_utf8() or Utf8::wide_to_utf8(), and to use
00314  * gostream/gistream/giostream with the converted text, or to attach a
00315  * converter for UTF-8, generated by GIO's g_charset_converter_new(),
00316  * directly to a wgostream, wgistream or wgiostream object (or their
00317  * char16_t and char32_t equivalents).
00318  *
00319  * Instead of converting exported text to UTF-8, another approach is
00320  * to use a byte order marker (BOM) as the first character of the wide
00321  * stream output.  UCS permits a BOM character to be inserted,
00322  * comprising static_cast<wchar_t>(0xfeff),
00323  * static_cast<char16_t>(0xfeff) or static_cast<char32_t>(0xfeff), at
00324  * the beginning of the output to the wide character stream.  At the
00325  * receiving end, this will appear as 0xfffe (UTF-16) or 0xfffe0000
00326  * (UTF-32) to a big endian machine with 8 bit char type if the text
00327  * is little endian, or to a little endian machine with big endian
00328  * text, so signaling a need to undertake byte swapping of text read
00329  * from the stream.  Another alternative is to label the physical
00330  * medium conveying the file as UTF-16LE, UTF-16BE, UTF-32LE or
00331  * UTF-32BE, as the case may be, in which case a BOM character should
00332  * not be prepended.
00333  *
00334  * Where it is established by either means that the input stream
00335  * requires byte swapping, the wide character input stream and wide
00336  * character input streambuffer classes have a set_byteswap() member
00337  * function which should be called on opening the input stream as soon
00338  * as it has been established that byte swapping is required.  Once
00339  * this function has been called with an argument of 'true', all
00340  * further calls to stream functions which provide characters will
00341  * provide those characters with the correct native endianness.
00342  * Calling set_byteswap() on the narrow stream gistream, giostream and
00343  * gstreambuf objects has no effect (byte order is irrelevant to
00344  * narrow streams).
00345  *
00346  * Here is an example of such use in a case where sizeof(wchar_t) is
00347  * 4:
00348  *
00349  * @code
00350  *   using Cgu::GobjHandle;
00351  *   Cgu::wgistream input;
00352  *   GobjHandle<GFile> file_in(g_file_new_for_path("filename"));
00353  *   GFileInputStream* is = g_file_read(file_in, 0, 0);
00354  *   if (is) 
00355  *     input.attach(GobjHandle<GInputStream>(G_INPUT_STREAM(is)), true); // takes ownership of 'is'
00356  *   else {
00357  *     std::cerr << "Can't open file 'filename'"
00358  *               << std::endl;
00359  *     return;
00360  *   }
00361  *   wchar_t item;
00362  *   input.get(item);
00363  *   if (!input) {
00364  *     std::cerr << "File 'filename' is empty" << std::endl;
00365  *     return;
00366  *   }
00367  *   if (item == static_cast<wchar_t>(0xfffe0000))
00368  *     input.set_byteswap(true);
00369  *   else if (item != static_cast<wchar_t>(0xfeff)) {
00370  *     // calling set_byteswap() will manipulate the buffers, so
00371  *     // either call putback() before we call set_byteswap(), or
00372  *     // call unget() instead
00373  *     input.putback(item);
00374  *     // the first character is not a BOM character so assume big endian
00375  *     // format, and byte swap if the local machine is little endian
00376  *  #if G_BYTE_ORDER == G_LITTLE_ENDIAN
00377  *     input.set_byteswap(true);
00378  *  #endif
00379  *   }
00380  *   [ ... do something with the input file ... ]
00381  * @endcode
00382  *
00383  * @b Other @b wide @b stream @b issues
00384  *
00385  *  basic_gostream, basic_gistream, basic_giostream and
00386  *  basic_gstreambuf objects can be instantiated for any integer type
00387  *  which has an appropriate traits class provided for it which has
00388  *  the copy(), eof(), eq_int_type(), move(), not_eof() and
00389  *  to_int_type() static member functions.  The integer type could in
00390  *  fact have any size, but the set_byteswap() methods for
00391  *  basic_gistream, basic_giostream and basic_gstreambuf will only
00392  *  have an effect if its size is either 2 or 4.  Typedef'ed instances
00393  *  of the classes are provided by the library for characters of type
00394  *  wchar_t, char16_t and char32_t.
00395  *
00396  * @b gtkmm @b users
00397  *
00398  * gtkmm/giomm does not provide C++ streams for GIO objects: instead,
00399  * it provides a literal function-for-function wrapping.  However,
00400  * giomm users can use the stream classes provided by this library by
00401  * converting the relevant Glib::RefPtr object to a Cgu::GobjHandle
00402  * object.  This can be done as follows:
00403  *
00404  * @code
00405  *   // Glib::RefPtr<Gio::InputStream> to Cgu::GobjHandle<GInputStream>
00406  *   inline
00407  *   Cgu::GobjHandle<GInputStream> giomm_input_convert(const Glib::RefPtr<Gio::InputStream>& in) {
00408  *     return Cgu::GobjHandle<GInputStream>(static_cast<GInputStream*>(g_object_ref(in.operator->()->gobj())));
00409  *   }
00410  *
00411  *   // Glib::RefPtr<Gio::OutputStream> to Cgu::GobjHandle<GOutputStream>
00412  *   inline
00413  *   Cgu::GobjHandle<GOutputStream> giomm_output_convert(const Glib::RefPtr<Gio::OutputStream>& out) {
00414  *     return Cgu::GobjHandle<GOutputStream>(static_cast<GOutputStream*>(g_object_ref(out.operator->()->gobj())));
00415  *   }
00416  *
00417  *   // Glib::RefPtr<Gio::IOStream> to Cgu::GobjHandle<GIOStream>
00418  *   inline
00419  *   Cgu::GobjHandle<GIOStream> giomm_io_convert(const Glib::RefPtr<Gio::IOStream>& io) {
00420  *     return Cgu::GobjHandle<GIOStream>(static_cast<GIOStream*>(g_object_ref(io.operator->()->gobj())));
00421  *   }
00422  *
00423  *   // example printing a text file to stdout with file opened with giomm
00424  *   Glib::RefPtr<Gio::File> file = Gio::File::create_for_path("filename");
00425  *   Glib::RefPtr<Gio::InputStream> is = file->read();
00426  *
00427  *   Cgu::gistream filein(giomm_input_convert(is), true);
00428  *
00429  *   std::string line;
00430  *   while (std::getline(filein, line)) {
00431  *     std::cout << line << '\n';
00432  *   }
00433  * @endcode
00434  */
00435 
00436 #ifndef CGU_GSTREAM_H
00437 #define CGU_GSTREAM_H
00438 
00439 #include <glib.h>
00440 
00441 #if defined(DOXYGEN_PARSING) || GLIB_CHECK_VERSION(2,16,0)
00442 
00443 // see above for what this does
00444 //#define CGU_GSTREAM_USE_STD_N_READ_WRITE 1
00445 
00446 #include <istream>
00447 #include <ostream>
00448 #include <streambuf>
00449 #include <algorithm>
00450 #include <string>
00451 #include <cstddef>
00452 
00453 #include <gio/gio.h>
00454 
00455 #include <c++-gtk-utils/gobj_handle.h>
00456 #include <c++-gtk-utils/shared_handle.h>
00457 #include <c++-gtk-utils/gerror_handle.h>
00458 #include <c++-gtk-utils/cgu_config.h>
00459 
00460 namespace Cgu {
00461 
00462 /*
00463 The following convenience typedefs appear at the end of this file:
00464 typedef basic_gstreambuf<char> gstreambuf;
00465 typedef basic_gistream<char> gistream;
00466 typedef basic_gostream<char> gostream;
00467 typedef basic_giostream<char> giostream;
00468 typedef basic_gstreambuf<wchar_t> wgstreambuf;
00469 typedef basic_gistream<wchar_t> wgistream;
00470 typedef basic_gostream<wchar_t> wgostream;
00471 typedef basic_giostream<wchar_t> wgiostream;
00472 typedef basic_gstreambuf<char16_t> u16gstreambuf;
00473 typedef basic_gistream<char16_t> u16gistream;
00474 typedef basic_gostream<char16_t> u16gostream;
00475 typedef basic_giostream<char16_t> u16giostream;
00476 typedef basic_gstreambuf<char32_t> u32gstreambuf;
00477 typedef basic_gistream<char32_t> u32gistream;
00478 typedef basic_gostream<char32_t> u32gostream;
00479 typedef basic_giostream<char32_t> u32giostream;
00480 */
00481 
00482 
00483 /**
00484  * @headerfile gstream.h c++-gtk-utils/gstream.h
00485  * @brief C++ stream buffer for GIO streams
00486  * @sa gstreams
00487  * @ingroup gstreams
00488  *
00489  * This class provides a stream buffer for interfacing with GIO
00490  * streams.  It does the buffering for the basic_gostream,
00491  * basic_gistream and basic_giostream stream classes.
00492  */
00493 
00494 template <class charT , class Traits = std::char_traits<charT> >
00495 class basic_gstreambuf: public std::basic_streambuf<charT, Traits> {
00496 
00497 public:
00498   typedef charT char_type;
00499   typedef Traits traits_type;
00500   typedef typename traits_type::int_type int_type;
00501   typedef typename traits_type::pos_type pos_type;
00502   typedef typename traits_type::off_type off_type;
00503 
00504 private:
00505   GobjHandle<GInputStream> input_stream;
00506   GobjHandle<GOutputStream> output_stream;
00507   GobjHandle<GIOStream> io_stream;
00508 
00509   bool manage;
00510   bool byteswap;
00511   bool seek_mismatch;
00512   bool seekable;
00513 
00514   static const int output_buf_size = 1024;   // size of the data write buffer
00515   static const int putback_size = 4;         // size of read putback area
00516   static const int input_buf_size = 1024;    // size of the data read buffer
00517 
00518 #if defined(CGU_USE_GLIB_MEMORY_SLICES_COMPAT) || defined(CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT)
00519   ScopedHandle<char_type*,
00520                GSliceFreeSize<(input_buf_size + putback_size) * sizeof(char_type)>> input_buffer;
00521   ScopedHandle<char_type*,
00522                GSliceFreeSize<output_buf_size * sizeof(char_type)>> output_buffer;
00523 #else
00524   ScopedHandle<char_type*> input_buffer;
00525   ScopedHandle<char_type*> output_buffer;
00526 #endif
00527 
00528   static void swap_element(char_type&);
00529   GobjHandle<GInputStream> find_base_input_stream(const GobjHandle<GInputStream>&);
00530   GobjHandle<GOutputStream> find_base_output_stream(const GobjHandle<GOutputStream>&);
00531   void reset_input_buffer_pointers();
00532   int flush_buffer();
00533   bool wind_back_input_buffer();
00534   bool is_input_stored();
00535   bool is_output_stored();
00536 
00537 protected:
00538 /**
00539  * This method will not throw.  This means that the input functions of
00540  * stream objects which have this streambuffer as a member will not
00541  * throw unless the underlying functions of the std::basic_istream
00542  * class throw, which they would not normally do unless they have been
00543  * required to do so on failbit, badbit or eofbit being set by an
00544  * explicit call to the exceptions() method of that class.  This class
00545  * does not offer concurrent access from multiple threads to the same
00546  * stream object, and if that is required users should provide their
00547  * own synchronisation.
00548  */
00549   virtual int_type underflow();
00550 
00551 /**
00552  * This method will not throw.  This class does not offer concurrent
00553  * access from multiple threads to the same stream object, and if that
00554  * is required users should provide their own synchronisation.
00555  */
00556   virtual int sync();
00557 
00558 /**
00559  * This method will not throw unless std::basic_streambuf<>::sputc()
00560  * throws, which it would not do on any sane implementation.  This
00561  * means that the output functions of stream objects which have this
00562  * streambuffer as a member will not throw unless the underlying
00563  * functions of the std::basic_ostream class throw, which they would
00564  * not normally do unless they have been required to do so on failbit,
00565  * badbit or eofbit being set by an explicit call to the exceptions()
00566  * method of that class.  This class does not offer concurrent access
00567  * from multiple threads to the same stream object, and if that is
00568  * required users should provide their own synchronisation.
00569  */
00570   virtual int_type overflow(int_type);
00571 #ifndef CGU_GSTREAM_USE_STD_N_READ_WRITE
00572 /**
00573  * This method will not throw.  This means that the input functions of
00574  * stream objects which have this streambuffer as a member will not
00575  * throw unless the underlying functions of the std::basic_istream
00576  * class throw, which they would not normally do unless they have been
00577  * required to do so on failbit, badbit or eofbit being set by an
00578  * explicit call to the exceptions() method of that class.  This class
00579  * does not offer concurrent access from multiple threads to the same
00580  * stream object, and if that is required users should provide their
00581  * own synchronisation.
00582  */
00583   virtual std::streamsize xsgetn(char_type*, std::streamsize);
00584 
00585 /**
00586  * This method will not throw.  This means that the output functions
00587  * of stream objects which have this streambuffer as a member will not
00588  * throw unless the underlying functions of the std::basic_ostream
00589  * class throw, which they would not normally do unless they have been
00590  * required to do so on failbit, badbit or eofbit being set by an
00591  * explicit call to the exceptions() method of that class.  This class
00592  * does not offer concurrent access from multiple threads to the same
00593  * stream object, and if that is required users should provide their
00594  * own synchronisation.
00595  */
00596   virtual std::streamsize xsputn(const char_type*, std::streamsize);
00597 #endif
00598 /**
00599  * This method provides random access on GIO streams that implement
00600  * GSeekable, so supporting the tellg(), tellp(), seekg() and seekp()
00601  * methods of the basic_gostream, basic_gistream and basic_giostream
00602  * classes.  Any output buffers will be flushed and if the seek
00603  * succeeds any input buffers will be reset.  This method does not
00604  * throw, but if it returns pos_type(off_type(-1)) to indicate
00605  * failure, it will cause the tellg(), tellp(), seekg() or seekp()
00606  * methods of the relevant stream class to throw
00607  * std::ios_base::failure if such an exception has been required by an
00608  * explicit call to the exceptions() method of that class (but not
00609  * otherwise).  This class does not offer concurrent access from
00610  * multiple threads to the same stream object, and if that is required
00611  * users should provide their own synchronisation.
00612  *
00613  * @param off The offset to be applied to the 'way' argument when
00614  * seeking.  It is a signed integer type, and on wide character
00615  * streams is dimensioned as the number of wchar_t/char32_t/char16_t
00616  * units not the number of bytes (that is, it is
00617  * bytes/sizeof(char_type)).
00618  *
00619  * @param way The file position to which the 'off' argument is to be
00620  * applied (either std::ios_base::beg, std::ios_base::cur or
00621  * std::ios_base::end).
00622  *
00623  * @param m The type of GIO stream which must have been attached to
00624  * this streambuffer for this method to attempt a seek.  For
00625  * GInputStream the argument should have the std::ios_base::in bit
00626  * set, for GOutputStream it should have the std::ios_base::out bit
00627  * set and for GIOStream it should have either (or both) set.
00628  * Provided the relevant bit is set, it doesn't matter if others are
00629  * also set.  However if, with a GIOStream object, both the
00630  * std::ios_base::in and std::ios_base::out bits are set, a seek on
00631  * both input and output streams will be attempted, unless the 'way'
00632  * argument is std::ios_base::cur, in which case a seek on the output
00633  * stream only will be attempted.  (Note that the only GIOStream which
00634  * at present supports seeking is GFileIOStream, and because
00635  * filesystem files only have one file pointer, which is used for both
00636  * input and output, both input seeking and output seeking have the
00637  * same result and affect both streams.)  As the tellg() and seekg()
00638  * stream methods only pass std::ios_base::in, and the tellp() and
00639  * seekp() methods only std::ios_base::out, these will always produce
00640  * the expected result, and for GIOStream streams tellg() will be
00641  * indistinguishable in effect from tellp(), and seekg() from seekp().
00642  *
00643  * @return If the seek succeeds, a std::char_traits<T>::pos_type
00644  * object representing the new stream position of the streambuffer
00645  * after the seek.  (This type is std::streampos for narrow character
00646  * (char) streams, std::wstreampos for wide character (wchar_t)
00647  * streams, std::u16streampos for the char16_t type and
00648  * std::u32streampos for the char32_t type.)  If the seek failed,
00649  * pos_type(off_type(-1)) is returned.  If a seek is made on a
00650  * GIOStream object with both std::ios_base::in and std::ios_base::out
00651  * set and a 'way' argument of std::ios_base::beg or
00652  * std::ios_base::end, the result of the seek which succeeds is
00653  * returned, or if both succeed, the result of the output seek is
00654  * returned.  (Note that the only GIOStream which at present supports
00655  * seeking is GFileIOStream, and because files only have one file
00656  * pointer, which is used for both input and output, both input
00657  * seeking and output seeking have the same result and affect both
00658  * streams.)
00659  */
00660   virtual pos_type seekoff(off_type off,
00661                            std::ios_base::seekdir way,
00662                            std::ios_base::openmode m = std::ios_base::in | std::ios_base::out);
00663 
00664 /**
00665  * This method provides random access on GIO streams that implement
00666  * GSeekable, so supporting the seekg() and seekp() methods of the
00667  * basic_gostream, basic_gistream and basic_giostream classes.  It is
00668  * equivalent to seekoff(off_type(p), std::ios_base::beg, m).  Any
00669  * output buffers will be flushed and if the seek succeeds any input
00670  * buffers will be reset.  This method does not throw, but if it
00671  * returns pos_type(off_type(-1)) to indicate failure, it will cause
00672  * the seekg() or seekp() methods of the relevant stream class to
00673  * throw std::ios_base::failure if such an exception has been required
00674  * by an explicit call to the exceptions() method of that class (but
00675  * not otherwise).  This class does not offer concurrent access from
00676  * multiple threads to the same stream object, and if that is required
00677  * users should provide their own synchronisation.
00678  *
00679  * @param p The absolute position to which the seek is to be made,
00680  * obtained by a previous call to seekoff() or to this method.
00681  *
00682  * @param m The type of GIO stream which must have been attached to
00683  * this streambuffer for this method to attempt a seek.  For
00684  * GInputStream the argument should have the std::ios_base::in bit
00685  * set, for GOutputStream it should have the std::ios_base::out bit
00686  * set and for GIOStream it should have either (or both) set.
00687  * Provided the relevant bit is set, it doesn't matter if others are
00688  * also set.  However if, with a GIOStream object, both the
00689  * std::ios_base::in and std::ios_base::out bits are set, a seek on
00690  * both input and output streams will be attempted.  (Note that the
00691  * only GIOStream which at present supports seeking is GFileIOStream,
00692  * and because filesystem files only have one file pointer, which is
00693  * used for both input and output, both input seeking and output
00694  * seeking have the same result and affect both streams.)  As the
00695  * seekg() stream method only passes std::ios_base::in, and the
00696  * seekp() method only std::ios_base::out, these will always produce
00697  * the expected result, and seekg() will be indistinguishable in
00698  * effect from seekp().
00699  *
00700  * @return If the seek succeeds, a std::char_traits<T>::pos_type
00701  * object representing the new stream position of the streambuffer
00702  * after the seek.  (This type is std::streampos for narrow character
00703  * (char) streams, std::wstreampos for wide character (wchar_t)
00704  * streams, std::u16streampos for the char16_t type and
00705  * std::u32streampos for the char32_t type.)  If the seek failed,
00706  * pos_type(off_type(-1)) is returned.
00707  */
00708   virtual pos_type seekpos(pos_type p,
00709                            std::ios_base::openmode m = std::ios_base::in | std::ios_base::out);
00710 
00711 public:
00712 /**
00713  * This class cannot be copied.  The copy constructor is deleted.
00714  */
00715   basic_gstreambuf(const basic_gstreambuf&) = delete;
00716 
00717 /**
00718  * This class cannot be copied.  The assignment operator is deleted.
00719  */
00720   basic_gstreambuf& operator=(const basic_gstreambuf&) = delete;
00721 
00722 /**
00723  * The default constructor: the GIO stream is attached later using the
00724  * attach_stream() method.  It will not throw unless the constructor
00725  * of std::basic_streambuf throws.  This class does not offer
00726  * concurrent access from multiple threads to the same stream object,
00727  * and if that is required users should provide their own
00728  * synchronisation.
00729  */
00730   basic_gstreambuf();
00731 
00732  /**
00733   * The constructor taking a GIO input stream.  This class does not
00734   * offer concurrent access from multiple threads to the same stream
00735   * object, and if that is required users should provide their own
00736   * synchronisation.
00737   *
00738   * @param input_stream_ A GIO input stream to be attached to the
00739   * streambuffer.  If the caller wants the input stream to survive
00740   * this class's destruction or a call to close_stream() or
00741   * attach_stream(), the caller should keep a separate GobjHandle
00742   * object which references the stream (obtained by, say, calling
00743   * get_istream()) and pass 'manage_' as false.  If this is a
00744   * GFilterInputStream object (that is, a GBufferedInputStream or
00745   * GConverterInputStream stream), only the underlying base input
00746   * stream will be attached and the other higher level streams will be
00747   * closed (buffering of input streams is always provided by this C++
00748   * streambuffer, and converting is controlled solely by the
00749   * 'converter_' argument).
00750   *
00751   * @param manage_ Whether the streambuffer should call
00752   * g_input_stream_close() on the stream in its destructor or when
00753   * another stream is attached.  Passing 'true' is usually what is
00754   * wanted - 'false' only makes sense if the caller keeps a separate
00755   * GobjHandle object which references the stream to keep it alive
00756   * (obtained by, say, calling get_istream()).  Unlike its fdstreams
00757   * equivalent, this parameter does not have a default value of
00758   * 'true': this is partly to make it less likely that a converter is
00759   * passed to this argument by mistake (that would not normally cause
00760   * a compiler warning because GobjHandle has a type conversion
00761   * operator providing the underlying C object by pointer, so
00762   * GobjHandles are type convertible to pointers, and such a pointer
00763   * will in turn provide a type match with a bool argument); and
00764   * partly because, given a GInputStream* p, the construction
00765   * \"Cgu::gstreambuf str(Cgu::GobjHandle<GInputStream>(p));\"
00766   * without an additional argument or additional parentheses (or the
00767   * use of uniform initializer syntax using braces) would cause a
00768   * compiler error as it would be interpreted as a function
00769   * declaration.
00770   *
00771   * @param converter_ A converter (if any) to be attached to the GIO
00772   * input stream (note that this does not affect the operation of
00773   * set_byteswap()).  The default value of an empty
00774   * GobjHandle<GConverter> object indicates no converter.
00775   *
00776   * @exception std::bad_alloc This constructor will throw
00777   * std::bad_alloc if memory is exhausted and the system throws on
00778   * such exhaustion (unless the library has been installed using the
00779   * --with-glib-memory-slices-compat or
00780   * --with-glib-memory-slices-no-compat configuration option, in which
00781   * case glib will terminate the program if it is unable to obtain
00782   * memory from the operating system).  No other exception will be
00783   * thrown unless the constructor of std::basic_streambuf throws.
00784   *
00785   * @note If a converter is provided, the stream will no longer be
00786   * seekable even if it otherwise would be, so tellg() and seekg()
00787   * will no longer work (they will return pos_type(off_type(-1)).
00788   */
00789   basic_gstreambuf(const GobjHandle<GInputStream>& input_stream_,
00790                    bool manage_,
00791                    const GobjHandle<GConverter>& converter_ = GobjHandle<GConverter>());
00792 
00793  /**
00794   * The constructor taking a GIO output stream.  This class does not
00795   * offer concurrent access from multiple threads to the same stream
00796   * object, and if that is required users should provide their own
00797   * synchronisation.
00798   *
00799   * @param output_stream_ A GIO output stream to be attached to the
00800   * streambuffer.  If the caller wants the output stream to survive
00801   * this class's destruction or a call to close_stream() or
00802   * attach_stream(), the caller should keep a separate GobjHandle
00803   * object which references the stream (obtained by, say, calling
00804   * get_ostream()) and pass 'manage_' as false.  If this is a
00805   * GFilterOutputStream object (that is, a GBufferedOutputStream,
00806   * GConverterOutputStream or GDataOutputStream stream), only the
00807   * underlying base output stream will be attached and the other
00808   * higher level streams will be closed (buffering and converting are
00809   * controlled solely by the set_output_buffered() method and
00810   * 'converter_' argument).
00811   *
00812   * @param manage_ Whether the streambuffer should call
00813   * g_output_stream_close() on the stream in its destructor or when
00814   * another stream is attached.  Passing 'true' is usually what is
00815   * wanted, and is particularly relevant on output streams because
00816   * unless g_output_stream_close() is called, GIO may not commit to
00817   * disk - 'false' only makes sense if the caller keeps a separate
00818   * GobjHandle object which references the stream to keep it alive
00819   * (obtained by, say, calling get_ostream()).  Unlike its fdstreams
00820   * equivalent, this parameter does not have a default value of
00821   * 'true': this is partly to make it less likely that a converter is
00822   * passed to this argument by mistake (that would not normally cause
00823   * a compiler warning because GobjHandle has a type conversion
00824   * operator providing the underlying C object by pointer, so
00825   * GobjHandles are type convertible to pointers, and such a pointer
00826   * will in turn provide a type match with a bool argument); and
00827   * partly because, given a GOutputStream* p, the construction
00828   * \"Cgu::gstreambuf str(Cgu::GobjHandle<GOutputStream>(p));\"
00829   * without an additional argument or additional parentheses (or the
00830   * use of uniform initializer syntax using braces) would cause a
00831   * compiler error as it would be interpreted as a function
00832   * declaration.
00833   *
00834   * @param converter_ A converter (if any) to be attached to the GIO
00835   * output stream.  The default value of an empty
00836   * GobjHandle<GConverter> object indicates no converter.
00837   *
00838   * @exception std::bad_alloc This constructor will throw
00839   * std::bad_alloc if memory is exhausted and the system throws on
00840   * such exhaustion (unless the library has been installed using the
00841   * --with-glib-memory-slices-compat or
00842   * --with-glib-memory-slices-no-compat configuration option, in which
00843   * case glib will terminate the program if it is unable to obtain
00844   * memory from the operating system).  No other exception will be
00845   * thrown unless the constructor of std::basic_streambuf throws.
00846   *
00847   * @note If a converter is provided, the stream will no longer be
00848   * seekable even if it otherwise would be, so tellp() and seekp()
00849   * will no longer work (they will return pos_type(off_type(-1)).
00850   */
00851   basic_gstreambuf(const GobjHandle<GOutputStream>& output_stream_,
00852                    bool manage_,
00853                    const GobjHandle<GConverter>& converter_ = GobjHandle<GConverter>());
00854 
00855  /**
00856   * The constructor taking a GIO input-output stream.  This class does
00857   * not offer concurrent access from multiple threads to the same
00858   * stream object, and if that is required users should provide their
00859   * own synchronisation.
00860   *
00861   * @param io_stream_ A GIO input-output stream to be attached to the
00862   * streambuffer.  If the caller wants the stream to survive this
00863   * class's destruction or a call to close_stream() or
00864   * attach_stream(), the caller should keep a separate GobjHandle
00865   * object which references the stream (obtained by, say, calling
00866   * get_iostream()) and pass 'manage_' as false.
00867   *
00868   * @param manage_ Whether the streambuffer should call
00869   * g_io_stream_close() on the stream in its destructor or when
00870   * another stream is attached.  Passing 'true' is usually what is
00871   * wanted, and is particularly relevant on output streams because
00872   * unless g_io_stream_close() is called, GIO may not commit to disk -
00873   * 'false' only makes sense if the caller keeps a separate GobjHandle
00874   * object which references the stream to keep it alive (obtained by,
00875   * say, calling get_iostream()).  Unlike its fdstreams equivalent,
00876   * this parameter does not have a default value of 'true': this is
00877   * partly to make it less likely that a converter is passed to this
00878   * argument by mistake (that would not normally cause a compiler
00879   * warning because GobjHandle has a type conversion operator
00880   * providing the underlying C object by pointer, so GobjHandles are
00881   * type convertible to pointers, and such a pointer will in turn
00882   * provide a type match with a bool argument); and partly because,
00883   * given a GIOStream* p, the construction \"Cgu::gstreambuf
00884   * str(Cgu::GobjHandle<GIOStream>(p));\" without an additional
00885   * argument or additional parentheses (or the use of uniform
00886   * initializer syntax using braces) would cause a compiler error as
00887   * it would be interpreted as a function declaration.
00888   *
00889   * @param input_converter_ A converter (if any) to be attached to the
00890   * input stream (note that this does not affect the operation of
00891   * set_byteswap()).  The default value of an empty
00892   * GobjHandle<GConverter> object indicates no converter.
00893   *
00894   * @param output_converter_ A converter (if any) to be attached to the
00895   * output stream.  The default value of an empty
00896   * GobjHandle<GConverter> object indicates no converter.
00897   *
00898   * @exception std::bad_alloc This constructor will throw
00899   * std::bad_alloc if memory is exhausted and the system throws on
00900   * such exhaustion (unless the library has been installed using the
00901   * --with-glib-memory-slices-compat or
00902   * --with-glib-memory-slices-no-compat configuration option, in which
00903   * case glib will terminate the program if it is unable to obtain
00904   * memory from the operating system).  No other exception will be
00905   * thrown unless the constructor of std::basic_streambuf throws.
00906   *
00907   * @note If a converter is provided, the stream will no longer be
00908   * seekable even if it otherwise would be, so tellg(), tellp(),
00909   * seekg() and seekp() will no longer work (they will return
00910   * pos_type(off_type(-1)).  If the stream to which a converter has
00911   * been attached represents a file on the file system (rather than a
00912   * socket), after a read has been made, no further write may be made
00913   * using the same GFileIOStream object.  These restrictions do not
00914   * apply to sockets (which are not seekable) so the use of converters
00915   * with input-output streams (GIOStream) should generally be
00916   * restricted to sockets.
00917   */
00918   basic_gstreambuf(const GobjHandle<GIOStream>& io_stream_,
00919                    bool manage_,
00920                    const GobjHandle<GConverter>& input_converter_ = GobjHandle<GConverter>(),
00921                    const GobjHandle<GConverter>& output_converter_ = GobjHandle<GConverter>());
00922   
00923 /**
00924  * The destructor does not throw.
00925  */
00926   virtual ~basic_gstreambuf();
00927 
00928  /**
00929   * Attach a new GIO input stream to the streambuffer (and close any
00930   * GIO stream at present managed by it).  In the case of wide
00931   * character input streams, it also switches off byte swapping, if it
00932   * was previously on.  This class does not offer concurrent access
00933   * from multiple threads to the same stream object, and if that is
00934   * required users should provide their own synchronisation.
00935   *
00936   * @param input_stream_ The GIO input stream to be attached to the
00937   * streambuffer.  If the caller wants the input stream to survive a
00938   * subsequent call to close_stream() or attach_stream() or this
00939   * class's destruction, the caller should keep a separate GobjHandle
00940   * object which references the stream (obtained by, say, calling
00941   * get_istream()) and pass 'manage_' as false.  If this is a
00942   * GFilterInputStream object (that is, a GBufferedInputStream or
00943   * GConverterInputStream stream), only the underlying base input
00944   * stream will be attached and the other higher level streams will be
00945   * closed (buffering of input streams is always provided by this C++
00946   * streambuffer, and converting is controlled solely by the
00947   * 'converter_' argument).
00948   *
00949   * @param manage_ Whether the streambuffer should call
00950   * g_input_stream_close() on the stream in its destructor or when
00951   * another stream is attached.  Passing 'true' is usually what is
00952   * wanted - 'false' only makes sense if the caller keeps a separate
00953   * GobjHandle object which references the stream to keep it alive
00954   * (obtained by, say, calling get_istream()).  Unlike its fdstreams
00955   * equivalent, this parameter does not have a default value of
00956   * 'true': this is partly to make it less likely that a converter is
00957   * passed to this argument by mistake (that would not normally cause
00958   * a compiler warning because GobjHandle has a type conversion
00959   * operator providing the underlying C object by pointer, so
00960   * GobjHandles are type convertible to pointers, and such a pointer
00961   * will in turn provide a type match with a bool argument); and
00962   * partly to maintain compatibility with the constructor's interface,
00963   * which has separate syntactic constraints.
00964   *
00965   * @param converter_ A converter (if any) to be attached to the GIO
00966   * input stream (note that this does not affect the operation of
00967   * set_byteswap()).  The default value of an empty
00968   * GobjHandle<GConverter> object indicates no converter.
00969   *
00970   * @exception std::bad_alloc This method will throw std::bad_alloc if
00971   * memory is exhausted and the system throws on such exhaustion
00972   * (unless the library has been installed using the
00973   * --with-glib-memory-slices-compat or
00974   * --with-glib-memory-slices-no-compat configuration option, in which
00975   * case glib will terminate the program if it is unable to obtain
00976   * memory from the operating system).
00977   *
00978   * @note If a converter is provided, the stream will no longer be
00979   * seekable even if it otherwise would be, so tellg() and seekg()
00980   * will no longer work (they will return pos_type(off_type(-1)).
00981   */
00982   void attach_stream(const GobjHandle<GInputStream>& input_stream_,
00983                      bool manage_,
00984                      const GobjHandle<GConverter>& converter_ = GobjHandle<GConverter>());
00985 
00986  /**
00987   * Attach a new GIO output stream to the streambuffer (and close any
00988   * GIO stream at present managed by it).  If output buffering was
00989   * previously switched off, it is switched back on again.  This class
00990   * does not offer concurrent access from multiple threads to the same
00991   * stream object, and if that is required users should provide their
00992   * own synchronisation.
00993   *
00994   * @param output_stream_ The GIO output stream to be attached to the
00995   * streambuffer.  If the caller wants the output stream to survive a
00996   * subsequent call to close_stream() or attach_stream() or this
00997   * class's destruction, the caller should keep a separate GobjHandle
00998   * object which references the stream (obtained by, say, calling
00999   * get_ostream()) and pass 'manage_' as false.  If this is a
01000   * GFilterOutputStream object (that is, a GBufferedOutputStream,
01001   * GConverterOutputStream or GDataOutputStream stream), only the
01002   * underlying base output stream will be attached and the other
01003   * higher level streams will be closed (buffering and converting are
01004   * controlled solely by the set_output_buffered() method and
01005   * 'converter_' argument).
01006   *
01007   * @param manage_ Whether the streambuffer should call
01008   * g_output_stream_close() on the stream in its destructor or when
01009   * another stream is attached.  Passing 'true' is usually what is
01010   * wanted, and is particularly relevant on output streams because
01011   * unless g_output_stream_close() is called, GIO may not commit to
01012   * disk - 'false' only makes sense if the caller keeps a separate
01013   * GobjHandle object which references the stream to keep it alive
01014   * (obtained by, say, calling get_ostream()).  Unlike its fdstreams
01015   * equivalent, this parameter does not have a default value of
01016   * 'true': this is partly to make it less likely that a converter is
01017   * passed to this argument by mistake (that would not normally cause
01018   * a compiler warning because GobjHandle has a type conversion
01019   * operator providing the underlying C object by pointer, so
01020   * GobjHandles are type convertible to pointers, and such a pointer
01021   * will in turn provide a type match with a bool argument); and
01022   * partly to maintain compatibility with the constructor's interface,
01023   * which has separate syntactic constraints.
01024   *
01025   * @param converter_ A converter (if any) to be attached to the GIO
01026   * output stream.  The default value of an empty
01027   * GobjHandle<GConverter> object indicates no converter.
01028   *
01029   * @exception std::bad_alloc This method will throw std::bad_alloc if
01030   * memory is exhausted and the system throws on such exhaustion
01031   * (unless the library has been installed using the
01032   * --with-glib-memory-slices-compat or
01033   * --with-glib-memory-slices-no-compat configuration option, in which
01034   * case glib will terminate the program if it is unable to obtain
01035   * memory from the operating system).
01036   *
01037   * @note If a converter is provided, the stream will no longer be
01038   * seekable even if it otherwise would be, so tellp() and seekp()
01039   * will no longer work (they will return pos_type(off_type(-1)).
01040   */
01041   void attach_stream(const GobjHandle<GOutputStream>& output_stream_,
01042                      bool manage_,
01043                      const GobjHandle<GConverter>& converter_ = GobjHandle<GConverter>());
01044 
01045  /**
01046   * Attach a new GIO input-output stream to the streambuffer (and
01047   * close any GIO stream at present managed by it).  If output
01048   * buffering was previously switched off, it is switched back on
01049   * again.  In the case of wide character input-output streams, it
01050   * also switches off byte swapping on input, if it was previously on.
01051   * This class does not offer concurrent access from multiple threads
01052   * to the same stream object, and if that is required users should
01053   * provide their own synchronisation.
01054   *
01055   * @param io_stream_ The GIO input-output stream to be attached to
01056   * the streambuffer.  If the caller wants the stream to survive a
01057   * subsequent call to close_stream() or attach_stream() or this
01058   * class's destruction, the caller should keep a separate GobjHandle
01059   * object which references the stream (obtained by, say, calling
01060   * get_iostream()) and pass 'manage_' as false.
01061   *
01062   * @param manage_ Whether the streambuffer should call
01063   * g_io_stream_close() on the stream in its destructor or when
01064   * another stream is attached.  Passing 'true' is usually what is
01065   * wanted, and is particularly relevant on output streams because
01066   * unless g_io_stream_close() is called, GIO may not commit to disk -
01067   * 'false' only makes sense if the caller keeps a separate GobjHandle
01068   * object which references the stream to keep it alive (obtained by,
01069   * say, calling get_iostream()).  Unlike its fdstreams equivalent,
01070   * this parameter does not have a default value of 'true': this is
01071   * partly to make it less likely that a converter is passed to this
01072   * argument by mistake (that would not normally cause a compiler
01073   * warning because GobjHandle has a type conversion operator
01074   * providing the underlying C object by pointer, so GobjHandles are
01075   * type convertible to pointers, and such a pointer will in turn
01076   * provide a type match with a bool argument); and partly to maintain
01077   * compatibility with the constructor's interface, which has separate
01078   * syntactic constraints.
01079   *
01080   * @param input_converter_ A converter (if any) to be attached to the
01081   * input stream (note that this does not affect the operation of
01082   * set_byteswap()).  The default value of an empty
01083   * GobjHandle<GConverter> object indicates no converter.
01084   *
01085   * @param output_converter_ A converter (if any) to be attached to the
01086   * output stream.  The default value of an empty
01087   * GobjHandle<GConverter> object indicates no converter.
01088   *
01089   * @exception std::bad_alloc This method will throw std::bad_alloc if
01090   * memory is exhausted and the system throws on such exhaustion
01091   * (unless the library has been installed using the
01092   * --with-glib-memory-slices-compat or
01093   * --with-glib-memory-slices-no-compat configuration option, in which
01094   * case glib will terminate the program if it is unable to obtain
01095   * memory from the operating system).
01096   *
01097   * @note If a converter is provided, the stream will no longer be
01098   * seekable even if it otherwise would be, so tellg(), tellp(),
01099   * seekg() and seekp() will no longer work (they will return
01100   * pos_type(off_type(-1)).  If the stream to which a converter has
01101   * been attached represents a file on the file system (rather than a
01102   * socket), after a read has been made, no further write may be made
01103   * using the same GFileIOStream object.  These restrictions do not
01104   * apply to sockets (which are not seekable) so the use of converters
01105   * with input-output streams (GIOStream) should generally be
01106   * restricted to sockets.
01107   */
01108   void attach_stream(const GobjHandle<GIOStream>& io_stream_,
01109                      bool manage_,
01110                      const GobjHandle<GConverter>& input_converter_ = GobjHandle<GConverter>(),
01111                      const GobjHandle<GConverter>& output_converter_ = GobjHandle<GConverter>());
01112 
01113 
01114  /**
01115   * Call g_input_stream_close(), g_output_stream_close() or
01116   * g_io_stream_close(), as the case may be, on the GIO stream at
01117   * present attached to the streambuffer (if any), and release the
01118   * streambuffer's reference to that stream (the reference will be
01119   * released even if an error arose in closing the stream).  If the
01120   * caller wants the GIO stream to survive the call to this method
01121   * (albeit in a closed state), the caller should, before the call is
01122   * made, keep a separate GobjHandle object which references the
01123   * stream.  This method does not throw.  This class does not offer
01124   * concurrent access from multiple threads to the same stream object,
01125   * and if that is required users should provide their own
01126   * synchronisation.
01127   *
01128   * @return true if the close succeeded, false if an error arose
01129   * (including in a case where no GIO stream has been attached or it
01130   * has already been closed).
01131   */
01132   bool close_stream();
01133 
01134  /**
01135   * Get the GIO input stream at present attached to the streambuffer
01136   * (if any), by GobjHandle.  If a GOutputStream object rather than a
01137   * GInputStream or GIOStream object has been attached (or no stream
01138   * has been attached) or it has been closed, then this method will
01139   * return an empty GobjHandle object.  If a GIOStream object has been
01140   * attached, this streambuffer's maintained GInputStream object will
01141   * be returned, which may be a converting stream manufactured from
01142   * the GInputStream object maintained by the GIOStream object.
01143   * Retaining the return value will cause the stream to survive a
01144   * subsequent call to attach_stream() or the destruction of this
01145   * object.  The return value may be a different stream from the one
01146   * originally passed to this object's constructor or to attach().  It
01147   * will be different if a converter has been attached to it.  This
01148   * method does not throw.  This class does not offer concurrent
01149   * access from multiple threads to the same stream object, and if
01150   * that is required users should provide their own synchronisation.
01151   *
01152   * @return The GIO input stream at present attached to the
01153   * streambuffer, or an empty GobjHandle object if none has been
01154   * attached
01155   */
01156   GobjHandle<GInputStream> get_istream() const;
01157 
01158  /**
01159   * Get the GIO output stream at present attached to the streambuffer
01160   * (if any), by GobjHandle.  If a GInputStream object rather than a
01161   * GOutputStream or GIOStream object has been attached (or no stream
01162   * has been attached) or it has been closed, then this method will
01163   * return an empty GobjHandle object.  If a GIOStream object has been
01164   * attached, this streambuffer's maintained GOutputStream object will
01165   * be returned, which may be a converting stream manufactured from
01166   * the GOutputStream object maintained by the GIOStream object.
01167   * Retaining the return value will cause the stream to survive a
01168   * subsequent call to attach_stream() or the destruction of this
01169   * object.  The return value may be a different stream from the one
01170   * originally passed to this object's constructor or to attach().  It
01171   * will be different if a converter has been attached to it.  This
01172   * method does not throw.  This class does not offer concurrent
01173   * access from multiple threads to the same stream object, and if
01174   * that is required users should provide their own synchronisation.
01175   *
01176   * @return The GIO output stream at present attached to the
01177   * streambuffer, or an empty GobjHandle object if none has been
01178   * attached
01179   */
01180   GobjHandle<GOutputStream> get_ostream() const;
01181 
01182  /**
01183   * Get the GIOStream input-output stream at present attached to the
01184   * streambuffer (if any), by GobjHandle.  If a GInputStream or
01185   * GOutputStream object rather than a GIOStream object has been
01186   * attached (or no stream has been attached) or it has been closed,
01187   * then this method will return an empty GobjHandle object.
01188   * Retaining the return value will cause the stream to survive a
01189   * subsequent call to attach_stream() or the destruction of this
01190   * object.  This method does not throw.  This class does not offer
01191   * concurrent access from multiple threads to the same stream object,
01192   * and if that is required users should provide their own
01193   * synchronisation.
01194   *
01195   * @return The GIOStream stream at present attached to the
01196   * streambuffer, or an empty GobjHandle object if none has been
01197   * attached
01198   */
01199   GobjHandle<GIOStream> get_iostream() const;
01200 
01201  /**
01202   * Causes the streambuffer to swap bytes in incoming text, so as to
01203   * convert big endian text to little endian text, or little endian
01204   * text to big endian text.  It is called by the user in response to
01205   * finding a byte order marker (BOM) 0xfffe (UTF-16) or 0xfffe0000
01206   * (UTF-32) as the first character of a newly opened file/stream, or
01207   * if the user knows by some other means that the native endianness
01208   * of the machine doing the reading differs from the endianness of
01209   * the file/stream being read.  This only has effect on wide
01210   * character streambuffers for input (for example, a wgstreambuf to
01211   * which a GInputStream or GIOStream object has been attached), and
01212   * not the gstreambuf narrow character stream buffer.  Note that
01213   * characters held for output are always outputted in native endian
01214   * format unless a GConverter object has been attached, and this
01215   * method does not affect that.  This method does not throw.  This
01216   * class does not offer concurrent access from multiple threads to
01217   * the same stream object, and if that is required users should
01218   * provide their own synchronisation.
01219   *
01220   * @param swap 'true' if byte swapping for input is to be turned on,
01221   * 'false' if it is to be turned off.  This will affect all
01222   * characters extracted from the underlying streambuffer after this
01223   * call is made.  If a previously extracted character is to be
01224   * putback(), it must be put back before this function is called (or
01225   * unget() should be called instead) to avoid a putback mismatch,
01226   * because this call will byte-swap anything already in the buffers.
01227   * (Characters extracted after the call to this method may be putback
01228   * normally.)
01229   */
01230   void set_byteswap(bool swap);
01231 
01232 /**
01233  * If the GIO stream attached to this object is GOutputStream or
01234  * GIOStream, this method converts it to an unbuffered stream for
01235  * output if 'buffered' is false, or back to a buffered stream if
01236  * buffering has previously been switched off and 'buffered' is true.
01237  * Buffering is on by default for any newly created gstreambuf object
01238  * and any newly attached GIO output stream or input-output stream.
01239  * If buffering is turned off, all characters at present in the
01240  * buffers which are stored for output are flushed (but if writing to
01241  * a file which is being written over/replaced, output from this
01242  * streambuffer may not appear in the destination until the GIO stream
01243  * is closed).  This method has no effect if no GIO output stream or
01244  * input-output stream has yet been attached to this streambuffer.
01245  * Switching output buffering off is similar in effect to setting the
01246  * std::ios_base::unitbuf flag in the relevant gostream or giostream
01247  * object, except that switching buffering off is slightly more
01248  * efficient, and setting the std::ios_base::unitbuf flag will not
01249  * retain the automatic tying of logical and actual file positions
01250  * that occurs when output buffering is switched off, as explained
01251  * @ref GioRandomAccessAnchor "here".  This class does not offer
01252  * concurrent access from multiple threads to the same stream object,
01253  * and if that is required users should provide their own
01254  * synchronisation.
01255  *
01256  * @param buffered 'false' if buffering is to be turned off, 'true' if
01257  * it is to be turned back on.
01258  *
01259  * @exception std::bad_alloc This method will throw std::bad_alloc if
01260  * 'buffered' is true, output buffering had previously been switched
01261  * off, memory is exhausted and the system throws on such exhaustion
01262  * (unless the library has been installed using the
01263  * --with-glib-memory-slices-compat or
01264  * --with-glib-memory-slices-no-compat configuration option, in which
01265  * case glib will terminate the program if it is unable to obtain
01266  * memory from the operating system).
01267  */
01268   void set_output_buffered(bool buffered);
01269 
01270 /**
01271  * This method indicates whether the attached GIO stream implements
01272  * GSeekable, so that a call to seekoff() or seekpos() can succeed.
01273  * This method does not throw.  This class does not offer concurrent
01274  * access from multiple threads to the same stream object, and if that
01275  * is required users should provide their own synchronisation.
01276  *
01277  * @return true if random access is supported, otherwise false.  The
01278  * result is only meaningful if a GIO stream has been attached to this
01279  * streambuffer.
01280  */
01281   bool can_seek() const {return seekable;}
01282 
01283 /* Only has effect if --with-glib-memory-slices-compat or
01284  * --with-glib-memory-slices-no-compat option picked */
01285   CGU_GLIB_MEMORY_SLICES_FUNCS
01286 };
01287 
01288 /**
01289  * @headerfile gstream.h c++-gtk-utils/gstream.h
01290  * @brief C++ output stream for GIO streams
01291  * @sa gstreams
01292  * @ingroup gstreams
01293  *
01294  * This class provides standard ostream services for GIO output
01295  * streams.
01296  */
01297 template <class charT , class Traits = std::char_traits<charT> >
01298 class basic_gostream: public std::basic_ostream<charT, Traits> {
01299 
01300   basic_gstreambuf<charT, Traits> buf;
01301 
01302 public:
01303 /**
01304  * This class cannot be copied.  The copy constructor is deleted.
01305  */
01306   basic_gostream(const basic_gostream&) = delete;
01307 
01308 /**
01309  * This class cannot be copied.  The assignment operator is deleted.
01310  */
01311   basic_gostream& operator=(const basic_gostream&) = delete;
01312 
01313  /**
01314   * The constructor taking a GIO output stream.  This class does not
01315   * offer concurrent access from multiple threads to the same stream
01316   * object, and if that is required users should provide their own
01317   * synchronisation.
01318   *
01319   * @param stream A GIO output stream to be attached.  If the caller
01320   * wants the output stream to survive this class's destruction or a
01321   * call to close() or attach(), the caller should keep a separate
01322   * GobjHandle object which references the stream (obtained by, say,
01323   * calling get_gio_stream()) and pass 'manage' as false.  If this is
01324   * a GFilterOutputStream object (that is, a GBufferedOutputStream,
01325   * GConverterOutputStream or GDataOutputStream stream), only the
01326   * underlying base output stream will be attached and the other
01327   * higher level streams will be closed (buffering and converting are
01328   * controlled solely by the set_buffered() method and 'converter'
01329   * argument).
01330   *
01331   * @param manage Whether the underlying streambuffer should call
01332   * g_output_stream_close() on the GIO stream in the streambuffer's
01333   * destructor or when another stream is attached.  Passing 'true' is
01334   * usually what is wanted, and is particularly relevant on output
01335   * streams because unless g_output_stream_close() is called, GIO may
01336   * not commit to disk - 'false' only makes sense if the caller keeps
01337   * a separate GobjHandle object which references the stream to keep
01338   * it alive (obtained by, say, calling get_gio_stream()).  Unlike its
01339   * fdstreams equivalent, this parameter does not have a default value
01340   * of 'true': this is partly to make it less likely that a converter
01341   * is passed to this argument by mistake (that would not normally
01342   * cause a compiler warning because GobjHandle has a type conversion
01343   * operator providing the underlying C object by pointer, so
01344   * GobjHandles are type convertible to pointers, and such a pointer
01345   * will in turn provide a type match with a bool argument); and
01346   * partly because, given a GOutputStream* p, the construction
01347   * \"Cgu::gostream str(Cgu::GobjHandle<GOutputStream>(p));\"
01348   * without an additional argument or additional parentheses (or the
01349   * use of uniform initializer syntax using braces) would cause a
01350   * compiler error as it would be interpreted as a function
01351   * declaration.
01352   *
01353   * @param converter A converter (if any) to be attached to the GIO
01354   * output stream.  The default value of an empty
01355   * GobjHandle<GConverter> object indicates no converter.
01356   *
01357   * @exception std::bad_alloc This constructor will throw
01358   * std::bad_alloc if memory is exhausted and the system throws on
01359   * such exhaustion (unless the library has been installed using the
01360   * --with-glib-memory-slices-compat or
01361   * --with-glib-memory-slices-no-compat configuration option, in which
01362   * case glib will terminate the program if it is unable to obtain
01363   * memory from the operating system).  No other exception will be
01364   * thrown unless the constructor of std::basic_streambuf,
01365   * std::basic_ostream or std::basic_istream throws.
01366   *
01367   * @note If a converter is provided, the stream will no longer be
01368   * seekable even if it otherwise would be, so tellp() and seekp()
01369   * will no longer work (they will return pos_type(off_type(-1)).
01370   */
01371   // using uniform initializer syntax here confuses doxygen
01372   basic_gostream(const GobjHandle<GOutputStream>& stream,
01373                  bool manage,
01374                  const GobjHandle<GConverter>& converter = GobjHandle<GConverter>()):
01375                                       std::basic_ostream<charT, Traits>(0),
01376                                       buf(stream, manage, converter) {
01377     rdbuf(&buf);
01378   }
01379 
01380  /**
01381   * With this constructor, the GIO output stream must be attached
01382   * later with the attach() method.  It will not throw unless the
01383   * constructor of std::basic_streambuf, std::basic_ostream or
01384   * std::basic_istream throws.  This class does not offer concurrent
01385   * access from multiple threads to the same stream object, and if
01386   * that is required users should provide their own synchronisation.
01387   */
01388   // using uniform initializer syntax here confuses doxygen
01389   basic_gostream(): std::basic_ostream<charT, Traits>(0) {
01390     rdbuf(&buf);
01391   }
01392 
01393  /**
01394   * Attach a new GIO output stream to this object (and close any GIO
01395   * stream at present managed by it).  If output buffering was
01396   * previously switched off, it is switched back on again.  If any
01397   * stream state flags were set (eofbit, failbit or badbit), they will
01398   * be cleared by a call to clear().  If this method closes a stream
01399   * at present managed by it and the close fails, failbit is not set
01400   * and no exception will be thrown.  Accordingly, if the user needs
01401   * to know whether there was an error in this method closing any
01402   * managed stream, she should call close() explicitly before calling
01403   * this method.  This class does not offer concurrent access from
01404   * multiple threads to the same stream object, and if that is
01405   * required users should provide their own synchronisation.
01406   *
01407   * @param stream A GIO output stream to be attached.  If the caller
01408   * wants the GIO output stream to survive a subsequent call to
01409   * close() or attach() or this class's destruction, the caller should
01410   * keep a separate GobjHandle object which references the stream
01411   * (obtained by, say, calling get_gio_stream()) and pass 'manage' as
01412   * false.  If this is a GFilterOutputStream object (that is, a
01413   * GBufferedOutputStream, GConverterOutputStream or GDataOutputStream
01414   * stream), only the underlying base output stream will be attached
01415   * and the other higher level streams will be closed (buffering and
01416   * converting are controlled solely by the set_buffered() method and
01417   * 'converter' argument).
01418   *
01419   * @param manage Whether the underlying streambuffer should call
01420   * g_output_stream_close() on the GIO stream in the streambuffer's
01421   * destructor or when another stream is attached.  Passing 'true' is
01422   * usually what is wanted, and is particularly relevant on output
01423   * streams because unless g_output_stream_close() is called, GIO may
01424   * not commit to disk - 'false' only makes sense if the caller keeps
01425   * a separate GobjHandle object which references the stream to keep
01426   * it alive (obtained by, say, calling get_gio_stream()).  Unlike its
01427   * fdstreams equivalent, this parameter does not have a default value
01428   * of 'true': this is partly to make it less likely that a converter
01429   * is passed to this argument by mistake (that would not normally
01430   * cause a compiler warning because GobjHandle has a type conversion
01431   * operator providing the underlying C object by pointer, so
01432   * GobjHandles are type convertible to pointers, and such a pointer
01433   * will in turn provide a type match with a bool argument); and
01434   * partly to maintain compatibility with the constructor's interface,
01435   * which has separate syntactic constraints.
01436   *
01437   * @param converter A converter (if any) to be attached to the GIO
01438   * output stream.  The default value of an empty
01439   * GobjHandle<GConverter> object indicates no converter.
01440   *
01441   * @exception std::bad_alloc This method will throw std::bad_alloc if
01442   * memory is exhausted and the system throws on such exhaustion
01443   * (unless the library has been installed using the
01444   * --with-glib-memory-slices-compat or
01445   * --with-glib-memory-slices-no-compat configuration option, in which
01446   * case glib will terminate the program if it is unable to obtain
01447   * memory from the operating system).
01448   *
01449   * @note If a converter is provided, the stream will no longer be
01450   * seekable even if it otherwise would be, so tellp() and seekp()
01451   * will no longer work (they will return pos_type(off_type(-1)).
01452   */
01453   void attach(const GobjHandle<GOutputStream>& stream,
01454               bool manage,
01455               const GobjHandle<GConverter>& converter = GobjHandle<GConverter>())
01456   {buf.attach_stream(stream, manage, converter); this->clear();}
01457 
01458  /**
01459   * Call g_output_stream_close() on the GIO stream at present attached
01460   * (if any), and release the underlying C++ streambuffer's reference
01461   * to that stream.  If the caller wants the GIO stream to survive the
01462   * call to this method (albeit in a closed state), the caller should,
01463   * before the call is made, keep a separate GobjHandle object which
01464   * references the stream.  If the close fails, the failbit will be
01465   * set with setstate(std::ios_base::failbit).  This class does not
01466   * offer concurrent access from multiple threads to the same stream
01467   * object, and if that is required users should provide their own
01468   * synchronisation.
01469   *
01470   * @exception std::ios_base::failure This exception will be thrown if
01471   * an error arises on closing the stream and such an exception has
01472   * been required by a call to the exceptions() method of this class
01473   * (inherited from std::basic_ios<>).  No exception will be thrown if
01474   * exceptions() has not been called.
01475   */
01476   void close() {if (!buf.close_stream()) this->setstate(std::ios_base::failbit);}
01477 
01478  /**
01479   * Get the GIO output stream at present attached (if any), by
01480   * GobjHandle.  If no stream has been attached, this method will
01481   * return an empty GobjHandle object.  Retaining the return value
01482   * will cause the GIO output stream to survive the destruction of
01483   * this object.  The return value may be a different stream from the
01484   * one originally passed to this object's constructor or to attach().
01485   * It will be different if a converter has been attached to it.  This
01486   * method does not throw.  This class does not offer concurrent
01487   * access from multiple threads to the same stream object, and if
01488   * that is required users should provide their own synchronisation.
01489   *
01490   * @return The GIO output stream at present attached, or an empty
01491   * GobjHandle object if none has been attached
01492   */
01493   GobjHandle<GOutputStream> get_gio_stream() const {return buf.get_ostream();}
01494 
01495 /**
01496  * This method converts the attached GIO output stream to an
01497  * unbuffered stream for output if 'buffered' is false, or back to a
01498  * buffered stream if buffering has previously been switched off and
01499  * 'buffered' is true.  Buffering is on by default for any newly
01500  * created gostream object and any newly attached GIO output stream.
01501  * If buffering is turned off, all characters at present in the
01502  * buffers which are stored for output are flushed (but if writing to
01503  * a file which is being written over/replaced, output may not appear
01504  * in the destination until the GIO stream is closed).  This method
01505  * has no effect if no GIO output stream has yet been attached.
01506  * Switching output buffering off is similar in effect to setting the
01507  * std::ios_base::unitbuf flag, but is slightly more efficient.  This
01508  * class does not offer concurrent access from multiple threads to the
01509  * same stream object, and if that is required users should provide
01510  * their own synchronisation.
01511  *
01512  * @param buffered 'false' if buffering is to be turned off, 'true' if
01513  * it is to be turned back on.
01514  *
01515  * @exception std::bad_alloc This method will throw std::bad_alloc if
01516  * 'buffered' is true, output buffering had previously been switched
01517  * off, memory is exhausted and the system throws on such exhaustion
01518  * (unless the library has been installed using the
01519  * --with-glib-memory-slices-compat or
01520  * --with-glib-memory-slices-no-compat configuration option, in which
01521  * case glib will terminate the program if it is unable to obtain
01522  * memory from the operating system).
01523  */
01524   void set_buffered(bool buffered) {buf.set_output_buffered(buffered);}
01525 
01526 /**
01527  * This method indicates whether the attached GIO output stream
01528  * implements GSeekable, so that a call to tellp() or seekp() can
01529  * succeed.  Note that in the seekp(off_type off, ios_base::seekdir
01530  * dir) variant, on wide character streams the 'off' argument is
01531  * dimensioned as the number of wchar_t/char32_t/char16_t units not
01532  * the number of bytes (that is, it is bytes/sizeof(char_type)).  This
01533  * method does not throw.  This class does not offer concurrent access
01534  * from multiple threads to the same stream object, and if that is
01535  * required users should provide their own synchronisation.
01536  *
01537  * @return true if the attached GIO stream implements GSeekable,
01538  * otherwise false.  The result is only meaningful if a GIO stream has
01539  * been attached to this C++ stream object.
01540  */
01541   bool can_seek() const {return buf.can_seek();}
01542 
01543 /* Only has effect if --with-glib-memory-slices-compat or
01544  * --with-glib-memory-slices-no-compat option picked */
01545   CGU_GLIB_MEMORY_SLICES_FUNCS
01546 };
01547 
01548 
01549 /**
01550  * @headerfile gstream.h c++-gtk-utils/gstream.h
01551  * @brief C++ input stream for GIO streams
01552  * @sa gstreams
01553  * @ingroup gstreams
01554  *
01555  * This class provides standard istream services for GIO input
01556  * streams.
01557  */
01558 template <class charT , class Traits = std::char_traits<charT> >
01559 class basic_gistream : public std::basic_istream<charT, Traits> {
01560 
01561   basic_gstreambuf<charT , Traits> buf;
01562 
01563 public:
01564 /**
01565  * This class cannot be copied.  The copy constructor is deleted.
01566  */
01567   basic_gistream(const basic_gistream&) = delete;
01568 
01569 /**
01570  * This class cannot be copied.  The assignment operator is deleted.
01571  */
01572   basic_gistream& operator=(const basic_gistream&) = delete;
01573 
01574  /**
01575   * The constructor taking a GIO input stream.  This class does not
01576   * offer concurrent access from multiple threads to the same stream
01577   * object, and if that is required users should provide their own
01578   * synchronisation.
01579   *
01580   * @param stream A GIO input stream to be attached.  If the caller
01581   * wants the GIO input stream to survive this class's destruction or
01582   * a call to close() or attach(), the caller should keep a separate
01583   * GobjHandle object which references the stream (obtained by, say,
01584   * calling get_gio_stream()) and pass 'manage' as false.  If this is
01585   * a GFilterInputStream object (that is, a GBufferedInputStream or
01586   * GConverterInputStream stream), only the underlying base input
01587   * stream will be attached and the other higher level streams will be
01588   * closed (buffering of input streams is always provided by the
01589   * underlying C++ streambuffer, and converting is controlled solely
01590   * by the 'converter' argument).
01591   *
01592   * @param manage Whether the underlying streambuffer should call
01593   * g_input_stream_close() on the GIO stream in the streambuffer's
01594   * destructor or when another stream is attached.  Passing 'true' is
01595   * usually what is wanted - 'false' only makes sense if the caller
01596   * keeps a separate GobjHandle object which references the stream to
01597   * keep it alive (obtained by, say, calling get_gio_stream()).
01598   * Unlike its fdstreams equivalent, this parameter does not have a
01599   * default value of 'true': this is partly to make it less likely
01600   * that a converter is passed to this argument by mistake (that would
01601   * not normally cause a compiler warning because GobjHandle has a
01602   * type conversion operator providing the underlying C object by
01603   * pointer, so GobjHandles are type convertible to pointers, and such
01604   * a pointer will in turn provide a type match with a bool argument);
01605   * and partly because, given a GInputStream* p, the construction
01606   * \"Cgu::gistream str(Cgu::GobjHandle<GInputStream>(p));\" without
01607   * an additional argument or additional parentheses (or the use of
01608   * uniform initializer syntax using braces) would cause a compiler
01609   * error as it would be interpreted as a function declaration.
01610   *
01611   * @param converter A converter (if any) to be attached to the GIO
01612   * input stream (note that this does not affect the operation of
01613   * set_byteswap()).  The default value of an empty
01614   * GobjHandle<GConverter> object indicates no converter.
01615   *
01616   * @exception std::bad_alloc This constructor will throw
01617   * std::bad_alloc if memory is exhausted and the system throws on
01618   * such exhaustion (unless the library has been installed using the
01619   * --with-glib-memory-slices-compat or
01620   * --with-glib-memory-slices-no-compat configuration option, in which
01621   * case glib will terminate the program if it is unable to obtain
01622   * memory from the operating system).  No other exception will be
01623   * thrown unless the constructor of std::basic_streambuf,
01624   * std::basic_ostream or std::basic_istream throws.
01625   *
01626   * @note If a converter is provided, the stream will no longer be
01627   * seekable even if it otherwise would be, so tellg() and seekg()
01628   * will no longer work (they will return pos_type(off_type(-1)).
01629   */
01630   // using uniform initializer syntax here confuses doxygen
01631   basic_gistream(const GobjHandle<GInputStream>& stream,
01632                  bool manage,
01633                  const GobjHandle<GConverter>& converter = GobjHandle<GConverter>()):
01634                                       std::basic_istream<charT, Traits>(0),
01635                                       buf(stream, manage, converter) {
01636     rdbuf(&buf);
01637   }
01638 
01639  /**
01640   * With this constructor, the GIO input stream must be attached later
01641   * with the attach() method.  It will not throw unless the
01642   * constructor of std::basic_streambuf, std::basic_ostream or
01643   * std::basic_istream throws.  This class does not offer concurrent
01644   * access from multiple threads to the same stream object, and if
01645   * that is required users should provide their own synchronisation.
01646   */
01647   // using uniform initializer syntax here confuses doxygen
01648   basic_gistream(): std::basic_istream<charT, Traits>(0) {
01649     rdbuf(&buf);
01650   }
01651 
01652  /**
01653   * Attach a new GIO input stream to this object (and close any GIO
01654   * stream at present managed by it).  In the case of wide character
01655   * input streams, it also switches off byte swapping, if it was
01656   * previously on.  If any stream state flags were set (eofbit,
01657   * failbit or badbit), they will be cleared by a call to clear().  If
01658   * this method closes a stream at present managed by it and the close
01659   * fails, failbit is not set and no exception will be thrown.
01660   * Accordingly, if the user needs to know whether there was an error
01661   * in this method closing any managed stream, she should call close()
01662   * explicitly before calling this method.  This class does not offer
01663   * concurrent access from multiple threads to the same stream object,
01664   * and if that is required users should provide their own
01665   * synchronisation.
01666   *
01667   * @param stream A GIO input stream to be attached.  If the caller
01668   * wants the GIO input stream to survive a subsequent call to close()
01669   * or attach() or this class's destruction, the caller should keep a
01670   * separate GobjHandle object which references the stream (obtained
01671   * by, say, calling get_gio_stream()) and pass 'manage' as false.  If
01672   * this is a GFilterInputStream object (that is, a
01673   * GBufferedInputStream or GConverterInputStream stream), only the
01674   * underlying base input stream will be attached and the other higher
01675   * level streams will be closed (buffering of input streams is always
01676   * provided by the underlying C++ streambuffer, and converting is
01677   * controlled solely by the 'converter' argument).
01678   *
01679   * @param manage Whether the underlying streambuffer should call
01680   * g_input_stream_close() on the GIO stream in the streambuffer's
01681   * destructor or when another stream is attached.  Passing 'true' is
01682   * usually what is wanted - 'false' only makes sense if the caller
01683   * keeps a separate GobjHandle object which references the stream to
01684   * keep it alive (obtained by, say, calling get_gio_stream()).
01685   * Unlike its fdstreams equivalent, this parameter does not have a
01686   * default value of 'true': this is partly to make it less likely
01687   * that a converter is passed to this argument by mistake (that would
01688   * not normally cause a compiler warning because GobjHandle has a
01689   * type conversion operator providing the underlying C object by
01690   * pointer, so GobjHandles are type convertible to pointers, and such
01691   * a pointer will in turn provide a type match with a bool argument);
01692   * and partly to maintain compatibility with the constructor's
01693   * interface, which has separate syntactic constraints.
01694   *
01695   * @param converter A converter (if any) to be attached to the GIO
01696   * input stream (note that this does not affect the operation of
01697   * set_byteswap()).  The default value of an empty
01698   * GobjHandle<GConverter> object indicates no converter.
01699   *
01700   * @exception std::bad_alloc This method will throw std::bad_alloc if
01701   * memory is exhausted and the system throws on such exhaustion
01702   * (unless the library has been installed using the
01703   * --with-glib-memory-slices-compat or
01704   * --with-glib-memory-slices-no-compat configuration option, in which
01705   * case glib will terminate the program if it is unable to obtain
01706   * memory from the operating system).
01707   *
01708   * @note If a converter is provided, the stream will no longer be
01709   * seekable even if it otherwise would be, so tellg() and seekg()
01710   * will no longer work (they will return pos_type(off_type(-1)).
01711   */
01712   void attach(const GobjHandle<GInputStream>& stream,
01713               bool manage,
01714               const GobjHandle<GConverter>& converter = GobjHandle<GConverter>())
01715     {buf.attach_stream(stream, manage, converter); this->clear();}
01716 
01717  /**
01718   * Call g_input_stream_close() on the GIO stream at present attached
01719   * (if any), and release the underlying C++ streambuffer's reference
01720   * to that stream.  If the caller wants the GIO stream to survive the
01721   * call to this method (albeit in a closed state), the caller should,
01722   * before the call is made, keep a separate GobjHandle object which
01723   * references the stream.  If the close fails, the failbit will be
01724   * set with setstate(std::ios_base::failbit).  This class does not
01725   * offer concurrent access from multiple threads to the same stream
01726   * object, and if that is required users should provide their own
01727   * synchronisation.
01728   *
01729   * @exception std::ios_base::failure This exception will be thrown if
01730   * an error arises on closing the stream and such an exception has
01731   * been required by a call to the exceptions() method of this class
01732   * (inherited from std::basic_ios<>).  No exception will be thrown if
01733   * exceptions() has not been called.
01734   */
01735   void close() {if (!buf.close_stream()) this->setstate(std::ios_base::failbit);}
01736 
01737   /**
01738   * Get the GIO input stream at present attached (if any), by
01739   * GobjHandle.  If no stream has been attached, this method will
01740   * return an empty GobjHandle object.  Retaining the return value
01741   * will cause the GIO input stream to survive the destruction of this
01742   * object.  The return value may be a different stream from the one
01743   * originally passed to this object's constructor or to attach().  It
01744   * will be different if a converter has been attached to it.  This
01745   * method does not throw.  This class does not offer concurrent
01746   * access from multiple threads to the same stream object, and if
01747   * that is required users should provide their own synchronisation.
01748   *
01749   * @return The GIO input stream at present attached, or an empty
01750   * GobjHandle object if none has been attached
01751   */
01752   GobjHandle<GInputStream> get_gio_stream() const {return buf.get_istream();}
01753 
01754  /**
01755   * Causes the underlying streambuffer to swap bytes in the incoming
01756   * text, so as to convert big endian text to little endian text, or
01757   * little endian text to big endian text.  It is called by the user
01758   * in response to finding a byte order marker (BOM) 0xfffe (UTF-16)
01759   * or 0xfffe0000 (UTF-32) as the first character of a newly opened
01760   * file/stream, or if the user knows by some other means that the
01761   * native endianness of the machine doing the reading differs from
01762   * the endianness of the file/stream being read.  This only has
01763   * effect on wide character streams (for example, a wgistream
01764   * object), and not the gistream narrow character stream.  This
01765   * method does not throw.  This class does not offer concurrent
01766   * access from multiple threads to the same stream object, and if
01767   * that is required users should provide their own synchronisation.
01768   *
01769   * @param swap 'true' if byte swapping is to be turned on, 'false' if
01770   * it is to be turned off.  This will affect all characters extracted
01771   * from the underlying streambuffer after this call is made.  If a
01772   * previously extracted character is to be putback(), it must be put
01773   * back before this function is called (or unget() should be called
01774   * instead) to avoid a putback mismatch, because this call will
01775   * byte-swap anything already in the buffers.  (Characters extracted
01776   * after the call to this method may be putback normally.)
01777   */
01778   void set_byteswap(bool swap) {buf.set_byteswap(swap);}
01779 
01780 /**
01781  * This method indicates whether the attached GIO input stream
01782  * implements GSeekable, so that a call to tellg() or seekg() can
01783  * succeed.  Note that in the seekg(off_type off, ios_base::seekdir
01784  * dir) variant, on wide character streams the 'off' argument is
01785  * dimensioned as the number of wchar_t/char32_t/char16_t units not
01786  * the number of bytes (that is, it is bytes/sizeof(char_type)).  This
01787  * method does not throw.  This class does not offer concurrent access
01788  * from multiple threads to the same stream object, and if that is
01789  * required users should provide their own synchronisation.
01790  *
01791  * @return true if the attached GIO stream implements GSeekable,
01792  * otherwise false.  The result is only meaningful if a GIO stream has
01793  * been attached to this C++ stream object.
01794  */
01795   bool can_seek() const {return buf.can_seek();}
01796 
01797 /* Only has effect if --with-glib-memory-slices-compat or
01798  * --with-glib-memory-slices-no-compat option picked */
01799   CGU_GLIB_MEMORY_SLICES_FUNCS
01800 };
01801 
01802 
01803 
01804 /**
01805  * @headerfile gstream.h c++-gtk-utils/gstream.h
01806  * @brief C++ input-output stream for GIO streams
01807  * @sa gstreams
01808  * @ingroup gstreams
01809  *
01810  * This class provides standard iostream services for GIO streams.
01811  */
01812 template <class charT , class Traits = std::char_traits<charT> >
01813 class basic_giostream : public std::basic_iostream<charT, Traits> {
01814 
01815   basic_gstreambuf<charT , Traits> buf;
01816 
01817 public:
01818 /**
01819  * This class cannot be copied.  The copy constructor is deleted.
01820  */
01821   basic_giostream(const basic_giostream&) = delete;
01822 
01823 /**
01824  * This class cannot be copied.  The assignment operator is deleted.
01825  */
01826   basic_giostream& operator=(const basic_giostream&) = delete;
01827 
01828  /**
01829   * The constructor taking a GIO input-output stream.  This class does
01830   * not offer concurrent access from multiple threads to the same
01831   * stream object, and if that is required users should provide their
01832   * own synchronisation.
01833   *
01834   * @param stream A GIO input-output stream to be attached.  If the
01835   * caller wants the GIO stream to survive this class's destruction or
01836   * a call to close() or attach(), the caller should keep a separate
01837   * GobjHandle object which references the stream (obtained by, say,
01838   * calling get_gio_io_stream()) and pass 'manage' as false.
01839   *
01840   * @param manage Whether the underlying streambuffer should call
01841   * g_io_stream_close() on the GIO stream in the streambuffer's
01842   * destructor or when another stream is attached.  Passing 'true' is
01843   * usually what is wanted, and is particularly relevant on output
01844   * streams because unless g_io_stream_close() is called, GIO may not
01845   * commit to disk - 'false' only makes sense if the caller keeps a
01846   * separate GobjHandle object which references the stream to keep it
01847   * alive (obtained by, say, calling get_gio_io_stream()).  Unlike its
01848   * fdstreams equivalent, this parameter does not have a default value
01849   * of 'true': this is partly to make it less likely that a converter
01850   * is passed to this argument by mistake (that would not normally
01851   * cause a compiler warning because GobjHandle has a type conversion
01852   * operator providing the underlying C object by pointer, so
01853   * GobjHandles are type convertible to pointers, and such a pointer
01854   * will in turn provide a type match with a bool argument); and
01855   * partly because, given a GIOStream* p, the construction
01856   * \"Cgu::giostream str(Cgu::GobjHandle<GIOStream>(p));\" without
01857   * an additional argument or additional parentheses (or the use of
01858   * uniform initializer syntax using braces) would cause a compiler
01859   * error as it would be interpreted as a function declaration.
01860   *
01861   * @param input_converter A converter (if any) to be attached to the
01862   * input stream (note that this does not affect the operation of
01863   * set_byteswap()).  The default value of an empty
01864   * GobjHandle<GConverter> object indicates no converter.
01865   *
01866   * @param output_converter A converter (if any) to be attached to the
01867   * output stream.  The default value of an empty
01868   * GobjHandle<GConverter> object indicates no converter.
01869   *
01870   * @exception std::bad_alloc This constructor will throw
01871   * std::bad_alloc if memory is exhausted and the system throws on
01872   * such exhaustion (unless the library has been installed using the
01873   * --with-glib-memory-slices-compat or
01874   * --with-glib-memory-slices-no-compat configuration option, in which
01875   * case glib will terminate the program if it is unable to obtain
01876   * memory from the operating system).  No other exception will be
01877   * thrown unless the constructor of std::basic_streambuf,
01878   * std::basic_ostream or std::basic_istream throws.
01879   *
01880   * @note If a converter is provided, the stream will no longer be
01881   * seekable even if it otherwise would be, so tellg(), tellp(),
01882   * seekg() and seekp() will no longer work (they will return
01883   * pos_type(off_type(-1)).  If the stream to which a converter has
01884   * been attached represents a file on the file system (rather than a
01885   * socket), after a read has been made, no further write may be made
01886   * using the same GFileIOStream object.  These restrictions do not
01887   * apply to sockets (which are not seekable) so the use of converters
01888   * with input-output streams (GIOStream) should generally be
01889   * restricted to sockets.
01890   */
01891   // using uniform initializer syntax here confuses doxygen
01892   basic_giostream(const GobjHandle<GIOStream>& stream,
01893                   bool manage,
01894                   const GobjHandle<GConverter>& input_converter = GobjHandle<GConverter>(),
01895                   const GobjHandle<GConverter>& output_converter = GobjHandle<GConverter>()):
01896                                  std::basic_iostream<charT, Traits>(0),
01897                                  buf(stream, manage, input_converter, output_converter) {
01898     rdbuf(&buf);  // std::basic_ios is a virtual base class
01899   }
01900 
01901  /**
01902   * With this constructor, the GIO input-output stream must be
01903   * attached later with the attach() method.  It will not throw unless
01904   * the constructor of std::basic_streambuf, std::basic_ostream or
01905   * std::basic_istream throws.  This class does not offer concurrent
01906   * access from multiple threads to the same stream object, and if
01907   * that is required users should provide their own synchronisation.
01908   */
01909   // using uniform initializer syntax here confuses doxygen
01910   basic_giostream() : std::basic_iostream<charT, Traits>(0) {
01911     rdbuf(&buf);  // std::basic_ios is a virtual base class
01912   }
01913 
01914  /**
01915   * Attach a new GIO input-output stream to this object (and close any
01916   * GIO stream at present managed by it).  If output buffering was
01917   * previously switched off, it is switched back on again.  In the
01918   * case of wide character input-output streams, it also switches off
01919   * byte swapping on input, if it was previously on.  If any stream
01920   * state flags were set (eofbit, failbit or badbit), they will be
01921   * cleared by a call to clear().  If this method closes a stream at
01922   * present managed by it and the close fails, failbit is not set and
01923   * no exception will be thrown.  Accordingly, if the user needs to
01924   * know whether there was an error in this method closing any managed
01925   * stream, she should call close() explicitly before calling this
01926   * method.  This class does not offer concurrent access from multiple
01927   * threads to the same stream object, and if that is required users
01928   * should provide their own synchronisation.
01929   *
01930   * @param stream A GIO input-output stream to be attached.  If the
01931   * caller wants the GIO stream to survive a subsequent call to
01932   * close() or attach() or this class's destruction, the caller should
01933   * keep a separate GobjHandle object which references the stream
01934   * (obtained by, say, calling get_gio_io_stream()) and pass 'manage'
01935   * as false.
01936   *
01937   * @param manage Whether the underlying streambuffer should call
01938   * g_io_stream_close() on the GIO stream in the streambuffer's
01939   * destructor or when another stream is attached.  Passing 'true' is
01940   * usually what is wanted, and is particularly relevant on output
01941   * streams because unless g_io_stream_close() is called, GIO may not
01942   * commit to disk - 'false' only makes sense if the caller keeps a
01943   * separate GobjHandle object which references the stream to keep it
01944   * alive (obtained by, say, calling get_gio_io_stream()).  Unlike its
01945   * fdstreams equivalent, this parameter does not have a default value
01946   * of 'true': this is partly to make it less likely that a converter
01947   * is passed to this argument by mistake (that would not normally
01948   * cause a compiler warning because GobjHandle has a type conversion
01949   * operator providing the underlying C object by pointer, so
01950   * GobjHandles are type convertible to pointers, and such a pointer
01951   * will in turn provide a type match with a bool argument); and
01952   * partly to maintain compatibility with the constructor's interface,
01953   * which has separate syntactic constraints.
01954   *
01955   * @param input_converter A converter (if any) to be attached to the
01956   * input stream (note that this does not affect the operation of
01957   * set_byteswap()).  The default value of an empty
01958   * GobjHandle<GConverter> object indicates no converter.
01959   *
01960   * @param output_converter A converter (if any) to be attached to the
01961   * output stream.  The default value of an empty
01962   * GobjHandle<GConverter> object indicates no converter.
01963   *
01964   * @exception std::bad_alloc This method will throw std::bad_alloc if
01965   * memory is exhausted and the system throws on such exhaustion
01966   * (unless the library has been installed using the
01967   * --with-glib-memory-slices-compat or
01968   * --with-glib-memory-slices-no-compat configuration option, in which
01969   * case glib will terminate the program if it is unable to obtain
01970   * memory from the operating system).
01971   *
01972   * @note If a converter is provided, the stream will no longer be
01973   * seekable even if it otherwise would be, so tellg(), tellp(),
01974   * seekg() and seekp() will no longer work (they will return
01975   * pos_type(off_type(-1)).  If the stream to which a converter has
01976   * been attached represents a file on the file system (rather than a
01977   * socket), after a read has been made, no further write may be made
01978   * using the same GFileIOStream object.  These restrictions do not
01979   * apply to sockets (which are not seekable) so the use of converters
01980   * with input-output streams (GIOStream) should generally be
01981   * restricted to sockets.
01982   */
01983   void attach(const GobjHandle<GIOStream>& stream,
01984               bool manage,
01985               const GobjHandle<GConverter>& input_converter = GobjHandle<GConverter>(),
01986               const GobjHandle<GConverter>& output_converter = GobjHandle<GConverter>())
01987     {buf.attach_stream(stream, manage, input_converter, output_converter); this->clear();}
01988 
01989  /**
01990   * Call g_io_stream_close() on the GIO stream at present attached (if
01991   * any), and release the underlying C++ streambuffer's reference to
01992   * that stream.  If the caller wants the GIO stream to survive the
01993   * call to this method (albeit in a closed state), the caller should,
01994   * before the call is made, keep a separate GobjHandle object which
01995   * references the stream.  If the close fails, the failbit will be
01996   * set with setstate(std::ios_base::failbit).  This class does not
01997   * offer concurrent access from multiple threads to the same stream
01998   * object, and if that is required users should provide their own
01999   * synchronisation.
02000   *
02001   * @exception std::ios_base::failure This exception will be thrown if
02002   * an error arises on closing the stream and such an exception has
02003   * been required by a call to the exceptions() method of this class
02004   * (inherited from std::basic_ios<>).  No exception will be thrown if
02005   * exceptions() has not been called.
02006   */
02007   void close() {if (!buf.close_stream()) this->setstate(std::ios_base::failbit);}
02008 
02009   /**
02010   * Get the GIO input-output stream at present attached (if any), by
02011   * GobjHandle.  If no stream has been attached, this method will
02012   * return an empty GobjHandle object.  Retaining the return value
02013   * will cause the GIO input-output stream to survive the destruction
02014   * of this object.  This method does not throw.  This class does not
02015   * offer concurrent access from multiple threads to the same stream
02016   * object, and if that is required users should provide their own
02017   * synchronisation.
02018   *
02019   * @return The GIO input-output stream at present attached, or an
02020   * empty GobjHandle object if none has been attached
02021   */
02022   GobjHandle<GIOStream> get_gio_io_stream() const {return buf.get_iostream();}
02023 
02024  /**
02025   * Get the underlying GIO output stream at present attached (if any),
02026   * by GobjHandle.  If none has been attached, this method will return
02027   * an empty GobjHandle object.  Retaining the return value will cause
02028   * the GIO output stream to survive the destruction of this object.
02029   * The return value may be a different stream from the one kept by
02030   * the GIOStream object passed to this object's constructor or to
02031   * attach().  It will be different if a converter has been attached
02032   * to it.  This method does not throw.  This class does not offer
02033   * concurrent access from multiple threads to the same stream object,
02034   * and if that is required users should provide their own
02035   * synchronisation.
02036   *
02037   * @return The GIO output stream at present attached, or an empty
02038   * GobjHandle object if none has been attached
02039   */
02040   GobjHandle<GOutputStream> get_gio_output_stream() const {return buf.get_ostream();}
02041 
02042   /**
02043   * Get the GIO input stream at present attached (if any), by
02044   * GobjHandle.  If none has been attached, this method will return an
02045   * empty GobjHandle object.  Retaining the return value will cause
02046   * the GIO input stream to survive the destruction of this object.  The
02047   * return value may be a different stream from the one kept by the
02048   * GIOStream object passed to this object's constructor or to
02049   * attach().  It will be different if a converter has been attached
02050   * to it.  This method does not throw.  This class does not offer
02051   * concurrent access from multiple threads to the same stream object,
02052   * and if that is required users should provide their own
02053   * synchronisation.
02054   *
02055   * @return The GIO input stream at present attached, or an empty
02056   * GobjHandle object if none has been attached
02057   */
02058   GobjHandle<GInputStream> get_gio_input_stream() const {return buf.get_istream();}
02059 
02060  /**
02061   * Causes the underlying streambuffer to swap bytes in the incoming
02062   * text, so as to convert big endian text to little endian text, or
02063   * little endian text to big endian text.  It is called by the user
02064   * in response to finding a byte order marker (BOM) 0xfffe (UTF-16)
02065   * or 0xfffe0000 (UTF-32) as the first character of a newly opened
02066   * file/stream, or if the user knows by some other means that the
02067   * native endianness of the machine doing the reading differs from
02068   * the endianness of the file/stream being read.  This only has
02069   * effect on wide character streams for input (for example, a
02070   * wgiostream object), and not the giostream narrow character stream.
02071   * Note also that characters held for output are always outputted in
02072   * native endian format unless a GConverter object has been attached,
02073   * and this method does not affect that.  This method does not throw.
02074   * This class does not offer concurrent access from multiple threads
02075   * to the same stream object, and if that is required users should
02076   * provide their own synchronisation.
02077   *
02078   * @param swap 'true' if byte swapping for input is to be turned on,
02079   * 'false' if it is to be turned off.  This will affect all
02080   * characters extracted from the underlying streambuffer after this
02081   * call is made.  If a previously extracted character is to be
02082   * putback(), it must be put back before this function is called (or
02083   * unget() should be called instead) to avoid a putback mismatch,
02084   * because this call will byte-swap anything already in the buffers.
02085   * (Characters extracted after the call to this method may be putback
02086   * normally.)
02087   */
02088   void set_byteswap(bool swap) {buf.set_byteswap(swap);}
02089 
02090 /**
02091  * This method converts the attached GIO input-output stream to an
02092  * unbuffered stream for output if 'buffered' is false, or back to a
02093  * buffered stream if buffering has previously been switched off and
02094  * 'buffered' is true.  Buffering is on by default for any newly
02095  * created giostream object and any newly attached GIO input-output
02096  * stream.  If buffering is turned off, all characters at present in
02097  * the buffers which are stored for output are flushed (but if writing
02098  * to a file which is being written over/replaced, output may not
02099  * appear in the destination until the GIO stream is closed).  This
02100  * method has no effect if no GIO input-output stream has yet been
02101  * attached.  Switching output buffering off is similar in effect to
02102  * setting the std::ios_base::unitbuf flag, except that switching
02103  * buffering off is slightly more efficient, and setting the
02104  * std::ios_base::unitbuf flag will not retain the automatic tying of
02105  * logical and actual file positions that occurs when output buffering
02106  * is switched off, as explained @ref GioRandomAccessAnchor "here".
02107  * This class does not offer concurrent access from multiple threads
02108  * to the same stream object, and if that is required users should
02109  * provide their own synchronisation.
02110  *
02111  * @param buffered 'false' if buffering for output is to be turned
02112  * off, 'true' if it is to be turned back on.
02113  *
02114  * @exception std::bad_alloc This method will throw std::bad_alloc if
02115  * 'buffered' is true, output buffering had previously been switched
02116  * off, memory is exhausted and the system throws on such exhaustion
02117  * (unless the library has been installed using the
02118  * --with-glib-memory-slices-compat or
02119  * --with-glib-memory-slices-no-compat configuration option, in which
02120  * case glib will terminate the program if it is unable to obtain
02121  * memory from the operating system).
02122  */
02123   void set_output_buffered(bool buffered) {buf.set_output_buffered(buffered);}
02124 
02125 /**
02126  * This method indicates whether the attached GIO stream implements
02127  * GSeekable, so that a call to tellg(), tellp(), seekg() or seekp()
02128  * can succeed.  Note that in the seekg(off_type off,
02129  * ios_base::seekdir dir) and seekp(off_type off, ios_base::seekdir
02130  * dir) variants, on wide character streams the 'off' argument is
02131  * dimensioned as the number of wchar_t/char32_t/char16_t units not
02132  * the number of bytes (that is, it is bytes/sizeof(char_type)).  This
02133  * method does not throw.  This class does not offer concurrent access
02134  * from multiple threads to the same stream object, and if that is
02135  * required users should provide their own synchronisation.
02136  *
02137  * @return true if the attached GIO stream implements GSeekable,
02138  * otherwise false.  The result is only meaningful if a GIO stream has
02139  * been attached to this C++ stream object.
02140  */
02141   bool can_seek() const {return buf.can_seek();}
02142 
02143 /* Only has effect if --with-glib-memory-slices-compat or
02144  * --with-glib-memory-slices-no-compat option picked */
02145   CGU_GLIB_MEMORY_SLICES_FUNCS
02146 };
02147 
02148 /**
02149  * @defgroup gstreams gstreams
02150  */
02151 /**
02152  * @typedef gstreambuf.
02153  * @brief C++ stream buffer for GIO streams for char type
02154  * @ingroup gstreams
02155  */
02156 typedef basic_gstreambuf<char> gstreambuf;
02157 
02158 /**
02159  * @typedef gistream.
02160  * @brief C++ input stream for GIO streams for char type
02161  * @anchor gistreamAnchor
02162  * @ingroup gstreams
02163  */
02164 typedef basic_gistream<char> gistream;
02165 
02166 /**
02167  * @typedef gostream.
02168  * @brief C++ output stream for GIO streams for char type
02169  * @anchor gostreamAnchor
02170  * @ingroup gstreams
02171  */
02172 typedef basic_gostream<char> gostream;
02173 
02174 /**
02175  * @typedef giostream.
02176  * @brief C++ input/output stream for GIO streams for char type
02177  * @anchor giostreamAnchor
02178  * @ingroup gstreams
02179  */
02180 typedef basic_giostream<char> giostream;
02181 
02182 /**
02183  * @typedef wgstreambuf.
02184  * @brief C++ stream buffer for GIO streams for wchar_t type
02185  * @ingroup gstreams
02186  */
02187 typedef basic_gstreambuf<wchar_t> wgstreambuf;
02188 
02189 /**
02190  * @typedef wgistream.
02191  * @brief C++ input stream for GIO streams for wchar_t type
02192  * @anchor wgistreamAnchor
02193  * @ingroup gstreams
02194  */
02195 typedef basic_gistream<wchar_t> wgistream;
02196 
02197 /**
02198  * @typedef wgostream.
02199  * @brief C++ output stream for GIO streams for wchar_t type
02200  * @anchor wgostreamAnchor
02201  * @ingroup gstreams
02202  */
02203 typedef basic_gostream<wchar_t> wgostream;
02204 
02205 /**
02206  * @typedef wgiostream.
02207  * @brief C++ input/output stream for GIO streams for wchar_t type
02208  * @anchor wgiostreamAnchor
02209  * @ingroup gstreams
02210  */
02211 typedef basic_giostream<wchar_t> wgiostream;
02212 
02213 /**
02214  * @typedef u16gstreambuf.
02215  * @brief C++ stream buffer for GIO streams for char16_t type
02216  * @ingroup gstreams
02217  */
02218 typedef basic_gstreambuf<char16_t> u16gstreambuf;
02219 
02220 /**
02221  * @typedef u16gistream.
02222  * @brief C++ input stream for GIO streams for char16_t type
02223  * @anchor u16gistreamAnchor
02224  * @ingroup gstreams
02225  */
02226 typedef basic_gistream<char16_t> u16gistream;
02227 
02228 /**
02229  * @typedef u16gostream.
02230  * @brief C++ output stream for GIO streams for char16_t type
02231  * @anchor u16gostreamAnchor
02232  * @ingroup gstreams
02233  */
02234 typedef basic_gostream<char16_t> u16gostream;
02235 
02236 /**
02237  * @typedef u16giostream.
02238  * @brief C++ input/output stream for GIO streams for char16_t type
02239  * @anchor u16giostreamAnchor
02240  * @ingroup gstreams
02241  */
02242 typedef basic_giostream<char16_t> u16giostream;
02243 
02244 /**
02245  * @typedef u32gstreambuf.
02246  * @brief C++ stream buffer for GIO streams for char32_t type
02247  * @ingroup gstreams
02248  */
02249 typedef basic_gstreambuf<char32_t> u32gstreambuf;
02250 
02251 /**
02252  * @typedef u32gistream.
02253  * @brief C++ input stream for GIO streams for char32_t type
02254  * @anchor u32gistreamAnchor
02255  * @ingroup gstreams
02256  */
02257 typedef basic_gistream<char32_t> u32gistream;
02258 
02259 /**
02260  * @typedef u32gostream.
02261  * @brief C++ output stream for GIO streams for char32_t type
02262  * @anchor u32gostreamAnchor
02263  * @ingroup gstreams
02264  */
02265 typedef basic_gostream<char32_t> u32gostream;
02266 
02267 /**
02268  * @typedef u32giostream.
02269  * @brief C++ input/output stream for GIO streams for char32_t type
02270  * @anchor u32giostreamAnchor
02271  * @ingroup gstreams
02272  */
02273 typedef basic_giostream<char32_t> u32giostream;
02274 
02275 } // namespace Cgu
02276 
02277 #include <c++-gtk-utils/gstream.tpp>
02278 
02279 #else
02280 #warning gstreams are not available: glib >= 2.16.0 is required
02281 #endif /*GLIB_CHECK_VERSION(2,16,0)*/
02282 
02283 #endif /*CGU_GSTREAM_H*/