c++-gtk-utils: gstream.h Source File

c++-gtk-utils

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

gstream.h
Go to the documentation of this file.
1 /* Copyright (C) 2010 to 2017 Chris Vine
2
3
4 The library comprised in this file or of which this file is part is
5 distributed by Chris Vine under the GNU Lesser General Public
6 License as follows:
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public License
10 as published by the Free Software Foundation; either version 2.1 of
11 the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public
19 License, version 2.1, along with this library (see the file LGPL.TXT
20 which came with this source code package in the c++-gtk-utils
21 sub-directory); if not, write to the Free Software Foundation, Inc.,
22 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23
24 However, it is not intended that the object code of a program whose
25 source code instantiates a template from this file or uses macros or
26 inline functions (of any length) should by reason only of that
27 instantiation or use be subject to the restrictions of use in the GNU
28 Lesser General Public License. With that in mind, the words "and
29 macros, inline functions and instantiations of templates (of any
30 length)" shall be treated as substituted for the words "and small
31 macros and small inline functions (ten lines or less in length)" in
32 the fourth paragraph of section 5 of that licence. This does not
33 affect any other reason why object code may be subject to the
34 restrictions in that licence (nor for the avoidance of doubt does it
35 affect the application of section 2 of that licence to modifications
36 of the source code in this file).
37 */
38
39 /**
40 * @defgroup gstreams gstreams
41 *
42 * \#include <c++-gtk-utils/gstream.h>
43 *
44 * The c++-gtk-utils library contains C++ classes providing a
45 * streambuffer and stream objects interfacing with GIO streams.
46 *
47 * Normally 'true' would be passed as the second (manage) argument of
48 * the gostream/gistream/giostream constructors or of the attach()
49 * methods, so that the destructors of these classes close the GIO
50 * streams concerned, which helps exception safety (the attach()
51 * method will also close any previous GIO stream). If this behaviour
52 * is not wanted, pass 'false' instead to that argument. The same
53 * applies to the wide stream classes.
54 *
55 * C++ stream objects are not suitable for asynchronous input and
56 * output. On sockets and pipes or other special devices, they may
57 * block on a read or write until the read or write request has been
58 * satisfied. In circumstances where asynchronous input and output is
59 * wanted, it will be necessary to start a new thread in which to
60 * carry out the input and output operations (which is what GIO does
61 * behind the scenes on its asynchronous operations) or use the GIO
62 * interfaces directly.
63 *
64 * Here are some examples of use:
65 *
66 * @code
67 * // open file for input, another for output, and make the
68 * // output file a gzipped copy of the input (gzipping a
69 * // file doesn't get much easier than this)
70 * Cgu::gistream input;
71 * Cgu::gostream output;
72 * Cgu::GobjHandle<GFile> file_in(g_file_new_for_path("filename"));
73 * GFileInputStream* is = g_file_read(file_in, 0, 0);
74 * if (is)
75 * input.attach(Cgu::GobjHandle<GInputStream>(G_INPUT_STREAM(is)), // takes ownership of 'is'
76 * true);
77 * else {
78 * std::cerr << "Can't open file 'filename'" << std::endl;
79 * return;
80 * }
81 * Cgu::GobjHandle<GFile> file_out(g_file_new_for_path("filename.gz"));
82 * GFileOutputStream* os = g_file_replace(file_out, 0, false,
83 * G_FILE_CREATE_REPLACE_DESTINATION,
84 * 0, 0);
85 * if (os) {
86 * output.attach(Cgu::GobjHandle<GOutputStream>(G_OUTPUT_STREAM(os)), // takes ownership of 'os'
87 * true,
88 * Cgu::GobjHandle<GConverter>(
89 * G_CONVERTER(g_zlib_compressor_new(G_ZLIB_COMPRESSOR_FORMAT_GZIP, -1)))
90 * );
91 * }
92 * else {
93 * std::cerr << "Can't create file 'filename.gz'" << std::endl;
94 * return;
95 * }
96 * // this does the copying, and is shorthand for creating your own buffer
97 * // and calling std::istream::read() and std::ostream::write() on it
98 * output << input.rdbuf();
99 *
100 * --------------------------------------------------------------------
101 *
102 * // establish a TCP socket on localhost, listen for connections on port
103 * // 1200 and receive whitespace-separated words for processing
104 * using Cgu::GobjHandle;
105 * GobjHandle<GInetAddress> i(g_inet_address_new_loopback(G_SOCKET_FAMILY_IPV4));
106 * GobjHandle<GSocketAddress> a(g_inet_socket_address_new(i, 1200));
107 * GobjHandle<GSocketListener> l(g_socket_listener_new());
108 *
109 * gboolean success = g_socket_listener_add_address(l,
110 * a,
111 * G_SOCKET_TYPE_STREAM,
112 * G_SOCKET_PROTOCOL_TCP,
113 * 0, 0, 0);
114 * if (!success) {
115 * std::cerr << "Can't bind socket on localhost" << std::endl;
116 * return;
117 * }
118 *
119 * GSocketConnection* c = g_socket_listener_accept(l, 0, 0, 0);
120 * if (!c) {
121 * std::cerr << "Can't listen on localhost" << std::endl;
122 * return;
123 * }
124 *
125 * Cgu::giostream sock_strm(GobjHandle<GIOStream>(G_IO_STREAM(c)), true); // takes ownership of c
126 * sock_strm.set_output_buffered(false);
127 * std::cout << "Connection accepted" << std::endl;
128 *
129 * std::string str;
130 * while (sock_strm >> str) {
131 * [ ... do something with the word in str ... ]
132 * // acknowledge the client
133 * sock_strm << "ACK\n";
134 * }
135 *
136 * --------------------------------------------------------------------
137 *
138 * // read line delimited text from a pipe until it is closed by the
139 * // writer: assume 'fd' is the read file descriptor of the pipe
140 * // (in real life you would probably want to use a Cgu::fdistream
141 * // object in this usage and bypass GIO)
142 * Cgu::gistream istrm(Cgu::GobjHandle<GInputStream>(g_unix_input_stream_new(fd, true)), true);
143 * if (!istrm.get_gio_stream().get()) {
144 * std::cerr << "Can't create gio file-descriptor input stream" << std::endl;
145 * return;
146 * }
147 * std::string line;
148 * while (std::getline(istrm, line)) {
149 * [ ... do something with the read text ... ]
150 * }
151 * @endcode
152 *
153 *
154 * @note 1. Users cannot (except by derivation) use the virtual
155 * protected methods of the streambuffer classes, including xsgetn()
156 * and xsputn(). Instead, if they want direct access to the
157 * streambuffer other than through the gostream/gistream/giostream
158 * methods (or their wide stream equivalents), they should use the
159 * public forwarding functions provided by std::streambuf base class.
160 * @note 2. These streambuffers and stream objects are not copiable.
161 * @note 3. The base glib requirement for the c++-gtk-utils library is
162 * glib >= 2.10.0, but the gstreams component will only be available
163 * if glib >= 2.16.0 is installed.
164 *
165 * Buffering
166 * ---------
167 *
168 * The classes implement buffering on input streams and (unless output
169 * buffering is switched off) on output streams. They implement the
170 * buffering internally and do not use GBufferedInputStream and
171 * GBufferedOutputStream. This has a number of efficiency advantages
172 * and also retains random access, on devices that support it, for
173 * buffered streams (GBufferedInputStream and GBufferedOutputStream do
174 * not do so). So far as concerns random access on GIOStream objects,
175 * which are opened for both read and write, see
176 * @ref GioRandomAccessAnchor "giostream and random access"
177 *
178 * The streambuf class provides a block read and write in xsgetn() and
179 * xsputn(), which will be called by the read() and write() methods
180 * (and some other output operators) inherited by gistream, gostream
181 * and giostream (and their wide stream equivalents) from
182 * std::basic_istream and std::basic_ostream. They operate (after
183 * appropriately vacating and resetting the buffers) by doing a block
184 * read and write directly to and from the target, and are very
185 * efficient for large block reads (those significantly exceeding the
186 * buffer size). If users want all reads and writes to go through the
187 * buffers, by using std::basic_streambuf<>::xsputn() and
188 * std::basic_streambuf<>::xsgetn() then the symbol
189 * CGU_GSTREAM_USE_STD_N_READ_WRITE can be defined. (libstdc++-3
190 * provides efficient inbuilt versions of these std::basic_streambuf
191 * functions for block reads not significantly larger than the buffer
192 * size, provided output buffering has not been turned off by the
193 * set_output_buffered() method of these classes.)
194 *
195 * @b Note @b however that if CGU_GSTREAM_USE_STD_N_READ_WRITE is to
196 * be defined, it is best to do this by textually amending the
197 * installed gstream.h header file rather than by defining the symbol
198 * in user code before that file is included. This will ensure that
199 * all source files in a program which include the gstream.h header
200 * are guaranteed to see the same definitions so that the C++
201 * standard's one-definition-rule is complied with.
202 *
203 * One possible case for defining that symbol is where the user wants
204 * to use the tie() method of gistream or giostream (inherited from
205 * std::basic_ios) to procure flushing of an output stream before
206 * extraction from an input stream is made by gistream::read() or
207 * giostream::read() (and likewise their wide stream equivalents).
208 * Such flushing might not occur where a call to read() is made unless
209 * CGU_GSTREAM_USE_STD_N_READ_WRITE is defined, because an
210 * implementation is permitted to defer such flushing until
211 * underflow() occurs, and the block read by read(), as forwarded to
212 * xsgetn(), will never invoke underflow() if that symbol is not
213 * defined. (Having said that, any basic_istream implementation which
214 * does defer output flushing until underflow() is called makes tie()
215 * unusable anyway for a number of purposes, because the time of
216 * flushing would become dependent on whether a read request can be
217 * satisfied by what is already in the buffers.)
218 *
219 * 4 characters are stored and available for putback. However, if the
220 * symbol CGU_GSTREAM_USE_STD_N_READ_WRITE is not defined, then a call
221 * to gstreambuf::xsgetn() via gistream::read() or giostream::read()
222 * (or their wide stream equivalents) with a request for less than 4
223 * characters will result in less than 4 characters available for
224 * putback (if these block read methods obtain some characters but
225 * less than 4, only the number of characters obtained by them is
226 * guaranteed to be available for putback).
227 *
228 * @anchor GioRandomAccessAnchor
229 * giostream and random access
230 * ---------------------------
231 *
232 * For GIO objects which implement GSeekable (which are GFileIOStream,
233 * GFileInputStream, GFileOutputStream, GMemoryInputStream and
234 * GMemoryOutputStream), the classes in this c++-gtk-utils library
235 * implement the tellg(), tellp(), seekg() and seekp() random access
236 * methods.
237 *
238 * The presence of buffering does not impede this where a stream is
239 * only opened for reading or only opened for writing. However, it
240 * presents complications if the giostream class or its wide stream
241 * equivalents are to be used with a GFIleIOStream object
242 * (GFileIOStream objects are opened for both read and write).
243 * Because the classes employ buffering of input, and optional
244 * buffering of output, the logical file position (the file position
245 * expected by the user from the reads and writes she has made) will
246 * usually differ from the actual file position seen by the underlying
247 * operating system. The gstreambuf class provided by this library
248 * implements intelligent tying between input and output streams for
249 * GFileIOStream objects which means that if output has been made
250 * unbuffered by a call to set_output_buffered(false) and no converter
251 * has been attached, all reads and writes onto the file system from
252 * the same giostream object (or its wide stream equivalents) will be
253 * made at the expected logical position.
254 *
255 * This cannot be done by the gstreambuf class where the output stream
256 * is set as buffered (the default). In that case, if the last
257 * operation on a giostream object 'strm' (or its wide stream
258 * equivalents) was a read, before the first write operation
259 * thereafter is made on it, the user should call
260 * strm.seekg(strm.tellg()) or strm.seekp(strm.tellp()) (the two have
261 * the same effect), in order to synchronise the logical and actual
262 * file positions, or if the user does not want to maintain the
263 * current logical file position, make some other call to seekg() or
264 * seekp() which does not comprise only seekg(0, std::ios_base::cur)
265 * or seekp(0, std::ios_base::cur). Many std::basic_iostream
266 * implementations, as inherited by Cgu::giostream, will synchronise
267 * positions automatically on seekable streams via their sentry
268 * objects in order to provide support for buffered random access on
269 * their std::basic_fstream class (gcc's libstdc++ library does this,
270 * for example), making these steps unnecessary, but following these
271 * steps will provide maximum portability.
272 *
273 * If a GFileIOStream object attached to a giostream object (or its
274 * wide stream equivalents) is not seekable (that is, can_seek()
275 * returns false), say because an input or output converter has been
276 * attached or the filesystem is a network file system, no random
277 * access may be attempted. In particular, the tellg(), tellp(),
278 * seekg() and seekp() methods will not work (they will return
279 * pos_type(off_type(-1))). Furthermore, if a giostream object (or
280 * its wide stream equivalents) which manages a GFileIOStream object
281 * (as opposed to a socket) has a converter attached or is not
282 * seekable for some other reason, then after a read has been made no
283 * further write may be made using the same GFileIOStream object, so
284 * the use of converters with giostream objects and their wide stream
285 * equivalents should generally be restricted to use with sockets
286 * (GSocketConnection objects) only. Where converters are used with
287 * files on a filesystem, it is best to use the gostream and gistream
288 * classes (or their wide stream equivalents), and to close one stream
289 * before opening the other where they address the same file.
290 *
291 * None of these restrictions applies to GSocketConnection objects
292 * obtained by a call to g_socket_listener_accept() or
293 * g_socket_client_connect(), or obtained in some other way, as these
294 * do not maintain file pointers. They can be attached to a giostream
295 * object or its wide stream equivalents, with or without a converter,
296 * without any special precautions being taken, other than the normal
297 * step of calling giostream::flush() (or using the std::flush
298 * manipulator) to flush the output buffer to the socket if the user
299 * needs to know that that has happened (or setting output buffering
300 * off with the set_output_buffered() method). In summary, on a
301 * socket, a read does not automatically flush the output buffer: it
302 * is for the user to do that.
303 *
304 * Wide streams and endianness
305 * ---------------------------
306 *
307 * This library provides typedef'ed instances of the template classes
308 * for wchar_t, char16_t and char32_t characters (but see below under
309 * "other wide stream issues" for more about the char16_t and char32_t
310 * typedefs). Unless a converter is attached (for, say, UTF-32LE to
311 * UTF-32BE, or vice versa), with these wide character classes wide
312 * characters are written out in the native endian format of the
313 * writing machine. Whether or not a converter from one endianness to
314 * another is attached, special steps need to be taken if the text
315 * which is sent for output might be read by machines of unknown
316 * endianness.
317 *
318 * No such special steps are required where the wide character classes
319 * are used with temporary files, pipes, fifos, unix domain sockets
320 * and network sockets on localhost, because in those cases they will
321 * be read by the same machine that writes; but they are required
322 * where sockets communicate with other computers over a network or
323 * when writing to files which may be distributed to and read by other
324 * computers with different endianness.
325 *
326 * Where wide characters are to be exported to other machines, one
327 * useful approach is to convert to and from UTF-8 using the
328 * conversion functions in the Cgu::Utf8 namespace, and to use
329 * gostream/gistream/giostream with the converted text, or to attach a
330 * converter for UTF-8, generated by GIO's g_charset_converter_new(),
331 * directly to a wgostream, wgistream or wgiostream object.
332 *
333 * Instead of converting exported text to UTF-8, another approach is
334 * to use a byte order marker (BOM) as the first character of the wide
335 * stream output. UCS permits a BOM character to be inserted,
336 * comprising static_cast<wchar_t>(0xfeff),
337 * static_cast<char16_t>(0xfeff) or static_cast<char32_t>(0xfeff), at
338 * the beginning of the output to the wide character stream. At the
339 * receiving end, this will appear as 0xfffe (UTF-16) or 0xfffe0000
340 * (UTF-32) to a big endian machine with 8 bit char type if the text
341 * is little endian, or to a little endian machine with big endian
342 * text, so signaling a need to undertake byte swapping of text read
343 * from the stream. Another alternative is to label the physical
344 * medium conveying the file as UTF-16LE, UTF-16BE, UTF-32LE or
345 * UTF-32BE, as the case may be, in which case a BOM character should
346 * not be prepended.
347 *
348 * Where it is established by either means that the input stream
349 * requires byte swapping, the wide character input stream and wide
350 * character input streambuffer classes have a set_byteswap() member
351 * function which should be called on opening the input stream as soon
352 * as it has been established that byte swapping is required. Once
353 * this function has been called with an argument of 'true', all
354 * further calls to stream functions which provide characters will
355 * provide those characters with the correct native endianness.
356 * Calling set_byteswap() on the narrow stream gistream, giostream and
357 * gstreambuf objects has no effect (byte order is irrelevant to
358 * narrow streams).
359 *
360 * Here is an example of such use in a case where sizeof(wchar_t) is
361 * 4:
362 *
363 * @code
364 * using Cgu::GobjHandle;
365 * Cgu::wgistream input;
366 * GobjHandle<GFile> file_in(g_file_new_for_path("filename"));
367 * GFileInputStream* is = g_file_read(file_in, 0, 0);
368 * if (is)
369 * input.attach(GobjHandle<GInputStream>(G_INPUT_STREAM(is)), true); // takes ownership of 'is'
370 * else {
371 * std::cerr << "Can't open file 'filename'"
372 * << std::endl;
373 * return;
374 * }
375 * wchar_t item;
376 * input.get(item);
377 * if (!input) {
378 * std::cerr << "File 'filename' is empty" << std::endl;
379 * return;
380 * }
381 * if (item == static_cast<wchar_t>(0xfffe0000))
382 * input.set_byteswap(true);
383 * else if (item != static_cast<wchar_t>(0xfeff)) {
384 * // calling set_byteswap() will manipulate the buffers, so
385 * // either call putback() before we call set_byteswap(), or
386 * // call unget() instead
387 * input.putback(item);
388 * // the first character is not a BOM character so assume big endian
389 * // format, and byte swap if the local machine is little endian
390 * #if G_BYTE_ORDER == G_LITTLE_ENDIAN
391 * input.set_byteswap(true);
392 * #endif
393 * }
394 * [ ... do something with the input file ... ]
395 * @endcode
396 *
397 * Other wide stream issues
398 * ------------------------
399 *
400 * basic_gstreambuf objects can be instantiated for any integer type
401 * which has an appropriate traits class provided for it which has the
402 * copy(), eof(), eq_int_type(), move(), not_eof() and to_int_type()
403 * static member functions. The integer type could in fact have any
404 * size, but the set_byteswap() methods for basic_gistream,
405 * basic_giostream and basic_gstreambuf will only have an effect if
406 * its size is either 2 or 4. Typedef'ed instances of the
407 * basic_gstreambuf class are provided by the library for characters
408 * of type wchar_t, char16_t and char32_t.
409 *
410 * basic_gostream, basic_gistream and basic_giostream objects can be
411 * instantiated for the wchar_t type, and there are
412 * wgostream. wgistream and wgiostream typedefs for these.
413 *
414 * In addition there are u16gistream, u16gostream, u16giostream,
415 * u32gistream, u32gostream and u32giostream typedefs for the
416 * corresponding char16_t and char32_t types. However these stream
417 * typedefs for char16_t and char32_t are more problematic, because to
418 * invoke them it is necessary for ctype (and other) facets to be
419 * provided for them. gcc's libstdc++ and clang's libc++ do not
420 * supply these (they only supply them for the wchar_t type): it would
421 * therefore for the user to provide them herself.
422 *
423 * gtkmm users
424 * -----------
425 *
426 * gtkmm/giomm does not provide C++ streams for GIO objects: instead,
427 * it provides a literal function-for-function wrapping. However,
428 * giomm users can use the stream classes provided by this library by
429 * converting the relevant Glib::RefPtr object to a Cgu::GobjHandle
430 * object. This can be done as follows:
431 *
432 * @code
433 * // Glib::RefPtr<Gio::InputStream> to Cgu::GobjHandle<GInputStream>
434 * inline
435 * Cgu::GobjHandle<GInputStream> giomm_input_convert(const Glib::RefPtr<Gio::InputStream>& in) {
436 * return Cgu::GobjHandle<GInputStream>(static_cast<GInputStream*>(g_object_ref(in.operator->()->gobj())));
437 * }
438 *
439 * // Glib::RefPtr<Gio::OutputStream> to Cgu::GobjHandle<GOutputStream>
440 * inline
441 * Cgu::GobjHandle<GOutputStream> giomm_output_convert(const Glib::RefPtr<Gio::OutputStream>& out) {
442 * return Cgu::GobjHandle<GOutputStream>(static_cast<GOutputStream*>(g_object_ref(out.operator->()->gobj())));
443 * }
444 *
445 * // Glib::RefPtr<Gio::IOStream> to Cgu::GobjHandle<GIOStream>
446 * inline
447 * Cgu::GobjHandle<GIOStream> giomm_io_convert(const Glib::RefPtr<Gio::IOStream>& io) {
448 * return Cgu::GobjHandle<GIOStream>(static_cast<GIOStream*>(g_object_ref(io.operator->()->gobj())));
449 * }
450 *
451 * // example printing a text file to stdout with file opened with giomm
452 * Glib::RefPtr<Gio::File> file = Gio::File::create_for_path("filename");
453 * Glib::RefPtr<Gio::InputStream> is = file->read();
454 *
455 * Cgu::gistream filein(giomm_input_convert(is), true);
456 *
457 * std::string line;
458 * while (std::getline(filein, line)) {
459 * std::cout << line << '\n';
460 * }
461 * @endcode
462 */
463
464 #ifndef CGU_GSTREAM_H
465 #define CGU_GSTREAM_H
466
467 #include <glib.h>
468
469 #if defined(DOXYGEN_PARSING) || GLIB_CHECK_VERSION(2,16,0)
470
471 // see above for what this does
472 //#define CGU_GSTREAM_USE_STD_N_READ_WRITE 1
473
474 #include <istream>
475 #include <ostream>
476 #include <streambuf>
477 #include <algorithm>
478 #include <string>
479 #include <cstddef>
480
481 #include <glib.h>
482 #include <glib-object.h>
483 #include <gio/gio.h>
484
485 #include <c++-gtk-utils/gobj_handle.h>
486 #include <c++-gtk-utils/shared_handle.h>
487 #include <c++-gtk-utils/gerror_handle.h>
488 #include <c++-gtk-utils/cgu_config.h>
489
490 namespace Cgu {
491
492 /*
493 The following convenience typedefs appear at the end of this file:
494 typedef basic_gstreambuf<char> gstreambuf;
495 typedef basic_gistream<char> gistream;
496 typedef basic_gostream<char> gostream;
497 typedef basic_giostream<char> giostream;
498 typedef basic_gstreambuf<wchar_t> wgstreambuf;
499 typedef basic_gistream<wchar_t> wgistream;
500 typedef basic_gostream<wchar_t> wgostream;
501 typedef basic_giostream<wchar_t> wgiostream;
502 typedef basic_gstreambuf<char16_t> u16gstreambuf;
503 typedef basic_gistream<char16_t> u16gistream;
504 typedef basic_gostream<char16_t> u16gostream;
505 typedef basic_giostream<char16_t> u16giostream;
506 typedef basic_gstreambuf<char32_t> u32gstreambuf;
507 typedef basic_gistream<char32_t> u32gistream;
508 typedef basic_gostream<char32_t> u32gostream;
509 typedef basic_giostream<char32_t> u32giostream;
510 */
511
512
513 /**
514 * @headerfile gstream.h c++-gtk-utils/gstream.h
515 * @brief C++ stream buffer for GIO streams
516 * @sa gstreams
517 * @ingroup gstreams
518 *
519 * This class provides a stream buffer for interfacing with GIO
520 * streams. It does the buffering for the basic_gostream,
521 * basic_gistream and basic_giostream stream classes.
522 */
523
524 template <class charT , class Traits = std::char_traits<charT> >
525 class basic_gstreambuf: public std::basic_streambuf<charT, Traits> {
526
527 public:
528 typedef charT char_type;
529 typedef Traits traits_type;
530 typedef typename traits_type::int_type int_type;
531 typedef typename traits_type::pos_type pos_type;
532 typedef typename traits_type::off_type off_type;
533
534 private:
535 GobjHandle<GInputStream> input_stream;
536 GobjHandle<GOutputStream> output_stream;
537 GobjHandle<GIOStream> io_stream;
538
539 bool manage;
540 bool byteswap;
541 bool seek_mismatch;
542 bool seekable;
543
544 static const int output_buf_size = 1024; // size of the data write buffer
545 static const int putback_size = 4; // size of read putback area
546 static const int input_buf_size = 1024; // size of the data read buffer
547
548 #if defined(CGU_USE_GLIB_MEMORY_SLICES_COMPAT) || defined(CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT)
549 ScopedHandle<char_type*,
550 GSliceFreeSize<(input_buf_size + putback_size) * sizeof(char_type)>> input_buffer;
551 ScopedHandle<char_type*,
552 GSliceFreeSize<output_buf_size * sizeof(char_type)>> output_buffer;
553 #else
554 ScopedHandle<char_type*> input_buffer;
555 ScopedHandle<char_type*> output_buffer;
556 #endif
557
558 static void swap_element(char_type&);
559 GobjHandle<GInputStream> find_base_input_stream(const GobjHandle<GInputStream>&);
560 GobjHandle<GOutputStream> find_base_output_stream(const GobjHandle<GOutputStream>&);
561 void reset_input_buffer_pointers();
562 int flush_buffer();
563 bool wind_back_input_buffer();
564 bool is_input_stored();
565 bool is_output_stored();
566 void set_input_error(GError*);
567 void set_output_error(GError*);
568
569 protected:
570 /**
571 * This method will not throw. This means that the input functions of
572 * stream objects which have this streambuffer as a member will not
573 * throw unless the underlying functions of the std::basic_istream
574 * class throw, which they would not normally do unless they have been
575 * required to do so on failbit, badbit or eofbit being set by an
576 * explicit call to the exceptions() method of that class. This class
577 * does not offer concurrent access from multiple threads to the same
578 * stream object, and if that is required users should provide their
579 * own synchronisation.
580 */
581 virtual int_type underflow();
582
583 /**
584 * This method will not throw. This class does not offer concurrent
585 * access from multiple threads to the same stream object, and if that
586 * is required users should provide their own synchronisation.
587 */
588 virtual int sync();
589
590 /**
591 * This method will not throw unless std::basic_streambuf<>::sputc()
592 * throws, which it would not do on any sane implementation. This
593 * means that the output functions of stream objects which have this
594 * streambuffer as a member will not throw unless the underlying
595 * functions of the std::basic_ostream class throw, which they would
596 * not normally do unless they have been required to do so on failbit,
597 * badbit or eofbit being set by an explicit call to the exceptions()
598 * method of that class. This class does not offer concurrent access
599 * from multiple threads to the same stream object, and if that is
600 * required users should provide their own synchronisation.
601 */
602 virtual int_type overflow(int_type);
603 #ifndef CGU_GSTREAM_USE_STD_N_READ_WRITE
604 /**
605 * This method will not throw. This means that the input functions of
606 * stream objects which have this streambuffer as a member will not
607 * throw unless the underlying functions of the std::basic_istream
608 * class throw, which they would not normally do unless they have been
609 * required to do so on failbit, badbit or eofbit being set by an
610 * explicit call to the exceptions() method of that class. This class
611 * does not offer concurrent access from multiple threads to the same
612 * stream object, and if that is required users should provide their
613 * own synchronisation.
614 */
615 virtual std::streamsize xsgetn(char_type*, std::streamsize);
616
617 /**
618 * This method will not throw. This means that the output functions
619 * of stream objects which have this streambuffer as a member will not
620 * throw unless the underlying functions of the std::basic_ostream
621 * class throw, which they would not normally do unless they have been
622 * required to do so on failbit, badbit or eofbit being set by an
623 * explicit call to the exceptions() method of that class. This class
624 * does not offer concurrent access from multiple threads to the same
625 * stream object, and if that is required users should provide their
626 * own synchronisation.
627 */
628 virtual std::streamsize xsputn(const char_type*, std::streamsize);
629 #endif
630 /**
631 * This method provides random access on GIO streams that implement
632 * GSeekable, so supporting the tellg(), tellp(), seekg() and seekp()
633 * methods of the basic_gostream, basic_gistream and basic_giostream
634 * classes. Any output buffers will be flushed and if the seek
635 * succeeds any input buffers will be reset. This method does not
636 * throw, but if it returns pos_type(off_type(-1)) to indicate
637 * failure, it will cause the tellg(), tellp(), seekg() or seekp()
638 * methods of the relevant stream class to throw
639 * std::ios_base::failure if such an exception has been required by an
640 * explicit call to the exceptions() method of that class (but not
641 * otherwise). This class does not offer concurrent access from
642 * multiple threads to the same stream object, and if that is required
643 * users should provide their own synchronisation.
644 *
645 * @param off The offset to be applied to the 'way' argument when
646 * seeking. It is a signed integer type, and on wide character
647 * streams is dimensioned as the number of wchar_t/char32_t/char16_t
648 * units not the number of bytes (that is, it is
649 * bytes/sizeof(char_type)).
650 *
651 * @param way The file position to which the 'off' argument is to be
652 * applied (either std::ios_base::beg, std::ios_base::cur or
653 * std::ios_base::end).
654 *
655 * @param m The type of GIO stream which must have been attached to
656 * this streambuffer for this method to attempt a seek. For
657 * GInputStream the argument should have the std::ios_base::in bit
658 * set, for GOutputStream it should have the std::ios_base::out bit
659 * set and for GIOStream it should have either (or both) set.
660 * Provided the relevant bit is set, it doesn't matter if others are
661 * also set. However if, with a GIOStream object, both the
662 * std::ios_base::in and std::ios_base::out bits are set, a seek on
663 * both input and output streams will be attempted, unless the 'way'
664 * argument is std::ios_base::cur, in which case a seek on the output
665 * stream only will be attempted. (Note that the only GIOStream which
666 * at present supports seeking is GFileIOStream, and because
667 * filesystem files only have one file pointer, which is used for both
668 * input and output, both input seeking and output seeking have the
669 * same result and affect both streams.) As the tellg() and seekg()
670 * stream methods only pass std::ios_base::in, and the tellp() and
671 * seekp() methods only std::ios_base::out, these will always produce
672 * the expected result, and for GIOStream streams tellg() will be
673 * indistinguishable in effect from tellp(), and seekg() from seekp().
674 *
675 * @return If the seek succeeds, a std::char_traits<T>::pos_type
676 * object representing the new stream position of the streambuffer
677 * after the seek. (This type is std::streampos for narrow character
678 * (char) streams, std::wstreampos for wide character (wchar_t)
679 * streams, std::u16streampos for the char16_t type and
680 * std::u32streampos for the char32_t type.) If the seek failed,
681 * pos_type(off_type(-1)) is returned. If a seek is made on a
682 * GIOStream object with both std::ios_base::in and std::ios_base::out
683 * set and a 'way' argument of std::ios_base::beg or
684 * std::ios_base::end, the result of the seek which succeeds is
685 * returned, or if both succeed, the result of the output seek is
686 * returned. (Note that the only GIOStream which at present supports
687 * seeking is GFileIOStream, and because files only have one file
688 * pointer, which is used for both input and output, both input
689 * seeking and output seeking have the same result and affect both
690 * streams.)
691 */
692 virtual pos_type seekoff(off_type off,
693 std::ios_base::seekdir way,
694 std::ios_base::openmode m = std::ios_base::in | std::ios_base::out);
695
696 /**
697 * This method provides random access on GIO streams that implement
698 * GSeekable, so supporting the seekg() and seekp() methods of the
699 * basic_gostream, basic_gistream and basic_giostream classes. It is
700 * equivalent to seekoff(off_type(p), std::ios_base::beg, m). Any
701 * output buffers will be flushed and if the seek succeeds any input
702 * buffers will be reset. This method does not throw, but if it
703 * returns pos_type(off_type(-1)) to indicate failure, it will cause
704 * the seekg() or seekp() methods of the relevant stream class to
705 * throw std::ios_base::failure if such an exception has been required
706 * by an explicit call to the exceptions() method of that class (but
707 * not otherwise). This class does not offer concurrent access from
708 * multiple threads to the same stream object, and if that is required
709 * users should provide their own synchronisation.
710 *
711 * @param p The absolute position to which the seek is to be made,
712 * obtained by a previous call to seekoff() or to this method.
713 *
714 * @param m The type of GIO stream which must have been attached to
715 * this streambuffer for this method to attempt a seek. For
716 * GInputStream the argument should have the std::ios_base::in bit
717 * set, for GOutputStream it should have the std::ios_base::out bit
718 * set and for GIOStream it should have either (or both) set.
719 * Provided the relevant bit is set, it doesn't matter if others are
720 * also set. However if, with a GIOStream object, both the
721 * std::ios_base::in and std::ios_base::out bits are set, a seek on
722 * both input and output streams will be attempted. (Note that the
723 * only GIOStream which at present supports seeking is GFileIOStream,
724 * and because filesystem files only have one file pointer, which is
725 * used for both input and output, both input seeking and output
726 * seeking have the same result and affect both streams.) As the
727 * seekg() stream method only passes std::ios_base::in, and the
728 * seekp() method only std::ios_base::out, these will always produce
729 * the expected result, and seekg() will be indistinguishable in
730 * effect from seekp().
731 *
732 * @return If the seek succeeds, a std::char_traits<T>::pos_type
733 * object representing the new stream position of the streambuffer
734 * after the seek. (This type is std::streampos for narrow character
735 * (char) streams, std::wstreampos for wide character (wchar_t)
736 * streams, std::u16streampos for the char16_t type and
737 * std::u32streampos for the char32_t type.) If the seek failed,
738 * pos_type(off_type(-1)) is returned.
739 */
740 virtual pos_type seekpos(pos_type p,
741 std::ios_base::openmode m = std::ios_base::in | std::ios_base::out);
742
743 public:
744 /**
745 * This class cannot be copied. The copy constructor is deleted.
746 */
747 basic_gstreambuf(const basic_gstreambuf&) = delete;
748
749 /**
750 * This class cannot be copied. The copy assignment operator is
751 * deleted.
752 */
753 basic_gstreambuf& operator=(const basic_gstreambuf&) = delete;
754
755 /**
756 * The default constructor: the GIO stream is attached later using the
757 * attach_stream() method. It will not throw unless the default
758 * constructor of std::basic_streambuf throws. This class does not
759 * offer concurrent access from multiple threads to the same stream
760 * object, and if that is required users should provide their own
761 * synchronisation.
762 */
763 basic_gstreambuf();
764
765 /**
766 * The constructor taking a GIO input stream. This class does not
767 * offer concurrent access from multiple threads to the same stream
768 * object, and if that is required users should provide their own
769 * synchronisation.
770 *
771 * @param input_stream_ A GIO input stream to be attached to the
772 * streambuffer. If the caller wants the input stream to survive
773 * this class's destruction or a call to close_stream() or
774 * attach_stream(), the caller should keep a separate GobjHandle
775 * object which references the stream (obtained by, say, calling
776 * get_istream()) and pass 'manage_' as false. If this is a
777 * GFilterInputStream object (that is, a GBufferedInputStream or
778 * GConverterInputStream stream), only the underlying base input
779 * stream will be attached and the other higher level streams will be
780 * closed (buffering of input streams is always provided by this C++
781 * streambuffer, and converting is controlled solely by the
782 * 'converter_' argument).
783 *
784 * @param manage_ Whether the streambuffer should call
785 * g_input_stream_close() on the stream in its destructor or when
786 * another stream is attached. Passing 'true' is usually what is
787 * wanted - 'false' only makes sense if the caller keeps a separate
788 * GobjHandle object which references the stream to keep it alive
789 * (obtained by, say, calling get_istream()). Unlike its fdstreams
790 * equivalent, this parameter does not have a default value of
791 * 'true': this is partly to make it less likely that a converter is
792 * passed to this argument by mistake (that would not normally cause
793 * a compiler warning because GobjHandle has a type conversion
794 * operator providing the underlying C object by pointer, so
795 * GobjHandles are type convertible to pointers, and such a pointer
796 * will in turn provide a type match with a bool argument); and
797 * partly because, given a GInputStream* p, the construction
798 * \"Cgu::gstreambuf str(Cgu::GobjHandle<GInputStream>(p));\"
799 * without an additional argument or additional parentheses (or the
800 * use of uniform initializer syntax using braces) would cause a
801 * compiler error as it would be interpreted as a function
802 * declaration.
803 *
804 * @param converter_ A converter (if any) to be attached to the GIO
805 * input stream (note that this does not affect the operation of
806 * set_byteswap()). The default value of an empty
807 * GobjHandle<GConverter> object indicates no converter.
808 *
809 * @exception std::bad_alloc This constructor will throw
810 * std::bad_alloc if memory is exhausted and the system throws on
811 * such exhaustion (unless the library has been installed using the
812 * \--with-glib-memory-slices-compat or
813 * \--with-glib-memory-slices-no-compat configuration option, in
814 * which case glib will terminate the program if it is unable to
815 * obtain memory from the operating system). No other exception will
816 * be thrown unless the constructor of std::basic_streambuf throws.
817 *
818 * @note If a converter is provided, the stream will no longer be
819 * seekable even if it otherwise would be, so tellg() and seekg()
820 * will no longer work (they will return pos_type(off_type(-1)).
821 */
822 basic_gstreambuf(const GobjHandle<GInputStream>& input_stream_,
823 bool manage_,
824 const GobjHandle<GConverter>& converter_ = GobjHandle<GConverter>());
825
826 /**
827 * The constructor taking a GIO output stream. This class does not
828 * offer concurrent access from multiple threads to the same stream
829 * object, and if that is required users should provide their own
830 * synchronisation.
831 *
832 * @param output_stream_ A GIO output stream to be attached to the
833 * streambuffer. If the caller wants the output stream to survive
834 * this class's destruction or a call to close_stream() or
835 * attach_stream(), the caller should keep a separate GobjHandle
836 * object which references the stream (obtained by, say, calling
837 * get_ostream()) and pass 'manage_' as false. If this is a
838 * GFilterOutputStream object (that is, a GBufferedOutputStream,
839 * GConverterOutputStream or GDataOutputStream stream), only the
840 * underlying base output stream will be attached and the other
841 * higher level streams will be closed (buffering and converting are
842 * controlled solely by the set_output_buffered() method and
843 * 'converter_' argument).
844 *
845 * @param manage_ Whether the streambuffer should call
846 * g_output_stream_close() on the stream in its destructor or when
847 * another stream is attached. Passing 'true' is usually what is
848 * wanted, and is particularly relevant on output streams because
849 * unless g_output_stream_close() is called, GIO may not commit to
850 * disk - 'false' only makes sense if the caller keeps a separate
851 * GobjHandle object which references the stream to keep it alive
852 * (obtained by, say, calling get_ostream()). Unlike its fdstreams
853 * equivalent, this parameter does not have a default value of
854 * 'true': this is partly to make it less likely that a converter is
855 * passed to this argument by mistake (that would not normally cause
856 * a compiler warning because GobjHandle has a type conversion
857 * operator providing the underlying C object by pointer, so
858 * GobjHandles are type convertible to pointers, and such a pointer
859 * will in turn provide a type match with a bool argument); and
860 * partly because, given a GOutputStream* p, the construction
861 * \"Cgu::gstreambuf str(Cgu::GobjHandle<GOutputStream>(p));\"
862 * without an additional argument or additional parentheses (or the
863 * use of uniform initializer syntax using braces) would cause a
864 * compiler error as it would be interpreted as a function
865 * declaration.
866 *
867 * @param converter_ A converter (if any) to be attached to the GIO
868 * output stream. The default value of an empty
869 * GobjHandle<GConverter> object indicates no converter.
870 *
871 * @exception std::bad_alloc This constructor will throw
872 * std::bad_alloc if memory is exhausted and the system throws on
873 * such exhaustion (unless the library has been installed using the
874 * \--with-glib-memory-slices-compat or
875 * \--with-glib-memory-slices-no-compat configuration option, in
876 * which case glib will terminate the program if it is unable to
877 * obtain memory from the operating system). No other exception will
878 * be thrown unless the constructor of std::basic_streambuf throws.
879 *
880 * @note If a converter is provided, the stream will no longer be
881 * seekable even if it otherwise would be, so tellp() and seekp()
882 * will no longer work (they will return pos_type(off_type(-1)).
883 */
884 basic_gstreambuf(const GobjHandle<GOutputStream>& output_stream_,
885 bool manage_,
886 const GobjHandle<GConverter>& converter_ = GobjHandle<GConverter>());
887
888 /**
889 * The constructor taking a GIO input-output stream. This class does
890 * not offer concurrent access from multiple threads to the same
891 * stream object, and if that is required users should provide their
892 * own synchronisation.
893 *
894 * @param io_stream_ A GIO input-output stream to be attached to the
895 * streambuffer. If the caller wants the stream to survive this
896 * class's destruction or a call to close_stream() or
897 * attach_stream(), the caller should keep a separate GobjHandle
898 * object which references the stream (obtained by, say, calling
899 * get_iostream()) and pass 'manage_' as false.
900 *
901 * @param manage_ Whether the streambuffer should call
902 * g_io_stream_close() on the stream in its destructor or when
903 * another stream is attached. Passing 'true' is usually what is
904 * wanted, and is particularly relevant on output streams because
905 * unless g_io_stream_close() is called, GIO may not commit to disk -
906 * 'false' only makes sense if the caller keeps a separate GobjHandle
907 * object which references the stream to keep it alive (obtained by,
908 * say, calling get_iostream()). Unlike its fdstreams equivalent,
909 * this parameter does not have a default value of 'true': this is
910 * partly to make it less likely that a converter is passed to this
911 * argument by mistake (that would not normally cause a compiler
912 * warning because GobjHandle has a type conversion operator
913 * providing the underlying C object by pointer, so GobjHandles are
914 * type convertible to pointers, and such a pointer will in turn
915 * provide a type match with a bool argument); and partly because,
916 * given a GIOStream* p, the construction \"Cgu::gstreambuf
917 * str(Cgu::GobjHandle<GIOStream>(p));\" without an additional
918 * argument or additional parentheses (or the use of uniform
919 * initializer syntax using braces) would cause a compiler error as
920 * it would be interpreted as a function declaration.
921 *
922 * @param input_converter_ A converter (if any) to be attached to the
923 * input stream (note that this does not affect the operation of
924 * set_byteswap()). The default value of an empty
925 * GobjHandle<GConverter> object indicates no converter.
926 *
927 * @param output_converter_ A converter (if any) to be attached to the
928 * output stream. The default value of an empty
929 * GobjHandle<GConverter> object indicates no converter.
930 *
931 * @exception std::bad_alloc This constructor will throw
932 * std::bad_alloc if memory is exhausted and the system throws on
933 * such exhaustion (unless the library has been installed using the
934 * \--with-glib-memory-slices-compat or
935 * \--with-glib-memory-slices-no-compat configuration option, in
936 * which case glib will terminate the program if it is unable to
937 * obtain memory from the operating system). No other exception will
938 * be thrown unless the constructor of std::basic_streambuf throws.
939 *
940 * @note If a converter is provided, the stream will no longer be
941 * seekable even if it otherwise would be, so tellg(), tellp(),
942 * seekg() and seekp() will no longer work (they will return
943 * pos_type(off_type(-1)). If the stream to which a converter has
944 * been attached represents a file on the file system (rather than a
945 * socket), after a read has been made, no further write may be made
946 * using the same GFileIOStream object. These restrictions do not
947 * apply to sockets (which are not seekable) so the use of converters
948 * with input-output streams (GIOStream) should generally be
949 * restricted to sockets.
950 */
951 basic_gstreambuf(const GobjHandle<GIOStream>& io_stream_,
952 bool manage_,
953 const GobjHandle<GConverter>& input_converter_ = GobjHandle<GConverter>(),
954 const GobjHandle<GConverter>& output_converter_ = GobjHandle<GConverter>());
955
956 /**
957 * The destructor does not throw.
958 */
959 virtual ~basic_gstreambuf();
960
961 /**
962 * Attach a new GIO input stream to the streambuffer (and close any
963 * GIO stream at present managed by it). In the case of wide
964 * character input streams, it also switches off byte swapping, if it
965 * was previously on. This class does not offer concurrent access
966 * from multiple threads to the same stream object, and if that is
967 * required users should provide their own synchronisation.
968 *
969 * @param input_stream_ The GIO input stream to be attached to the
970 * streambuffer. If the caller wants the input stream to survive a
971 * subsequent call to close_stream() or attach_stream() or this
972 * class's destruction, the caller should keep a separate GobjHandle
973 * object which references the stream (obtained by, say, calling
974 * get_istream()) and pass 'manage_' as false. If this is a
975 * GFilterInputStream object (that is, a GBufferedInputStream or
976 * GConverterInputStream stream), only the underlying base input
977 * stream will be attached and the other higher level streams will be
978 * closed (buffering of input streams is always provided by this C++
979 * streambuffer, and converting is controlled solely by the
980 * 'converter_' argument).
981 *
982 * @param manage_ Whether the streambuffer should call
983 * g_input_stream_close() on the stream in its destructor or when
984 * another stream is attached. Passing 'true' is usually what is
985 * wanted - 'false' only makes sense if the caller keeps a separate
986 * GobjHandle object which references the stream to keep it alive
987 * (obtained by, say, calling get_istream()). Unlike its fdstreams
988 * equivalent, this parameter does not have a default value of
989 * 'true': this is partly to make it less likely that a converter is
990 * passed to this argument by mistake (that would not normally cause
991 * a compiler warning because GobjHandle has a type conversion
992 * operator providing the underlying C object by pointer, so
993 * GobjHandles are type convertible to pointers, and such a pointer
994 * will in turn provide a type match with a bool argument); and
995 * partly to maintain compatibility with the constructor's interface,
996 * which has separate syntactic constraints.
997 *
998 * @param converter_ A converter (if any) to be attached to the GIO
999 * input stream (note that this does not affect the operation of
1000 * set_byteswap()). The default value of an empty
1001 * GobjHandle<GConverter> object indicates no converter.
1002 *
1003 * @exception std::bad_alloc This method will throw std::bad_alloc if
1004 * memory is exhausted and the system throws on such exhaustion
1005 * (unless the library has been installed using the
1006 * \--with-glib-memory-slices-compat or
1007 * \--with-glib-memory-slices-no-compat configuration option, in
1008 * which case glib will terminate the program if it is unable to
1009 * obtain memory from the operating system).
1010 *
1011 * @note If a converter is provided, the stream will no longer be
1012 * seekable even if it otherwise would be, so tellg() and seekg()
1013 * will no longer work (they will return pos_type(off_type(-1)).
1014 */
1015 void attach_stream(const GobjHandle<GInputStream>& input_stream_,
1016 bool manage_,
1017 const GobjHandle<GConverter>& converter_ = GobjHandle<GConverter>());
1018
1019 /**
1020 * Attach a new GIO output stream to the streambuffer (and close any
1021 * GIO stream at present managed by it). If output buffering was
1022 * previously switched off, it is switched back on again. This class
1023 * does not offer concurrent access from multiple threads to the same
1024 * stream object, and if that is required users should provide their
1025 * own synchronisation.
1026 *
1027 * @param output_stream_ The GIO output stream to be attached to the
1028 * streambuffer. If the caller wants the output stream to survive a
1029 * subsequent call to close_stream() or attach_stream() or this
1030 * class's destruction, the caller should keep a separate GobjHandle
1031 * object which references the stream (obtained by, say, calling
1032 * get_ostream()) and pass 'manage_' as false. If this is a
1033 * GFilterOutputStream object (that is, a GBufferedOutputStream,
1034 * GConverterOutputStream or GDataOutputStream stream), only the
1035 * underlying base output stream will be attached and the other
1036 * higher level streams will be closed (buffering and converting are
1037 * controlled solely by the set_output_buffered() method and
1038 * 'converter_' argument).
1039 *
1040 * @param manage_ Whether the streambuffer should call
1041 * g_output_stream_close() on the stream in its destructor or when
1042 * another stream is attached. Passing 'true' is usually what is
1043 * wanted, and is particularly relevant on output streams because
1044 * unless g_output_stream_close() is called, GIO may not commit to
1045 * disk - 'false' only makes sense if the caller keeps a separate
1046 * GobjHandle object which references the stream to keep it alive
1047 * (obtained by, say, calling get_ostream()). Unlike its fdstreams
1048 * equivalent, this parameter does not have a default value of
1049 * 'true': this is partly to make it less likely that a converter is
1050 * passed to this argument by mistake (that would not normally cause
1051 * a compiler warning because GobjHandle has a type conversion
1052 * operator providing the underlying C object by pointer, so
1053 * GobjHandles are type convertible to pointers, and such a pointer
1054 * will in turn provide a type match with a bool argument); and
1055 * partly to maintain compatibility with the constructor's interface,
1056 * which has separate syntactic constraints.
1057 *
1058 * @param converter_ A converter (if any) to be attached to the GIO
1059 * output stream. The default value of an empty
1060 * GobjHandle<GConverter> object indicates no converter.
1061 *
1062 * @exception std::bad_alloc This method will throw std::bad_alloc if
1063 * memory is exhausted and the system throws on such exhaustion
1064 * (unless the library has been installed using the
1065 * \--with-glib-memory-slices-compat or
1066 * \--with-glib-memory-slices-no-compat configuration option, in
1067 * which case glib will terminate the program if it is unable to
1068 * obtain memory from the operating system).
1069 *
1070 * @note If a converter is provided, the stream will no longer be
1071 * seekable even if it otherwise would be, so tellp() and seekp()
1072 * will no longer work (they will return pos_type(off_type(-1)).
1073 */
1074 void attach_stream(const GobjHandle<GOutputStream>& output_stream_,
1075 bool manage_,
1076 const GobjHandle<GConverter>& converter_ = GobjHandle<GConverter>());
1077
1078 /**
1079 * Attach a new GIO input-output stream to the streambuffer (and
1080 * close any GIO stream at present managed by it). If output
1081 * buffering was previously switched off, it is switched back on
1082 * again. In the case of wide character input-output streams, it
1083 * also switches off byte swapping on input, if it was previously on.
1084 * This class does not offer concurrent access from multiple threads
1085 * to the same stream object, and if that is required users should
1086 * provide their own synchronisation.
1087 *
1088 * @param io_stream_ The GIO input-output stream to be attached to
1089 * the streambuffer. If the caller wants the stream to survive a
1090 * subsequent call to close_stream() or attach_stream() or this
1091 * class's destruction, the caller should keep a separate GobjHandle
1092 * object which references the stream (obtained by, say, calling
1093 * get_iostream()) and pass 'manage_' as false.
1094 *
1095 * @param manage_ Whether the streambuffer should call
1096 * g_io_stream_close() on the stream in its destructor or when
1097 * another stream is attached. Passing 'true' is usually what is
1098 * wanted, and is particularly relevant on output streams because
1099 * unless g_io_stream_close() is called, GIO may not commit to disk -
1100 * 'false' only makes sense if the caller keeps a separate GobjHandle
1101 * object which references the stream to keep it alive (obtained by,
1102 * say, calling get_iostream()). Unlike its fdstreams equivalent,
1103 * this parameter does not have a default value of 'true': this is
1104 * partly to make it less likely that a converter is passed to this
1105 * argument by mistake (that would not normally cause a compiler
1106 * warning because GobjHandle has a type conversion operator
1107 * providing the underlying C object by pointer, so GobjHandles are
1108 * type convertible to pointers, and such a pointer will in turn
1109 * provide a type match with a bool argument); and partly to maintain
1110 * compatibility with the constructor's interface, which has separate
1111 * syntactic constraints.
1112 *
1113 * @param input_converter_ A converter (if any) to be attached to the
1114 * input stream (note that this does not affect the operation of
1115 * set_byteswap()). The default value of an empty
1116 * GobjHandle<GConverter> object indicates no converter.
1117 *
1118 * @param output_converter_ A converter (if any) to be attached to the
1119 * output stream. The default value of an empty
1120 * GobjHandle<GConverter> object indicates no converter.
1121 *
1122 * @exception std::bad_alloc This method will throw std::bad_alloc if
1123 * memory is exhausted and the system throws on such exhaustion
1124 * (unless the library has been installed using the
1125 * \--with-glib-memory-slices-compat or
1126 * \--with-glib-memory-slices-no-compat configuration option, in
1127 * which case glib will terminate the program if it is unable to
1128 * obtain memory from the operating system).
1129 *
1130 * @note If a converter is provided, the stream will no longer be
1131 * seekable even if it otherwise would be, so tellg(), tellp(),
1132 * seekg() and seekp() will no longer work (they will return
1133 * pos_type(off_type(-1)). If the stream to which a converter has
1134 * been attached represents a file on the file system (rather than a
1135 * socket), after a read has been made, no further write may be made
1136 * using the same GFileIOStream object. These restrictions do not
1137 * apply to sockets (which are not seekable) so the use of converters
1138 * with input-output streams (GIOStream) should generally be
1139 * restricted to sockets.
1140 */
1141 void attach_stream(const GobjHandle<GIOStream>& io_stream_,
1142 bool manage_,
1143 const GobjHandle<GConverter>& input_converter_ = GobjHandle<GConverter>(),
1144 const GobjHandle<GConverter>& output_converter_ = GobjHandle<GConverter>());
1145
1146
1147 /**
1148 * Call g_input_stream_close(), g_output_stream_close() or
1149 * g_io_stream_close(), as the case may be, on the GIO stream at
1150 * present attached to the streambuffer (if any), and release the
1151 * streambuffer's reference to that stream (the reference will be
1152 * released even if an error arose in closing the stream). If the
1153 * caller wants the GIO stream to survive the call to this method
1154 * (albeit in a closed state), the caller should, before the call is
1155 * made, keep a separate GobjHandle object which references the
1156 * stream. This method does not throw. This class does not offer
1157 * concurrent access from multiple threads to the same stream object,
1158 * and if that is required users should provide their own
1159 * synchronisation.
1160 *
1161 * @return true if the close succeeded, false if an error arose
1162 * (including in a case where no GIO stream has been attached or it
1163 * has already been closed).
1164 */
1165 bool close_stream();
1166
1167 /**
1168 * Get the GIO input stream at present attached to the streambuffer
1169 * (if any), by GobjHandle. If a GOutputStream object rather than a
1170 * GInputStream or GIOStream object has been attached (or no stream
1171 * has been attached) or it has been closed, then this method will
1172 * return an empty GobjHandle object. If a GIOStream object has been
1173 * attached, this streambuffer's maintained GInputStream object will
1174 * be returned, which may be a converting stream manufactured from
1175 * the GInputStream object maintained by the GIOStream object.
1176 * Retaining the return value will cause the stream to survive a
1177 * subsequent call to attach_stream() or the destruction of this
1178 * object. The return value may be a different stream from the one
1179 * originally passed to this object's constructor or to attach(). It
1180 * will be different if a converter has been attached to it. This
1181 * method does not throw. This class does not offer concurrent
1182 * access from multiple threads to the same stream object, and if
1183 * that is required users should provide their own synchronisation.
1184 *
1185 * @return The GIO input stream at present attached to the
1186 * streambuffer, or an empty GobjHandle object if none has been
1187 * attached
1188 */
1189 GobjHandle<GInputStream> get_istream() const;
1190
1191 /**
1192 * Get the GIO output stream at present attached to the streambuffer
1193 * (if any), by GobjHandle. If a GInputStream object rather than a
1194 * GOutputStream or GIOStream object has been attached (or no stream
1195 * has been attached) or it has been closed, then this method will
1196 * return an empty GobjHandle object. If a GIOStream object has been
1197 * attached, this streambuffer's maintained GOutputStream object will
1198 * be returned, which may be a converting stream manufactured from
1199 * the GOutputStream object maintained by the GIOStream object.
1200 * Retaining the return value will cause the stream to survive a
1201 * subsequent call to attach_stream() or the destruction of this
1202 * object. The return value may be a different stream from the one
1203 * originally passed to this object's constructor or to attach(). It
1204 * will be different if a converter has been attached to it. This
1205 * method does not throw. This class does not offer concurrent
1206 * access from multiple threads to the same stream object, and if
1207 * that is required users should provide their own synchronisation.
1208 *
1209 * @return The GIO output stream at present attached to the
1210 * streambuffer, or an empty GobjHandle object if none has been
1211 * attached
1212 */
1213 GobjHandle<GOutputStream> get_ostream() const;
1214
1215 /**
1216 * Get the GIOStream input-output stream at present attached to the
1217 * streambuffer (if any), by GobjHandle. If a GInputStream or
1218 * GOutputStream object rather than a GIOStream object has been
1219 * attached (or no stream has been attached) or it has been closed,
1220 * then this method will return an empty GobjHandle object.
1221 * Retaining the return value will cause the stream to survive a
1222 * subsequent call to attach_stream() or the destruction of this
1223 * object. This method does not throw. This class does not offer
1224 * concurrent access from multiple threads to the same stream object,
1225 * and if that is required users should provide their own
1226 * synchronisation.
1227 *
1228 * @return The GIOStream stream at present attached to the
1229 * streambuffer, or an empty GobjHandle object if none has been
1230 * attached
1231 */
1232 GobjHandle<GIOStream> get_iostream() const;
1233
1234 /**
1235 * Causes the streambuffer to swap bytes in incoming text, so as to
1236 * convert big endian text to little endian text, or little endian
1237 * text to big endian text. It is called by the user in response to
1238 * finding a byte order marker (BOM) 0xfffe (UTF-16) or 0xfffe0000
1239 * (UTF-32) as the first character of a newly opened file/stream, or
1240 * if the user knows by some other means that the native endianness
1241 * of the machine doing the reading differs from the endianness of
1242 * the file/stream being read. This only has effect on wide
1243 * character streambuffers for input (for example, a wgstreambuf to
1244 * which a GInputStream or GIOStream object has been attached), and
1245 * not the gstreambuf narrow character stream buffer. Note that
1246 * characters held for output are always outputted in native endian
1247 * format unless a GConverter object has been attached, and this
1248 * method does not affect that. This method does not throw. This
1249 * class does not offer concurrent access from multiple threads to
1250 * the same stream object, and if that is required users should
1251 * provide their own synchronisation.
1252 *
1253 * @param swap 'true' if byte swapping for input is to be turned on,
1254 * 'false' if it is to be turned off. This will affect all
1255 * characters extracted from the underlying streambuffer after this
1256 * call is made. If a previously extracted character is to be
1257 * putback(), it must be put back before this function is called (or
1258 * unget() should be called instead) to avoid a putback mismatch,
1259 * because this call will byte-swap anything already in the buffers.
1260 * (Characters extracted after the call to this method may be putback
1261 * normally.)
1262 */
1263 void set_byteswap(bool swap);
1264
1265 /**
1266 * If the GIO stream attached to this object is GOutputStream or
1267 * GIOStream, this method converts it to an unbuffered stream for
1268 * output if 'buffered' is false, or back to a buffered stream if
1269 * buffering has previously been switched off and 'buffered' is true.
1270 * Buffering is on by default for any newly created gstreambuf object
1271 * and any newly attached GIO output stream or input-output stream.
1272 * If buffering is turned off, all characters at present in the
1273 * buffers which are stored for output are flushed (but if writing to
1274 * a file which is being written over/replaced, output from this
1275 * streambuffer may not appear in the destination until the GIO stream
1276 * is closed). This method has no effect if no GIO output stream or
1277 * input-output stream has yet been attached to this streambuffer.
1278 * Switching output buffering off is similar in effect to setting the
1279 * std::ios_base::unitbuf flag in the relevant gostream or giostream
1280 * object, except that switching buffering off is slightly more
1281 * efficient, and setting the std::ios_base::unitbuf flag will not
1282 * retain the automatic tying of logical and actual file positions
1283 * that occurs when output buffering is switched off, as explained
1284 * @ref GioRandomAccessAnchor "here". This class does not offer
1285 * concurrent access from multiple threads to the same stream object,
1286 * and if that is required users should provide their own
1287 * synchronisation.
1288 *
1289 * @param buffered 'false' if buffering is to be turned off, 'true' if
1290 * it is to be turned back on.
1291 *
1292 * @exception std::bad_alloc This method will throw std::bad_alloc if
1293 * 'buffered' is true, output buffering had previously been switched
1294 * off, memory is exhausted and the system throws on such exhaustion
1295 * (unless the library has been installed using the
1296 * \--with-glib-memory-slices-compat or
1297 * \--with-glib-memory-slices-no-compat configuration option, in which
1298 * case glib will terminate the program if it is unable to obtain
1299 * memory from the operating system).
1300 */
1301 void set_output_buffered(bool buffered);
1302
1303 /**
1304 * This method indicates whether the attached GIO stream implements
1305 * GSeekable, so that a call to seekoff() or seekpos() can succeed.
1306 * This method does not throw. This class does not offer concurrent
1307 * access from multiple threads to the same stream object, and if that
1308 * is required users should provide their own synchronisation.
1309 *
1310 * @return true if random access is supported, otherwise false. The
1311 * result is only meaningful if a GIO stream has been attached to this
1312 * streambuffer.
1313 */
1314 bool can_seek() const {return seekable;}
1315
1316 /**
1317 * This method indicates whether any attached GIO input stream is in
1318 * an error state. It can be useful for detecting conversion errors
1319 * on converting streams. This class does not offer concurrent access
1320 * from multiple threads to the same stream object, and if that is
1321 * required users should provide their own synchronisation.
1322 *
1323 * @return NULL if no input stream is attached, or it is not in an
1324 * error state. If an attached input stream is in an error state, say
1325 * because it is a converting input stream which has encountered a
1326 * conversion error, the most recent GError object emitted by a read
1327 * operation on it is returned. Ownership of the return value is
1328 * retained, so if it is intended to be used after the next read
1329 * operation, it should be copied using g_error_copy().
1330 *
1331 * Since 2.0.5
1332 */
1333 GError* is_input_error();
1334
1335 /**
1336 * This method indicates whether any attached GIO output stream is in
1337 * an error state. It can be useful for detecting conversion errors
1338 * on converting streams. This class does not offer concurrent access
1339 * from multiple threads to the same stream object, and if that is
1340 * required users should provide their own synchronisation.
1341 *
1342 * @return NULL if no output stream is attached, or it is not in an
1343 * error state. If an attached output stream is in an error state,
1344 * say because it is a converting output stream which has encountered
1345 * a conversion error, the most recent GError object emitted by a
1346 * write operation on it is returned. Ownership of the return value
1347 * is retained, so if it is intended to be used after the next write
1348 * operation, it should be copied using g_error_copy().
1349 *
1350 * Since 2.0.5
1351 */
1352 GError* is_output_error();
1353
1354 /* Only has effect if --with-glib-memory-slices-compat or
1355 * --with-glib-memory-slices-no-compat option picked */
1356 CGU_GLIB_MEMORY_SLICES_FUNCS
1357 };
1358
1359 /**
1360 * @headerfile gstream.h c++-gtk-utils/gstream.h
1361 * @brief C++ output stream for GIO streams
1362 * @sa gstreams
1363 * @ingroup gstreams
1364 *
1365 * This class provides standard ostream services for GIO output
1366 * streams.
1367 */
1368 template <class charT , class Traits = std::char_traits<charT> >
1369 class basic_gostream: public std::basic_ostream<charT, Traits> {
1370
1371 basic_gstreambuf<charT, Traits> buf;
1372
1373 public:
1374 /**
1375 * This class cannot be copied. The copy constructor is deleted.
1376 */
1377 basic_gostream(const basic_gostream&) = delete;
1378
1379 /**
1380 * This class cannot be copied. The copy assignment operator is
1381 * deleted.
1382 */
1383 basic_gostream& operator=(const basic_gostream&) = delete;
1384
1385 /**
1386 * The constructor taking a GIO output stream. This class does not
1387 * offer concurrent access from multiple threads to the same stream
1388 * object, and if that is required users should provide their own
1389 * synchronisation.
1390 *
1391 * @param stream A GIO output stream to be attached. If the caller
1392 * wants the output stream to survive this class's destruction or a
1393 * call to close() or attach(), the caller should keep a separate
1394 * GobjHandle object which references the stream (obtained by, say,
1395 * calling get_gio_stream()) and pass 'manage' as false. If this is
1396 * a GFilterOutputStream object (that is, a GBufferedOutputStream,
1397 * GConverterOutputStream or GDataOutputStream stream), only the
1398 * underlying base output stream will be attached and the other
1399 * higher level streams will be closed (buffering and converting are
1400 * controlled solely by the set_buffered() method and 'converter'
1401 * argument).
1402 *
1403 * @param manage Whether the underlying streambuffer should call
1404 * g_output_stream_close() on the GIO stream in the streambuffer's
1405 * destructor or when another stream is attached. Passing 'true' is
1406 * usually what is wanted, and is particularly relevant on output
1407 * streams because unless g_output_stream_close() is called, GIO may
1408 * not commit to disk - 'false' only makes sense if the caller keeps
1409 * a separate GobjHandle object which references the stream to keep
1410 * it alive (obtained by, say, calling get_gio_stream()). Unlike its
1411 * fdstreams equivalent, this parameter does not have a default value
1412 * of 'true': this is partly to make it less likely that a converter
1413 * is passed to this argument by mistake (that would not normally
1414 * cause a compiler warning because GobjHandle has a type conversion
1415 * operator providing the underlying C object by pointer, so
1416 * GobjHandles are type convertible to pointers, and such a pointer
1417 * will in turn provide a type match with a bool argument); and
1418 * partly because, given a GOutputStream* p, the construction
1419 * \"Cgu::gostream str(Cgu::GobjHandle<GOutputStream>(p));\"
1420 * without an additional argument or additional parentheses (or the
1421 * use of uniform initializer syntax using braces) would cause a
1422 * compiler error as it would be interpreted as a function
1423 * declaration.
1424 *
1425 * @param converter A converter (if any) to be attached to the GIO
1426 * output stream. The default value of an empty
1427 * GobjHandle<GConverter> object indicates no converter.
1428 *
1429 * @exception std::bad_alloc This constructor will throw
1430 * std::bad_alloc if memory is exhausted and the system throws on
1431 * such exhaustion (unless the library has been installed using the
1432 * \--with-glib-memory-slices-compat or
1433 * \--with-glib-memory-slices-no-compat configuration option, in
1434 * which case glib will terminate the program if it is unable to
1435 * obtain memory from the operating system). No other exception will
1436 * be thrown unless the constructor of std::basic_streambuf or
1437 * std::basic_ostream throws.
1438 *
1439 * @note If a converter is provided, the stream will no longer be
1440 * seekable even if it otherwise would be, so tellp() and seekp()
1441 * will no longer work (they will return pos_type(off_type(-1)).
1442 */
1443 // using uniform initializer syntax here confuses doxygen
1444 basic_gostream(const GobjHandle<GOutputStream>& stream,
1445 bool manage,
1446 const GobjHandle<GConverter>& converter = GobjHandle<GConverter>()):
1447 std::basic_ostream<charT, Traits>(0),
1448 buf(stream, manage, converter) {
1449 this->rdbuf(&buf);
1450 }
1451
1452 /**
1453 * With this constructor, the GIO output stream must be attached
1454 * later with the attach() method. It will not throw unless the
1455 * default constructor of std::basic_streambuf or std::basic_ostream
1456 * throws. This class does not offer concurrent access from multiple
1457 * threads to the same stream object, and if that is required users
1458 * should provide their own synchronisation.
1459 */
1460 // using uniform initializer syntax here confuses doxygen
1461 basic_gostream(): std::basic_ostream<charT, Traits>(0) {
1462 this->rdbuf(&buf);
1463 }
1464
1465 /**
1466 * Attach a new GIO output stream to this object (and close any GIO
1467 * stream at present managed by it). If output buffering was
1468 * previously switched off, it is switched back on again. If any
1469 * stream state flags were set (eofbit, failbit or badbit), they will
1470 * be cleared by a call to clear(). If this method closes a stream
1471 * at present managed by it and the close fails, failbit is not set
1472 * and no exception will be thrown. Accordingly, if the user needs
1473 * to know whether there was an error in this method closing any
1474 * managed stream, she should call close() explicitly before calling
1475 * this method. This class does not offer concurrent access from
1476 * multiple threads to the same stream object, and if that is
1477 * required users should provide their own synchronisation.
1478 *
1479 * @param stream A GIO output stream to be attached. If the caller
1480 * wants the GIO output stream to survive a subsequent call to
1481 * close() or attach() or this class's destruction, the caller should
1482 * keep a separate GobjHandle object which references the stream
1483 * (obtained by, say, calling get_gio_stream()) and pass 'manage' as
1484 * false. If this is a GFilterOutputStream object (that is, a
1485 * GBufferedOutputStream, GConverterOutputStream or GDataOutputStream
1486 * stream), only the underlying base output stream will be attached
1487 * and the other higher level streams will be closed (buffering and
1488 * converting are controlled solely by the set_buffered() method and
1489 * 'converter' argument).
1490 *
1491 * @param manage Whether the underlying streambuffer should call
1492 * g_output_stream_close() on the GIO stream in the streambuffer's
1493 * destructor or when another stream is attached. Passing 'true' is
1494 * usually what is wanted, and is particularly relevant on output
1495 * streams because unless g_output_stream_close() is called, GIO may
1496 * not commit to disk - 'false' only makes sense if the caller keeps
1497 * a separate GobjHandle object which references the stream to keep
1498 * it alive (obtained by, say, calling get_gio_stream()). Unlike its
1499 * fdstreams equivalent, this parameter does not have a default value
1500 * of 'true': this is partly to make it less likely that a converter
1501 * is passed to this argument by mistake (that would not normally
1502 * cause a compiler warning because GobjHandle has a type conversion
1503 * operator providing the underlying C object by pointer, so
1504 * GobjHandles are type convertible to pointers, and such a pointer
1505 * will in turn provide a type match with a bool argument); and
1506 * partly to maintain compatibility with the constructor's interface,
1507 * which has separate syntactic constraints.
1508 *
1509 * @param converter A converter (if any) to be attached to the GIO
1510 * output stream. The default value of an empty
1511 * GobjHandle<GConverter> object indicates no converter.
1512 *
1513 * @exception std::bad_alloc This method will throw std::bad_alloc if
1514 * memory is exhausted and the system throws on such exhaustion
1515 * (unless the library has been installed using the
1516 * \--with-glib-memory-slices-compat or
1517 * \--with-glib-memory-slices-no-compat configuration option, in
1518 * which case glib will terminate the program if it is unable to
1519 * obtain memory from the operating system).
1520 *
1521 * @note If a converter is provided, the stream will no longer be
1522 * seekable even if it otherwise would be, so tellp() and seekp()
1523 * will no longer work (they will return pos_type(off_type(-1)).
1524 */
1525 void attach(const GobjHandle<GOutputStream>& stream,
1526 bool manage,
1527 const GobjHandle<GConverter>& converter = GobjHandle<GConverter>())
1528 {buf.attach_stream(stream, manage, converter); this->clear();}
1529
1530 /**
1531 * Call g_output_stream_close() on the GIO stream at present attached
1532 * (if any), and release the underlying C++ streambuffer's reference
1533 * to that stream. If the caller wants the GIO stream to survive the
1534 * call to this method (albeit in a closed state), the caller should,
1535 * before the call is made, keep a separate GobjHandle object which
1536 * references the stream. If the close fails, the failbit will be
1537 * set with setstate(std::ios_base::failbit). This class does not
1538 * offer concurrent access from multiple threads to the same stream
1539 * object, and if that is required users should provide their own
1540 * synchronisation.
1541 *
1542 * @exception std::ios_base::failure This exception will be thrown if
1543 * an error arises on closing the stream and such an exception has
1544 * been required by a call to the exceptions() method of this class
1545 * (inherited from std::basic_ios<>). No exception will be thrown if
1546 * exceptions() has not been called.
1547 */
1548 void close() {if (!buf.close_stream()) this->setstate(std::ios_base::failbit);}
1549
1550 /**
1551 * Get the GIO output stream at present attached (if any), by
1552 * GobjHandle. If no stream has been attached, this method will
1553 * return an empty GobjHandle object. Retaining the return value
1554 * will cause the GIO output stream to survive the destruction of
1555 * this object. The return value may be a different stream from the
1556 * one originally passed to this object's constructor or to attach().
1557 * It will be different if a converter has been attached to it. This
1558 * method does not throw. This class does not offer concurrent
1559 * access from multiple threads to the same stream object, and if
1560 * that is required users should provide their own synchronisation.
1561 *
1562 * @return The GIO output stream at present attached, or an empty
1563 * GobjHandle object if none has been attached
1564 */
1565 GobjHandle<GOutputStream> get_gio_stream() const {return buf.get_ostream();}
1566
1567 /**
1568 * This method converts the attached GIO output stream to an
1569 * unbuffered stream for output if 'buffered' is false, or back to a
1570 * buffered stream if buffering has previously been switched off and
1571 * 'buffered' is true. Buffering is on by default for any newly
1572 * created gostream object and any newly attached GIO output stream.
1573 * If buffering is turned off, all characters at present in the
1574 * buffers which are stored for output are flushed (but if writing to
1575 * a file which is being written over/replaced, output may not appear
1576 * in the destination until the GIO stream is closed). This method
1577 * has no effect if no GIO output stream has yet been attached.
1578 * Switching output buffering off is similar in effect to setting the
1579 * std::ios_base::unitbuf flag, but is slightly more efficient. This
1580 * class does not offer concurrent access from multiple threads to the
1581 * same stream object, and if that is required users should provide
1582 * their own synchronisation.
1583 *
1584 * @param buffered 'false' if buffering is to be turned off, 'true' if
1585 * it is to be turned back on.
1586 *
1587 * @exception std::bad_alloc This method will throw std::bad_alloc if
1588 * 'buffered' is true, output buffering had previously been switched
1589 * off, memory is exhausted and the system throws on such exhaustion
1590 * (unless the library has been installed using the
1591 * \--with-glib-memory-slices-compat or
1592 * \--with-glib-memory-slices-no-compat configuration option, in which
1593 * case glib will terminate the program if it is unable to obtain
1594 * memory from the operating system).
1595 */
1596 void set_buffered(bool buffered) {buf.set_output_buffered(buffered);}
1597
1598 /**
1599 * This method indicates whether the attached GIO output stream
1600 * implements GSeekable, so that a call to tellp() or seekp() can
1601 * succeed. Note that in the seekp(off_type off, ios_base::seekdir
1602 * dir) variant, on wide character streams the 'off' argument is
1603 * dimensioned as the number of wchar_t/char32_t/char16_t units not
1604 * the number of bytes (that is, it is bytes/sizeof(char_type)). This
1605 * method does not throw. This class does not offer concurrent access
1606 * from multiple threads to the same stream object, and if that is
1607 * required users should provide their own synchronisation.
1608 *
1609 * @return true if the attached GIO stream implements GSeekable,
1610 * otherwise false. The result is only meaningful if a GIO stream has
1611 * been attached to this C++ stream object.
1612 */
1613 bool can_seek() const {return buf.can_seek();}
1614
1615 /**
1616 * This method reports the error status of any attached GIO output
1617 * stream, and is intended to be called where failbit or badbit has
1618 * been set. It can be useful for interpreting conversion errors on
1619 * converting streams where one of those bits is set. This class does
1620 * not offer concurrent access from multiple threads to the same
1621 * stream object, and if that is required users should provide their
1622 * own synchronisation.
1623 *
1624 * @return NULL if no output stream is attached, or it is not in an
1625 * error state. If an attached output stream is in an error state,
1626 * say because it is a converting output stream which has encountered
1627 * a conversion error, the most recent GError object emitted by a
1628 * write operation on it is returned. Ownership of the return value
1629 * is retained, so if it is intended to be used after the next write
1630 * operation, it should be copied using g_error_copy().
1631 *
1632 * Since 2.0.5
1633 */
1634 GError* is_error() {return buf.is_output_error();}
1635
1636 /* Only has effect if --with-glib-memory-slices-compat or
1637 * --with-glib-memory-slices-no-compat option picked */
1638 CGU_GLIB_MEMORY_SLICES_FUNCS
1639 };
1640
1641
1642 /**
1643 * @headerfile gstream.h c++-gtk-utils/gstream.h
1644 * @brief C++ input stream for GIO streams
1645 * @sa gstreams
1646 * @ingroup gstreams
1647 *
1648 * This class provides standard istream services for GIO input
1649 * streams.
1650 */
1651 template <class charT , class Traits = std::char_traits<charT> >
1652 class basic_gistream : public std::basic_istream<charT, Traits> {
1653
1654 basic_gstreambuf<charT , Traits> buf;
1655
1656 public:
1657 /**
1658 * This class cannot be copied. The copy constructor is deleted.
1659 */
1660 basic_gistream(const basic_gistream&) = delete;
1661
1662 /**
1663 * This class cannot be copied. The copy assignment operator is
1664 * deleted.
1665 */
1666 basic_gistream& operator=(const basic_gistream&) = delete;
1667
1668 /**
1669 * The constructor taking a GIO input stream. This class does not
1670 * offer concurrent access from multiple threads to the same stream
1671 * object, and if that is required users should provide their own
1672 * synchronisation.
1673 *
1674 * @param stream A GIO input stream to be attached. If the caller
1675 * wants the GIO input stream to survive this class's destruction or
1676 * a call to close() or attach(), the caller should keep a separate
1677 * GobjHandle object which references the stream (obtained by, say,
1678 * calling get_gio_stream()) and pass 'manage' as false. If this is
1679 * a GFilterInputStream object (that is, a GBufferedInputStream or
1680 * GConverterInputStream stream), only the underlying base input
1681 * stream will be attached and the other higher level streams will be
1682 * closed (buffering of input streams is always provided by the
1683 * underlying C++ streambuffer, and converting is controlled solely
1684 * by the 'converter' argument).
1685 *
1686 * @param manage Whether the underlying streambuffer should call
1687 * g_input_stream_close() on the GIO stream in the streambuffer's
1688 * destructor or when another stream is attached. Passing 'true' is
1689 * usually what is wanted - 'false' only makes sense if the caller
1690 * keeps a separate GobjHandle object which references the stream to
1691 * keep it alive (obtained by, say, calling get_gio_stream()).
1692 * Unlike its fdstreams equivalent, this parameter does not have a
1693 * default value of 'true': this is partly to make it less likely
1694 * that a converter is passed to this argument by mistake (that would
1695 * not normally cause a compiler warning because GobjHandle has a
1696 * type conversion operator providing the underlying C object by
1697 * pointer, so GobjHandles are type convertible to pointers, and such
1698 * a pointer will in turn provide a type match with a bool argument);
1699 * and partly because, given a GInputStream* p, the construction
1700 * \"Cgu::gistream str(Cgu::GobjHandle<GInputStream>(p));\" without
1701 * an additional argument or additional parentheses (or the use of
1702 * uniform initializer syntax using braces) would cause a compiler
1703 * error as it would be interpreted as a function declaration.
1704 *
1705 * @param converter A converter (if any) to be attached to the GIO
1706 * input stream (note that this does not affect the operation of
1707 * set_byteswap()). The default value of an empty
1708 * GobjHandle<GConverter> object indicates no converter.
1709 *
1710 * @exception std::bad_alloc This constructor will throw
1711 * std::bad_alloc if memory is exhausted and the system throws on
1712 * such exhaustion (unless the library has been installed using the
1713 * \--with-glib-memory-slices-compat or
1714 * \--with-glib-memory-slices-no-compat configuration option, in
1715 * which case glib will terminate the program if it is unable to
1716 * obtain memory from the operating system). No other exception will
1717 * be thrown unless the constructor of std::basic_streambuf or
1718 * std::basic_istream throws.
1719 *
1720 * @note If a converter is provided, the stream will no longer be
1721 * seekable even if it otherwise would be, so tellg() and seekg()
1722 * will no longer work (they will return pos_type(off_type(-1)).
1723 */
1724 // using uniform initializer syntax here confuses doxygen
1725 basic_gistream(const GobjHandle<GInputStream>& stream,
1726 bool manage,
1727 const GobjHandle<GConverter>& converter = GobjHandle<GConverter>()):
1728 std::basic_istream<charT, Traits>(0),
1729 buf(stream, manage, converter) {
1730 this->rdbuf(&buf);
1731 }
1732
1733 /**
1734 * With this constructor, the GIO input stream must be attached later
1735 * with the attach() method. It will not throw unless the default
1736 * constructor of std::basic_streambuf or std::basic_istream throws.
1737 * This class does not offer concurrent access from multiple threads
1738 * to the same stream object, and if that is required users should
1739 * provide their own synchronisation.
1740 */
1741 // using uniform initializer syntax here confuses doxygen
1742 basic_gistream(): std::basic_istream<charT, Traits>(0) {
1743 this->rdbuf(&buf);
1744 }
1745
1746 /**
1747 * Attach a new GIO input stream to this object (and close any GIO
1748 * stream at present managed by it). In the case of wide character
1749 * input streams, it also switches off byte swapping, if it was
1750 * previously on. If any stream state flags were set (eofbit,
1751 * failbit or badbit), they will be cleared by a call to clear(). If
1752 * this method closes a stream at present managed by it and the close
1753 * fails, failbit is not set and no exception will be thrown.
1754 * Accordingly, if the user needs to know whether there was an error
1755 * in this method closing any managed stream, she should call close()
1756 * explicitly before calling this method. This class does not offer
1757 * concurrent access from multiple threads to the same stream object,
1758 * and if that is required users should provide their own
1759 * synchronisation.
1760 *
1761 * @param stream A GIO input stream to be attached. If the caller
1762 * wants the GIO input stream to survive a subsequent call to close()
1763 * or attach() or this class's destruction, the caller should keep a
1764 * separate GobjHandle object which references the stream (obtained
1765 * by, say, calling get_gio_stream()) and pass 'manage' as false. If
1766 * this is a GFilterInputStream object (that is, a
1767 * GBufferedInputStream or GConverterInputStream stream), only the
1768 * underlying base input stream will be attached and the other higher
1769 * level streams will be closed (buffering of input streams is always
1770 * provided by the underlying C++ streambuffer, and converting is
1771 * controlled solely by the 'converter' argument).
1772 *
1773 * @param manage Whether the underlying streambuffer should call
1774 * g_input_stream_close() on the GIO stream in the streambuffer's
1775 * destructor or when another stream is attached. Passing 'true' is
1776 * usually what is wanted - 'false' only makes sense if the caller
1777 * keeps a separate GobjHandle object which references the stream to
1778 * keep it alive (obtained by, say, calling get_gio_stream()).
1779 * Unlike its fdstreams equivalent, this parameter does not have a
1780 * default value of 'true': this is partly to make it less likely
1781 * that a converter is passed to this argument by mistake (that would
1782 * not normally cause a compiler warning because GobjHandle has a
1783 * type conversion operator providing the underlying C object by
1784 * pointer, so GobjHandles are type convertible to pointers, and such
1785 * a pointer will in turn provide a type match with a bool argument);
1786 * and partly to maintain compatibility with the constructor's
1787 * interface, which has separate syntactic constraints.
1788 *
1789 * @param converter A converter (if any) to be attached to the GIO
1790 * input stream (note that this does not affect the operation of
1791 * set_byteswap()). The default value of an empty
1792 * GobjHandle<GConverter> object indicates no converter.
1793 *
1794 * @exception std::bad_alloc This method will throw std::bad_alloc if
1795 * memory is exhausted and the system throws on such exhaustion
1796 * (unless the library has been installed using the
1797 * \--with-glib-memory-slices-compat or
1798 * \--with-glib-memory-slices-no-compat configuration option, in
1799 * which case glib will terminate the program if it is unable to
1800 * obtain memory from the operating system).
1801 *
1802 * @note If a converter is provided, the stream will no longer be
1803 * seekable even if it otherwise would be, so tellg() and seekg()
1804 * will no longer work (they will return pos_type(off_type(-1)).
1805 */
1806 void attach(const GobjHandle<GInputStream>& stream,
1807 bool manage,
1808 const GobjHandle<GConverter>& converter = GobjHandle<GConverter>())
1809 {buf.attach_stream(stream, manage, converter); this->clear();}
1810
1811 /**
1812 * Call g_input_stream_close() on the GIO stream at present attached
1813 * (if any), and release the underlying C++ streambuffer's reference
1814 * to that stream. If the caller wants the GIO stream to survive the
1815 * call to this method (albeit in a closed state), the caller should,
1816 * before the call is made, keep a separate GobjHandle object which
1817 * references the stream. If the close fails, the failbit will be
1818 * set with setstate(std::ios_base::failbit). This class does not
1819 * offer concurrent access from multiple threads to the same stream
1820 * object, and if that is required users should provide their own
1821 * synchronisation.
1822 *
1823 * @exception std::ios_base::failure This exception will be thrown if
1824 * an error arises on closing the stream and such an exception has
1825 * been required by a call to the exceptions() method of this class
1826 * (inherited from std::basic_ios<>). No exception will be thrown if
1827 * exceptions() has not been called.
1828 */
1829 void close() {if (!buf.close_stream()) this->setstate(std::ios_base::failbit);}
1830
1831 /**
1832 * Get the GIO input stream at present attached (if any), by
1833 * GobjHandle. If no stream has been attached, this method will
1834 * return an empty GobjHandle object. Retaining the return value
1835 * will cause the GIO input stream to survive the destruction of this
1836 * object. The return value may be a different stream from the one
1837 * originally passed to this object's constructor or to attach(). It
1838 * will be different if a converter has been attached to it. This
1839 * method does not throw. This class does not offer concurrent
1840 * access from multiple threads to the same stream object, and if
1841 * that is required users should provide their own synchronisation.
1842 *
1843 * @return The GIO input stream at present attached, or an empty
1844 * GobjHandle object if none has been attached
1845 */
1846 GobjHandle<GInputStream> get_gio_stream() const {return buf.get_istream();}
1847
1848 /**
1849 * Causes the underlying streambuffer to swap bytes in the incoming
1850 * text, so as to convert big endian text to little endian text, or
1851 * little endian text to big endian text. It is called by the user
1852 * in response to finding a byte order marker (BOM) 0xfffe (UTF-16)
1853 * or 0xfffe0000 (UTF-32) as the first character of a newly opened
1854 * file/stream, or if the user knows by some other means that the
1855 * native endianness of the machine doing the reading differs from
1856 * the endianness of the file/stream being read. This only has
1857 * effect on wide character streams (for example, a wgistream
1858 * object), and not the gistream narrow character stream. This
1859 * method does not throw. This class does not offer concurrent
1860 * access from multiple threads to the same stream object, and if
1861 * that is required users should provide their own synchronisation.
1862 *
1863 * @param swap 'true' if byte swapping is to be turned on, 'false' if
1864 * it is to be turned off. This will affect all characters extracted
1865 * from the underlying streambuffer after this call is made. If a
1866 * previously extracted character is to be putback(), it must be put
1867 * back before this function is called (or unget() should be called
1868 * instead) to avoid a putback mismatch, because this call will
1869 * byte-swap anything already in the buffers. (Characters extracted
1870 * after the call to this method may be putback normally.)
1871 */
1872 void set_byteswap(bool swap) {buf.set_byteswap(swap);}
1873
1874 /**
1875 * This method indicates whether the attached GIO input stream
1876 * implements GSeekable, so that a call to tellg() or seekg() can
1877 * succeed. Note that in the seekg(off_type off, ios_base::seekdir
1878 * dir) variant, on wide character streams the 'off' argument is
1879 * dimensioned as the number of wchar_t/char32_t/char16_t units not
1880 * the number of bytes (that is, it is bytes/sizeof(char_type)). This
1881 * method does not throw. This class does not offer concurrent access
1882 * from multiple threads to the same stream object, and if that is
1883 * required users should provide their own synchronisation.
1884 *
1885 * @return true if the attached GIO stream implements GSeekable,
1886 * otherwise false. The result is only meaningful if a GIO stream has
1887 * been attached to this C++ stream object.
1888 */
1889 bool can_seek() const {return buf.can_seek();}
1890
1891 /**
1892 * This method reports the error status of any attached GIO input
1893 * stream, and is intended to be called where failbit has been set.
1894 * It can be useful for establishing, where that bit is set, whether
1895 * failbit indicates normal end-of-file or a conversion error on a
1896 * converting stream. This class does not offer concurrent access
1897 * from multiple threads to the same stream object, and if that is
1898 * required users should provide their own synchronisation.
1899 *
1900 * @return NULL if no input stream is attached, or it is not in an
1901 * error state. If an attached input stream is in an error state, say
1902 * because it is a converting input stream which has encountered a
1903 * conversion error, the most recent GError object emitted by a read
1904 * operation on it is returned. Ownership of the return value is
1905 * retained, so if it is intended to be used after the next read
1906 * operation, it should be copied using g_error_copy().
1907 *
1908 * Since 2.0.5
1909 */
1910 GError* is_error() {return buf.is_input_error();}
1911
1912 /* Only has effect if --with-glib-memory-slices-compat or
1913 * --with-glib-memory-slices-no-compat option picked */
1914 CGU_GLIB_MEMORY_SLICES_FUNCS
1915 };
1916
1917
1918
1919 /**
1920 * @headerfile gstream.h c++-gtk-utils/gstream.h
1921 * @brief C++ input-output stream for GIO streams
1922 * @sa gstreams
1923 * @ingroup gstreams
1924 *
1925 * This class provides standard iostream services for GIO streams.
1926 */
1927 template <class charT , class Traits = std::char_traits<charT> >
1928 class basic_giostream : public std::basic_iostream<charT, Traits> {
1929
1930 basic_gstreambuf<charT , Traits> buf;
1931
1932 public:
1933 /**
1934 * This class cannot be copied. The copy constructor is deleted.
1935 */
1936 basic_giostream(const basic_giostream&) = delete;
1937
1938 /**
1939 * This class cannot be copied. The copy assignment operator is
1940 * deleted.
1941 */
1942 basic_giostream& operator=(const basic_giostream&) = delete;
1943
1944 /**
1945 * The constructor taking a GIO input-output stream. This class does
1946 * not offer concurrent access from multiple threads to the same
1947 * stream object, and if that is required users should provide their
1948 * own synchronisation.
1949 *
1950 * @param stream A GIO input-output stream to be attached. If the
1951 * caller wants the GIO stream to survive this class's destruction or
1952 * a call to close() or attach(), the caller should keep a separate
1953 * GobjHandle object which references the stream (obtained by, say,
1954 * calling get_gio_io_stream()) and pass 'manage' as false.
1955 *
1956 * @param manage Whether the underlying streambuffer should call
1957 * g_io_stream_close() on the GIO stream in the streambuffer's
1958 * destructor or when another stream is attached. Passing 'true' is
1959 * usually what is wanted, and is particularly relevant on output
1960 * streams because unless g_io_stream_close() is called, GIO may not
1961 * commit to disk - 'false' only makes sense if the caller keeps a
1962 * separate GobjHandle object which references the stream to keep it
1963 * alive (obtained by, say, calling get_gio_io_stream()). Unlike its
1964 * fdstreams equivalent, this parameter does not have a default value
1965 * of 'true': this is partly to make it less likely that a converter
1966 * is passed to this argument by mistake (that would not normally
1967 * cause a compiler warning because GobjHandle has a type conversion
1968 * operator providing the underlying C object by pointer, so
1969 * GobjHandles are type convertible to pointers, and such a pointer
1970 * will in turn provide a type match with a bool argument); and
1971 * partly because, given a GIOStream* p, the construction
1972 * \"Cgu::giostream str(Cgu::GobjHandle<GIOStream>(p));\" without
1973 * an additional argument or additional parentheses (or the use of
1974 * uniform initializer syntax using braces) would cause a compiler
1975 * error as it would be interpreted as a function declaration.
1976 *
1977 * @param input_converter A converter (if any) to be attached to the
1978 * input stream (note that this does not affect the operation of
1979 * set_byteswap()). The default value of an empty
1980 * GobjHandle<GConverter> object indicates no converter.
1981 *
1982 * @param output_converter A converter (if any) to be attached to the
1983 * output stream. The default value of an empty
1984 * GobjHandle<GConverter> object indicates no converter.
1985 *
1986 * @exception std::bad_alloc This constructor will throw
1987 * std::bad_alloc if memory is exhausted and the system throws on
1988 * such exhaustion (unless the library has been installed using the
1989 * \--with-glib-memory-slices-compat or
1990 * \--with-glib-memory-slices-no-compat configuration option, in
1991 * which case glib will terminate the program if it is unable to
1992 * obtain memory from the operating system). No other exception will
1993 * be thrown unless the constructor of std::basic_streambuf or
1994 * std::basic_iostream throws.
1995 *
1996 * @note If a converter is provided, the stream will no longer be
1997 * seekable even if it otherwise would be, so tellg(), tellp(),
1998 * seekg() and seekp() will no longer work (they will return
1999 * pos_type(off_type(-1)). If the stream to which a converter has
2000 * been attached represents a file on the file system (rather than a
2001 * socket), after a read has been made, no further write may be made
2002 * using the same GFileIOStream object. These restrictions do not
2003 * apply to sockets (which are not seekable) so the use of converters
2004 * with input-output streams (GIOStream) should generally be
2005 * restricted to sockets.
2006 */
2007 // using uniform initializer syntax here confuses doxygen
2008 basic_giostream(const GobjHandle<GIOStream>& stream,
2009 bool manage,
2010 const GobjHandle<GConverter>& input_converter = GobjHandle<GConverter>(),
2011 const GobjHandle<GConverter>& output_converter = GobjHandle<GConverter>()):
2012 std::basic_iostream<charT, Traits>(0),
2013 buf(stream, manage, input_converter, output_converter) {
2014 this->rdbuf(&buf); // std::basic_ios is a virtual base class
2015 }
2016
2017 /**
2018 * With this constructor, the GIO input-output stream must be
2019 * attached later with the attach() method. It will not throw unless
2020 * the constructor of std::basic_streambuf or std::basic_iostream
2021 * throws. This class does not offer concurrent access from multiple
2022 * threads to the same stream object, and if that is required users
2023 * should provide their own synchronisation.
2024 */
2025 // using uniform initializer syntax here confuses doxygen
2026 basic_giostream() : std::basic_iostream<charT, Traits>(0) {
2027 this->rdbuf(&buf); // std::basic_ios is a virtual base class
2028 }
2029
2030 /**
2031 * Attach a new GIO input-output stream to this object (and close any
2032 * GIO stream at present managed by it). If output buffering was
2033 * previously switched off, it is switched back on again. In the
2034 * case of wide character input-output streams, it also switches off
2035 * byte swapping on input, if it was previously on. If any stream
2036 * state flags were set (eofbit, failbit or badbit), they will be
2037 * cleared by a call to clear(). If this method closes a stream at
2038 * present managed by it and the close fails, failbit is not set and
2039 * no exception will be thrown. Accordingly, if the user needs to
2040 * know whether there was an error in this method closing any managed
2041 * stream, she should call close() explicitly before calling this
2042 * method. This class does not offer concurrent access from multiple
2043 * threads to the same stream object, and if that is required users
2044 * should provide their own synchronisation.
2045 *
2046 * @param stream A GIO input-output stream to be attached. If the
2047 * caller wants the GIO stream to survive a subsequent call to
2048 * close() or attach() or this class's destruction, the caller should
2049 * keep a separate GobjHandle object which references the stream
2050 * (obtained by, say, calling get_gio_io_stream()) and pass 'manage'
2051 * as false.
2052 *
2053 * @param manage Whether the underlying streambuffer should call
2054 * g_io_stream_close() on the GIO stream in the streambuffer's
2055 * destructor or when another stream is attached. Passing 'true' is
2056 * usually what is wanted, and is particularly relevant on output
2057 * streams because unless g_io_stream_close() is called, GIO may not
2058 * commit to disk - 'false' only makes sense if the caller keeps a
2059 * separate GobjHandle object which references the stream to keep it
2060 * alive (obtained by, say, calling get_gio_io_stream()). Unlike its
2061 * fdstreams equivalent, this parameter does not have a default value
2062 * of 'true': this is partly to make it less likely that a converter
2063 * is passed to this argument by mistake (that would not normally
2064 * cause a compiler warning because GobjHandle has a type conversion
2065 * operator providing the underlying C object by pointer, so
2066 * GobjHandles are type convertible to pointers, and such a pointer
2067 * will in turn provide a type match with a bool argument); and
2068 * partly to maintain compatibility with the constructor's interface,
2069 * which has separate syntactic constraints.
2070 *
2071 * @param input_converter A converter (if any) to be attached to the
2072 * input stream (note that this does not affect the operation of
2073 * set_byteswap()). The default value of an empty
2074 * GobjHandle<GConverter> object indicates no converter.
2075 *
2076 * @param output_converter A converter (if any) to be attached to the
2077 * output stream. The default value of an empty
2078 * GobjHandle<GConverter> object indicates no converter.
2079 *
2080 * @exception std::bad_alloc This method will throw std::bad_alloc if
2081 * memory is exhausted and the system throws on such exhaustion
2082 * (unless the library has been installed using the
2083 * \--with-glib-memory-slices-compat or
2084 * \--with-glib-memory-slices-no-compat configuration option, in
2085 * which case glib will terminate the program if it is unable to
2086 * obtain memory from the operating system).
2087 *
2088 * @note If a converter is provided, the stream will no longer be
2089 * seekable even if it otherwise would be, so tellg(), tellp(),
2090 * seekg() and seekp() will no longer work (they will return
2091 * pos_type(off_type(-1)). If the stream to which a converter has
2092 * been attached represents a file on the file system (rather than a
2093 * socket), after a read has been made, no further write may be made
2094 * using the same GFileIOStream object. These restrictions do not
2095 * apply to sockets (which are not seekable) so the use of converters
2096 * with input-output streams (GIOStream) should generally be
2097 * restricted to sockets.
2098 */
2099 void attach(const GobjHandle<GIOStream>& stream,
2100 bool manage,
2101 const GobjHandle<GConverter>& input_converter = GobjHandle<GConverter>(),
2102 const GobjHandle<GConverter>& output_converter = GobjHandle<GConverter>())
2103 {buf.attach_stream(stream, manage, input_converter, output_converter); this->clear();}
2104
2105 /**
2106 * Call g_io_stream_close() on the GIO stream at present attached (if
2107 * any), and release the underlying C++ streambuffer's reference to
2108 * that stream. If the caller wants the GIO stream to survive the
2109 * call to this method (albeit in a closed state), the caller should,
2110 * before the call is made, keep a separate GobjHandle object which
2111 * references the stream. If the close fails, the failbit will be
2112 * set with setstate(std::ios_base::failbit). This class does not
2113 * offer concurrent access from multiple threads to the same stream
2114 * object, and if that is required users should provide their own
2115 * synchronisation.
2116 *
2117 * @exception std::ios_base::failure This exception will be thrown if
2118 * an error arises on closing the stream and such an exception has
2119 * been required by a call to the exceptions() method of this class
2120 * (inherited from std::basic_ios<>). No exception will be thrown if
2121 * exceptions() has not been called.
2122 */
2123 void close() {if (!buf.close_stream()) this->setstate(std::ios_base::failbit);}
2124
2125 /**
2126 * Get the GIO input-output stream at present attached (if any), by
2127 * GobjHandle. If no stream has been attached, this method will
2128 * return an empty GobjHandle object. Retaining the return value
2129 * will cause the GIO input-output stream to survive the destruction
2130 * of this object. This method does not throw. This class does not
2131 * offer concurrent access from multiple threads to the same stream
2132 * object, and if that is required users should provide their own
2133 * synchronisation.
2134 *
2135 * @return The GIO input-output stream at present attached, or an
2136 * empty GobjHandle object if none has been attached
2137 */
2138 GobjHandle<GIOStream> get_gio_io_stream() const {return buf.get_iostream();}
2139
2140 /**
2141 * Get the underlying GIO output stream at present attached (if any),
2142 * by GobjHandle. If none has been attached, this method will return
2143 * an empty GobjHandle object. Retaining the return value will cause
2144 * the GIO output stream to survive the destruction of this object.
2145 * The return value may be a different stream from the one kept by
2146 * the GIOStream object passed to this object's constructor or to
2147 * attach(). It will be different if a converter has been attached
2148 * to it. This method does not throw. This class does not offer
2149 * concurrent access from multiple threads to the same stream object,
2150 * and if that is required users should provide their own
2151 * synchronisation.
2152 *
2153 * @return The GIO output stream at present attached, or an empty
2154 * GobjHandle object if none has been attached
2155 */
2156 GobjHandle<GOutputStream> get_gio_output_stream() const {return buf.get_ostream();}
2157
2158 /**
2159 * Get the GIO input stream at present attached (if any), by
2160 * GobjHandle. If none has been attached, this method will return an
2161 * empty GobjHandle object. Retaining the return value will cause
2162 * the GIO input stream to survive the destruction of this object. The
2163 * return value may be a different stream from the one kept by the
2164 * GIOStream object passed to this object's constructor or to
2165 * attach(). It will be different if a converter has been attached
2166 * to it. This method does not throw. This class does not offer
2167 * concurrent access from multiple threads to the same stream object,
2168 * and if that is required users should provide their own
2169 * synchronisation.
2170 *
2171 * @return The GIO input stream at present attached, or an empty
2172 * GobjHandle object if none has been attached
2173 */
2174 GobjHandle<GInputStream> get_gio_input_stream() const {return buf.get_istream();}
2175
2176 /**
2177 * Causes the underlying streambuffer to swap bytes in the incoming
2178 * text, so as to convert big endian text to little endian text, or
2179 * little endian text to big endian text. It is called by the user
2180 * in response to finding a byte order marker (BOM) 0xfffe (UTF-16)
2181 * or 0xfffe0000 (UTF-32) as the first character of a newly opened
2182 * file/stream, or if the user knows by some other means that the
2183 * native endianness of the machine doing the reading differs from
2184 * the endianness of the file/stream being read. This only has
2185 * effect on wide character streams for input (for example, a
2186 * wgiostream object), and not the giostream narrow character stream.
2187 * Note also that characters held for output are always outputted in
2188 * native endian format unless a GConverter object has been attached,
2189 * and this method does not affect that. This method does not throw.
2190 * This class does not offer concurrent access from multiple threads
2191 * to the same stream object, and if that is required users should
2192 * provide their own synchronisation.
2193 *
2194 * @param swap 'true' if byte swapping for input is to be turned on,
2195 * 'false' if it is to be turned off. This will affect all
2196 * characters extracted from the underlying streambuffer after this
2197 * call is made. If a previously extracted character is to be
2198 * putback(), it must be put back before this function is called (or
2199 * unget() should be called instead) to avoid a putback mismatch,
2200 * because this call will byte-swap anything already in the buffers.
2201 * (Characters extracted after the call to this method may be putback
2202 * normally.)
2203 */
2204 void set_byteswap(bool swap) {buf.set_byteswap(swap);}
2205
2206 /**
2207 * This method converts the attached GIO input-output stream to an
2208 * unbuffered stream for output if 'buffered' is false, or back to a
2209 * buffered stream if buffering has previously been switched off and
2210 * 'buffered' is true. Buffering is on by default for any newly
2211 * created giostream object and any newly attached GIO input-output
2212 * stream. If buffering is turned off, all characters at present in
2213 * the buffers which are stored for output are flushed (but if writing
2214 * to a file which is being written over/replaced, output may not
2215 * appear in the destination until the GIO stream is closed). This
2216 * method has no effect if no GIO input-output stream has yet been
2217 * attached. Switching output buffering off is similar in effect to
2218 * setting the std::ios_base::unitbuf flag, except that switching
2219 * buffering off is slightly more efficient, and setting the
2220 * std::ios_base::unitbuf flag will not retain the automatic tying of
2221 * logical and actual file positions that occurs when output buffering
2222 * is switched off, as explained @ref GioRandomAccessAnchor "here".
2223 * This class does not offer concurrent access from multiple threads
2224 * to the same stream object, and if that is required users should
2225 * provide their own synchronisation.
2226 *
2227 * @param buffered 'false' if buffering for output is to be turned
2228 * off, 'true' if it is to be turned back on.
2229 *
2230 * @exception std::bad_alloc This method will throw std::bad_alloc if
2231 * 'buffered' is true, output buffering had previously been switched
2232 * off, memory is exhausted and the system throws on such exhaustion
2233 * (unless the library has been installed using the
2234 * \--with-glib-memory-slices-compat or
2235 * \--with-glib-memory-slices-no-compat configuration option, in which
2236 * case glib will terminate the program if it is unable to obtain
2237 * memory from the operating system).
2238 */
2239 void set_output_buffered(bool buffered) {buf.set_output_buffered(buffered);}
2240
2241 /**
2242 * This method indicates whether the attached GIO stream implements
2243 * GSeekable, so that a call to tellg(), tellp(), seekg() or seekp()
2244 * can succeed. Note that in the seekg(off_type off,
2245 * ios_base::seekdir dir) and seekp(off_type off, ios_base::seekdir
2246 * dir) variants, on wide character streams the 'off' argument is
2247 * dimensioned as the number of wchar_t/char32_t/char16_t units not
2248 * the number of bytes (that is, it is bytes/sizeof(char_type)). This
2249 * method does not throw. This class does not offer concurrent access
2250 * from multiple threads to the same stream object, and if that is
2251 * required users should provide their own synchronisation.
2252 *
2253 * @return true if the attached GIO stream implements GSeekable,
2254 * otherwise false. The result is only meaningful if a GIO stream has
2255 * been attached to this C++ stream object.
2256 */
2257 bool can_seek() const {return buf.can_seek();}
2258
2259 /**
2260 * This method reports the error status of any attached GIO output
2261 * stream, and is intended to be called where failbit or badbit has
2262 * been set. It can be useful for interpreting conversion errors on
2263 * converting streams where one of those bits is set. This class does
2264 * not offer concurrent access from multiple threads to the same
2265 * stream object, and if that is required users should provide their
2266 * own synchronisation.
2267 *
2268 * @return NULL if no output stream is attached, or it is not in an
2269 * error state. If an attached output stream is in an error state,
2270 * say because it is a converting output stream which has encountered
2271 * a conversion error, the most recent GError object emitted by a
2272 * write operation on it is returned. Ownership of the return value
2273 * is retained, so if it is intended to be used after the next write
2274 * operation, it should be copied using g_error_copy().
2275 *
2276 * Since 2.0.5
2277 */
2278 GError* is_output_error() {return buf.is_output_error();}
2279
2280 /**
2281 * This method reports the error status of any attached GIO input
2282 * stream, and is intended to be called where failbit has been set.
2283 * It can be useful for establishing, where that bit is set, whether
2284 * failbit indicates normal end-of-file or a conversion error on a
2285 * converting stream. This class does not offer concurrent access
2286 * from multiple threads to the same stream object, and if that is
2287 * required users should provide their own synchronisation.
2288 *
2289 * @return NULL if no input stream is attached, or it is not in an
2290 * error state. If an attached input stream is in an error state, say
2291 * because it is a converting input stream which has encountered a
2292 * conversion error, the most recent GError object emitted by a read
2293 * operation on it is returned. Ownership of the return value is
2294 * retained, so if it is intended to be used after the next read
2295 * operation, it should be copied using g_error_copy().
2296 *
2297 * Since 2.0.5
2298 */
2299 GError* is_input_error() {return buf.is_input_error();}
2300
2301 /* Only has effect if --with-glib-memory-slices-compat or
2302 * --with-glib-memory-slices-no-compat option picked */
2303 CGU_GLIB_MEMORY_SLICES_FUNCS
2304 };
2305
2306 /**
2307 * @defgroup gstreams gstreams
2308 */
2309 /**
2310 * @typedef gstreambuf.
2311 * @brief C++ stream buffer for GIO streams for char type
2312 * @ingroup gstreams
2313 */
2314 typedef basic_gstreambuf<char> gstreambuf;
2315
2316 /**
2317 * @typedef gistream.
2318 * @brief C++ input stream for GIO streams for char type
2319 * @anchor gistreamAnchor
2320 * @ingroup gstreams
2321 */
2322 typedef basic_gistream<char> gistream;
2323
2324 /**
2325 * @typedef gostream.
2326 * @brief C++ output stream for GIO streams for char type
2327 * @anchor gostreamAnchor
2328 * @ingroup gstreams
2329 */
2330 typedef basic_gostream<char> gostream;
2331
2332 /**
2333 * @typedef giostream.
2334 * @brief C++ input/output stream for GIO streams for char type
2335 * @anchor giostreamAnchor
2336 * @ingroup gstreams
2337 */
2338 typedef basic_giostream<char> giostream;
2339
2340 /**
2341 * @typedef wgstreambuf.
2342 * @brief C++ stream buffer for GIO streams for wchar_t type
2343 * @ingroup gstreams
2344 */
2345 typedef basic_gstreambuf<wchar_t> wgstreambuf;
2346
2347 /**
2348 * @typedef wgistream.
2349 * @brief C++ input stream for GIO streams for wchar_t type
2350 * @anchor wgistreamAnchor
2351 * @ingroup gstreams
2352 */
2353 typedef basic_gistream<wchar_t> wgistream;
2354
2355 /**
2356 * @typedef wgostream.
2357 * @brief C++ output stream for GIO streams for wchar_t type
2358 * @anchor wgostreamAnchor
2359 * @ingroup gstreams
2360 */
2361 typedef basic_gostream<wchar_t> wgostream;
2362
2363 /**
2364 * @typedef wgiostream.
2365 * @brief C++ input/output stream for GIO streams for wchar_t type
2366 * @anchor wgiostreamAnchor
2367 * @ingroup gstreams
2368 */
2369 typedef basic_giostream<wchar_t> wgiostream;
2370
2371 /**
2372 * @typedef u16gstreambuf.
2373 * @brief C++ stream buffer for GIO streams for char16_t type
2374 * @ingroup gstreams
2375 */
2376 typedef basic_gstreambuf<char16_t> u16gstreambuf;
2377
2378 /**
2379 * @typedef u16gistream.
2380 * @brief C++ input stream for GIO streams for char16_t type
2381 * @anchor u16gistreamAnchor
2382 * @ingroup gstreams
2383 */
2384 typedef basic_gistream<char16_t> u16gistream;
2385
2386 /**
2387 * @typedef u16gostream.
2388 * @brief C++ output stream for GIO streams for char16_t type
2389 * @anchor u16gostreamAnchor
2390 * @ingroup gstreams
2391 */
2392 typedef basic_gostream<char16_t> u16gostream;
2393
2394 /**
2395 * @typedef u16giostream.
2396 * @brief C++ input/output stream for GIO streams for char16_t type
2397 * @anchor u16giostreamAnchor
2398 * @ingroup gstreams
2399 */
2400 typedef basic_giostream<char16_t> u16giostream;
2401
2402 /**
2403 * @typedef u32gstreambuf.
2404 * @brief C++ stream buffer for GIO streams for char32_t type
2405 * @ingroup gstreams
2406 */
2407 typedef basic_gstreambuf<char32_t> u32gstreambuf;
2408
2409 /**
2410 * @typedef u32gistream.
2411 * @brief C++ input stream for GIO streams for char32_t type
2412 * @anchor u32gistreamAnchor
2413 * @ingroup gstreams
2414 */
2415 typedef basic_gistream<char32_t> u32gistream;
2416
2417 /**
2418 * @typedef u32gostream.
2419 * @brief C++ output stream for GIO streams for char32_t type
2420 * @anchor u32gostreamAnchor
2421 * @ingroup gstreams
2422 */
2423 typedef basic_gostream<char32_t> u32gostream;
2424
2425 /**
2426 * @typedef u32giostream.
2427 * @brief C++ input/output stream for GIO streams for char32_t type
2428 * @anchor u32giostreamAnchor
2429 * @ingroup gstreams
2430 */
2431 typedef basic_giostream<char32_t> u32giostream;
2432
2433 } // namespace Cgu
2434
2435 #include <c++-gtk-utils/gstream.tpp>
2436
2437 #else
2438 #warning gstreams are not available: glib >= 2.16.0 is required
2439 #endif /*GLIB_CHECK_VERSION(2,16,0)*/
2440
2441 #endif /*CGU_GSTREAM_H*/
Cgu::basic_giostream::set_output_buffered
void set_output_buffered(bool buffered)
Definition: gstream.h:2239
Cgu::wgstreambuf
basic_gstreambuf< wchar_t > wgstreambuf
C++ stream buffer for GIO streams for wchar_t type.
Definition: gstream.h:2345
Cgu::basic_gstreambuf::~basic_gstreambuf
virtual ~basic_gstreambuf()
Cgu::u32gistream
basic_gistream< char32_t > u32gistream
C++ input stream for GIO streams for char32_t type.
Definition: gstream.h:2415
Cgu::basic_gostream
C++ output stream for GIO streams.
Definition: gstream.h:1369
Cgu
Definition: application.h:44
Cgu::gstreambuf
basic_gstreambuf< char > gstreambuf
C++ stream buffer for GIO streams for char type.
Definition: gstream.h:2314
Cgu::wgiostream
basic_giostream< wchar_t > wgiostream
C++ input/output stream for GIO streams for wchar_t type.
Definition: gstream.h:2369
Cgu::basic_giostream::is_output_error
GError * is_output_error()
Definition: gstream.h:2278
Cgu::basic_giostream::basic_giostream
basic_giostream(const GobjHandle< GIOStream > &stream, bool manage, const GobjHandle< GConverter > &input_converter=GobjHandle< GConverter >(), const GobjHandle< GConverter > &output_converter=GobjHandle< GConverter >())
Definition: gstream.h:2008
Cgu::basic_gstreambuf::seekoff
virtual pos_type seekoff(off_type off, std::ios_base::seekdir way, std::ios_base::openmode m=std::ios_base::in|std::ios_base::out)
Cgu::basic_giostream::close
void close()
Definition: gstream.h:2123
Cgu::GobjHandle< GInputStream >
Cgu::basic_giostream::operator=
basic_giostream & operator=(const basic_giostream &)=delete
Cgu::basic_gstreambuf::off_type
traits_type::off_type off_type
Definition: gstream.h:532
Cgu::basic_gistream::operator=
basic_gistream & operator=(const basic_gistream &)=delete
Cgu::wgostream
basic_gostream< wchar_t > wgostream
C++ output stream for GIO streams for wchar_t type.
Definition: gstream.h:2361
Cgu::basic_gstreambuf::is_output_error
GError * is_output_error()
Cgu::basic_gistream::basic_gistream
basic_gistream(const GobjHandle< GInputStream > &stream, bool manage, const GobjHandle< GConverter > &converter=GobjHandle< GConverter >())
Definition: gstream.h:1725
Cgu::basic_gistream
C++ input stream for GIO streams.
Definition: gstream.h:1652
Cgu::basic_gstreambuf::can_seek
bool can_seek() const
Definition: gstream.h:1314
Cgu::basic_giostream::attach
void attach(const GobjHandle< GIOStream > &stream, bool manage, const GobjHandle< GConverter > &input_converter=GobjHandle< GConverter >(), const GobjHandle< GConverter > &output_converter=GobjHandle< GConverter >())
Definition: gstream.h:2099
Cgu::basic_gstreambuf::xsgetn
virtual std::streamsize xsgetn(char_type *, std::streamsize)
Cgu::giostream
basic_giostream< char > giostream
C++ input/output stream for GIO streams for char type.
Definition: gstream.h:2338
Cgu::u32gostream
basic_gostream< char32_t > u32gostream
C++ output stream for GIO streams for char32_t type.
Definition: gstream.h:2423
Cgu::swap
void swap(Cgu::AsyncQueue< T, Container > &q1, Cgu::AsyncQueue< T, Container > &q2)
Definition: async_queue.h:1493
Cgu::basic_gostream::operator=
basic_gostream & operator=(const basic_gostream &)=delete
Cgu::basic_gstreambuf::set_byteswap
void set_byteswap(bool swap)
Cgu::basic_gostream::is_error
GError * is_error()
Definition: gstream.h:1634
Cgu::basic_gistream::set_byteswap
void set_byteswap(bool swap)
Definition: gstream.h:1872
Cgu::GSliceFreeSize
A deleter functor for use as the second (Dealloc) template parameter of the SharedHandle,...
Definition: shared_handle.h:421
Cgu::basic_gstreambuf::close_stream
bool close_stream()
gobj_handle.h
Cgu::basic_gstreambuf::operator=
basic_gstreambuf & operator=(const basic_gstreambuf &)=delete
Cgu::basic_gstreambuf::int_type
traits_type::int_type int_type
Definition: gstream.h:530
Cgu::basic_gistream::attach
void attach(const GobjHandle< GInputStream > &stream, bool manage, const GobjHandle< GConverter > &converter=GobjHandle< GConverter >())
Definition: gstream.h:1806
Cgu::basic_gostream::set_buffered
void set_buffered(bool buffered)
Definition: gstream.h:1596
Cgu::u16giostream
basic_giostream< char16_t > u16giostream
C++ input/output stream for GIO streams for char16_t type.
Definition: gstream.h:2400
Cgu::basic_giostream::basic_giostream
basic_giostream()
Definition: gstream.h:2026
Cgu::gostream
basic_gostream< char > gostream
C++ output stream for GIO streams for char type.
Definition: gstream.h:2330
Cgu::basic_gstreambuf::set_output_buffered
void set_output_buffered(bool buffered)
Cgu::basic_gstreambuf::get_istream
GobjHandle< GInputStream > get_istream() const
Cgu::basic_giostream
C++ input-output stream for GIO streams.
Definition: gstream.h:1928
Cgu::basic_giostream::get_gio_io_stream
GobjHandle< GIOStream > get_gio_io_stream() const
Definition: gstream.h:2138
Cgu::basic_giostream::is_input_error
GError * is_input_error()
Definition: gstream.h:2299
Cgu::basic_gstreambuf::underflow
virtual int_type underflow()
Cgu::basic_gstreambuf::overflow
virtual int_type overflow(int_type)
Cgu::basic_gstreambuf::get_iostream
GobjHandle< GIOStream > get_iostream() const
gerror_handle.h
Cgu::basic_gstreambuf::is_input_error
GError * is_input_error()
Cgu::basic_gostream::basic_gostream
basic_gostream()
Definition: gstream.h:1461
Cgu::basic_gostream::attach
void attach(const GobjHandle< GOutputStream > &stream, bool manage, const GobjHandle< GConverter > &converter=GobjHandle< GConverter >())
Definition: gstream.h:1525
Cgu::basic_gstreambuf::attach_stream
void attach_stream(const GobjHandle< GInputStream > &input_stream_, bool manage_, const GobjHandle< GConverter > &converter_=GobjHandle< GConverter >())
CGU_GLIB_MEMORY_SLICES_FUNCS
#define CGU_GLIB_MEMORY_SLICES_FUNCS
Definition: cgu_config.h:84
Cgu::basic_giostream::get_gio_output_stream
GobjHandle< GOutputStream > get_gio_output_stream() const
Definition: gstream.h:2156
shared_handle.h
Cgu::basic_gistream::get_gio_stream
GobjHandle< GInputStream > get_gio_stream() const
Definition: gstream.h:1846
Cgu::u32gstreambuf
basic_gstreambuf< char32_t > u32gstreambuf
C++ stream buffer for GIO streams for char32_t type.
Definition: gstream.h:2407
Cgu::basic_gistream::close
void close()
Definition: gstream.h:1829
Cgu::u32giostream
basic_giostream< char32_t > u32giostream
C++ input/output stream for GIO streams for char32_t type.
Definition: gstream.h:2431
Cgu::basic_gistream::basic_gistream
basic_gistream()
Definition: gstream.h:1742
Cgu::basic_gostream::get_gio_stream
GobjHandle< GOutputStream > get_gio_stream() const
Definition: gstream.h:1565
Cgu::basic_giostream::get_gio_input_stream
GobjHandle< GInputStream > get_gio_input_stream() const
Definition: gstream.h:2174
Cgu::basic_gostream::close
void close()
Definition: gstream.h:1548
Cgu::u16gostream
basic_gostream< char16_t > u16gostream
C++ output stream for GIO streams for char16_t type.
Definition: gstream.h:2392
Cgu::basic_gstreambuf::seekpos
virtual pos_type seekpos(pos_type p, std::ios_base::openmode m=std::ios_base::in|std::ios_base::out)
Cgu::ScopedHandle
This is a generic scoped class for managing the lifetime of objects allocated on freestore.
Definition: shared_handle.h:452
Cgu::basic_gistream::can_seek
bool can_seek() const
Definition: gstream.h:1889
Cgu::u16gistream
basic_gistream< char16_t > u16gistream
C++ input stream for GIO streams for char16_t type.
Definition: gstream.h:2384
Cgu::basic_gstreambuf::sync
virtual int sync()
Cgu::basic_gstreambuf::pos_type
traits_type::pos_type pos_type
Definition: gstream.h:531
Cgu::basic_gstreambuf
C++ stream buffer for GIO streams.
Definition: gstream.h:525
Cgu::gistream
basic_gistream< char > gistream
C++ input stream for GIO streams for char type.
Definition: gstream.h:2322
Cgu::basic_giostream::can_seek
bool can_seek() const
Definition: gstream.h:2257
Cgu::basic_gstreambuf::xsputn
virtual std::streamsize xsputn(const char_type *, std::streamsize)
Cgu::basic_gostream::basic_gostream
basic_gostream(const GobjHandle< GOutputStream > &stream, bool manage, const GobjHandle< GConverter > &converter=GobjHandle< GConverter >())
Definition: gstream.h:1444
Cgu::basic_gstreambuf::basic_gstreambuf
basic_gstreambuf()
Cgu::wgistream
basic_gistream< wchar_t > wgistream
C++ input stream for GIO streams for wchar_t type.
Definition: gstream.h:2353
Cgu::basic_gstreambuf::get_ostream
GobjHandle< GOutputStream > get_ostream() const
Cgu::basic_giostream::set_byteswap
void set_byteswap(bool swap)
Definition: gstream.h:2204
Cgu::basic_gistream::is_error
GError * is_error()
Definition: gstream.h:1910
Cgu::u16gstreambuf
basic_gstreambuf< char16_t > u16gstreambuf
C++ stream buffer for GIO streams for char16_t type.
Definition: gstream.h:2376
cgu_config.h
Cgu::basic_gstreambuf::char_type
charT char_type
Definition: gstream.h:528
Cgu::basic_gstreambuf::traits_type
Traits traits_type
Definition: gstream.h:529
Cgu::basic_gostream::can_seek
bool can_seek() const
Definition: gstream.h:1613