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