c++-gtk-utils: fdstream.h Source File

c++-gtk-utils

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

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