c++-gtk-utils
fdstream.h
Go to the documentation of this file.
1 /* Copyright (C) 2001, 2004, 2009, 2010, 2011 and 2012 Chris Vine
2 
3  The following code declares classes to read from and write to
4  Unix file descriptors.
5 
6  The whole work comprised in files fdstream.h and fdstream.tpp is
7  distributed by Chris Vine under the GNU Lesser General Public License
8  as follows:
9 
10  This library is free software; you can redistribute it and/or
11  modify it under the terms of the GNU Lesser General Public License
12  as published by the Free Software Foundation; either version 2.1 of
13  the License, or (at your option) any later version.
14 
15  This library is distributed in the hope that it will be useful, but
16  WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  Lesser General Public License for more details.
19 
20  You should have received a copy of the GNU Lesser General Public
21  License, version 2.1, along with this library (see the file LGPL.TXT
22  which came with this source code package in the c++-gtk-utils
23  sub-directory); if not, write to the Free Software Foundation, Inc.,
24  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 
26 However, it is not intended that the object code of a program whose
27 source code instantiates a template from this file or uses macros or
28 inline functions (of any length) should by reason only of that
29 instantiation or use be subject to the restrictions of use in the GNU
30 Lesser General Public License. With that in mind, the words "and
31 macros, inline functions and instantiations of templates (of any
32 length)" shall be treated as substituted for the words "and small
33 macros and small inline functions (ten lines or less in length)" in
34 the fourth paragraph of section 5 of that licence. This does not
35 affect any other reason why object code may be subject to the
36 restrictions in that licence (nor for the avoidance of doubt does it
37 affect the application of section 2 of that licence to modifications
38 of the source code in this file).
39 
40 The attach(), close() and xsputn() methods added by Chris Vine, 2001.
41 All the classes were rewritten, and also provided in template form for
42 wide characters, by Chris Vine 2004.
43 */
44 
45 /**
46  * @defgroup fdstreams fdstreams
47  *
48  * \#include <c++-gtk-utils/fdstream.h>
49  *
50  * The c++-gtk-utils library contains classes providing streambuffers
51  * and stream objects for unix file descriptors.
52  *
53  * By default, like the fstream::fstream(int fd) and
54  * fstream::attach(int fd) extensions in libstdc++-v2, the destructors
55  * of these classes close the file descriptors concerned, which helps
56  * exception safety (the attach() method will also close any previous
57  * file descriptor). If this behaviour is not wanted, pass 'false' as
58  * the second argument of fdostream/fdistream constructor or of the
59  * attach() method. This will enable the same file descriptor to be
60  * used successively for, say, reading and writing, or to be shared
61  * between fdistream and fdostream objects (but if the file descriptor
62  * represents a device providing random access, such as a local file
63  * on the filesystem, which has been opened for both reading and
64  * writing, the special precautions described under @ref
65  * FdRandomAccessAnchor "fdstreams and random access" are required).
66  *
67  * Here are some examples of use:
68  *
69  * @code
70  * // the safe creation of a temporary file with standard iostreams
71  * char filename[] = "/tmp/myprog-XXXXXX";
72  * Cgu::fdostream ostrm;
73  * int fd = mkstemp(filename);
74  * if (fd != -1) {
75  * ostrm.attach(fd); // take ownership of the file descriptor
76  * ostrm << "Temporary file text" << std::endl;
77  * }
78  * else {
79  * std::cerr << "Can't open temporary file " << filename
80  * << ", please check permissions" << std::endl;
81  * }
82  *
83  * --------------------------------------------------------------------
84  *
85  * // mimic std::cout but explicitly use UNIX stdout
86  * Cgu::fdostream out(1, false); // don't take ownership of the file descriptor
87  * out << "Hello" << std::endl;
88  *
89  * --------------------------------------------------------------------
90  *
91  * // read line delimited text from a pipe until it is closed by the
92  * // writer: assume 'fd' is the read file descriptor of the pipe
93  * Cgu::fdistream istrm(fd); // take ownership of the read file descriptor
94  * std::string line;
95  * while (std::getline(istrm, line)) {
96  * [ ... do something with the read text ... ]
97  * }
98  * @endcode
99  *
100  *
101  * @note 1. Users cannot (except by derivation) use the virtual
102  * protected methods of the streambuffer classes, including xsgetn()
103  * and xsputn(). Instead, if they want direct access to the
104  * streambuffer other than through the fdostreamfdistream methods (or
105  * their wide stream equivalents), they should use the public
106  * forwarding functions provided by std::streambuf base class.
107  * @note 2. These streambuffers and stream objects are not copiable.
108  *
109  * @b Buffering
110  *
111  * The streambuffer classes provide buffering for both input and
112  * output, although output buffering can be switched off using the
113  * set_buffered() method.
114  *
115  * The streambuf classes provide a block read and write in xsgetn()
116  * and xsputn(), which will be called by the read() and write()
117  * methods (and some other output operators) inherited by (w)fdistream
118  * and (w)fdostream from std::basic_istream and std::basic_ostream.
119  * They operate (after appropriately vacating and resetting the
120  * buffers) by doing a block read and write by calling Unix read() and
121  * write() and are very efficient for large block reads (those
122  * significantly exceeding the buffer size). If users want all reads
123  * and writes to go through the buffers, by using
124  * std::basic_streambuf<>::xsputn() and
125  * std::basic_streambuf<>::xsgetn() then the symbol
126  * FDSTREAM_USE_STD_N_READ_WRITE can be defined for the purpose before
127  * fdstream.h is \#include'd. (libstdc++-3 provides efficient inbuilt
128  * versions of these std::basic_streambuf functions for block reads
129  * not significantly larger than the buffer size, provided output
130  * buffering has not been turned off by the set_buffered() method of
131  * the output streambuffer or stream object.)
132  *
133  * One possible case for defining that symbol is where the user wants
134  * to use the tie() method of (w)fdistream (inherited from
135  * std::basic_ios) to procure flushing of an output stream before
136  * extraction from an input stream is made by (w)fdistream::read().
137  * Such flushing might not occur where a call to (w)fdistream::read()
138  * is made unless FDSTREAM_USE_STD_N_READ_WRITE is defined, because an
139  * implementation is permitted to defer such flushing until
140  * underflow() occurs, and the block read by (w)fdistream::read(), as
141  * forwarded to xsgetn(), will never invoke underflow() if that symbol
142  * is not defined. (Having said that, any basic_istream
143  * implementation which does defer output flushing until underflow()
144  * is called makes tie() unusable anyway for a number of purposes,
145  * because the time of flushing would become dependent on whether a
146  * read request can be satisfied by what is already in the buffers.)
147  *
148  * 4 characters are stored and available for putback. However, if the
149  * symbol FDSTREAM_USE_STD_N_READ_WRITE is not defined, then a call to
150  * fdinbuf::xsgetn() via (w)fdistream::read() with a request for less
151  * than 4 characters will result in less than 4 characters available
152  * for putback (if these block read methods obtain some characters but
153  * less than 4, only the number of characters obtained by them is
154  * guaranteed to be available for putback).
155  *
156  * @anchor FdRandomAccessAnchor
157  * @b fdstreams @b and @b random @b access
158  *
159  * For file descriptors representing files which offer random access,
160  * the classes in this c++-gtk-utils library implement the tellg(),
161  * tellp(), seekg() and seekp() random access methods.
162  *
163  * The presence of buffering does not impede this where a file
164  * descriptor is only opened for reading or only opened for writing.
165  * However, it presents complications if a fdistream object and a
166  * fdostream object (or their wide stream equivalents) reference the
167  * same file descriptor on a file which offers random access and which
168  * is opened for both reading and writing. To prevent the file
169  * pointer getting out of sync with the buffers maintained by the
170  * fdistream and fdostream objects, if the last operation carried out
171  * on the fdostream/fdistream pair was a write then, if the output
172  * stream is set as buffered (the default), before the first read
173  * operation thereafter is made on the pair or a call to seekg() is
174  * made, the fdostream object must be flushed by calling
175  * std::ostream::flush() or by using the std::flush manipulator (or
176  * setting the std::ios_base::unitbuf flag). If the last operation on
177  * the pair (having, say, the names 'ostr' and 'istr') was a read,
178  * then before the first write operation thereafter is made on the
179  * pair, or a call to seekp() is made, the user must call
180  * istr.seekg(istr.tellg()) in order to synchronise the logical and
181  * actual file positions, or if the user does not want to maintain the
182  * current logical file position, make some other call to seekg() on
183  * 'istr' which does not comprise only seekg(0, std::ios_base::cur).
184  * This requirement to call seekg() when moving from reading to
185  * writing applies whether or not the output stream is buffered. It
186  * similarly applies to the wide stream classes.
187  *
188  * Note that the tie() method of (w)fdistream (inherited from
189  * std::basic_ios) cannot reliably to used to procure output flushing
190  * of a (w)fdostream object before a read is made, unless
191  * FDSTREAM_USE_STD_N_READ_WRITE is defined before fdstream.h is
192  * \#include'd, for the reason mentioned under "Buffering" above.
193  *
194  * Where a file is to be opened for both reading and writing and more
195  * automatic tying of input and output is wanted, the Cgu::giostream
196  * classes or their wide stream equivalents can be used in conjunction
197  * with GIO streams.
198  *
199  * None of these restrictions applies to file descriptors opened for
200  * reading and writing which represent devices for which the operating
201  * system does not maintain file pointers, such as sockets. They can
202  * be attached to a fdostream and fdistream object without any special
203  * precautions being taken, other than the normal step of calling
204  * fdostream::flush() (or using the std::flush manipulator) to flush
205  * the output buffer to the socket if the user needs to know that that
206  * has happened (or setting output buffering off with the
207  * set_buffered() method). In summary, on a socket, a read does not
208  * automatically flush the output buffer: it is for the user to do
209  * that. Note also that only one of the stream objects should be set
210  * to manage the file descriptor, and this should normally be the
211  * output stream as it may have characters to flush when closing.
212  *
213  * A (w)fdostream and (w)fdistream object should not reference the
214  * same file descriptor on any file on a file system which permits
215  * read-write opening of files and reports itself as not supporting
216  * random access, but which in fact maintains a file position pointer
217  * which is shared for reading and writing. This might apply to some
218  * network file systems. The best rule to apply is not to reference
219  * the same file descriptor on a (w)fdostream and (w)fdistream object
220  * if the device is not a socket, unless can_seek() returns true.
221  *
222  * @b Wide @b streams @b and @b endianness
223  *
224  * This library provides typedef'ed instances of the template classes
225  * for wchar_t, char16_t and char32_t characters. With the wide
226  * stream ostream classes and wide character output streambuffer
227  * classes, wide characters are written out in the native endian
228  * format of the writing machine. Special steps need to be taken if
229  * the text which is sent for output might be read by machines with a
230  * different endianness.
231  *
232  * No such special steps are required where the wide character classes
233  * are used with temporary files, pipes, fifos, unix domain sockets
234  * and network sockets on localhost, because in those cases they will
235  * be read by the same machine that writes; but they are required
236  * where sockets communicate with other computers over a network or
237  * when writing to files which may be distributed to and read by other
238  * computers with different endianness.
239  *
240  * Where wide characters are to be exported to other machines, one
241  * useful approach is to convert to and from UTF-8 with
242  * Utf8::uniwide_from_utf8(), Utf8::uniwide_to_utf8(),
243  * Utf8::wide_from_utf8() or Utf8::wide_to_utf8(), and to use
244  * fdostream/fdistream with the converted text. Alternatively, the
245  * wgostream, wgistream and wgiostream classes (and their char16_t and
246  * char32_t equivalents) can be used for the purposes of attaching a
247  * UTF-8 converter directly to a GIO stream. (Those classes also
248  * enable a UTF-32LE to UTF-32BE converter, and vice versa, to be
249  * attached to an output stream for the purpose of writing out UTF-32
250  * in other than native endianness, and similarly as regards UTF-16.)
251  *
252  * Instead of converting exported text to UTF-8, another approach is
253  * to use a byte order marker (BOM) as the first character of the wide
254  * stream output. UCS permits a BOM character to be inserted,
255  * comprising static_cast<wchar_t>(0xfeff),
256  * static_cast<char16_t>(0xfeff) or static_cast<char32_t>(0xfeff), at
257  * the beginning of the output to the wide character stream. At the
258  * receiving end, this will appear as 0xfffe (UTF-16) or 0xfffe0000
259  * (UTF-32) to a big endian machine with 8 bit char type if the text
260  * is little endian, or to a little endian machine with big endian
261  * text, so signaling a need to undertake byte swapping of text read
262  * from the stream. Another alternative is to label the physical
263  * medium conveying the file as UTF-16LE, UTF-16BE, UTF-32LE or
264  * UTF-32BE, as the case may be, in which case a BOM character should
265  * not be prepended.
266  *
267  * Where it is established by either means that the input stream
268  * requires byte swapping, the wide character input stream and wide
269  * character input streambuffer classes have a set_byteswap() member
270  * function which should be called on opening the input stream as soon
271  * as it has been established that byte swapping is required. Once
272  * this function has been called with an argument of 'true', all
273  * further calls to stream functions which provide characters will
274  * provide those characters with the correct native endianness.
275  * Calling set_byteswap() on the narrow stream fdistream or fdinbuf
276  * objects has no effect (byte order is irrelevant to narrow streams).
277  *
278  * Here is an example of such use in a case where sizeof(wchar_t) is
279  * 4:
280  *
281  * @code
282  * int fd = open("filename", O_RDONLY);
283  * Cgu::wfdistream input;
284  * if (fd != -1)
285  * input.attach(fd); // take ownership of the file descriptor
286  * else {
287  * std::cerr << "Can't open file 'filename', "
288  * << "please check permissions" << std::endl;
289  * return;
290  * }
291  * wchar_t item;
292  * input.get(item);
293  * if (!input) {
294  * std::cerr << "File 'filename' is empty" << std::endl;
295  * return;
296  * }
297  * if (item == static_cast<wchar_t>(0xfffe0000))
298  * input.set_byteswap(true);
299  * else if (item != static_cast<wchar_t>(0xfeff)) {
300  * // calling set_byteswap() will manipulate the buffers, so
301  * // either call putback() before we call set_byteswap(), or
302  * // call unget() instead
303  * input.putback(item);
304  * // the first character is not a BOM character so assume big endian
305  * // format, and byte swap if the local machine is little endian
306  * #if G_BYTE_ORDER == G_LITTLE_ENDIAN
307  * input.set_byteswap(true);
308  * #endif
309  * }
310  * [ ... do something with the input file ... ]
311  * @endcode
312  *
313  * @b Other @b wide @b stream @b issues
314  *
315  * basic_fdostream, basic_fdoutbuf, basic_fdistream and basic_fdinbuf
316  * objects can be instantiated for any integer type which has an
317  * appropriate traits class provided for it which has the copy(),
318  * eof(), eq_int_type(), move(), not_eof() and to_int_type() static
319  * member functions. The integer type could in fact have any size,
320  * but the set_byteswap() methods for basic_fdistream and
321  * basic_fdinbuf will only have an effect if its size is either 2 or
322  * 4. Typedef'ed instances of the classes are provided by the library
323  * for characters of type wchar_t, char16_t and char32_t.
324  */
325 
326 #ifndef CGU_FDSTREAM_H
327 #define CGU_FDSTREAM_H
328 
329 // see above for what this does
330 //#define FDSTREAM_USE_STD_N_READ_WRITE 1
331 
332 #include <unistd.h>
333 #include <sys/types.h>
334 #include <errno.h>
335 #include <istream>
336 #include <ostream>
337 #include <streambuf>
338 #include <algorithm>
339 #include <string>
340 #include <cstddef>
341 
344 
345 namespace Cgu {
346 
347 /*
348 The following convenience typedefs appear at the end of this file:
349 typedef basic_fdinbuf<char> fdinbuf;
350 typedef basic_fdoutbuf<char> fdoutbuf;
351 typedef basic_fdistream<char> fdistream;
352 typedef basic_fdostream<char> fdostream;
353 typedef basic_fdinbuf<wchar_t> wfdinbuf;
354 typedef basic_fdoutbuf<wchar_t> wfdoutbuf;
355 typedef basic_fdistream<wchar_t> wfdistream;
356 typedef basic_fdostream<wchar_t> wfdostream;
357 typedef basic_fdinbut<char16_t> u16fdinbuf;
358 typedef basic_fdoutbuf<char16_t> u16fdoutbuf;
359 typedef basic_fdistream<char16_t> u16fdistream;
360 typedef basic_fdostream<char16_t> u16fdostream;
361 typedef basic_fdinbut<char32_t> u32fdinbuf;
362 typedef basic_fdoutbuf<char32_t> u32fdoutbuf;
363 typedef basic_fdistream<char32_t> u32fdistream;
364 typedef basic_fdostream<char32_t> u32fdostream;
365 */
366 
367 
368 /**
369  * @headerfile fdstream.h c++-gtk-utils/fdstream.h
370  * @brief Output stream buffer for unix file descriptors
371  * @sa fdstreams
372  * @ingroup fdstreams
373  *
374  * This class provides an output stream buffer for unix file
375  * descriptors. It does the buffering for the basic_fdostream stream
376  * class.
377  */
378 template <class charT , class Traits = std::char_traits<charT> >
379 class basic_fdoutbuf: public std::basic_streambuf<charT, Traits> {
380 
381 public:
382  typedef charT char_type;
383  typedef Traits traits_type;
384  typedef typename traits_type::int_type int_type;
385  typedef typename traits_type::pos_type pos_type;
386  typedef typename traits_type::off_type off_type;
387 
388 private:
389  int fd; // file descriptor
390  bool manage;
391 
392  static const int buf_size = 1024; // size of the data write buffer
393 #if defined(CGU_USE_GLIB_MEMORY_SLICES_COMPAT) || defined(CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT)
396 #else
398 #endif
399  int flush_buffer();
400 
401 protected:
402 /**
403  * This method will not throw. fdstreams do not offer concurrent
404  * access from multiple threads to the same stream object, and if that
405  * is required users should provide their own synchronisation.
406  */
407  virtual int sync();
408 
409 /**
410  * This method will not throw unless std::basic_streambuf<>::sputc()
411  * throws, which it would not do on any sane implementation. This
412  * means that the output functions of stream objects which have this
413  * streambuffer as a member will not throw unless the underlying
414  * functions of the std::basic_ostream class throw, which they would
415  * not normally do unless they have been required to do so on failbit,
416  * badbit or eofbit being set by an explicit call to the exceptions()
417  * method of that class. fdstreams do not offer concurrent access
418  * from multiple threads to the same stream object, and if that is
419  * required users should provide their own synchronisation.
420  */
421  virtual int_type overflow(int_type);
422 
423 #ifndef FDSTREAM_USE_STD_N_READ_WRITE
424 /**
425  * This method will not throw. This means that the output functions
426  * of stream objects which have this streambuffer as a member will not
427  * throw unless the underlying functions of the std::basic_ostream
428  * class throw, which they would not normally do unless they have been
429  * required to do so on failbit, badbit or eofbit being set by an
430  * explicit call to the exceptions() method of that class. fdstreams
431  * do not offer concurrent access from multiple threads to the same
432  * stream object, and if that is required users should provide their
433  * own synchronisation.
434  */
435  virtual std::streamsize xsputn(const char_type*, std::streamsize);
436 #endif
437 
438 /**
439  * This method provides random access on output devices that support
440  * it, so supporting the tellp() and seekp() methods of the
441  * basic_fdostream class. Any output buffer will be flushed. This
442  * method does not throw, but if it returns pos_type(off_type(-1)) to
443  * indicate failure, it will cause the seekp() or tellp() methods of
444  * the relevant stream class to throw std::ios_base::failure if such
445  * an exception has been required by an explicit call to the
446  * exceptions() method of that class (but not otherwise). fdstreams
447  * do not offer concurrent access from multiple threads to the same
448  * stream object, and if that is required users should provide their
449  * own synchronisation.
450  *
451  * @param off The offset to be applied to the 'way' argument when
452  * seeking. It is a signed integer type, and on wide character
453  * streams is dimensioned as the number of wchar_t units not the
454  * number of bytes (that is, it is bytes/sizeof(char_type)).
455  *
456  * @param way The file position to which the 'off' argument is to be
457  * applied (either std::ios_base::beg, std::ios_base::cur or
458  * std::ios_base::end).
459  *
460  * @param m The required read/write status of the file descriptor
461  * attached to this streambuffer for this method to attempt a seek.
462  * As this is an output streambuffer, the argument should have the
463  * std::ios_base::out bit set. Provided that bit is set, it doesn't
464  * matter if others are also set.
465  *
466  * @return If the seek succeeds, a std::char_traits<T>::pos_type
467  * object representing the new stream position of the streambuffer
468  * after the seek. (This type is std::streampos for narrow character
469  * (char) streams, std::wstreampos for wide character (wchar_t)
470  * streams, std::u16streampos for the char16_t type and
471  * std::u32streampos for the char32_t type.) If the seek failed,
472  * pos_type(off_type(-1)) is returned.
473  */
474  virtual pos_type seekoff(off_type off,
475  std::ios_base::seekdir way,
476  std::ios_base::openmode m = std::ios_base::in | std::ios_base::out);
477 
478 /**
479  * This method provides random access on output devices that support
480  * it, so supporting the seekp() method of the basic_fdostream class.
481  * It is equivalent to seekoff(off_type(p), std::ios_base::beg, m).
482  * Any output buffer will be flushed. This method does not throw, but
483  * if it returns pos_type(off_type(-1)) to indicate failure, it will
484  * cause the seekp() method of the relevant stream class to throw
485  * std::ios_base::failure if such an exception has been required by an
486  * explicit call to the exceptions() method of that class (but not
487  * otherwise). fdstreams do not offer concurrent access from multiple
488  * threads to the same stream object, and if that is required users
489  * should provide their own synchronisation.
490  *
491  * @param p The absolute position to which the seek is to be made,
492  * obtained by a previous call to seekoff() or to this method.
493  *
494  * @param m The required read/write status of the file descriptor
495  * attached to this streambuffer for this method to attempt a seek.
496  * As this is an output stream buffer, the argument should have the
497  * std::ios_base::out bit set. Provided that bit is set, it doesn't
498  * matter if others are also set.
499  *
500  * @return If the seek succeeds, a std::char_traits<T>::pos_type
501  * object representing the new stream position of the streambuffer
502  * after the seek. (This type is std::streampos for narrow character
503  * (char) streams, std::wstreampos for wide character (wchar_t)
504  * streams, std::u16streampos for the char16_t type and
505  * std::u32streampos for the char32_t type.) If the seek failed,
506  * pos_type(off_type(-1)) is returned.
507  */
508  virtual pos_type seekpos(pos_type p,
509  std::ios_base::openmode m = std::ios_base::in | std::ios_base::out);
510 public:
511 /**
512  * This class cannot be copied. The copy constructor is deleted.
513  */
514  basic_fdoutbuf(const basic_fdoutbuf&) = delete;
515 
516 /**
517  * This class cannot be copied. The assignment operator is deleted.
518  */
519  basic_fdoutbuf& operator=(const basic_fdoutbuf&) = delete;
520 
521  /**
522  * As this constructor has default argument values, it is also a
523  * default constructor. fdstreams do not offer concurrent access
524  * from multiple threads to the same stream object, and if that is
525  * required users should provide their own synchronisation.
526  *
527  * @param fd_ The file descriptor to be attached to the streambuffer,
528  * or -1 to attach it latter with the attach_fd() method.
529  *
530  * @param manage_ Whether the streambuffer should manage the file
531  * descriptor (that is, close it in its destructor or when a new file
532  * descriptor is attached).
533  *
534  * @exception std::bad_alloc This constructor will throw
535  * std::bad_alloc if fd_ >= 0, memory is exhausted and the system
536  * throws on such exhaustion (unless the library has been installed
537  * using the --with-glib-memory-slices-compat or
538  * --with-glib-memory-slices-no-compat configuration option, in which
539  * case glib will terminate the program if it is unable to obtain
540  * memory from the operating system). No other exception will be
541  * thrown unless the constructor of std::basic_streambuf throws.
542  */
543  basic_fdoutbuf(int fd_ = -1, bool manage_ = true);
544 
545 /**
546  * The destructor does not throw.
547  */
548  virtual ~basic_fdoutbuf();
549 
550  /**
551  * Attach a new file descriptor to the streambuffer (and close any
552  * file descriptor at present managed by it). If output buffering
553  * was previously switched off, it is switched back on again.
554  * fdstreams do not offer concurrent access from multiple threads to
555  * the same stream object, and if that is required users should
556  * provide their own synchronisation.
557  *
558  * @param fd_ The new file descriptor to be attached to the
559  * streambuffer.
560  *
561  * @param manage_ Whether the streambuffer should manage the new file
562  * descriptor (that is, close it in its destructor or when a further
563  * file descriptor is attached).
564  *
565  * @exception std::bad_alloc This method will throw std::bad_alloc if
566  * fd_ >= 0, output buffering had previously been switched off,
567  * memory is exhausted and the system throws on such exhaustion
568  * (unless the library has been installed using the
569  * --with-glib-memory-slices-compat or
570  * --with-glib-memory-slices-no-compat configuration option, in which
571  * case glib will terminate the program if it is unable to obtain
572  * memory from the operating system).
573  */
574  void attach_fd(int fd_, bool manage_ = true);
575 
576  /**
577  * Close the file descriptor at present attached to the streambuffer
578  * (if any). This method does not throw. fdstreams do not offer
579  * concurrent access from multiple threads to the same stream object,
580  * and if that is required users should provide their own
581  * synchronisation.
582  *
583  * @return From version 1.2.6, 'true' if the close succeeded, 'false'
584  * if an error arose (including in a case where no descriptor has
585  * been attached or it has already been closed). Prior to version
586  * 1.2.6, this method had void return type.
587  */
588  bool close_fd();
589 
590  /**
591  * Get the file descriptor at present attached to the streambuffer
592  * (if any). This method does not throw. fdstreams do not offer
593  * concurrent access from multiple threads to the same stream object,
594  * and if that is required users should provide their own
595  * synchronisation.
596  *
597  * @return The file descriptor at present attached to the
598  * streambuffer, or -1 if none has been attached
599  */
600  int get_fd() const {return fd;}
601 
602 /**
603  * Stops output buffering if 'buffered' is false, or reverts to
604  * buffering if buffering has previously been switched off and
605  * 'buffered' is true. Buffering is on by default for any newly
606  * created fdoutbuf object and any newly attached file descriptor. If
607  * buffering is turned off, all characters at present in the buffers
608  * which are stored for output are flushed. This method has no effect
609  * if no file descriptor has yet been attached to this streambuffer.
610  * Switching output buffering off is similar in effect to setting the
611  * std::ios_base::unitbuf flag in the relevant fdostream object, but
612  * is slightly more efficient. fdstreams do not offer concurrent
613  * access from multiple threads to the same stream object, and if that
614  * is required users should provide their own synchronisation.
615  *
616  * @param buffered 'false' if buffering is to be turned off, 'true' if
617  * it is to be turned back on.
618  *
619  * @exception std::bad_alloc This method will throw std::bad_alloc if
620  * 'buffered' is true, output buffering had previously been switched
621  * off, memory is exhausted and the system throws on such exhaustion
622  * (unless the library has been installed using the
623  * --with-glib-memory-slices-compat or
624  * --with-glib-memory-slices-no-compat configuration option, in which
625  * case glib will terminate the program if it is unable to obtain
626  * memory from the operating system).
627  */
628  void set_buffered(bool buffered);
629 
630 /**
631  * This method indicates whether the output device concerned supports
632  * random access, so that a call to seekoff() or seekpos() can
633  * succeed. This method does not throw. fdstreams do not offer
634  * concurrent access from multiple threads to the same stream object,
635  * and if that is required users should provide their own
636  * synchronisation.
637  *
638  * @return true if random access is supported, otherwise false. The
639  * result is only meaningful if a file descriptor has been attached to
640  * this streambuffer.
641  */
642  bool can_seek() const;
643 
644 /* Only has effect if --with-glib-memory-slices-compat or
645  * --with-glib-memory-slices-no-compat option picked */
647 };
648 
649 /**
650  * @headerfile fdstream.h c++-gtk-utils/fdstream.h
651  * @brief Output stream for unix file descriptors
652  * @sa fdstreams
653  * @ingroup fdstreams
654  *
655  * This class provides standard ostream services for unix file
656  * descriptors.
657  */
658 template <class charT , class Traits = std::char_traits<charT> >
659 class basic_fdostream: public std::basic_ostream<charT, Traits> {
660 
662 
663 public:
664 /**
665  * This class cannot be copied. The copy constructor is deleted.
666  */
668 
669 /**
670  * This class cannot be copied. The assignment operator is deleted.
671  */
673 
674  /**
675  * This is the constructor which passes a file descriptor. fdstreams
676  * do not offer concurrent access from multiple threads to the same
677  * stream object, and if that is required users should provide their
678  * own synchronisation.
679  *
680  * @param fd The file descriptor to be attached to the stream object.
681  *
682  * @param manage Whether the stream should manage the file descriptor
683  * (that is, close it in its destructor or when a new file descriptor
684  * is attached).
685  *
686  * @exception std::bad_alloc This constructor will throw
687  * std::bad_alloc if fd >= 0, memory is exhausted and the system
688  * throws on such exhaustion (unless the library has been installed
689  * using the --with-glib-memory-slices-compat or
690  * --with-glib-memory-slices-no-compat configuration option, in which
691  * case glib will terminate the program if it is unable to obtain
692  * memory from the operating system). No other exception will be
693  * thrown unless the constructor of std::basic_streambuf or
694  * std::basic_ostream throws.
695  */
696  // using uniform initializer syntax here confuses doxygen
697  basic_fdostream(int fd, bool manage = true): std::basic_ostream<charT, Traits>(0),
698  buf(fd, manage) { // pass the descriptor at construction
699  this->rdbuf(&buf);
700  }
701 
702  /**
703  * With this constructor, the file descriptor must be attached later
704  * with the attach() method. It will not throw unless the
705  * constructor of std::basic_streambuf or std::basic_ostream throws.
706  * fdstreams do not offer concurrent access from multiple threads to
707  * the same stream object, and if that is required users should
708  * provide their own synchronisation.
709  */
710  // using uniform initializer syntax here confuses doxygen
711  basic_fdostream(): std::basic_ostream<charT, Traits>(0) { // attach the descriptor later
712  this->rdbuf(&buf);
713  }
714 
715  /**
716  * Attach a new file descriptor to the stream object (and close any
717  * file descriptor at present managed by it). From version 1.2.6, if
718  * output buffering was previously switched off, it is switched back
719  * on again. Also from version 1.2.6, if any stream state flags were
720  * set (eofbit, failbit or badbit), they will be cleared by a call to
721  * clear() (prior to that version, the user had to call clear()
722  * explicitly to do so). If this method closes a file descriptor at
723  * present managed by it and the close fails, failbit is not set and
724  * no exception will be thrown. Accordingly, if the user needs to
725  * know whether there was an error in this method closing any
726  * descriptor, she should call close() explicitly before calling this
727  * method. fdstreams do not offer concurrent access from multiple
728  * threads to the same stream object, and if that is required users
729  * should provide their own synchronisation.
730  *
731  * @param fd The new file descriptor to be attached to the stream
732  * object.
733  *
734  * @param manage Whether the stream object should manage the new file
735  * descriptor (that is, close it in its destructor or when a further
736  * file descriptor is attached).
737  *
738  * @exception std::bad_alloc This method will throw std::bad_alloc if
739  * fd >= 0, output buffering had previously been switched off, memory
740  * is exhausted and the system throws on such exhaustion (unless the
741  * library has been installed using the
742  * --with-glib-memory-slices-compat or
743  * --with-glib-memory-slices-no-compat configuration option, in which
744  * case glib will terminate the program if it is unable to obtain
745  * memory from the operating system).
746  */
747  void attach(int fd, bool manage = true) {buf.attach_fd(fd, manage); this->clear();}
748 
749  /**
750  * Close the file descriptor at present attached to the stream object
751  * (if any). From version 1.2.6, if the close fails, the failbit
752  * will be set with setstate(std::ios_base::failbit). fdstreams do
753  * not offer concurrent access from multiple threads to the same
754  * stream object, and if that is required users should provide their
755  * own synchronisation.
756  *
757  * @exception std::ios_base::failure From version 1.2.6, this
758  * exception will be thrown if an error arises on closing the
759  * descriptor and such an exception has been required by a call to
760  * the exceptions() method of this class (inherited from
761  * std::basic_ios<>). No exception will be thrown if exceptions()
762  * has not been called.
763  */
764  void close() {if (!buf.close_fd()) this->setstate(std::ios_base::failbit);}
765 
766  /**
767  * Get the file descriptor at present attached to the stream object
768  * (if any). This method does not throw. fdstreams do not offer
769  * concurrent access from multiple threads to the same stream object,
770  * and if that is required users should provide their own
771  * synchronisation.
772  *
773  * @return The file descriptor at present attached to the
774  * stream object, or -1 if none has been attached
775  */
776  int filedesc() const {return buf.get_fd();}
777 
778 /**
779  * Stops output buffering if 'buffered' is false, or reverts to
780  * buffering if buffering has previously been switched off and
781  * 'buffered' is true. Buffering is on by default for any newly
782  * created fdostream object and any newly attached file descriptor.
783  * If buffering is turned off, all characters at present in the
784  * buffers which are stored for output are flushed. This method has
785  * no effect if no file descriptor has yet been attached. Switching
786  * output buffering off is similar in effect to setting the
787  * std::ios_base::unitbuf flag, but is slightly more efficient.
788  * fdstreams do not offer concurrent access from multiple threads to
789  * the same stream object, and if that is required users should
790  * provide their own synchronisation.
791  *
792  * @param buffered 'false' if buffering is to be turned off, 'true' if
793  * it is to be turned back on.
794  *
795  * @exception std::bad_alloc This method will throw std::bad_alloc if
796  * 'buffered' is true, output buffering had previously been switched
797  * off, memory is exhausted and the system throws on such exhaustion
798  * (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 which
801  * case glib will terminate the program if it is unable to obtain
802  * memory from the operating system).
803  */
804  void set_buffered(bool buffered) {buf.set_buffered(buffered);}
805 
806 /**
807  * This method indicates whether the output device concerned supports
808  * random access, so that a call to tellp() or seekp() can succeed.
809  * Note that in the seekp(off_type off, ios_base::seekdir dir)
810  * variant, on wide character streams the 'off' argument is
811  * dimensioned as the number of wchar_t units not the number of bytes
812  * (that is, it is bytes/sizeof(char_type)). This method does not
813  * throw. fdstreams do not offer concurrent access from multiple
814  * threads to the same stream object, and if that is required users
815  * should provide their own synchronisation.
816  *
817  * @return true if random access is supported, otherwise false. The
818  * result is only meaningful if a file descriptor has been attached to
819  * this stream.
820  */
821  bool can_seek() const {return buf.can_seek();}
822 
823 /* Only has effect if --with-glib-memory-slices-compat or
824  * --with-glib-memory-slices-no-compat option picked */
826 };
827 
828 
829 /**
830  * @headerfile fdstream.h c++-gtk-utils/fdstream.h
831  * @brief Input stream buffer for unix file descriptors
832  * @sa fdstreams
833  * @ingroup fdstreams
834  *
835  * This class provides an input stream buffer for unix file
836  * descriptors. It does the buffering for the basic_fdistream stream
837  * class.
838  */
839 template <class charT , class Traits = std::char_traits<charT> >
840 class basic_fdinbuf : public std::basic_streambuf<charT, Traits> {
841 
842 public:
843  typedef charT char_type;
844  typedef Traits traits_type;
845  typedef typename traits_type::int_type int_type;
846  typedef typename traits_type::pos_type pos_type;
847  typedef typename traits_type::off_type off_type;
848 
849 private:
850  int fd; // file descriptor
851  bool manage;
852  bool byteswap;
853 
854  static const int putback_size = 4; // size of putback area
855  static const int buf_size = 1024; // size of the data buffer
856  char_type buffer[buf_size + putback_size]; // data buffer
857  void reset();
858  static void swap_element(char_type&);
859 
860 protected:
861 /**
862  * This method will not throw. This means that the input functions of
863  * stream objects which have this streambuffer as a member will not
864  * throw unless the underlying functions of the std::basic_istream
865  * class throw, which they would not normally do unless they have been
866  * required to do so on failbit, badbit or eofbit being set by an
867  * explicit call to the exceptions() method of that class. fdstreams
868  * do not offer concurrent access from multiple threads to the same
869  * stream object, and if that is required users should provide their
870  * own synchronisation.
871  */
872  virtual int_type underflow();
873 
874 #ifndef FDSTREAM_USE_STD_N_READ_WRITE
875 /**
876  * This method will not throw. This means that the input functions of
877  * stream objects which have this streambuffer as a member will not
878  * throw unless the underlying functions of the std::basic_istream
879  * class throw, which they would not normally do unless they have been
880  * required to do so on failbit, badbit or eofbit being set by an
881  * explicit call to the exceptions() method of that class. fdstreams
882  * do not offer concurrent access from multiple threads to the same
883  * stream object, and if that is required users should provide their
884  * own synchronisation.
885  */
886  virtual std::streamsize xsgetn(char_type*, std::streamsize);
887 #endif
888 /**
889  * This method provides random access on input devices that support
890  * it, so supporting the tellg() and seekg() methods of the
891  * basic_fdistream class. This method does not throw, but if it
892  * returns pos_type(off_type(-1)) to indicate failure, it will cause
893  * the seekg() or tellg() methods of the relevant stream class to
894  * throw std::ios_base::failure if such an exception has been required
895  * by an explicit call to the exceptions() method of that class (but
896  * not otherwise). fdstreams do not offer concurrent access from
897  * multiple threads to the same stream object, and if that is required
898  * users should provide their own synchronisation.
899  *
900  * @param off The offset to be applied to the 'way' argument when
901  * seeking. It is a signed integer type, and on wide character
902  * streams is dimensioned as the number of wchar_t units not the
903  * number of bytes (that is, it is bytes/sizeof(char_type)).
904  *
905  * @param way The file position to which the 'off' argument is to be
906  * applied (either std::ios_base::beg, std::ios_base::cur or
907  * std::ios_base::end).
908  *
909  * @param m The required read/write status of the file descriptor
910  * attached to this streambuffer for this method to attempt a seek.
911  * As this is an input streambuffer, the argument should have the
912  * std::ios_base::in bit set. Provided that bit is set, it doesn't
913  * matter if others are also set.
914  *
915  * @return If the seek succeeds, a std::char_traits<T>::pos_type
916  * object representing the new stream position of the streambuffer
917  * after the seek. (This type is std::streampos for narrow character
918  * (char) streams, std::wstreampos for wide character (wchar_t)
919  * streams, std::u16streampos for the char16_t type and
920  * std::u32streampos for the char32_t type.) If the seek failed,
921  * pos_type(off_type(-1)) is returned.
922  */
923  virtual pos_type seekoff(off_type off,
924  std::ios_base::seekdir way,
925  std::ios_base::openmode m = std::ios_base::in | std::ios_base::out);
926 
927 /**
928  * This method provides random access on input devices that support
929  * it, so supporting the seekg() method of the basic_fdistream class.
930  * It is equivalent to seekoff(off_type(p), std::ios_base::beg, m).
931  * This method does not throw, but if it returns
932  * pos_type(off_type(-1)) to indicate failure, it will cause the
933  * seekg() method of the relevant stream class to throw
934  * std::ios_base::failure if such an exception has been required by an
935  * explicit call to the exceptions() method of that class (but not
936  * otherwise). fdstreams do not offer concurrent access from multiple
937  * threads to the same stream object, and if that is required users
938  * should provide their own synchronisation.
939  *
940  * @param p The absolute position to which the seek is to be made,
941  * obtained by a previous call to seekoff() or to this method.
942  *
943  * @param m The required read/write status of the file descriptor
944  * attached to this streambuffer for this method to attempt a seek.
945  * As this is an input streambuffer, the argument should have the
946  * std::ios_base::in bit set. Provided that bit is set, it doesn't
947  * matter if others are also set.
948  *
949  * @return If the seek succeeds, a std::char_traits<T>::pos_type
950  * object representing the new stream position of the streambuffer
951  * after the seek. (This type is std::streampos for narrow character
952  * (char) streams, std::wstreampos for wide character (wchar_t)
953  * streams, std::u16streampos for the char16_t type and
954  * std::u32streampos for the char32_t type.) If the seek failed,
955  * pos_type(off_type(-1)) is returned.
956  */
957  virtual pos_type seekpos(pos_type p,
958  std::ios_base::openmode m = std::ios_base::in | std::ios_base::out);
959 public:
960 /**
961  * This class cannot be copied. The copy constructor is deleted.
962  */
963  basic_fdinbuf(const basic_fdinbuf&) = delete;
964 
965 /**
966  * This class cannot be copied. The assignment operator is deleted.
967  */
968  basic_fdinbuf& operator=(const basic_fdinbuf&) = delete;
969 
970  /**
971  * As this constructor has default argument values, it is also a
972  * default constructor. It does not throw unless the constructor of
973  * std::basic_streambuf throws. fdstreams do not offer concurrent
974  * access from multiple threads to the same stream object, and if
975  * that is required users should provide their own synchronisation.
976  *
977  * @param fd_ The file descriptor to be attached to the streambuffer,
978  * or -1 to attach it latter with the attach() method.
979  *
980  * @param manage_ Whether the streambuffer should manage the file
981  * descriptor (that is, close it in its destructor or when a new file
982  * descriptor is attached).
983  */
984  basic_fdinbuf(int fd_ = -1, bool manage_ = true);
985 
986 /**
987  * The destructor does not throw.
988  */
989  virtual ~basic_fdinbuf();
990 
991  /**
992  * Attach a new file descriptor to the streambuffer (and close any
993  * file descriptor at present managed by it). In the case of a wide
994  * character streambuffer, it also switches off byte swapping, if it
995  * was previously on. This method does not throw. fdstreams do not
996  * offer concurrent access from multiple threads to the same stream
997  * object, and if that is required users should provide their own
998  * synchronisation.
999  *
1000  * @param fd_ The new file descriptor to be attached to the
1001  * streambuffer.
1002  *
1003  * @param manage_ Whether the streambuffer should manage the new file
1004  * descriptor (that is, close it in its destructor or when a further
1005  * file descriptor is attached).
1006  */
1007  void attach_fd(int fd_, bool manage_ = true);
1008 
1009  /**
1010  * Close the file descriptor at present attached to the streambuffer
1011  * (if any). This method does not throw. fdstreams do not offer
1012  * concurrent access from multiple threads to the same stream object,
1013  * and if that is required users should provide their own
1014  * synchronisation.
1015  *
1016  * @return From version 1.2.6, 'true' if the close succeeded, 'false'
1017  * if an error arose (including in a case where no descriptor has
1018  * been attached or it has already been closed). Prior to version
1019  * 1.2.6, this method had void return type.
1020  */
1021  bool close_fd();
1022 
1023  /**
1024  * Get the file descriptor at present attached to the streambuffer
1025  * (if any). This method does not throw. fdstreams do not offer
1026  * concurrent access from multiple threads to the same stream object,
1027  * and if that is required users should provide their own
1028  * synchronisation.
1029  *
1030  * @return The file descriptor at present attached to the
1031  * streambuffer, or -1 if none has been attached
1032  */
1033  int get_fd() const {return fd;}
1034 
1035  /**
1036  * Causes the streambuffer to swap bytes in the incoming text, so as
1037  * to convert big endian text to little endian text, or little endian
1038  * text to big endian text. It is called by the user in response to
1039  * finding a byte order marker (BOM) 0xfffe (UTF-16) or 0xfffe0000
1040  * (UTF-32) as the first character of a newly opened file/stream, or
1041  * if the user knows by some other means that the native endianness
1042  * of the machine doing the reading differs from the endianness of
1043  * the file/stream being read. This only has effect on wide
1044  * character input streambuffers (for example, wfdinbuf), and not the
1045  * fdinbuf narrow character stream buffer. This method does not
1046  * throw. fdstreams do not offer concurrent access from multiple
1047  * threads to the same stream object, and if that is required users
1048  * should provide their own synchronisation.
1049  *
1050  * @param swap 'true' if byte swapping is to be turned on, 'false' if
1051  * it is to be turned off. This will affect all characters extracted
1052  * from the streambuffer after this call is made. If any previously
1053  * extracted character is to be putback(), it must be put back before
1054  * this function is called (or unget() should be called instead) to
1055  * avoid a putback mismatch, because this call will byte-swap
1056  * anything already in the buffers. (Characters extracted after the
1057  * call to this method may be putback normally.)
1058  */
1059  void set_byteswap(bool swap);
1060 
1061 /**
1062  * This method indicates whether the input device concerned supports
1063  * random access, so that a call to seekoff() or seekpos() can
1064  * succeed. This method does not throw. fdstreams do not offer
1065  * concurrent access from multiple threads to the same stream object,
1066  * and if that is required users should provide their own
1067  * synchronisation.
1068  *
1069  * @return true if random access is supported, otherwise false. The
1070  * result is only meaningful if a file descriptor has been attached to
1071  * this streambuffer.
1072  */
1073  bool can_seek() const;
1074 
1075 /* Only has effect if --with-glib-memory-slices-compat or
1076  * --with-glib-memory-slices-no-compat option picked */
1078 };
1079 
1080 /**
1081  * @headerfile fdstream.h c++-gtk-utils/fdstream.h
1082  * @brief Input stream for unix file descriptors
1083  * @sa fdstreams
1084  * @ingroup fdstreams
1085  *
1086  * This class provides standard istream services for unix file
1087  * descriptors.
1088  */
1089 template <class charT , class Traits = std::char_traits<charT> >
1090 class basic_fdistream : public std::basic_istream<charT, Traits> {
1091 
1093 
1094 public:
1095 /**
1096  * This class cannot be copied. The copy constructor is deleted.
1097  */
1098  basic_fdistream(const basic_fdistream&) = delete;
1099 
1100 /**
1101  * This class cannot be copied. The assignment operator is deleted.
1102  */
1103  basic_fdistream& operator=(const basic_fdistream&) = delete;
1104 
1105  /**
1106  * This is the constructor which passes a file descriptor. It will
1107  * not throw unless the constructor of std::basic_streambuf or
1108  * std::basic_istream throws. fdstreams do not offer concurrent
1109  * access from multiple threads to the same stream object, and if
1110  * that is required users should provide their own synchronisation.
1111  *
1112  * @param fd The file descriptor to be attached to the stream object.
1113  *
1114  * @param manage Whether the stream should manage the file descriptor
1115  * (that is, close it in its destructor or when a new file descriptor
1116  * is attached).
1117  */
1118  // using uniform initializer syntax here confuses doxygen
1119  basic_fdistream (int fd, bool manage = true) : std::basic_istream<charT, Traits>(0),
1120  buf(fd, manage) { // pass the descriptor at construction
1121  this->rdbuf(&buf);
1122  }
1123 
1124  /**
1125  * With this constructor, the file descriptor must be attached later
1126  * with the attach() method. It will not throw unless the
1127  * constructor of std::basic_streambuf or std::basic_istream throws.
1128  * fdstreams do not offer concurrent access from multiple threads to
1129  * the same stream object, and if that is required users should
1130  * provide their own synchronisation.
1131  */
1132  // using uniform initializer syntax here confuses doxygen
1133  basic_fdistream () : std::basic_istream<charT, Traits>(0) { // attach the descriptor later
1134  this->rdbuf(&buf);
1135  }
1136 
1137  /**
1138  * Attach a new file descriptor to the stream object (and close any
1139  * file descriptor at present managed by it). In the case of wide
1140  * character streams, it also switches off byte swapping, if it was
1141  * previously on. From version 1.2.6, if any stream state flags were
1142  * set (eofbit, failbit or badbit), they will be cleared by a call to
1143  * clear() (prior to that version, the user had to call clear()
1144  * explicitly to do so). If this method closes a file descriptor at
1145  * present managed by it and the close fails, failbit is not set and
1146  * no exception will be thrown. Accordingly, if the user needs to
1147  * know whether there was an error in this method closing any
1148  * descriptor, she should call close() explicitly before calling this
1149  * method. This method does not throw. fdstreams do not offer
1150  * concurrent access from multiple threads to the same stream object,
1151  * and if that is required users should provide their own
1152  * synchronisation.
1153  *
1154  * @param fd The new file descriptor to be attached to the stream
1155  * object.
1156  *
1157  * @param manage Whether the stream object should manage the new file
1158  * descriptor (that is, close it in its destructor or when a further
1159  * file descriptor is attached).
1160  */
1161  void attach(int fd, bool manage = true) {buf.attach_fd(fd, manage); this->clear();}
1162 
1163  /**
1164  * Close the file descriptor at present attached to the stream object
1165  * (if any). From version 1.2.6, if the close fails, the failbit
1166  * will be set with setstate(std::ios_base::failbit). fdstreams do
1167  * not offer concurrent access from multiple threads to the same
1168  * stream object, and if that is required users should provide their
1169  * own synchronisation.
1170  *
1171  * @exception std::ios_base::failure From version 1.2.6, this
1172  * exception will be thrown if an error arises on closing the
1173  * descriptor and such an exception has been required by a call to
1174  * the exceptions() method of this class (inherited from
1175  * std::basic_ios<>). No exception will be thrown if exceptions()
1176  * has not been called.
1177  */
1178  void close() {if (!buf.close_fd()) this->setstate(std::ios_base::failbit);}
1179 
1180  /**
1181  * Get the file descriptor at present attached to the stream object
1182  * (if any). This method does not throw. fdstreams do not offer
1183  * concurrent access from multiple threads to the same stream object,
1184  * and if that is required users should provide their own
1185  * synchronisation.
1186  *
1187  * @return The file descriptor at present attached to the
1188  * stream object, or -1 if none has been attached
1189  */
1190  int filedesc() const {return buf.get_fd();}
1191 
1192  /**
1193  * Causes the underlying stream buffer to swap bytes in the incoming
1194  * text, so as to convert big endian text to little endian text, or
1195  * little endian text to big endian text. It is called in response
1196  * to finding a byte order marker (BOM) 0xfffe (UTF-16) or 0xfffe0000
1197  * (UTF-32) as the first character of a newly opened file/stream, or
1198  * if the user knows by some other means that the native endianness
1199  * of the machine doing the reading differs from the endianness of
1200  * the file/stream being read. This only has effect on wide
1201  * character istreams (for example, wfdistream), and not the
1202  * fdistream narrow character stream. This method does not throw.
1203  * fdstreams do not offer concurrent access from multiple threads to
1204  * the same stream object, and if that is required users should
1205  * provide their own synchronisation.
1206  *
1207  * @param swap 'true' if byte swapping is to be turned on, 'false' if
1208  * it is to be turned off. This will affect all characters extracted
1209  * from the underlying streambuffer after this call is made. If any
1210  * previously extracted character is to be putback(), it must be put
1211  * back before this function is called (or unget() should be called
1212  * instead) to avoid a putback mismatch, because this call will
1213  * byte-swap anything already in the buffers. (Characters extracted
1214  * after the call to this method may be putback normally.)
1215  */
1216  void set_byteswap(bool swap) {buf.set_byteswap(swap);}
1217 
1218 /**
1219  * This method indicates whether the input device concerned supports
1220  * random access, so that a call to tellg() or seekg() can succeed.
1221  * Note that in the seekg(off_type off, ios_base::seekdir dir)
1222  * variant, on wide character streams the 'off' argument is
1223  * dimensioned as the number of wchar_t units not the number of bytes
1224  * (that is, it is bytes/sizeof(char_type)). This method does not
1225  * throw. fdstreams do not offer concurrent access from multiple
1226  * threads to the same stream object, and if that is required users
1227  * should provide their own synchronisation.
1228  *
1229  * @return true if random access is supported, otherwise false. The
1230  * result is only meaningful if a file descriptor has been attached to
1231  * this stream.
1232  */
1233  bool can_seek() const {return buf.can_seek();}
1234 
1235 /* Only has effect if --with-glib-memory-slices-compat or
1236  * --with-glib-memory-slices-no-compat option picked */
1238 };
1239 
1240 /**
1241  * @defgroup fdstreams fdstreams
1242  */
1243 /**
1244  * @typedef fdinbuf.
1245  * @brief Input stream buffer for file descriptors for char type
1246  * @ingroup fdstreams
1247  */
1249 
1250 /**
1251  * @typedef fdoutbuf.
1252  * @brief Output stream buffer for file descriptors for char type
1253  * @ingroup fdstreams
1254  */
1256 
1257 /**
1258  * @typedef fdistream.
1259  * @brief Input stream for file descriptors for char type
1260  * @anchor fdistreamAnchor
1261  * @ingroup fdstreams
1262  */
1264 
1265 /**
1266  * @typedef fdostream.
1267  * @brief Output stream for file descriptors for char type
1268  * @anchor fdostreamAnchor
1269  * @ingroup fdstreams
1270  */
1272 
1273 /**
1274  * @typedef wfdinbuf.
1275  * @brief Input stream buffer for file descriptors for wchar_t type
1276  * @ingroup fdstreams
1277  */
1279 
1280 /**
1281  * @typedef wfdoutbuf.
1282  * @brief Output stream buffer for file descriptors for wchar_t type
1283  * @ingroup fdstreams
1284  */
1286 
1287 /**
1288  * @typedef wfdistream.
1289  * @brief Input stream for file descriptors for wchar_t type
1290  * @anchor wfdistreamAnchor
1291  * @ingroup fdstreams
1292  */
1294 
1295 /**
1296  * @typedef wfdostream.
1297  * @brief Output stream for file descriptors for wchar_t type
1298  * @anchor wfdostreamAnchor
1299  * @ingroup fdstreams
1300  */
1302 
1303 /**
1304  * @typedef u16fdinbuf.
1305  * @brief Input stream buffer for file descriptors for char16_t type
1306  * @ingroup fdstreams
1307  */
1309 
1310 /**
1311  * @typedef u16fdoutbuf.
1312  * @brief Output stream buffer for file descriptors for char16_t type
1313  * @ingroup fdstreams
1314  */
1316 
1317 /**
1318  * @typedef u16fdistream.
1319  * @brief Input stream for file descriptors for char16_t type
1320  * @anchor u16fdistreamAnchor
1321  * @ingroup fdstreams
1322  */
1324 
1325 /**
1326  * @typedef u16fdostream.
1327  * @brief Output stream for file descriptors for char16_t type
1328  * @anchor u16fdostreamAnchor
1329  * @ingroup fdstreams
1330  */
1332 
1333 /**
1334  * @typedef u32fdinbuf.
1335  * @brief Input stream buffer for file descriptors for char32_t type
1336  * @ingroup fdstreams
1337  */
1339 
1340 /**
1341  * @typedef u32fdoutbuf.
1342  * @brief Output stream buffer for file descriptors for char32_t type
1343  * @ingroup fdstreams
1344  */
1346 
1347 /**
1348  * @typedef u32fdistream.
1349  * @brief Input stream for file descriptors for char32_t type
1350  * @anchor u32fdistreamAnchor
1351  * @ingroup fdstreams
1352  */
1354 
1355 /**
1356  * @typedef u32fdostream.
1357  * @brief Output stream for file descriptors for char32_t type
1358  * @anchor u32fdostreamAnchor
1359  * @ingroup fdstreams
1360  */
1362 
1363 } // namespace Cgu
1364 
1365 #include <c++-gtk-utils/fdstream.tpp>
1366 
1367 #endif /*CGU_FDSTREAM_H*/