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