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