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