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