c++-gtk-utils

fdstream.h

Go to the documentation of this file.
00001 /* Copyright (C) 2001, 2004, 2009, 2010, 2011 and 2012 Chris Vine
00002 
00003  The following code declares classes to read from and write to
00004  Unix file descriptors.
00005 
00006  The whole work comprised in files fdstream.h and fdstream.tpp is
00007  distributed by Chris Vine under the GNU Lesser General Public License
00008  as follows:
00009 
00010    This library is free software; you can redistribute it and/or
00011    modify it under the terms of the GNU Lesser General Public License
00012    as published by the Free Software Foundation; either version 2.1 of
00013    the License, or (at your option) any later version.
00014 
00015    This library is distributed in the hope that it will be useful, but
00016    WITHOUT ANY WARRANTY; without even the implied warranty of
00017    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018    Lesser General Public License for more details.
00019 
00020    You should have received a copy of the GNU Lesser General Public
00021    License, version 2.1, along with this library (see the file LGPL.TXT
00022    which came with this source code package in the c++-gtk-utils
00023    sub-directory); if not, write to the Free Software Foundation, Inc.,
00024    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00025 
00026 However, it is not intended that the object code of a program whose
00027 source code instantiates a template from this file or uses macros or
00028 inline functions (of any length) should by reason only of that
00029 instantiation or use be subject to the restrictions of use in the GNU
00030 Lesser General Public License.  With that in mind, the words "and
00031 macros, inline functions and instantiations of templates (of any
00032 length)" shall be treated as substituted for the words "and small
00033 macros and small inline functions (ten lines or less in length)" in
00034 the fourth paragraph of section 5 of that licence.  This does not
00035 affect any other reason why object code may be subject to the
00036 restrictions in that licence (nor for the avoidance of doubt does it
00037 affect the application of section 2 of that licence to modifications
00038 of the source code in this file).
00039 
00040 The attach(), close() and xsputn() methods added by Chris Vine, 2001.
00041 All the classes were rewritten, and also provided in template form for
00042 wide characters, by Chris Vine 2004.
00043 */
00044 
00045 /**
00046  * @defgroup fdstreams fdstreams
00047  *
00048  * \#include <c++-gtk-utils/fdstream.h>
00049  *
00050  * The c++-gtk-utils library contains classes providing streambuffers
00051  * and stream objects for unix file descriptors.
00052  *
00053  * By default, like the fstream::fstream(int fd) and
00054  * fstream::attach(int fd) extensions in libstdc++-v2, the destructors
00055  * of these classes close the file descriptors concerned, which helps
00056  * exception safety (the attach() method will also close any previous
00057  * file descriptor).  If this behaviour is not wanted, pass 'false' as
00058  * the second argument of fdostream/fdistream constructor or of the
00059  * attach() method.  This will enable the same file descriptor to be
00060  * used successively for, say, reading and writing, or to be shared
00061  * between fdistream and fdostream objects (but if the file descriptor
00062  * represents a device providing random access, such as a local file
00063  * on the filesystem, which has been opened for both reading and
00064  * writing, the special precautions described under @ref
00065  * FdRandomAccessAnchor "fdstreams and random access" are required).
00066  *
00067  * Here are some examples of use:
00068  *
00069  * @code
00070  *   // the safe creation of a temporary file with standard iostreams
00071  *   char filename[] = "/tmp/myprog-XXXXXX";
00072  *   Cgu::fdostream ostrm;
00073  *   int fd = mkstemp(filename);
00074  *   if (fd != -1) {
00075  *     ostrm.attach(fd); // take ownership of the file descriptor
00076  *     ostrm << "Temporary file text" << std::endl;
00077  *   }
00078  *   else {
00079  *     std::cerr << "Can't open temporary file " << filename
00080  *               << ", please check permissions" << std::endl;
00081  *   }
00082  *
00083  *   --------------------------------------------------------------------
00084  *
00085  *   // mimic std::cout but explicitly use UNIX stdout
00086  *   Cgu::fdostream out(1, false); // don't take ownership of the file descriptor
00087  *   out << "Hello" << std::endl;
00088  *
00089  *   --------------------------------------------------------------------
00090  *
00091  *   // read line delimited text from a pipe until it is closed by the
00092  *   // writer: assume 'fd' is the read file descriptor of the pipe
00093  *   Cgu::fdistream istrm(fd); // take ownership of the read file descriptor
00094  *   std::string line;
00095  *   while (std::getline(istrm, line)) {
00096  *     [ ... do something with the read text ... ]
00097  *   }
00098  * @endcode
00099  *
00100  *
00101  * @note 1. Users cannot (except by derivation) use the virtual
00102  * protected methods of the streambuffer classes, including xsgetn()
00103  * and xsputn().  Instead, if they want direct access to the
00104  * streambuffer other than through the fdostreamfdistream methods (or
00105  * their wide stream equivalents), they should use the public
00106  * forwarding functions provided by std::streambuf base class.
00107  * @note 2. These streambuffers and stream objects are not copiable.
00108  *
00109  * @b Buffering
00110  *
00111  * The streambuffer classes provide buffering for both input and
00112  * output, although output buffering can be switched off using the
00113  * set_buffered() method.
00114  *
00115  * The streambuf classes provide a block read and write in xsgetn()
00116  * and xsputn(), which will be called by the read() and write()
00117  * methods (and some other output operators) inherited by (w)fdistream
00118  * and (w)fdostream from std::basic_istream and std::basic_ostream.
00119  * They operate (after appropriately vacating and resetting the
00120  * buffers) by doing a block read and write by calling Unix read() and
00121  * write() and are very efficient for large block reads (those
00122  * significantly exceeding the buffer size).  If users want all reads
00123  * and writes to go through the buffers, by using
00124  * std::basic_streambuf<>::xsputn() and
00125  * std::basic_streambuf<>::xsgetn() then the symbol
00126  * FDSTREAM_USE_STD_N_READ_WRITE can be defined for the purpose before
00127  * fdstream.h is \#include'd.  (libstdc++-3 provides efficient inbuilt
00128  * versions of these std::basic_streambuf functions for block reads
00129  * not significantly larger than the buffer size, provided output
00130  * buffering has not been turned off by the set_buffered() method of
00131  * the output streambuffer or stream object.)
00132  *
00133  * One possible case for defining that symbol is where the user wants
00134  * to use the tie() method of (w)fdistream (inherited from
00135  * std::basic_ios) to procure flushing of an output stream before
00136  * extraction from an input stream is made by (w)fdistream::read().
00137  * Such flushing might not occur where a call to (w)fdistream::read()
00138  * is made unless FDSTREAM_USE_STD_N_READ_WRITE is defined, because an
00139  * implementation is permitted to defer such flushing until
00140  * underflow() occurs, and the block read by (w)fdistream::read(), as
00141  * forwarded to xsgetn(), will never invoke underflow() if that symbol
00142  * is not defined.  (Having said that, any basic_istream
00143  * implementation which does defer output flushing until underflow()
00144  * is called makes tie() unusable anyway for a number of purposes,
00145  * because the time of flushing would become dependent on whether a
00146  * read request can be satisfied by what is already in the buffers.)
00147  *
00148  * 4 characters are stored and available for putback.  However, if the
00149  * symbol FDSTREAM_USE_STD_N_READ_WRITE is not defined, then a call to
00150  * fdinbuf::xsgetn() via (w)fdistream::read() with a request for less
00151  * than 4 characters will result in less than 4 characters available
00152  * for putback (if these block read methods obtain some characters but
00153  * less than 4, only the number of characters obtained by them is
00154  * guaranteed to be available for putback).
00155  *
00156  * @anchor FdRandomAccessAnchor
00157  * @b fdstreams @b and @b random @b access
00158  *
00159  * For file descriptors representing files which offer random access,
00160  * the classes in this c++-gtk-utils library implement the tellg(),
00161  * tellp(), seekg() and seekp() random access methods.
00162  *
00163  * The presence of buffering does not impede this where a file
00164  * descriptor is only opened for reading or only opened for writing.
00165  * However, it presents complications if a fdistream object and a
00166  * fdostream object (or their wide stream equivalents) reference the
00167  * same file descriptor on a file which offers random access and which
00168  * is opened for both reading and writing.  To prevent the file
00169  * pointer getting out of sync with the buffers maintained by the
00170  * fdistream and fdostream objects, if the last operation carried out
00171  * on the fdostream/fdistream pair was a write then, if the output
00172  * stream is set as buffered (the default), before the first read
00173  * operation thereafter is made on the pair or a call to seekg() is
00174  * made, the fdostream object must be flushed by calling
00175  * std::ostream::flush() or by using the std::flush manipulator (or
00176  * setting the std::ios_base::unitbuf flag).  If the last operation on
00177  * the pair (having, say, the names 'ostr' and 'istr') was a read,
00178  * then before the first write operation thereafter is made on the
00179  * pair, or a call to seekp() is made, the user must call
00180  * istr.seekg(istr.tellg()) in order to synchronise the logical and
00181  * actual file positions, or if the user does not want to maintain the
00182  * current logical file position, make some other call to seekg() on
00183  * 'istr' which does not comprise only seekg(0, std::ios_base::cur).
00184  * This requirement to call seekg() when moving from reading to
00185  * writing applies whether or not the output stream is buffered.  It
00186  * similarly applies to the wide stream classes.
00187  *
00188  * Note that the tie() method of (w)fdistream (inherited from
00189  * std::basic_ios) cannot reliably to used to procure output flushing
00190  * of a (w)fdostream object before a read is made, unless
00191  * FDSTREAM_USE_STD_N_READ_WRITE is defined before fdstream.h is
00192  * \#include'd, for the reason mentioned under "Buffering" above.
00193  *
00194  * Where a file is to be opened for both reading and writing and more
00195  * automatic tying of input and output is wanted, the Cgu::giostream
00196  * classes or their wide stream equivalents can be used in conjunction
00197  * with GIO streams.
00198  *
00199  * None of these restrictions applies to file descriptors opened for
00200  * reading and writing which represent devices for which the operating
00201  * system does not maintain file pointers, such as sockets.  They can
00202  * be attached to a fdostream and fdistream object without any special
00203  * precautions being taken, other than the normal step of calling
00204  * fdostream::flush() (or using the std::flush manipulator) to flush
00205  * the output buffer to the socket if the user needs to know that that
00206  * has happened (or setting output buffering off with the
00207  * set_buffered() method).  In summary, on a socket, a read does not
00208  * automatically flush the output buffer: it is for the user to do
00209  * that.  Note also that only one of the stream objects should be set
00210  * to manage the file descriptor, and this should normally be the
00211  * output stream as it may have characters to flush when closing.
00212  *
00213  * A (w)fdostream and (w)fdistream object should not reference the
00214  * same file descriptor on any file on a file system which permits
00215  * read-write opening of files and reports itself as not supporting
00216  * random access, but which in fact maintains a file position pointer
00217  * which is shared for reading and writing.  This might apply to some
00218  * network file systems.  The best rule to apply is not to reference
00219  * the same file descriptor on a (w)fdostream and (w)fdistream object
00220  * if the device is not a socket, unless can_seek() returns true.
00221  *
00222  * @b Wide @b streams @b and @b endianness
00223  *
00224  * This library provides typedef'ed instances of the template classes
00225  * for wchar_t, char16_t and char32_t characters.  With the wide
00226  * stream ostream classes and wide character output streambuffer
00227  * classes, wide characters are written out in the native endian
00228  * format of the writing machine.  Special steps need to be taken if
00229  * the text which is sent for output might be read by machines with a
00230  * different endianness.
00231  *
00232  * No such special steps are required where the wide character classes
00233  * are used with temporary files, pipes, fifos, unix domain sockets
00234  * and network sockets on localhost, because in those cases they will
00235  * be read by the same machine that writes; but they are required
00236  * where sockets communicate with other computers over a network or
00237  * when writing to files which may be distributed to and read by other
00238  * computers with different endianness.
00239  *
00240  * Where wide characters are to be exported to other machines, one
00241  * useful approach is to convert to and from UTF-8 with
00242  * Utf8::uniwide_from_utf8(), Utf8::uniwide_to_utf8(),
00243  * Utf8::wide_from_utf8() or Utf8::wide_to_utf8(), and to use
00244  * fdostream/fdistream with the converted text.  Alternatively, the
00245  * wgostream, wgistream and wgiostream classes (and their char16_t and
00246  * char32_t equivalents) can be used for the purposes of attaching a
00247  * UTF-8 converter directly to a GIO stream.  (Those classes also
00248  * enable a UTF-32LE to UTF-32BE converter, and vice versa, to be
00249  * attached to an output stream for the purpose of writing out UTF-32
00250  * in other than native endianness, and similarly as regards UTF-16.)
00251  *
00252  * Instead of converting exported text to UTF-8, another approach is
00253  * to use a byte order marker (BOM) as the first character of the wide
00254  * stream output.  UCS permits a BOM character to be inserted,
00255  * comprising static_cast<wchar_t>(0xfeff),
00256  * static_cast<char16_t>(0xfeff) or static_cast<char32_t>(0xfeff), at
00257  * the beginning of the output to the wide character stream.  At the
00258  * receiving end, this will appear as 0xfffe (UTF-16) or 0xfffe0000
00259  * (UTF-32) to a big endian machine with 8 bit char type if the text
00260  * is little endian, or to a little endian machine with big endian
00261  * text, so signaling a need to undertake byte swapping of text read
00262  * from the stream.  Another alternative is to label the physical
00263  * medium conveying the file as UTF-16LE, UTF-16BE, UTF-32LE or
00264  * UTF-32BE, as the case may be, in which case a BOM character should
00265  * not be prepended.
00266  *
00267  * Where it is established by either means that the input stream
00268  * requires byte swapping, the wide character input stream and wide
00269  * character input streambuffer classes have a set_byteswap() member
00270  * function which should be called on opening the input stream as soon
00271  * as it has been established that byte swapping is required.  Once
00272  * this function has been called with an argument of 'true', all
00273  * further calls to stream functions which provide characters will
00274  * provide those characters with the correct native endianness.
00275  * Calling set_byteswap() on the narrow stream fdistream or fdinbuf
00276  * objects has no effect (byte order is irrelevant to narrow streams).
00277  *
00278  * Here is an example of such use in a case where sizeof(wchar_t) is
00279  * 4:
00280  *
00281  * @code
00282  *   int fd = open("filename", O_RDONLY);
00283  *   Cgu::wfdistream input;
00284  *   if (fd != -1)
00285  *     input.attach(fd); // take ownership of the file descriptor
00286  *   else {
00287  *     std::cerr << "Can't open file 'filename', "
00288  *               << "please check permissions" << std::endl;
00289  *     return;
00290  *   }
00291  *   wchar_t item;
00292  *   input.get(item);
00293  *   if (!input) {
00294  *     std::cerr << "File 'filename' is empty" << std::endl;
00295  *     return;
00296  *   }
00297  *   if (item == static_cast<wchar_t>(0xfffe0000))
00298  *     input.set_byteswap(true);
00299  *   else if (item != static_cast<wchar_t>(0xfeff)) {
00300  *     // calling set_byteswap() will manipulate the buffers, so
00301  *     // either call putback() before we call set_byteswap(), or
00302  *     // call unget() instead
00303  *     input.putback(item);
00304  *     // the first character is not a BOM character so assume big endian
00305  *     // format, and byte swap if the local machine is little endian
00306  *  #if G_BYTE_ORDER == G_LITTLE_ENDIAN
00307  *     input.set_byteswap(true);
00308  *  #endif
00309  *   }
00310  *   [ ... do something with the input file ... ]
00311  * @endcode
00312  *
00313  * @b Other @b wide @b stream @b issues
00314  *
00315  * basic_fdostream, basic_fdoutbuf, basic_fdistream and basic_fdinbuf
00316  * objects can be instantiated for any integer type which has an
00317  * appropriate traits class provided for it which has the copy(),
00318  * eof(), eq_int_type(), move(), not_eof() and to_int_type() static
00319  * member functions.  The integer type could in fact have any size,
00320  * but the set_byteswap() methods for basic_fdistream and
00321  * basic_fdinbuf will only have an effect if its size is either 2 or
00322  * 4.  Typedef'ed instances of the classes are provided by the library
00323  * for characters of type wchar_t, char16_t and char32_t.
00324  */
00325 
00326 #ifndef CGU_FDSTREAM_H
00327 #define CGU_FDSTREAM_H
00328 
00329 // see above for what this does
00330 //#define FDSTREAM_USE_STD_N_READ_WRITE 1
00331 
00332 #include <unistd.h>
00333 #include <sys/types.h>
00334 #include <errno.h>
00335 #include <istream>
00336 #include <ostream>
00337 #include <streambuf>
00338 #include <algorithm>
00339 #include <string>
00340 #include <cstddef>
00341 
00342 #include <c++-gtk-utils/shared_handle.h>
00343 #include <c++-gtk-utils/cgu_config.h>
00344 
00345 namespace Cgu {
00346 
00347 /*
00348 The following convenience typedefs appear at the end of this file:
00349 typedef basic_fdinbuf<char> fdinbuf;
00350 typedef basic_fdoutbuf<char> fdoutbuf;
00351 typedef basic_fdistream<char> fdistream;
00352 typedef basic_fdostream<char> fdostream;
00353 typedef basic_fdinbuf<wchar_t> wfdinbuf;
00354 typedef basic_fdoutbuf<wchar_t> wfdoutbuf;
00355 typedef basic_fdistream<wchar_t> wfdistream;
00356 typedef basic_fdostream<wchar_t> wfdostream;
00357 typedef basic_fdinbut<char16_t> u16fdinbuf;
00358 typedef basic_fdoutbuf<char16_t> u16fdoutbuf;
00359 typedef basic_fdistream<char16_t> u16fdistream;
00360 typedef basic_fdostream<char16_t> u16fdostream;
00361 typedef basic_fdinbut<char32_t> u32fdinbuf;
00362 typedef basic_fdoutbuf<char32_t> u32fdoutbuf;
00363 typedef basic_fdistream<char32_t> u32fdistream;
00364 typedef basic_fdostream<char32_t> u32fdostream;
00365 */
00366 
00367 
00368 /**
00369  * @headerfile fdstream.h c++-gtk-utils/fdstream.h
00370  * @brief Output stream buffer for unix file descriptors
00371  * @sa fdstreams
00372  * @ingroup fdstreams
00373  *
00374  * This class provides an output stream buffer for unix file
00375  * descriptors.  It does the buffering for the basic_fdostream stream
00376  * class.
00377  */
00378 template <class charT , class Traits = std::char_traits<charT> >
00379 class basic_fdoutbuf: public std::basic_streambuf<charT, Traits> {
00380 
00381 public:
00382   typedef charT char_type;
00383   typedef Traits traits_type;
00384   typedef typename traits_type::int_type int_type;
00385   typedef typename traits_type::pos_type pos_type;
00386   typedef typename traits_type::off_type off_type;
00387 
00388 private:
00389   int fd;    // file descriptor
00390   bool manage;
00391 
00392   static const int buf_size = 1024;   // size of the data write buffer
00393 #if defined(CGU_USE_GLIB_MEMORY_SLICES_COMPAT) || defined(CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT)
00394   ScopedHandle<char_type*,
00395                GSliceFreeSize<buf_size * sizeof(char_type)>> buffer;
00396 #else
00397   ScopedHandle<char_type*> buffer;
00398 #endif
00399   int flush_buffer();
00400 
00401 protected:
00402 /**
00403  * This method will not throw.  fdstreams do not offer concurrent
00404  * access from multiple threads to the same stream object, and if that
00405  * is required users should provide their own synchronisation.
00406  */
00407   virtual int sync();
00408 
00409 /**
00410  * This method will not throw unless std::basic_streambuf<>::sputc()
00411  * throws, which it would not do on any sane implementation.  This
00412  * means that the output functions of stream objects which have this
00413  * streambuffer as a member will not throw unless the underlying
00414  * functions of the std::basic_ostream class throw, which they would
00415  * not normally do unless they have been required to do so on failbit,
00416  * badbit or eofbit being set by an explicit call to the exceptions()
00417  * method of that class.  fdstreams do not offer concurrent access
00418  * from multiple threads to the same stream object, and if that is
00419  * required users should provide their own synchronisation.
00420  */
00421   virtual int_type overflow(int_type);
00422 
00423 #ifndef FDSTREAM_USE_STD_N_READ_WRITE
00424 /**
00425  * This method will not throw.  This means that the output functions
00426  * of stream objects which have this streambuffer as a member will not
00427  * throw unless the underlying functions of the std::basic_ostream
00428  * class throw, which they would not normally do unless they have been
00429  * required to do so on failbit, badbit or eofbit being set by an
00430  * explicit call to the exceptions() method of that class.  fdstreams
00431  * do not offer concurrent access from multiple threads to the same
00432  * stream object, and if that is required users should provide their
00433  * own synchronisation.
00434  */
00435   virtual std::streamsize xsputn(const char_type*, std::streamsize);
00436 #endif
00437 
00438 /**
00439  * This method provides random access on output devices that support
00440  * it, so supporting the tellp() and seekp() methods of the
00441  * basic_fdostream class.  Any output buffer will be flushed.  This
00442  * method does not throw, but if it returns pos_type(off_type(-1)) to
00443  * indicate failure, it will cause the seekp() or tellp() methods of
00444  * the relevant stream class to throw std::ios_base::failure if such
00445  * an exception has been required by an explicit call to the
00446  * exceptions() method of that class (but not otherwise).  fdstreams
00447  * do not offer concurrent access from multiple threads to the same
00448  * stream object, and if that is required users should provide their
00449  * own synchronisation.
00450  *
00451  * @param off The offset to be applied to the 'way' argument when
00452  * seeking.  It is a signed integer type, and on wide character
00453  * streams is dimensioned as the number of wchar_t units not the
00454  * number of bytes (that is, it is bytes/sizeof(char_type)).
00455  *
00456  * @param way The file position to which the 'off' argument is to be
00457  * applied (either std::ios_base::beg, std::ios_base::cur or
00458  * std::ios_base::end).
00459  *
00460  * @param m The required read/write status of the file descriptor
00461  * attached to this streambuffer for this method to attempt a seek.
00462  * As this is an output streambuffer, the argument should have the
00463  * std::ios_base::out bit set.  Provided that bit is set, it doesn't
00464  * matter if others are also set.
00465  *
00466  * @return If the seek succeeds, a std::char_traits<T>::pos_type
00467  * object representing the new stream position of the streambuffer
00468  * after the seek.  (This type is std::streampos for narrow character
00469  * (char) streams, std::wstreampos for wide character (wchar_t)
00470  * streams, std::u16streampos for the char16_t type and
00471  * std::u32streampos for the char32_t type.)  If the seek failed,
00472  * pos_type(off_type(-1)) is returned.
00473  */
00474   virtual pos_type seekoff(off_type off,
00475                            std::ios_base::seekdir way,
00476                            std::ios_base::openmode m = std::ios_base::in | std::ios_base::out);
00477 
00478 /**
00479  * This method provides random access on output devices that support
00480  * it, so supporting the seekp() method of the basic_fdostream class.
00481  * It is equivalent to seekoff(off_type(p), std::ios_base::beg, m).
00482  * Any output buffer will be flushed.  This method does not throw, but
00483  * if it returns pos_type(off_type(-1)) to indicate failure, it will
00484  * cause the seekp() method of the relevant stream class to throw
00485  * std::ios_base::failure if such an exception has been required by an
00486  * explicit call to the exceptions() method of that class (but not
00487  * otherwise).  fdstreams do not offer concurrent access from multiple
00488  * threads to the same stream object, and if that is required users
00489  * should provide their own synchronisation.
00490  *
00491  * @param p The absolute position to which the seek is to be made,
00492  * obtained by a previous call to seekoff() or to this method.
00493  *
00494  * @param m The required read/write status of the file descriptor
00495  * attached to this streambuffer for this method to attempt a seek.
00496  * As this is an output stream buffer, the argument should have the
00497  * std::ios_base::out bit set.  Provided that bit is set, it doesn't
00498  * matter if others are also set.
00499  *
00500  * @return If the seek succeeds, a std::char_traits<T>::pos_type
00501  * object representing the new stream position of the streambuffer
00502  * after the seek.  (This type is std::streampos for narrow character
00503  * (char) streams, std::wstreampos for wide character (wchar_t)
00504  * streams, std::u16streampos for the char16_t type and
00505  * std::u32streampos for the char32_t type.)  If the seek failed,
00506  * pos_type(off_type(-1)) is returned.
00507  */
00508   virtual pos_type seekpos(pos_type p,
00509                            std::ios_base::openmode m = std::ios_base::in | std::ios_base::out);
00510 public:
00511 /**
00512  * This class cannot be copied.  The copy constructor is deleted.
00513  */
00514   basic_fdoutbuf(const basic_fdoutbuf&) = delete;
00515 
00516 /**
00517  * This class cannot be copied.  The assignment operator is deleted.
00518  */
00519   basic_fdoutbuf& operator=(const basic_fdoutbuf&) = delete;
00520 
00521  /**
00522   * As this constructor has default argument values, it is also a
00523   * default constructor.  fdstreams do not offer concurrent access
00524   * from multiple threads to the same stream object, and if that is
00525   * required users should provide their own synchronisation.
00526   *
00527   * @param fd_ The file descriptor to be attached to the streambuffer,
00528   * or -1 to attach it latter with the attach_fd() method.
00529   *
00530   * @param manage_ Whether the streambuffer should manage the file
00531   * descriptor (that is, close it in its destructor or when a new file
00532   * descriptor is attached).
00533   *
00534   * @exception std::bad_alloc This constructor will throw
00535   * std::bad_alloc if fd_ >= 0, memory is exhausted and the system
00536   * throws on such exhaustion (unless the library has been installed
00537   * using the --with-glib-memory-slices-compat or
00538   * --with-glib-memory-slices-no-compat configuration option, in which
00539   * case glib will terminate the program if it is unable to obtain
00540   * memory from the operating system).  No other exception will be
00541   * thrown unless the constructor of std::basic_streambuf throws.
00542   */
00543   basic_fdoutbuf(int fd_ = -1, bool manage_ = true);
00544 
00545 /**
00546  * The destructor does not throw.
00547  */
00548   virtual ~basic_fdoutbuf();
00549 
00550  /**
00551   * Attach a new file descriptor to the streambuffer (and close any
00552   * file descriptor at present managed by it).  If output buffering
00553   * was previously switched off, it is switched back on again.
00554   * fdstreams do not offer concurrent access from multiple threads to
00555   * the same stream object, and if that is required users should
00556   * provide their own synchronisation.
00557   *
00558   * @param fd_ The new file descriptor to be attached to the
00559   * streambuffer.
00560   *
00561   * @param manage_ Whether the streambuffer should manage the new file
00562   * descriptor (that is, close it in its destructor or when a further
00563   * file descriptor is attached).
00564   *
00565   * @exception std::bad_alloc This method will throw std::bad_alloc if
00566   * fd_ >= 0, output buffering had previously been switched off,
00567   * memory is exhausted and the system throws on such exhaustion
00568   * (unless the library has been installed using the
00569   * --with-glib-memory-slices-compat or
00570   * --with-glib-memory-slices-no-compat configuration option, in which
00571   * case glib will terminate the program if it is unable to obtain
00572   * memory from the operating system).
00573   */
00574   void attach_fd(int fd_, bool manage_ = true);
00575 
00576  /**
00577   * Close the file descriptor at present attached to the streambuffer
00578   * (if any).  This method does not throw.  fdstreams do not offer
00579   * concurrent access from multiple threads to the same stream object,
00580   * and if that is required users should provide their own
00581   * synchronisation.
00582   *
00583   * @return From version 1.2.6, 'true' if the close succeeded, 'false'
00584   * if an error arose (including in a case where no descriptor has
00585   * been attached or it has already been closed).  Prior to version
00586   * 1.2.6, this method had void return type.
00587   */
00588   bool close_fd();
00589 
00590  /**
00591   * Get the file descriptor at present attached to the streambuffer
00592   * (if any).  This method does not throw.  fdstreams do not offer
00593   * concurrent access from multiple threads to the same stream object,
00594   * and if that is required users should provide their own
00595   * synchronisation.
00596   *
00597   * @return The file descriptor at present attached to the
00598   * streambuffer, or -1 if none has been attached
00599   */
00600   int get_fd() const {return fd;}
00601 
00602 /**
00603  * Stops output buffering if 'buffered' is false, or reverts to
00604  * buffering if buffering has previously been switched off and
00605  * 'buffered' is true.  Buffering is on by default for any newly
00606  * created fdoutbuf object and any newly attached file descriptor.  If
00607  * buffering is turned off, all characters at present in the buffers
00608  * which are stored for output are flushed.  This method has no effect
00609  * if no file descriptor has yet been attached to this streambuffer.
00610  * Switching output buffering off is similar in effect to setting the
00611  * std::ios_base::unitbuf flag in the relevant fdostream object, but
00612  * is slightly more efficient.  fdstreams do not offer concurrent
00613  * access from multiple threads to the same stream object, and if that
00614  * is required users should provide their own synchronisation.
00615  *
00616  * @param buffered 'false' if buffering is to be turned off, 'true' if
00617  * it is to be turned back on.
00618  *
00619  * @exception std::bad_alloc This method will throw std::bad_alloc if
00620  * 'buffered' is true, output buffering had previously been switched
00621  * off, memory is exhausted and the system throws on such exhaustion
00622  * (unless the library has been installed using the
00623  * --with-glib-memory-slices-compat or
00624  * --with-glib-memory-slices-no-compat configuration option, in which
00625  * case glib will terminate the program if it is unable to obtain
00626  * memory from the operating system).
00627  */
00628   void set_buffered(bool buffered);
00629 
00630 /**
00631  * This method indicates whether the output device concerned supports
00632  * random access, so that a call to seekoff() or seekpos() can
00633  * succeed.  This method does not throw.  fdstreams do not offer
00634  * concurrent access from multiple threads to the same stream object,
00635  * and if that is required users should provide their own
00636  * synchronisation.
00637  *
00638  * @return true if random access is supported, otherwise false.  The
00639  * result is only meaningful if a file descriptor has been attached to
00640  * this streambuffer.
00641  */
00642   bool can_seek() const;
00643 
00644 /* Only has effect if --with-glib-memory-slices-compat or
00645  * --with-glib-memory-slices-no-compat option picked */
00646   CGU_GLIB_MEMORY_SLICES_FUNCS
00647 };
00648 
00649 /**
00650  * @headerfile fdstream.h c++-gtk-utils/fdstream.h
00651  * @brief Output stream for unix file descriptors
00652  * @sa fdstreams
00653  * @ingroup fdstreams
00654  *
00655  * This class provides standard ostream services for unix file
00656  * descriptors.
00657  */
00658 template <class charT , class Traits = std::char_traits<charT> >
00659 class basic_fdostream: public std::basic_ostream<charT, Traits> {
00660 
00661   basic_fdoutbuf<charT, Traits> buf;
00662 
00663 public:
00664 /**
00665  * This class cannot be copied.  The copy constructor is deleted.
00666  */
00667   basic_fdostream(const basic_fdostream&);
00668 
00669 /**
00670  * This class cannot be copied.  The assignment operator is deleted.
00671  */
00672   basic_fdostream& operator=(const basic_fdostream&);
00673 
00674  /**
00675   * This is the constructor which passes a file descriptor.  fdstreams
00676   * do not offer concurrent access from multiple threads to the same
00677   * stream object, and if that is required users should provide their
00678   * own synchronisation.
00679   *
00680   * @param fd The file descriptor to be attached to the stream object.
00681   *
00682   * @param manage Whether the stream should manage the file descriptor
00683   * (that is, close it in its destructor or when a new file descriptor
00684   * is attached).
00685   *
00686   * @exception std::bad_alloc This constructor will throw
00687   * std::bad_alloc if fd >= 0, memory is exhausted and the system
00688   * throws on such exhaustion (unless the library has been installed
00689   * using the --with-glib-memory-slices-compat or
00690   * --with-glib-memory-slices-no-compat configuration option, in which
00691   * case glib will terminate the program if it is unable to obtain
00692   * memory from the operating system).  No other exception will be
00693   * thrown unless the constructor of std::basic_streambuf or
00694   * std::basic_ostream throws.
00695   */
00696   // using uniform initializer syntax here confuses doxygen
00697   basic_fdostream(int fd, bool manage = true): std::basic_ostream<charT, Traits>(0),
00698                                                buf(fd, manage) { // pass the descriptor at construction
00699     this->rdbuf(&buf);
00700   }
00701 
00702  /**
00703   * With this constructor, the file descriptor must be attached later
00704   * with the attach() method.  It will not throw unless the
00705   * constructor of std::basic_streambuf or std::basic_ostream throws.
00706   * fdstreams do not offer concurrent access from multiple threads to
00707   * the same stream object, and if that is required users should
00708   * provide their own synchronisation.
00709  */
00710   // using uniform initializer syntax here confuses doxygen
00711   basic_fdostream(): std::basic_ostream<charT, Traits>(0) {      // attach the descriptor later
00712     this->rdbuf(&buf);
00713   }
00714 
00715  /**
00716   * Attach a new file descriptor to the stream object (and close any
00717   * file descriptor at present managed by it).  From version 1.2.6, if
00718   * output buffering was previously switched off, it is switched back
00719   * on again.  Also from version 1.2.6, if any stream state flags were
00720   * set (eofbit, failbit or badbit), they will be cleared by a call to
00721   * clear() (prior to that version, the user had to call clear()
00722   * explicitly to do so).  If this method closes a file descriptor at
00723   * present managed by it and the close fails, failbit is not set and
00724   * no exception will be thrown.  Accordingly, if the user needs to
00725   * know whether there was an error in this method closing any
00726   * descriptor, she should call close() explicitly before calling this
00727   * method.  fdstreams do not offer concurrent access from multiple
00728   * threads to the same stream object, and if that is required users
00729   * should provide their own synchronisation.
00730   *
00731   * @param fd The new file descriptor to be attached to the stream
00732   * object.
00733   *
00734   * @param manage Whether the stream object should manage the new file
00735   * descriptor (that is, close it in its destructor or when a further
00736   * file descriptor is attached).
00737   *
00738   * @exception std::bad_alloc This method will throw std::bad_alloc if
00739   * fd >= 0, output buffering had previously been switched off, memory
00740   * is exhausted and the system throws on such exhaustion (unless the
00741   * library has been installed using the
00742   * --with-glib-memory-slices-compat or
00743   * --with-glib-memory-slices-no-compat configuration option, in which
00744   * case glib will terminate the program if it is unable to obtain
00745   * memory from the operating system).
00746   */
00747   void attach(int fd, bool manage = true) {buf.attach_fd(fd, manage); this->clear();}
00748 
00749  /**
00750   * Close the file descriptor at present attached to the stream object
00751   * (if any).  From version 1.2.6, if the close fails, the failbit
00752   * will be set with setstate(std::ios_base::failbit).  fdstreams do
00753   * not offer concurrent access from multiple threads to the same
00754   * stream object, and if that is required users should provide their
00755   * own synchronisation.
00756   *
00757   * @exception std::ios_base::failure From version 1.2.6, this
00758   * exception will be thrown if an error arises on closing the
00759   * descriptor and such an exception has been required by a call to
00760   * the exceptions() method of this class (inherited from
00761   * std::basic_ios<>).  No exception will be thrown if exceptions()
00762   * has not been called.
00763   */
00764   void close() {if (!buf.close_fd()) this->setstate(std::ios_base::failbit);}
00765 
00766  /**
00767   * Get the file descriptor at present attached to the stream object
00768   * (if any).  This method does not throw.  fdstreams do not offer
00769   * concurrent access from multiple threads to the same stream object,
00770   * and if that is required users should provide their own
00771   * synchronisation.
00772   *
00773   * @return The file descriptor at present attached to the
00774   * stream object, or -1 if none has been attached
00775   */
00776   int filedesc() const {return buf.get_fd();}
00777 
00778 /**
00779  * Stops output buffering if 'buffered' is false, or reverts to
00780  * buffering if buffering has previously been switched off and
00781  * 'buffered' is true.  Buffering is on by default for any newly
00782  * created fdostream object and any newly attached file descriptor.
00783  * If buffering is turned off, all characters at present in the
00784  * buffers which are stored for output are flushed.  This method has
00785  * no effect if no file descriptor has yet been attached.  Switching
00786  * output buffering off is similar in effect to setting the
00787  * std::ios_base::unitbuf flag, but is slightly more efficient.
00788  * fdstreams do not offer concurrent access from multiple threads to
00789  * the same stream object, and if that is required users should
00790  * provide their own synchronisation.
00791  *
00792  * @param buffered 'false' if buffering is to be turned off, 'true' if
00793  * it is to be turned back on.
00794  *
00795  * @exception std::bad_alloc This method will throw std::bad_alloc if
00796  * 'buffered' is true, output buffering had previously been switched
00797  * off, memory is exhausted and the system throws on such exhaustion
00798  * (unless the library has been installed using the
00799  * --with-glib-memory-slices-compat or
00800  * --with-glib-memory-slices-no-compat configuration option, in which
00801  * case glib will terminate the program if it is unable to obtain
00802  * memory from the operating system).
00803  */
00804   void set_buffered(bool buffered) {buf.set_buffered(buffered);}
00805 
00806 /**
00807  * This method indicates whether the output device concerned supports
00808  * random access, so that a call to tellp() or seekp() can succeed.
00809  * Note that in the seekp(off_type off, ios_base::seekdir dir)
00810  * variant, on wide character streams the 'off' argument is
00811  * dimensioned as the number of wchar_t units not the number of bytes
00812  * (that is, it is bytes/sizeof(char_type)).  This method does not
00813  * throw.  fdstreams do not offer concurrent access from multiple
00814  * threads to the same stream object, and if that is required users
00815  * should provide their own synchronisation.
00816  *
00817  * @return true if random access is supported, otherwise false.  The
00818  * result is only meaningful if a file descriptor has been attached to
00819  * this stream.
00820  */
00821   bool can_seek() const {return buf.can_seek();}
00822 
00823 /* Only has effect if --with-glib-memory-slices-compat or
00824  * --with-glib-memory-slices-no-compat option picked */
00825   CGU_GLIB_MEMORY_SLICES_FUNCS
00826 };
00827 
00828 
00829 /**
00830  * @headerfile fdstream.h c++-gtk-utils/fdstream.h
00831  * @brief Input stream buffer for unix file descriptors
00832  * @sa fdstreams
00833  * @ingroup fdstreams
00834  *
00835  * This class provides an input stream buffer for unix file
00836  * descriptors.  It does the buffering for the basic_fdistream stream
00837  * class.
00838  */
00839 template <class charT , class Traits = std::char_traits<charT> >
00840 class basic_fdinbuf : public std::basic_streambuf<charT, Traits> {
00841 
00842 public:
00843   typedef charT char_type;
00844   typedef Traits traits_type;
00845   typedef typename traits_type::int_type int_type;
00846   typedef typename traits_type::pos_type pos_type;
00847   typedef typename traits_type::off_type off_type;
00848 
00849 private:
00850   int fd;    // file descriptor
00851   bool manage;
00852   bool byteswap;
00853 
00854   static const int putback_size = 4;     // size of putback area
00855   static const int buf_size = 1024;      // size of the data buffer
00856   char_type buffer[buf_size + putback_size];  // data buffer
00857   void reset();
00858   static void swap_element(char_type&);
00859 
00860 protected:
00861 /**
00862  * This method will not throw.  This means that the input functions of
00863  * stream objects which have this streambuffer as a member will not
00864  * throw unless the underlying functions of the std::basic_istream
00865  * class throw, which they would not normally do unless they have been
00866  * required to do so on failbit, badbit or eofbit being set by an
00867  * explicit call to the exceptions() method of that class.  fdstreams
00868  * do not offer concurrent access from multiple threads to the same
00869  * stream object, and if that is required users should provide their
00870  * own synchronisation.
00871  */
00872   virtual int_type underflow();
00873 
00874 #ifndef FDSTREAM_USE_STD_N_READ_WRITE
00875 /**
00876  * This method will not throw.  This means that the input functions of
00877  * stream objects which have this streambuffer as a member will not
00878  * throw unless the underlying functions of the std::basic_istream
00879  * class throw, which they would not normally do unless they have been
00880  * required to do so on failbit, badbit or eofbit being set by an
00881  * explicit call to the exceptions() method of that class.  fdstreams
00882  * do not offer concurrent access from multiple threads to the same
00883  * stream object, and if that is required users should provide their
00884  * own synchronisation.
00885  */
00886   virtual std::streamsize xsgetn(char_type*, std::streamsize);
00887 #endif
00888 /**
00889  * This method provides random access on input devices that support
00890  * it, so supporting the tellg() and seekg() methods of the
00891  * basic_fdistream class.  This method does not throw, but if it
00892  * returns pos_type(off_type(-1)) to indicate failure, it will cause
00893  * the seekg() or tellg() methods of the relevant stream class to
00894  * throw std::ios_base::failure if such an exception has been required
00895  * by an explicit call to the exceptions() method of that class (but
00896  * not otherwise).  fdstreams do not offer concurrent access from
00897  * multiple threads to the same stream object, and if that is required
00898  * users should provide their own synchronisation.
00899  *
00900  * @param off The offset to be applied to the 'way' argument when
00901  * seeking.  It is a signed integer type, and on wide character
00902  * streams is dimensioned as the number of wchar_t units not the
00903  * number of bytes (that is, it is bytes/sizeof(char_type)).
00904  *
00905  * @param way The file position to which the 'off' argument is to be
00906  * applied (either std::ios_base::beg, std::ios_base::cur or
00907  * std::ios_base::end).
00908  *
00909  * @param m The required read/write status of the file descriptor
00910  * attached to this streambuffer for this method to attempt a seek.
00911  * As this is an input streambuffer, the argument should have the
00912  * std::ios_base::in bit set.  Provided that bit is set, it doesn't
00913  * matter if others are also set.
00914  *
00915  * @return If the seek succeeds, a std::char_traits<T>::pos_type
00916  * object representing the new stream position of the streambuffer
00917  * after the seek.  (This type is std::streampos for narrow character
00918  * (char) streams, std::wstreampos for wide character (wchar_t)
00919  * streams, std::u16streampos for the char16_t type and
00920  * std::u32streampos for the char32_t type.)  If the seek failed,
00921  * pos_type(off_type(-1)) is returned.
00922  */
00923   virtual pos_type seekoff(off_type off,
00924                            std::ios_base::seekdir way,
00925                            std::ios_base::openmode m = std::ios_base::in | std::ios_base::out);
00926 
00927 /**
00928  * This method provides random access on input devices that support
00929  * it, so supporting the seekg() method of the basic_fdistream class.
00930  * It is equivalent to seekoff(off_type(p), std::ios_base::beg, m).
00931  * This method does not throw, but if it returns
00932  * pos_type(off_type(-1)) to indicate failure, it will cause the
00933  * seekg() method of the relevant stream class to throw
00934  * std::ios_base::failure if such an exception has been required by an
00935  * explicit call to the exceptions() method of that class (but not
00936  * otherwise).  fdstreams do not offer concurrent access from multiple
00937  * threads to the same stream object, and if that is required users
00938  * should provide their own synchronisation.
00939  *
00940  * @param p The absolute position to which the seek is to be made,
00941  * obtained by a previous call to seekoff() or to this method.
00942  *
00943  * @param m The required read/write status of the file descriptor
00944  * attached to this streambuffer for this method to attempt a seek.
00945  * As this is an input streambuffer, the argument should have the
00946  * std::ios_base::in bit set.  Provided that bit is set, it doesn't
00947  * matter if others are also set.
00948  *
00949  * @return If the seek succeeds, a std::char_traits<T>::pos_type
00950  * object representing the new stream position of the streambuffer
00951  * after the seek.  (This type is std::streampos for narrow character
00952  * (char) streams, std::wstreampos for wide character (wchar_t)
00953  * streams, std::u16streampos for the char16_t type and
00954  * std::u32streampos for the char32_t type.)  If the seek failed,
00955  * pos_type(off_type(-1)) is returned.
00956  */
00957   virtual pos_type seekpos(pos_type p,
00958                            std::ios_base::openmode m = std::ios_base::in | std::ios_base::out);
00959 public:
00960 /**
00961  * This class cannot be copied.  The copy constructor is deleted.
00962  */
00963   basic_fdinbuf(const basic_fdinbuf&) = delete;
00964 
00965 /**
00966  * This class cannot be copied.  The assignment operator is deleted.
00967  */
00968   basic_fdinbuf& operator=(const basic_fdinbuf&) = delete;
00969 
00970  /**
00971   * As this constructor has default argument values, it is also a
00972   * default constructor.  It does not throw unless the constructor of
00973   * std::basic_streambuf throws.  fdstreams do not offer concurrent
00974   * access from multiple threads to the same stream object, and if
00975   * that is required users should provide their own synchronisation.
00976   *
00977   * @param fd_ The file descriptor to be attached to the streambuffer,
00978   * or -1 to attach it latter with the attach() method.
00979   *
00980   * @param manage_ Whether the streambuffer should manage the file
00981   * descriptor (that is, close it in its destructor or when a new file
00982   * descriptor is attached).
00983   */
00984   basic_fdinbuf(int fd_ = -1, bool manage_ = true);
00985 
00986 /**
00987  * The destructor does not throw.
00988  */
00989   virtual ~basic_fdinbuf();
00990 
00991  /**
00992   * Attach a new file descriptor to the streambuffer (and close any
00993   * file descriptor at present managed by it).  In the case of a wide
00994   * character streambuffer, it also switches off byte swapping, if it
00995   * was previously on.  This method does not throw.  fdstreams do not
00996   * offer concurrent access from multiple threads to the same stream
00997   * object, and if that is required users should provide their own
00998   * synchronisation.
00999   *
01000   * @param fd_ The new file descriptor to be attached to the
01001   * streambuffer.
01002   *
01003   * @param manage_ Whether the streambuffer should manage the new file
01004   * descriptor (that is, close it in its destructor or when a further
01005   * file descriptor is attached).
01006   */
01007   void attach_fd(int fd_, bool manage_ = true);
01008 
01009  /**
01010   * Close the file descriptor at present attached to the streambuffer
01011   * (if any).  This method does not throw.  fdstreams do not offer
01012   * concurrent access from multiple threads to the same stream object,
01013   * and if that is required users should provide their own
01014   * synchronisation.
01015   *
01016   * @return From version 1.2.6, 'true' if the close succeeded, 'false'
01017   * if an error arose (including in a case where no descriptor has
01018   * been attached or it has already been closed).  Prior to version
01019   * 1.2.6, this method had void return type.
01020   */
01021   bool close_fd();
01022 
01023  /**
01024   * Get the file descriptor at present attached to the streambuffer
01025   * (if any).  This method does not throw.  fdstreams do not offer
01026   * concurrent access from multiple threads to the same stream object,
01027   * and if that is required users should provide their own
01028   * synchronisation.
01029   *
01030   * @return The file descriptor at present attached to the
01031   * streambuffer, or -1 if none has been attached
01032   */
01033   int get_fd() const {return fd;}
01034 
01035  /**
01036   * Causes the streambuffer to swap bytes in the incoming text, so as
01037   * to convert big endian text to little endian text, or little endian
01038   * text to big endian text.  It is called by the user in response to
01039   * finding a byte order marker (BOM) 0xfffe (UTF-16) or 0xfffe0000
01040   * (UTF-32) as the first character of a newly opened file/stream, or
01041   * if the user knows by some other means that the native endianness
01042   * of the machine doing the reading differs from the endianness of
01043   * the file/stream being read.  This only has effect on wide
01044   * character input streambuffers (for example, wfdinbuf), and not the
01045   * fdinbuf narrow character stream buffer.  This method does not
01046   * throw.  fdstreams do not offer concurrent access from multiple
01047   * threads to the same stream object, and if that is required users
01048   * should provide their own synchronisation.
01049   *
01050   * @param swap 'true' if byte swapping is to be turned on, 'false' if
01051   * it is to be turned off.  This will affect all characters extracted
01052   * from the streambuffer after this call is made.  If any previously
01053   * extracted character is to be putback(), it must be put back before
01054   * this function is called (or unget() should be called instead) to
01055   * avoid a putback mismatch, because this call will byte-swap
01056   * anything already in the buffers.  (Characters extracted after the
01057   * call to this method may be putback normally.)
01058   */
01059   void set_byteswap(bool swap);
01060 
01061 /**
01062  * This method indicates whether the input device concerned supports
01063  * random access, so that a call to seekoff() or seekpos() can
01064  * succeed.  This method does not throw.  fdstreams do not offer
01065  * concurrent access from multiple threads to the same stream object,
01066  * and if that is required users should provide their own
01067  * synchronisation.
01068  *
01069  * @return true if random access is supported, otherwise false.  The
01070  * result is only meaningful if a file descriptor has been attached to
01071  * this streambuffer.
01072  */
01073   bool can_seek() const;
01074 
01075 /* Only has effect if --with-glib-memory-slices-compat or
01076  * --with-glib-memory-slices-no-compat option picked */
01077   CGU_GLIB_MEMORY_SLICES_FUNCS
01078 };
01079 
01080 /**
01081  * @headerfile fdstream.h c++-gtk-utils/fdstream.h
01082  * @brief Input stream for unix file descriptors
01083  * @sa fdstreams
01084  * @ingroup fdstreams
01085  *
01086  * This class provides standard istream services for unix file
01087  * descriptors.
01088  */
01089 template <class charT , class Traits = std::char_traits<charT> >
01090 class basic_fdistream : public std::basic_istream<charT, Traits> {
01091 
01092   basic_fdinbuf<charT , Traits> buf;
01093 
01094 public:
01095 /**
01096  * This class cannot be copied.  The copy constructor is deleted.
01097  */
01098   basic_fdistream(const basic_fdistream&) = delete;
01099 
01100 /**
01101  * This class cannot be copied.  The assignment operator is deleted.
01102  */
01103   basic_fdistream& operator=(const basic_fdistream&) = delete;
01104 
01105  /**
01106   * This is the constructor which passes a file descriptor.  It will
01107   * not throw unless the constructor of std::basic_streambuf or
01108   * std::basic_istream throws.  fdstreams do not offer concurrent
01109   * access from multiple threads to the same stream object, and if
01110   * that is required users should provide their own synchronisation.
01111   *
01112   * @param fd The file descriptor to be attached to the stream object.
01113   *
01114   * @param manage Whether the stream should manage the file descriptor
01115   * (that is, close it in its destructor or when a new file descriptor
01116   * is attached).
01117   */
01118   // using uniform initializer syntax here confuses doxygen
01119   basic_fdistream (int fd, bool manage = true) : std::basic_istream<charT, Traits>(0),
01120                                                  buf(fd, manage) { // pass the descriptor at construction
01121     this->rdbuf(&buf);
01122   }
01123 
01124  /**
01125   * With this constructor, the file descriptor must be attached later
01126   * with the attach() method.  It will not throw unless the
01127   * constructor of std::basic_streambuf or std::basic_istream throws.
01128   * fdstreams do not offer concurrent access from multiple threads to
01129   * the same stream object, and if that is required users should
01130   * provide their own synchronisation.
01131   */
01132   // using uniform initializer syntax here confuses doxygen
01133   basic_fdistream () : std::basic_istream<charT, Traits>(0) {      // attach the descriptor later
01134     this->rdbuf(&buf);
01135   }
01136 
01137  /**
01138   * Attach a new file descriptor to the stream object (and close any
01139   * file descriptor at present managed by it).  In the case of wide
01140   * character streams, it also switches off byte swapping, if it was
01141   * previously on.  From version 1.2.6, if any stream state flags were
01142   * set (eofbit, failbit or badbit), they will be cleared by a call to
01143   * clear() (prior to that version, the user had to call clear()
01144   * explicitly to do so).  If this method closes a file descriptor at
01145   * present managed by it and the close fails, failbit is not set and
01146   * no exception will be thrown.  Accordingly, if the user needs to
01147   * know whether there was an error in this method closing any
01148   * descriptor, she should call close() explicitly before calling this
01149   * method.  This method does not throw.  fdstreams do not offer
01150   * concurrent access from multiple threads to the same stream object,
01151   * and if that is required users should provide their own
01152   * synchronisation.
01153   *
01154   * @param fd The new file descriptor to be attached to the stream
01155   * object.
01156   *
01157   * @param manage Whether the stream object should manage the new file
01158   * descriptor (that is, close it in its destructor or when a further
01159   * file descriptor is attached).
01160   */
01161   void attach(int fd, bool manage = true) {buf.attach_fd(fd, manage); this->clear();}
01162 
01163  /**
01164   * Close the file descriptor at present attached to the stream object
01165   * (if any).  From version 1.2.6, if the close fails, the failbit
01166   * will be set with setstate(std::ios_base::failbit).  fdstreams do
01167   * not offer concurrent access from multiple threads to the same
01168   * stream object, and if that is required users should provide their
01169   * own synchronisation.
01170   *
01171   * @exception std::ios_base::failure From version 1.2.6, this
01172   * exception will be thrown if an error arises on closing the
01173   * descriptor and such an exception has been required by a call to
01174   * the exceptions() method of this class (inherited from
01175   * std::basic_ios<>).  No exception will be thrown if exceptions()
01176   * has not been called.
01177   */
01178   void close() {if (!buf.close_fd()) this->setstate(std::ios_base::failbit);}
01179 
01180  /**
01181   * Get the file descriptor at present attached to the stream object
01182   * (if any).  This method does not throw.  fdstreams do not offer
01183   * concurrent access from multiple threads to the same stream object,
01184   * and if that is required users should provide their own
01185   * synchronisation.
01186   *
01187   * @return The file descriptor at present attached to the
01188   * stream object, or -1 if none has been attached
01189   */
01190   int filedesc() const {return buf.get_fd();}
01191 
01192  /**
01193   * Causes the underlying stream buffer to swap bytes in the incoming
01194   * text, so as to convert big endian text to little endian text, or
01195   * little endian text to big endian text.  It is called in response
01196   * to finding a byte order marker (BOM) 0xfffe (UTF-16) or 0xfffe0000
01197   * (UTF-32) as the first character of a newly opened file/stream, or
01198   * if the user knows by some other means that the native endianness
01199   * of the machine doing the reading differs from the endianness of
01200   * the file/stream being read.  This only has effect on wide
01201   * character istreams (for example, wfdistream), and not the
01202   * fdistream narrow character stream.  This method does not throw.
01203   * fdstreams do not offer concurrent access from multiple threads to
01204   * the same stream object, and if that is required users should
01205   * provide their own synchronisation.
01206   *
01207   * @param swap 'true' if byte swapping is to be turned on, 'false' if
01208   * it is to be turned off.  This will affect all characters extracted
01209   * from the underlying streambuffer after this call is made.  If any
01210   * previously extracted character is to be putback(), it must be put
01211   * back before this function is called (or unget() should be called
01212   * instead) to avoid a putback mismatch, because this call will
01213   * byte-swap anything already in the buffers.  (Characters extracted
01214   * after the call to this method may be putback normally.)
01215   */
01216   void set_byteswap(bool swap) {buf.set_byteswap(swap);}
01217 
01218 /**
01219  * This method indicates whether the input device concerned supports
01220  * random access, so that a call to tellg() or seekg() can succeed.
01221  * Note that in the seekg(off_type off, ios_base::seekdir dir)
01222  * variant, on wide character streams the 'off' argument is
01223  * dimensioned as the number of wchar_t units not the number of bytes
01224  * (that is, it is bytes/sizeof(char_type)).  This method does not
01225  * throw.  fdstreams do not offer concurrent access from multiple
01226  * threads to the same stream object, and if that is required users
01227  * should provide their own synchronisation.
01228  *
01229  * @return true if random access is supported, otherwise false.  The
01230  * result is only meaningful if a file descriptor has been attached to
01231  * this stream.
01232  */
01233   bool can_seek() const {return buf.can_seek();}
01234 
01235 /* Only has effect if --with-glib-memory-slices-compat or
01236  * --with-glib-memory-slices-no-compat option picked */
01237   CGU_GLIB_MEMORY_SLICES_FUNCS
01238 };
01239 
01240 /**
01241  * @defgroup fdstreams fdstreams
01242  */
01243 /**
01244  * @typedef fdinbuf.
01245  * @brief Input stream buffer for file descriptors for char type
01246  * @ingroup fdstreams
01247  */
01248 typedef basic_fdinbuf<char> fdinbuf;
01249 
01250 /**
01251  * @typedef fdoutbuf.
01252  * @brief Output stream buffer for file descriptors for char type
01253  * @ingroup fdstreams
01254  */
01255 typedef basic_fdoutbuf<char> fdoutbuf;
01256 
01257 /**
01258  * @typedef fdistream.
01259  * @brief Input stream for file descriptors for char type
01260  * @anchor fdistreamAnchor
01261  * @ingroup fdstreams
01262  */
01263 typedef basic_fdistream<char> fdistream;
01264 
01265 /**
01266  * @typedef fdostream.
01267  * @brief Output stream for file descriptors for char type
01268  * @anchor fdostreamAnchor
01269  * @ingroup fdstreams
01270  */
01271 typedef basic_fdostream<char> fdostream;
01272 
01273 /**
01274  * @typedef wfdinbuf.
01275  * @brief Input stream buffer for file descriptors for wchar_t type
01276  * @ingroup fdstreams
01277  */
01278 typedef basic_fdinbuf<wchar_t> wfdinbuf;
01279 
01280 /**
01281  * @typedef wfdoutbuf.
01282  * @brief Output stream buffer for file descriptors for wchar_t type
01283  * @ingroup fdstreams
01284  */
01285 typedef basic_fdoutbuf<wchar_t> wfdoutbuf;
01286 
01287 /**
01288  * @typedef wfdistream.
01289  * @brief Input stream for file descriptors for wchar_t type
01290  * @anchor wfdistreamAnchor
01291  * @ingroup fdstreams
01292  */
01293 typedef basic_fdistream<wchar_t> wfdistream;
01294 
01295 /**
01296  * @typedef wfdostream.
01297  * @brief Output stream for file descriptors for wchar_t type
01298  * @anchor wfdostreamAnchor
01299  * @ingroup fdstreams
01300  */
01301 typedef basic_fdostream<wchar_t> wfdostream;
01302 
01303 /**
01304  * @typedef u16fdinbuf.
01305  * @brief Input stream buffer for file descriptors for char16_t type
01306  * @ingroup fdstreams
01307  */
01308  typedef basic_fdinbuf<char16_t> u16fdinbuf;
01309 
01310 /**
01311  * @typedef u16fdoutbuf.
01312  * @brief Output stream buffer for file descriptors for char16_t type
01313  * @ingroup fdstreams
01314  */
01315 typedef basic_fdoutbuf<char16_t> u16fdoutbuf;
01316 
01317 /**
01318  * @typedef u16fdistream.
01319  * @brief Input stream for file descriptors for char16_t type
01320  * @anchor u16fdistreamAnchor
01321  * @ingroup fdstreams
01322  */
01323 typedef basic_fdistream<char16_t> u16fdistream;
01324 
01325 /**
01326  * @typedef u16fdostream.
01327  * @brief Output stream for file descriptors for char16_t type
01328  * @anchor u16fdostreamAnchor
01329  * @ingroup fdstreams
01330  */
01331 typedef basic_fdostream<char16_t> u16fdostream;
01332 
01333 /**
01334  * @typedef u32fdinbuf.
01335  * @brief Input stream buffer for file descriptors for char32_t type
01336  * @ingroup fdstreams
01337  */
01338 typedef basic_fdinbuf<char32_t> u32fdinbuf;
01339 
01340 /**
01341  * @typedef u32fdoutbuf.
01342  * @brief Output stream buffer for file descriptors for char32_t type
01343  * @ingroup fdstreams
01344  */
01345 typedef basic_fdoutbuf<char32_t> u32fdoutbuf;
01346 
01347 /**
01348  * @typedef u32fdistream.
01349  * @brief Input stream for file descriptors for char32_t type
01350  * @anchor u32fdistreamAnchor
01351  * @ingroup fdstreams
01352  */
01353 typedef basic_fdistream<char32_t> u32fdistream;
01354 
01355 /**
01356  * @typedef u32fdostream.
01357  * @brief Output stream for file descriptors for char32_t type
01358  * @anchor u32fdostreamAnchor
01359  * @ingroup fdstreams
01360  */
01361 typedef basic_fdostream<char32_t> u32fdostream;
01362 
01363 } // namespace Cgu
01364 
01365 #include <c++-gtk-utils/fdstream.tpp>
01366 
01367 #endif /*CGU_FDSTREAM_H*/