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