c++-gtk-utils
|
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*/