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