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 * 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 this->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 this->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 this->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 this->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*/