|
|
1.1 root 1: /*
2: stream.h, the header file for the C++ stream i/o system 4/06/85
3: */
4: #ifndef STREAMH
5: #define STREAMH
6: #include <stdio.h>
7: #ifndef NULL
8: #define NULL 0
9: #endif
10: #ifndef EOF
11: #define EOF (-1)
12: #endif
13: #ifndef BUFSIZE
14: #define BUFSIZE 1024
15: #endif
16:
17: enum state_value { _good=0, _eof=1, _fail=2, _bad=4 };
18: enum open_mode { input=0, output=1, append=2 };
19:
20: struct streambuf { // a buffer for streams
21:
22: char* base; // pointer to beginning of buffer
23: char* pptr; // pointer to next free byte
24: char* gptr; // pointer to next filled byte
25: char* eptr; // pointer to first byte following buffer
26: char alloc; // true if buffer is allocated using "new"
27: FILE* fp; // for stdio compatibility
28:
29: virtual overflow(int c=EOF); // Empty a buffer.
30: // Return EOF on error
31: // 0 on success
32:
33: virtual int underflow(); // Fill a buffer
34: // Return EOF on error or end of input
35: // next character on success
36:
37: inline int sgetc() // get the current character
38: {
39: return (gptr>=pptr) ? underflow() : *gptr&0377;
40: }
41:
42:
43: inline int snextc() // get the next character
44: {
45: return (gptr>=(pptr-1)) ? underflow() : *++gptr&0377;
46: }
47:
48: inline void stossc() // advance to the next character
49: {
50: if (gptr++ >= pptr)
51: underflow();
52: }
53:
54: inline void sputbackc(char c)
55: /*
56: Return a character to the buffer (ala lookahead 1). Since
57: the user may be "playing games" the character might be
58: different than the last one returned by sgetc or snextc.
59: If the user attempts to put back more characters than have
60: been extracted, nothing will be put back.
61: Putting back an EOF is DANGEROUS.
62: */
63: {
64: if (gptr > base) *--gptr = c;
65: }
66:
67: inline int sputc(int c =EOF) // put a character into the buffer
68: {
69: if (fp == 0)
70: return (eptr<=pptr) ? overflow(c&0377) : (*pptr++=c&0377);
71: else
72: return putc(c, fp);
73: }
74:
75:
76: inline streambuf * setbuf(char *p, int len, int count =0)
77: /*
78: supply an area for a buffer.
79: The "count" parameter allows the buffer to start in non-empty.
80: */
81: {
82: base = gptr = p;
83: pptr = p + count;
84: eptr = base + len;
85: return this;
86: }
87:
88: int doallocate(); // allocate some space for the buffer
89: inline int allocate(){ return base==0 ? doallocate() : 0; }
90:
91: streambuf() { base = gptr = pptr = eptr = 0; alloc = 0; fp = 0; }
92: streambuf(char* p, int l) { setbuf(p,l); alloc = 0; }
93: ~streambuf() { if (base && alloc) delete base; }
94: };
95:
96: extern int close(int);
97:
98: struct filebuf : public streambuf { // a stream buffer for files
99:
100: int fd; // file descriptor
101: char opened; // non-zero if file has been opened
102:
103: int overflow(int c=EOF); // Empty a buffer.
104: // Return EOF on error
105: // 0 on success
106:
107: int underflow(); // Fill a buffer.
108: // Return EOF on error or end of input
109: // next character on success
110:
111: filebuf* open(char *name, open_mode om); // Open a file
112: // return 0 if failure
113: // return "this" if success
114: int close() { int i = opened?::close(fd):0; opened=0; return i; }
115:
116: filebuf() { opened = 0; fp = 0; }
117: filebuf(FILE* p) { fp = p; opened = 1; }
118: filebuf(int nfd) { fd = nfd; opened = 1; }
119: filebuf(int nfd, char* p, int l) : (p,l) { fd = nfd; opened = 1; }
120: ~filebuf() { close(); }
121: };
122:
123: struct circbuf : public streambuf { // a circular stream buffer
124:
125: int overflow(int c=EOF); // Empty a buffer.
126: // Return EOF on error
127: // 0 on success
128:
129: int underflow(); // Fill a buffer.
130: // Return EOF on error or end of input
131: // next character on success
132: circbuf() { }
133: ~circbuf() { }
134:
135: };
136:
137: /*
138: * This type defines white space. Any number of whitespace
139: * characters can be used to separate two fields in an input
140: * stream. The effect of sending an input stream to a whitespace
141: * object is to cause all whitespace in the input stream, up to the
142: * next non-whitespace character, to be discarded. The whitespace
143: * characters are space, tab, form feed, and new line.
144: */
145: struct whitespace { };
146:
147: /***************************** output: *********************************/
148:
149: extern char* oct(long, int =0);
150: extern char* dec(long, int =0);
151: extern char* hex(long, int =0);
152:
153: extern char* chr(int, int =0); // chr(0) is the empty string ""
154: extern char* str(const char*, int =0);
155: extern char* form(const char* ...); // printf format
156:
157: class istream;
158: class common;
159:
160: class ostream {
161: friend istream;
162:
163: streambuf* bp;
164: short state;
165: public:
166: ostream& operator<<(const char*); // write
167: ostream& operator<<(int a) { return *this<<long(a); }
168: ostream& operator<<(long); // beware: << 'a' writes 97
169: ostream& operator<<(double);
170: ostream& operator<<(const streambuf&);
171: ostream& operator<<(const whitespace&);
172: ostream& operator<<(const common&);
173:
174: ostream& put(char); // put('a') writes a
175: ostream& flush() { bp->overflow(); return *this; }
176:
177:
178: operator void*(){ return _eof<state?0:this; }
179: int operator!() { return _eof<state; }
180: int eof() { return state&_eof; }
181: int fail() { return _eof<state; }
182: int bad() { return _fail<state; }
183: int good() { return state==_good; }
184: void clear(state_value i =0) { state=i; }
185: int rdstate() { return state; }
186: char* bufptr() { return bp->base; }
187:
188: ostream(streambuf* s) { bp = s; state = 0; }
189: ostream(int fd) { bp = new filebuf(fd); state = 0; }
190: ostream(int size, char* p)
191: {
192: state = 0;
193: bp = new streambuf();
194: if (p == 0) p = new char[size];
195: bp->setbuf(p, size);
196: }
197: ~ostream() { flush(); }
198: };
199:
200: /***************************** input: ***********************************/
201:
202: /*
203: The >> operator reads after skipping initial whitespace
204: get() reads but does not skip whitespace
205:
206: if >> fails (1) the state of the stream turns non-zero
207: (2) the value of the argument does not change
208: (3) non-whitespace characters are put back onto the stream
209:
210: >> get() fails if the state of the stream is non-zero
211: */
212:
213: class istream {
214: friend ostream;
215:
216: streambuf* bp;
217: ostream* tied_to;
218: char skipws; // if non-null, automaticly skip whitespace
219: short state;
220:
221: friend void eatwhite (istream&);
222: public:
223: int skip(int i) { int ii=skipws; skipws=i; return ii; }
224:
225: /*
226: formatted input: >> skip whitespace
227: */
228: istream& operator>>(char*); // string
229: istream& operator>>(char&); // single character
230: istream& operator>>(short&);
231: istream& operator>>(int&);
232: istream& operator>>(long&);
233: istream& operator>>(float&);
234: istream& operator>>(double&);
235: istream& operator>>(streambuf&);
236: istream& operator>>(whitespace&); // skip whitespace
237: istream& operator>>(common&);
238:
239: /*
240: raw input: get's do not skip whitespace
241: */
242: istream& get(char*, int, char ='\n'); // string
243: istream& get(streambuf& sb, char ='\n');
244: istream& get(char& c) // single character
245: {
246: int os = skipws;
247: skipws = 0;
248: *this >> c;
249: skipws = os;
250: return *this;
251: }
252:
253: istream& putback(char c);
254: ostream* tie(ostream* s) { ostream* t = tied_to; tied_to = s; return t; }
255:
256: operator void*(){ return _eof<state?0:this; }
257: int operator!() { return _eof<state; }
258: int eof() { return state&_eof; }
259: int fail() { return _eof<state; }
260: int bad() { return _fail<state; }
261: int good() { return state==_good; }
262: void clear(state_value i =0) { state=i; }
263: int rdstate() { return state; }
264: char* bufptr() { return bp->base; }
265:
266: istream(streambuf* s, int sk =1, ostream* t =0) // bind to buffer
267: {
268: state = 0;
269: skipws = sk;
270: tied_to = t;
271: bp = s;
272: }
273:
274: istream(int size, char* p, int sk =1) // bind to string
275: {
276: state = 0;
277: skipws = sk;
278: tied_to = 0;
279: bp = new streambuf();
280: if (p == 0) p = new char[size];
281: bp->setbuf(p, size, size);
282: }
283:
284: istream(int fd, int sk =1, ostream* t =0) // bind to file
285: {
286: state = 0;
287: skipws = sk;
288: tied_to = t;
289: bp = new filebuf(fd);
290: }
291: };
292:
293:
294: extern istream cin; // standard input predefined
295: extern ostream cout; // standard output
296: extern ostream cerr; // error output
297:
298: extern whitespace WS; // predefined white space
299:
300: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.