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