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