00001 /* Class modified by ADL for randlm namespace on Feb 15th, 2008. 00002 * 00003 * The following code declares classes to read from and write to 00004 * file descriptore or file handles. 00005 * 00006 * See 00007 * http://www.josuttis.com/cppcode 00008 * for details and the latest version. 00009 * 00010 * - open: 00011 * - integrating BUFSIZ on some systems? 00012 * - optimized reading of multiple characters 00013 * - stream for reading AND writing 00014 * - i18n 00015 * 00016 * (C) Copyright Nicolai M. Josuttis 2001. 00017 * Permission to copy, use, modify, sell and distribute this software 00018 * is granted provided this copyright notice appears in all copies. 00019 * This software is provided "as is" without express or implied 00020 * warranty, and with no claim as to its suitability for any purpose. 00021 * 00022 * Version: Jul 28, 2002 00023 * History: 00024 * Jul 28, 2002: bugfix memcpy() => memmove() 00025 * fdinbuf::underflow(): cast for return statements 00026 * Aug 05, 2001: first public version 00027 */ 00028 #ifndef moses_DynSAInclude_fdstream_h 00029 #define moses_DynSAInclude_fdstream_h 00030 00031 #include <streambuf> 00032 // for EOF: 00033 #include <cstdio> 00034 // for memmove(): 00035 #include <cstring> 00036 00037 00038 // low-level read and write functions 00039 #ifdef _MSC_VER 00040 # include <io.h> 00041 #else 00042 # include <unistd.h> 00043 //extern "C" { 00044 // int write (int fd, const char* buf, int num); 00045 // int read (int fd, char* buf, int num); 00046 //} 00047 #endif 00048 00049 00050 // BEGIN namespace 00051 //namespace randlm { 00052 00053 /************************************************************ 00054 * fdstreambuf 00055 * - a stream that reads on a file descriptor 00056 ************************************************************/ 00057 00058 class fdstreambuf : public std::streambuf 00059 { 00060 protected: 00061 int fd; // file descriptor 00062 protected: 00063 /* data buffer: 00064 * - at most, pbSize characters in putback area plus 00065 * - at most, bufSize characters in ordinary read buffer 00066 */ 00067 static const int pbSize = 4; // size of putback area 00068 static const int bufSize = 1024; // size of the data buffer 00069 char buffer[bufSize+pbSize]; // data buffer 00070 00071 public: 00072 /* constructor 00073 * - initialize file descriptor 00074 * - initialize empty data buffer 00075 * - no putback area 00076 * => force underflow() 00077 */ 00078 fdstreambuf (int _fd) : fd(_fd) { 00079 setg (buffer+pbSize, // beginning of putback area 00080 buffer+pbSize, // read position 00081 buffer+pbSize); // end position 00082 } 00083 protected: 00084 // insert new characters into the buffer 00085 virtual int_type underflow () { 00086 #ifndef _MSC_VER 00087 using std::memmove; 00088 #endif 00089 00090 // is read position before end of buffer? 00091 if (gptr() < egptr()) { 00092 return traits_type::to_int_type(*gptr()); 00093 } 00094 /* process size of putback area 00095 * - use number of characters read 00096 * - but at most size of putback area 00097 */ 00098 int numPutback; 00099 numPutback = gptr() - eback(); 00100 if (numPutback > pbSize) { 00101 numPutback = pbSize; 00102 } 00103 00104 /* copy up to pbSize characters previously read into 00105 * the putback area 00106 */ 00107 memmove (buffer+(pbSize-numPutback), gptr()-numPutback, 00108 numPutback); 00109 00110 // read at most bufSize new characters 00111 int num; 00112 num = read (fd, buffer+pbSize, bufSize); 00113 if (num <= 0) { 00114 // ERROR or EOF 00115 return EOF; 00116 } 00117 00118 // reset buffer pointers 00119 setg (buffer+(pbSize-numPutback), // beginning of putback area 00120 buffer+pbSize, // read position 00121 buffer+pbSize+num); // end of buffer 00122 00123 // return next character 00124 return traits_type::to_int_type(*gptr()); 00125 } 00126 00127 // write one character 00128 virtual int_type overflow (int_type c) { 00129 if (c != EOF) { 00130 char z = c; 00131 if (write (fd, &z, 1) != 1) { 00132 return EOF; 00133 } 00134 } 00135 return c; 00136 } 00137 // write multiple characters 00138 virtual 00139 std::streamsize xsputn (const char* s, 00140 std::streamsize num) { 00141 return write(fd,s,num); 00142 } 00143 }; 00144 //} // END namespace 00145 00146 #endif