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