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 copy assignment operator is
548  * deleted.
549  */
550  basic_fdoutbuf& operator=(const basic_fdoutbuf&) = delete;
551 
552  /**
553  * As this constructor has default argument values, it is also a
554  * default constructor. fdstreams do not offer concurrent access
555  * from multiple threads to the same stream object, and if that is
556  * required users should provide their own synchronisation.
557  *
558  * @param fd_ The file descriptor to be attached to the streambuffer,
559  * or -1 to attach it latter with the attach_fd() method.
560  *
561  * @param manage_ Whether the streambuffer should manage the file
562  * descriptor (that is, close it in its destructor or when a new file
563  * descriptor is attached).
564  *
565  * @exception std::bad_alloc This constructor will throw
566  * std::bad_alloc if fd_ >= 0, memory is exhausted and the system
567  * throws on such exhaustion (unless the library has been installed
568  * using the \--with-glib-memory-slices-compat or
569  * \--with-glib-memory-slices-no-compat configuration option, in
570  * which case glib will terminate the program if it is unable to
571  * obtain memory from the operating system). No other exception will
572  * be thrown unless the default constructor of std::basic_streambuf
573  * throws.
574  */
575  basic_fdoutbuf(int fd_ = -1, bool manage_ = true);
576 
577 /**
578  * The destructor does not throw.
579  */
580  virtual ~basic_fdoutbuf();
581 
582  /**
583  * Attach a new file descriptor to the streambuffer (and close any
584  * file descriptor at present managed by it). If output buffering
585  * was previously switched off, it is switched back on again.
586  * fdstreams do not offer concurrent access from multiple threads to
587  * the same stream object, and if that is required users should
588  * provide their own synchronisation.
589  *
590  * @param fd_ The new file descriptor to be attached to the
591  * streambuffer.
592  *
593  * @param manage_ Whether the streambuffer should manage the new file
594  * descriptor (that is, close it in its destructor or when a further
595  * file descriptor is attached).
596  *
597  * @exception std::bad_alloc This method will throw std::bad_alloc if
598  * fd_ >= 0, output buffering had previously been switched off,
599  * memory is exhausted and the system throws on such exhaustion
600  * (unless the library has been installed using the
601  * \--with-glib-memory-slices-compat or
602  * \--with-glib-memory-slices-no-compat configuration option, in
603  * which case glib will terminate the program if it is unable to
604  * obtain memory from the operating system).
605  */
606  void attach_fd(int fd_, bool manage_ = true);
607 
608  /**
609  * Close 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 From version 1.2.6, 'true' if the close succeeded, 'false'
616  * if an error arose (including in a case where no descriptor has
617  * been attached or it has already been closed). Prior to version
618  * 1.2.6, this method had void return type.
619  */
620  bool close_fd();
621 
622  /**
623  * Get the file descriptor at present attached to the streambuffer
624  * (if any). This method does not throw. fdstreams do not offer
625  * concurrent access from multiple threads to the same stream object,
626  * and if that is required users should provide their own
627  * synchronisation.
628  *
629  * @return The file descriptor at present attached to the
630  * streambuffer, or -1 if none has been attached
631  */
632  int get_fd() const {return fd;}
633 
634 /**
635  * Stops output buffering if 'buffered' is false, or reverts to
636  * buffering if buffering has previously been switched off and
637  * 'buffered' is true. Buffering is on by default for any newly
638  * created fdoutbuf object and any newly attached file descriptor. If
639  * buffering is turned off, all characters at present in the buffers
640  * which are stored for output are flushed. This method has no effect
641  * if no file descriptor has yet been attached to this streambuffer.
642  * Switching output buffering off is similar in effect to setting the
643  * std::ios_base::unitbuf flag in the relevant fdostream object, but
644  * is slightly more efficient. fdstreams do not offer concurrent
645  * access from multiple threads to the same stream object, and if that
646  * is required users should provide their own synchronisation.
647  *
648  * @param buffered 'false' if buffering is to be turned off, 'true' if
649  * it is to be turned back on.
650  *
651  * @exception std::bad_alloc This method will throw std::bad_alloc if
652  * 'buffered' is true, output buffering had previously been switched
653  * off, memory is exhausted and the system throws on such exhaustion
654  * (unless the library has been installed using the
655  * \--with-glib-memory-slices-compat or
656  * \--with-glib-memory-slices-no-compat configuration option, in which
657  * case glib will terminate the program if it is unable to obtain
658  * memory from the operating system).
659  */
660  void set_buffered(bool buffered);
661 
662 /**
663  * This method indicates whether the output device concerned supports
664  * random access, so that a call to seekoff() or seekpos() can
665  * succeed. This method does not throw. fdstreams do not offer
666  * concurrent access from multiple threads to the same stream object,
667  * and if that is required users should provide their own
668  * synchronisation.
669  *
670  * @return true if random access is supported, otherwise false. The
671  * result is only meaningful if a file descriptor has been attached to
672  * this streambuffer.
673  */
674  bool can_seek() const;
675 
676 /* Only has effect if --with-glib-memory-slices-compat or
677  * --with-glib-memory-slices-no-compat option picked */
679 };
680 
681 /**
682  * @headerfile fdstream.h c++-gtk-utils/fdstream.h
683  * @brief Output stream for unix file descriptors
684  * @sa fdstreams
685  * @ingroup fdstreams
686  *
687  * This class provides standard ostream services for unix file
688  * descriptors.
689  */
690 template <class charT , class Traits = std::char_traits<charT> >
691 class basic_fdostream: public std::basic_ostream<charT, Traits> {
692 
694 
695 public:
696 /**
697  * This class cannot be copied. The copy constructor is deleted.
698  */
699  basic_fdostream(const basic_fdostream&) = delete;
700 
701 /**
702  * This class cannot be copied. The copy assignment operator is
703  * deleted.
704  */
705  basic_fdostream& operator=(const basic_fdostream&) = delete;
706 
707  /**
708  * This is the constructor which passes a file descriptor. fdstreams
709  * do not offer concurrent access from multiple threads to the same
710  * stream object, and if that is required users should provide their
711  * own synchronisation.
712  *
713  * @param fd The file descriptor to be attached to the stream object.
714  *
715  * @param manage Whether the stream should manage the file descriptor
716  * (that is, close it in its destructor or when a new file descriptor
717  * is attached).
718  *
719  * @exception std::bad_alloc This constructor will throw
720  * std::bad_alloc if fd >= 0, memory is exhausted and the system
721  * throws on such exhaustion (unless the library has been installed
722  * using the \--with-glib-memory-slices-compat or
723  * \--with-glib-memory-slices-no-compat configuration option, in
724  * which case glib will terminate the program if it is unable to
725  * obtain memory from the operating system). No other exception will
726  * be thrown unless the constructor of std::basic_streambuf or
727  * std::basic_ostream throws.
728  */
729  // using uniform initializer syntax here confuses doxygen
730  basic_fdostream(int fd, bool manage = true): std::basic_ostream<charT, Traits>(0),
731  buf(fd, manage) { // pass the descriptor at construction
732  this->rdbuf(&buf);
733  }
734 
735  /**
736  * With this constructor, the file descriptor must be attached later
737  * with the attach() method. It will not throw unless the default
738  * constructor of std::basic_streambuf or std::basic_ostream throws.
739  * fdstreams do not offer concurrent access from multiple threads to
740  * the same stream object, and if that is required users should
741  * provide their own synchronisation.
742  */
743  // using uniform initializer syntax here confuses doxygen
744  basic_fdostream(): std::basic_ostream<charT, Traits>(0) { // attach the descriptor later
745  this->rdbuf(&buf);
746  }
747 
748  /**
749  * Attach a new file descriptor to the stream object (and close any
750  * file descriptor at present managed by it). From version 1.2.6, if
751  * output buffering was previously switched off, it is switched back
752  * on again. Also from version 1.2.6, if any stream state flags were
753  * set (eofbit, failbit or badbit), they will be cleared by a call to
754  * clear() (prior to that version, the user had to call clear()
755  * explicitly to do so). If this method closes a file descriptor at
756  * present managed by it and the close fails, failbit is not set and
757  * no exception will be thrown. Accordingly, if the user needs to
758  * know whether there was an error in this method closing any
759  * descriptor, she should call close() explicitly before calling this
760  * method. fdstreams do not offer concurrent access from multiple
761  * threads to the same stream object, and if that is required users
762  * should provide their own synchronisation.
763  *
764  * @param fd The new file descriptor to be attached to the stream
765  * object.
766  *
767  * @param manage Whether the stream object should manage the new file
768  * descriptor (that is, close it in its destructor or when a further
769  * file descriptor is attached).
770  *
771  * @exception std::bad_alloc This method will throw std::bad_alloc if
772  * fd >= 0, output buffering had previously been switched off, memory
773  * is exhausted and the system throws on such exhaustion (unless the
774  * library has been installed using the
775  * \--with-glib-memory-slices-compat or
776  * \--with-glib-memory-slices-no-compat configuration option, in
777  * which case glib will terminate the program if it is unable to
778  * obtain memory from the operating system).
779  */
780  void attach(int fd, bool manage = true) {buf.attach_fd(fd, manage); this->clear();}
781 
782  /**
783  * Close the file descriptor at present attached to the stream object
784  * (if any). From version 1.2.6, if the close fails, the failbit
785  * will be set with setstate(std::ios_base::failbit). fdstreams do
786  * not offer concurrent access from multiple threads to the same
787  * stream object, and if that is required users should provide their
788  * own synchronisation.
789  *
790  * @exception std::ios_base::failure From version 1.2.6, this
791  * exception will be thrown if an error arises on closing the
792  * descriptor and such an exception has been required by a call to
793  * the exceptions() method of this class (inherited from
794  * std::basic_ios<>). No exception will be thrown if exceptions()
795  * has not been called.
796  */
797  void close() {if (!buf.close_fd()) this->setstate(std::ios_base::failbit);}
798 
799  /**
800  * Get the file descriptor at present attached to the stream object
801  * (if any). This method does not throw. fdstreams do not offer
802  * concurrent access from multiple threads to the same stream object,
803  * and if that is required users should provide their own
804  * synchronisation.
805  *
806  * @return The file descriptor at present attached to the
807  * stream object, or -1 if none has been attached
808  */
809  int filedesc() const {return buf.get_fd();}
810 
811 /**
812  * Stops output buffering if 'buffered' is false, or reverts to
813  * buffering if buffering has previously been switched off and
814  * 'buffered' is true. Buffering is on by default for any newly
815  * created fdostream object and any newly attached file descriptor.
816  * If buffering is turned off, all characters at present in the
817  * buffers which are stored for output are flushed. This method has
818  * no effect if no file descriptor has yet been attached. Switching
819  * output buffering off is similar in effect to setting the
820  * std::ios_base::unitbuf flag, but is slightly more efficient.
821  * fdstreams do not offer concurrent access from multiple threads to
822  * the same stream object, and if that is required users should
823  * provide their own synchronisation.
824  *
825  * @param buffered 'false' if buffering is to be turned off, 'true' if
826  * it is to be turned back on.
827  *
828  * @exception std::bad_alloc This method will throw std::bad_alloc if
829  * 'buffered' is true, output buffering had previously been switched
830  * off, memory is exhausted and the system throws on such exhaustion
831  * (unless the library has been installed using the
832  * \--with-glib-memory-slices-compat or
833  * \--with-glib-memory-slices-no-compat configuration option, in which
834  * case glib will terminate the program if it is unable to obtain
835  * memory from the operating system).
836  */
837  void set_buffered(bool buffered) {buf.set_buffered(buffered);}
838 
839 /**
840  * This method indicates whether the output device concerned supports
841  * random access, so that a call to tellp() or seekp() can succeed.
842  * Note that in the seekp(off_type off, ios_base::seekdir dir)
843  * variant, on wide character streams the 'off' argument is
844  * dimensioned as the number of wchar_t units not the number of bytes
845  * (that is, it is bytes/sizeof(char_type)). This method does not
846  * throw. fdstreams do not offer concurrent access from multiple
847  * threads to the same stream object, and if that is required users
848  * should provide their own synchronisation.
849  *
850  * @return true if random access is supported, otherwise false. The
851  * result is only meaningful if a file descriptor has been attached to
852  * this stream.
853  */
854  bool can_seek() const {return buf.can_seek();}
855 
856 /* Only has effect if --with-glib-memory-slices-compat or
857  * --with-glib-memory-slices-no-compat option picked */
859 };
860 
861 
862 /**
863  * @headerfile fdstream.h c++-gtk-utils/fdstream.h
864  * @brief Input stream buffer for unix file descriptors
865  * @sa fdstreams
866  * @ingroup fdstreams
867  *
868  * This class provides an input stream buffer for unix file
869  * descriptors. It does the buffering for the basic_fdistream stream
870  * class.
871  */
872 template <class charT , class Traits = std::char_traits<charT> >
873 class basic_fdinbuf : public std::basic_streambuf<charT, Traits> {
874 
875 public:
876  typedef charT char_type;
877  typedef Traits traits_type;
878  typedef typename traits_type::int_type int_type;
879  typedef typename traits_type::pos_type pos_type;
880  typedef typename traits_type::off_type off_type;
881 
882 private:
883  int fd; // file descriptor
884  bool manage;
885  bool byteswap;
886 
887  static const int putback_size = 4; // size of putback area
888  static const int buf_size = 1024; // size of the data buffer
889  char_type buffer[buf_size + putback_size]; // data buffer
890  void reset();
891  static void swap_element(char_type&);
892 
893 protected:
894 /**
895  * This method will not throw. This means that the input functions of
896  * stream objects which have this streambuffer as a member will not
897  * throw unless the underlying functions of the std::basic_istream
898  * class throw, which they would not normally do unless they have been
899  * required to do so on failbit, badbit or eofbit being set by an
900  * explicit call to the exceptions() method of that class. fdstreams
901  * do not offer concurrent access from multiple threads to the same
902  * stream object, and if that is required users should provide their
903  * own synchronisation.
904  */
905  virtual int_type underflow();
906 
907 #ifndef FDSTREAM_USE_STD_N_READ_WRITE
908 /**
909  * This method will not throw. This means that the input functions of
910  * stream objects which have this streambuffer as a member will not
911  * throw unless the underlying functions of the std::basic_istream
912  * class throw, which they would not normally do unless they have been
913  * required to do so on failbit, badbit or eofbit being set by an
914  * explicit call to the exceptions() method of that class. fdstreams
915  * do not offer concurrent access from multiple threads to the same
916  * stream object, and if that is required users should provide their
917  * own synchronisation.
918  */
919  virtual std::streamsize xsgetn(char_type*, std::streamsize);
920 #endif
921 /**
922  * This method provides random access on input devices that support
923  * it, so supporting the tellg() and seekg() methods of the
924  * basic_fdistream class. This method does not throw, but if it
925  * returns pos_type(off_type(-1)) to indicate failure, it will cause
926  * the seekg() or tellg() methods of the relevant stream class to
927  * throw std::ios_base::failure if such an exception has been required
928  * by an explicit call to the exceptions() method of that class (but
929  * not otherwise). fdstreams do not offer concurrent access from
930  * multiple threads to the same stream object, and if that is required
931  * users should provide their own synchronisation.
932  *
933  * @param off The offset to be applied to the 'way' argument when
934  * seeking. It is a signed integer type, and on wide character
935  * streams is dimensioned as the number of wchar_t units not the
936  * number of bytes (that is, it is bytes/sizeof(char_type)).
937  *
938  * @param way The file position to which the 'off' argument is to be
939  * applied (either std::ios_base::beg, std::ios_base::cur or
940  * std::ios_base::end).
941  *
942  * @param m The required read/write status of the file descriptor
943  * attached to this streambuffer for this method to attempt a seek.
944  * As this is an input streambuffer, the argument should have the
945  * std::ios_base::in bit set. Provided that bit is set, it doesn't
946  * matter if others are also set.
947  *
948  * @return If the seek succeeds, a std::char_traits<T>::pos_type
949  * object representing the new stream position of the streambuffer
950  * after the seek. (This type is std::streampos for narrow character
951  * (char) streams, std::wstreampos for wide character (wchar_t)
952  * streams, std::u16streampos for the char16_t type and
953  * std::u32streampos for the char32_t type.) If the seek failed,
954  * pos_type(off_type(-1)) is returned.
955  */
956  virtual pos_type seekoff(off_type off,
957  std::ios_base::seekdir way,
958  std::ios_base::openmode m = std::ios_base::in | std::ios_base::out);
959 
960 /**
961  * This method provides random access on input devices that support
962  * it, so supporting the seekg() method of the basic_fdistream class.
963  * It is equivalent to seekoff(off_type(p), std::ios_base::beg, m).
964  * This method does not throw, but if it returns
965  * pos_type(off_type(-1)) to indicate failure, it will cause the
966  * seekg() method of the relevant stream class to throw
967  * std::ios_base::failure if such an exception has been required by an
968  * explicit call to the exceptions() method of that class (but not
969  * otherwise). fdstreams do not offer concurrent access from multiple
970  * threads to the same stream object, and if that is required users
971  * should provide their own synchronisation.
972  *
973  * @param p The absolute position to which the seek is to be made,
974  * obtained by a previous call to seekoff() or to this method.
975  *
976  * @param m The required read/write status of the file descriptor
977  * attached to this streambuffer for this method to attempt a seek.
978  * As this is an input streambuffer, the argument should have the
979  * std::ios_base::in bit set. Provided that bit is set, it doesn't
980  * matter if others are also set.
981  *
982  * @return If the seek succeeds, a std::char_traits<T>::pos_type
983  * object representing the new stream position of the streambuffer
984  * after the seek. (This type is std::streampos for narrow character
985  * (char) streams, std::wstreampos for wide character (wchar_t)
986  * streams, std::u16streampos for the char16_t type and
987  * std::u32streampos for the char32_t type.) If the seek failed,
988  * pos_type(off_type(-1)) is returned.
989  */
990  virtual pos_type seekpos(pos_type p,
991  std::ios_base::openmode m = std::ios_base::in | std::ios_base::out);
992 public:
993 /**
994  * This class cannot be copied. The copy constructor is deleted.
995  */
996  basic_fdinbuf(const basic_fdinbuf&) = delete;
997 
998 /**
999  * This class cannot be copied. The copy assignment operator is
1000  * deleted.
1001  */
1002  basic_fdinbuf& operator=(const basic_fdinbuf&) = delete;
1003 
1004  /**
1005  * As this constructor has default argument values, it is also a
1006  * default constructor. It does not throw unless the default
1007  * constructor of std::basic_streambuf throws. fdstreams do not
1008  * offer concurrent access from multiple threads to the same stream
1009  * object, and if that is required users should provide their own
1010  * synchronisation.
1011  *
1012  * @param fd_ The file descriptor to be attached to the streambuffer,
1013  * or -1 to attach it latter with the attach() method.
1014  *
1015  * @param manage_ Whether the streambuffer should manage the file
1016  * descriptor (that is, close it in its destructor or when a new file
1017  * descriptor is attached).
1018  */
1019  basic_fdinbuf(int fd_ = -1, bool manage_ = true);
1020 
1021 /**
1022  * The destructor does not throw.
1023  */
1024  virtual ~basic_fdinbuf();
1025 
1026  /**
1027  * Attach a new file descriptor to the streambuffer (and close any
1028  * file descriptor at present managed by it). In the case of a wide
1029  * character streambuffer, it also switches off byte swapping, if it
1030  * was previously on. This method does not throw. fdstreams do not
1031  * offer concurrent access from multiple threads to the same stream
1032  * object, and if that is required users should provide their own
1033  * synchronisation.
1034  *
1035  * @param fd_ The new file descriptor to be attached to the
1036  * streambuffer.
1037  *
1038  * @param manage_ Whether the streambuffer should manage the new file
1039  * descriptor (that is, close it in its destructor or when a further
1040  * file descriptor is attached).
1041  */
1042  void attach_fd(int fd_, bool manage_ = true);
1043 
1044  /**
1045  * Close the file descriptor at present attached to the streambuffer
1046  * (if any). This method does not throw. fdstreams do not offer
1047  * concurrent access from multiple threads to the same stream object,
1048  * and if that is required users should provide their own
1049  * synchronisation.
1050  *
1051  * @return From version 1.2.6, 'true' if the close succeeded, 'false'
1052  * if an error arose (including in a case where no descriptor has
1053  * been attached or it has already been closed). Prior to version
1054  * 1.2.6, this method had void return type.
1055  */
1056  bool close_fd();
1057 
1058  /**
1059  * Get the file descriptor at present attached to the streambuffer
1060  * (if any). This method does not throw. fdstreams do not offer
1061  * concurrent access from multiple threads to the same stream object,
1062  * and if that is required users should provide their own
1063  * synchronisation.
1064  *
1065  * @return The file descriptor at present attached to the
1066  * streambuffer, or -1 if none has been attached
1067  */
1068  int get_fd() const {return fd;}
1069 
1070  /**
1071  * Causes the streambuffer to swap bytes in the incoming text, so as
1072  * to convert big endian text to little endian text, or little endian
1073  * text to big endian text. It is called by the user in response to
1074  * finding a byte order marker (BOM) 0xfffe (UTF-16) or 0xfffe0000
1075  * (UTF-32) as the first character of a newly opened file/stream, or
1076  * if the user knows by some other means that the native endianness
1077  * of the machine doing the reading differs from the endianness of
1078  * the file/stream being read. This only has effect on wide
1079  * character input streambuffers (for example, wfdinbuf), and not the
1080  * fdinbuf narrow character stream buffer. This method does not
1081  * throw. fdstreams do not offer concurrent access from multiple
1082  * threads to the same stream object, and if that is required users
1083  * should provide their own synchronisation.
1084  *
1085  * @param swap 'true' if byte swapping is to be turned on, 'false' if
1086  * it is to be turned off. This will affect all characters extracted
1087  * from the streambuffer after this call is made. If any previously
1088  * extracted character is to be putback(), it must be put back before
1089  * this function is called (or unget() should be called instead) to
1090  * avoid a putback mismatch, because this call will byte-swap
1091  * anything already in the buffers. (Characters extracted after the
1092  * call to this method may be putback normally.)
1093  */
1094  void set_byteswap(bool swap);
1095 
1096 /**
1097  * This method indicates whether the input device concerned supports
1098  * random access, so that a call to seekoff() or seekpos() can
1099  * succeed. This method does not throw. fdstreams do not offer
1100  * concurrent access from multiple threads to the same stream object,
1101  * and if that is required users should provide their own
1102  * synchronisation.
1103  *
1104  * @return true if random access is supported, otherwise false. The
1105  * result is only meaningful if a file descriptor has been attached to
1106  * this streambuffer.
1107  */
1108  bool can_seek() const;
1109 
1110 /* Only has effect if --with-glib-memory-slices-compat or
1111  * --with-glib-memory-slices-no-compat option picked */
1113 };
1114 
1115 /**
1116  * @headerfile fdstream.h c++-gtk-utils/fdstream.h
1117  * @brief Input stream for unix file descriptors
1118  * @sa fdstreams
1119  * @ingroup fdstreams
1120  *
1121  * This class provides standard istream services for unix file
1122  * descriptors.
1123  */
1124 template <class charT , class Traits = std::char_traits<charT> >
1125 class basic_fdistream : public std::basic_istream<charT, Traits> {
1126 
1128 
1129 public:
1130 /**
1131  * This class cannot be copied. The copy constructor is deleted.
1132  */
1133  basic_fdistream(const basic_fdistream&) = delete;
1134 
1135 /**
1136  * This class cannot be copied. The copy assignment operator is
1137  * deleted.
1138  */
1139  basic_fdistream& operator=(const basic_fdistream&) = delete;
1140 
1141  /**
1142  * This is the constructor which passes a file descriptor. It will
1143  * not throw unless the constructor of std::basic_streambuf or
1144  * std::basic_istream throws. fdstreams do not offer concurrent
1145  * access from multiple threads to the same stream object, and if
1146  * that is required users should provide their own synchronisation.
1147  *
1148  * @param fd The file descriptor to be attached to the stream object.
1149  *
1150  * @param manage Whether the stream should manage the file descriptor
1151  * (that is, close it in its destructor or when a new file descriptor
1152  * is attached).
1153  */
1154  // using uniform initializer syntax here confuses doxygen
1155  basic_fdistream (int fd, bool manage = true) : std::basic_istream<charT, Traits>(0),
1156  buf(fd, manage) { // pass the descriptor at construction
1157  this->rdbuf(&buf);
1158  }
1159 
1160  /**
1161  * With this constructor, the file descriptor must be attached later
1162  * with the attach() method. It will not throw unless the default
1163  * constructor of std::basic_streambuf or std::basic_istream throws.
1164  * fdstreams do not offer concurrent access from multiple threads to
1165  * the same stream object, and if that is required users should
1166  * provide their own synchronisation.
1167  */
1168  // using uniform initializer syntax here confuses doxygen
1169  basic_fdistream () : std::basic_istream<charT, Traits>(0) { // attach the descriptor later
1170  this->rdbuf(&buf);
1171  }
1172 
1173  /**
1174  * Attach a new file descriptor to the stream object (and close any
1175  * file descriptor at present managed by it). In the case of wide
1176  * character streams, it also switches off byte swapping, if it was
1177  * previously on. From version 1.2.6, if any stream state flags were
1178  * set (eofbit, failbit or badbit), they will be cleared by a call to
1179  * clear() (prior to that version, the user had to call clear()
1180  * explicitly to do so). If this method closes a file descriptor at
1181  * present managed by it and the close fails, failbit is not set and
1182  * no exception will be thrown. Accordingly, if the user needs to
1183  * know whether there was an error in this method closing any
1184  * descriptor, she should call close() explicitly before calling this
1185  * method. This method does not throw. fdstreams do not offer
1186  * concurrent access from multiple threads to the same stream object,
1187  * and if that is required users should provide their own
1188  * synchronisation.
1189  *
1190  * @param fd The new file descriptor to be attached to the stream
1191  * object.
1192  *
1193  * @param manage Whether the stream object should manage the new file
1194  * descriptor (that is, close it in its destructor or when a further
1195  * file descriptor is attached).
1196  */
1197  void attach(int fd, bool manage = true) {buf.attach_fd(fd, manage); this->clear();}
1198 
1199  /**
1200  * Close the file descriptor at present attached to the stream object
1201  * (if any). From version 1.2.6, if the close fails, the failbit
1202  * will be set with setstate(std::ios_base::failbit). fdstreams do
1203  * not offer concurrent access from multiple threads to the same
1204  * stream object, and if that is required users should provide their
1205  * own synchronisation.
1206  *
1207  * @exception std::ios_base::failure From version 1.2.6, this
1208  * exception will be thrown if an error arises on closing the
1209  * descriptor and such an exception has been required by a call to
1210  * the exceptions() method of this class (inherited from
1211  * std::basic_ios<>). No exception will be thrown if exceptions()
1212  * has not been called.
1213  */
1214  void close() {if (!buf.close_fd()) this->setstate(std::ios_base::failbit);}
1215 
1216  /**
1217  * Get the file descriptor at present attached to the stream object
1218  * (if any). This method does not throw. fdstreams do not offer
1219  * concurrent access from multiple threads to the same stream object,
1220  * and if that is required users should provide their own
1221  * synchronisation.
1222  *
1223  * @return The file descriptor at present attached to the
1224  * stream object, or -1 if none has been attached
1225  */
1226  int filedesc() const {return buf.get_fd();}
1227 
1228  /**
1229  * Causes the underlying stream buffer to swap bytes in the incoming
1230  * text, so as to convert big endian text to little endian text, or
1231  * little endian text to big endian text. It is called in response
1232  * to finding a byte order marker (BOM) 0xfffe (UTF-16) or 0xfffe0000
1233  * (UTF-32) as the first character of a newly opened file/stream, or
1234  * if the user knows by some other means that the native endianness
1235  * of the machine doing the reading differs from the endianness of
1236  * the file/stream being read. This only has effect on wide
1237  * character istreams (for example, wfdistream), and not the
1238  * fdistream narrow character stream. This method does not throw.
1239  * fdstreams do not offer concurrent access from multiple threads to
1240  * the same stream object, and if that is required users should
1241  * provide their own synchronisation.
1242  *
1243  * @param swap 'true' if byte swapping is to be turned on, 'false' if
1244  * it is to be turned off. This will affect all characters extracted
1245  * from the underlying streambuffer after this call is made. If any
1246  * previously extracted character is to be putback(), it must be put
1247  * back before this function is called (or unget() should be called
1248  * instead) to avoid a putback mismatch, because this call will
1249  * byte-swap anything already in the buffers. (Characters extracted
1250  * after the call to this method may be putback normally.)
1251  */
1252  void set_byteswap(bool swap) {buf.set_byteswap(swap);}
1253 
1254 /**
1255  * This method indicates whether the input device concerned supports
1256  * random access, so that a call to tellg() or seekg() can succeed.
1257  * Note that in the seekg(off_type off, ios_base::seekdir dir)
1258  * variant, on wide character streams the 'off' argument is
1259  * dimensioned as the number of wchar_t units not the number of bytes
1260  * (that is, it is bytes/sizeof(char_type)). This method does not
1261  * throw. fdstreams do not offer concurrent access from multiple
1262  * threads to the same stream object, and if that is required users
1263  * should provide their own synchronisation.
1264  *
1265  * @return true if random access is supported, otherwise false. The
1266  * result is only meaningful if a file descriptor has been attached to
1267  * this stream.
1268  */
1269  bool can_seek() const {return buf.can_seek();}
1270 
1271 /* Only has effect if --with-glib-memory-slices-compat or
1272  * --with-glib-memory-slices-no-compat option picked */
1274 };
1275 
1276 /**
1277  * @defgroup fdstreams fdstreams
1278  */
1279 /**
1280  * @typedef fdinbuf.
1281  * @brief Input stream buffer for file descriptors for char type
1282  * @ingroup fdstreams
1283  */
1285 
1286 /**
1287  * @typedef fdoutbuf.
1288  * @brief Output stream buffer for file descriptors for char type
1289  * @ingroup fdstreams
1290  */
1292 
1293 /**
1294  * @typedef fdistream.
1295  * @brief Input stream for file descriptors for char type
1296  * @anchor fdistreamAnchor
1297  * @ingroup fdstreams
1298  */
1300 
1301 /**
1302  * @typedef fdostream.
1303  * @brief Output stream for file descriptors for char type
1304  * @anchor fdostreamAnchor
1305  * @ingroup fdstreams
1306  */
1308 
1309 /**
1310  * @typedef wfdinbuf.
1311  * @brief Input stream buffer for file descriptors for wchar_t type
1312  * @ingroup fdstreams
1313  */
1315 
1316 /**
1317  * @typedef wfdoutbuf.
1318  * @brief Output stream buffer for file descriptors for wchar_t type
1319  * @ingroup fdstreams
1320  */
1322 
1323 /**
1324  * @typedef wfdistream.
1325  * @brief Input stream for file descriptors for wchar_t type
1326  * @anchor wfdistreamAnchor
1327  * @ingroup fdstreams
1328  */
1330 
1331 /**
1332  * @typedef wfdostream.
1333  * @brief Output stream for file descriptors for wchar_t type
1334  * @anchor wfdostreamAnchor
1335  * @ingroup fdstreams
1336  */
1338 
1339 /**
1340  * @typedef u16fdinbuf.
1341  * @brief Input stream buffer for file descriptors for char16_t type
1342  * @ingroup fdstreams
1343  */
1345 
1346 /**
1347  * @typedef u16fdoutbuf.
1348  * @brief Output stream buffer for file descriptors for char16_t type
1349  * @ingroup fdstreams
1350  */
1352 
1353 /**
1354  * @typedef u16fdistream.
1355  * @brief Input stream for file descriptors for char16_t type
1356  * @anchor u16fdistreamAnchor
1357  * @ingroup fdstreams
1358  */
1360 
1361 /**
1362  * @typedef u16fdostream.
1363  * @brief Output stream for file descriptors for char16_t type
1364  * @anchor u16fdostreamAnchor
1365  * @ingroup fdstreams
1366  */
1368 
1369 /**
1370  * @typedef u32fdinbuf.
1371  * @brief Input stream buffer for file descriptors for char32_t type
1372  * @ingroup fdstreams
1373  */
1375 
1376 /**
1377  * @typedef u32fdoutbuf.
1378  * @brief Output stream buffer for file descriptors for char32_t type
1379  * @ingroup fdstreams
1380  */
1382 
1383 /**
1384  * @typedef u32fdistream.
1385  * @brief Input stream for file descriptors for char32_t type
1386  * @anchor u32fdistreamAnchor
1387  * @ingroup fdstreams
1388  */
1390 
1391 /**
1392  * @typedef u32fdostream.
1393  * @brief Output stream for file descriptors for char32_t type
1394  * @anchor u32fdostreamAnchor
1395  * @ingroup fdstreams
1396  */
1398 
1399 } // namespace Cgu
1400 
1401 #include <c++-gtk-utils/fdstream.tpp>
1402 
1403 #endif /*CGU_FDSTREAM_H*/