c++-gtk-utils

gstream.h

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