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