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