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