CVC3  2.4.1
fdstream.h
Go to the documentation of this file.
1 /*! \file fdstream.h
2  * @brief The following code declares classes to read from and write to
3  * file descriptore or file handles.
4  *
5  * See
6  * http://www.josuttis.com/cppcode
7  * for details and the latest version.
8  *
9  * - open:
10  * - integrating BUFSIZ on some systems?
11  * - optimized reading of multiple characters
12  * - stream for reading AND writing
13  * - i18n
14  *
15  * (C) Copyright Nicolai M. Josuttis 2001.
16  * Permission to copy, use, modify, sell and distribute this software
17  * is granted provided this copyright notice appears in all copies.
18  * This software is provided "as is" without express or implied
19  * warranty, and with no claim as to its suitability for any purpose.
20  *
21  * Version: Jul 28, 2002
22  * History:
23  * Jul 28, 2002: bugfix memcpy() => memmove()
24  * fdinbuf::underflow(): cast for return statements
25  * Aug 05, 2001: first public version
26  */
27 #ifndef BOOST_FDSTREAM_HPP
28 #define BOOST_FDSTREAM_HPP
29 
30 #include <istream>
31 #include <ostream>
32 #include <streambuf>
33 // for EOF:
34 #include <cstdio>
35 // for memmove():
36 #include <cstring>
37 
38 
39 // low-level read and write functions
40 #ifdef _MSC_VER
41 # include <io.h>
42 #else
43 # include <unistd.h>
44 //extern "C" {
45 // int write (int fd, const char* buf, int num);
46 // int read (int fd, char* buf, int num);
47 //}
48 #endif
49 
50 
51 // BEGIN namespace BOOST
52 namespace std {
53 
54 
55 /************************************************************
56  * fdostream
57  * - a stream that writes on a file descriptor
58  ************************************************************/
59 
60 
61 class fdoutbuf : public std::streambuf {
62  protected:
63  int fd; // file descriptor
64  public:
65  // constructor
66  fdoutbuf (int _fd) : fd(_fd) {
67  }
68  protected:
69  // write one character
70  virtual int_type overflow (int_type c) {
71  if (c != EOF) {
72  char z = c;
73  if (write (fd, &z, 1) != 1) {
74  return EOF;
75  }
76  }
77  return c;
78  }
79  // write multiple characters
80  virtual
81  std::streamsize xsputn (const char* s,
82  std::streamsize num) {
83  return write(fd,s,num);
84  }
85 };
86 
87 class fdostream : public std::ostream {
88  protected:
90  public:
91  fdostream (int fd) : std::ostream(0), buf(fd) {
92  rdbuf(&buf);
93  }
94 };
95 
96 
97 /************************************************************
98  * fdistream
99  * - a stream that reads on a file descriptor
100  ************************************************************/
101 
102 class fdinbuf : public std::streambuf {
103  protected:
104  int fd; // file descriptor
105  protected:
106  /* data buffer:
107  * - at most, pbSize characters in putback area plus
108  * - at most, bufSize characters in ordinary read buffer
109  */
110  static const int pbSize = 4; // size of putback area
111  static const int bufSize = 1024; // size of the data buffer
112  char buffer[bufSize+pbSize]; // data buffer
113 
114  public:
115  /* constructor
116  * - initialize file descriptor
117  * - initialize empty data buffer
118  * - no putback area
119  * => force underflow()
120  */
121  fdinbuf (int _fd) : fd(_fd) {
122  setg (buffer+pbSize, // beginning of putback area
123  buffer+pbSize, // read position
124  buffer+pbSize); // end position
125  }
126 
127  protected:
128  // insert new characters into the buffer
129  virtual int_type underflow () {
130 #ifndef _MSC_VER
131  using std::memmove;
132 #endif
133 
134  // is read position before end of buffer?
135  if (gptr() < egptr()) {
136  return traits_type::to_int_type(*gptr());
137  }
138 
139  /* process size of putback area
140  * - use number of characters read
141  * - but at most size of putback area
142  */
143  int numPutback;
144  numPutback = gptr() - eback();
145  if (numPutback > pbSize) {
146  numPutback = pbSize;
147  }
148 
149  /* copy up to pbSize characters previously read into
150  * the putback area
151  */
152  memmove (buffer+(pbSize-numPutback), gptr()-numPutback,
153  numPutback);
154 
155  // read at most bufSize new characters
156  int num;
157  num = read (fd, buffer+pbSize, bufSize);
158  if (num <= 0) {
159  // ERROR or EOF
160  return EOF;
161  }
162 
163  // reset buffer pointers
164  setg (buffer+(pbSize-numPutback), // beginning of putback area
165  buffer+pbSize, // read position
166  buffer+pbSize+num); // end of buffer
167 
168  // return next character
169  return traits_type::to_int_type(*gptr());
170  }
171 };
172 
173 class fdistream : public std::istream {
174  protected:
176  public:
177  fdistream (int fd) : std::istream(0), buf(fd) {
178  rdbuf(&buf);
179  }
180 };
181 
182 
183 } // END namespace boost
184 
185 #endif /*BOOST_FDSTREAM_HPP*/