|
|
1.1 root 1: /*ident "@(#)ctrans:lib/stream/streambuf.c 1.1.6.2" */
2: /**************************************************************************
3: Copyright (c) 1984 AT&T
4: All Rights Reserved
5:
6: THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T
7:
8: The copyright notice above does not evidence any
9: actual or intended publication of such source code.
10:
11: streambuf.c:
12:
13: *****************************************************************************/
14:
15: #include <iostream.h>
16: #include "streamdefs.h"
17: #include <string.h>
18: #include <memory.h>
19:
20: /*
21: Allocate some space for the buffer.
22: Returns: EOF on error
23: 0 on success
24: */
25: int streambuf::doallocate()
26: {
27: char *buf = new char[STREAMBUFSIZE] ;
28: if ( !buf ) return EOF ;
29: setb(buf,buf+STREAMBUFSIZE,1) ;
30: return 0;
31: }
32:
33: /*
34: Come here on a put to a full buffer. Allocate the buffer if
35: it is uninitialized.
36: Returns: EOF on error
37: the argument on success
38: */
39: int streambuf::overflow(int c)
40: {
41: if ( c==EOF ) return zapeof(c) ;
42: if ( allocate() == EOF) return EOF;
43:
44: if ( x_pptr <= x_epptr ) return sputc(c) ;
45: else return EOF ;
46: }
47:
48: /*
49: Fill a buffer.
50: Returns: EOF on error or end of input
51: next character on success
52: */
53: int streambuf::underflow()
54: {
55: if ( x_pptr > x_egptr ) setg(x_eback,x_gptr,x_pptr) ;
56:
57: if ( x_egptr > x_gptr ) return 0 ;
58: else return EOF ;
59: }
60:
61: int streambuf::pbackfail(int)
62: {
63: return EOF;
64: }
65:
66: int streambuf::sync()
67: {
68: // It's unclear exactly what this should do. Should it reset
69: // the buffer or what. One theory (that used to be in the code.
70: // was that it should insert a 0. Which seems to be the
71: // right thing for "strings".
72: if ( x_pptr && x_epptr > x_pptr ) sputc(0) ;
73: return EOF ;
74: }
75:
76:
77: streampos streambuf::seekpos(streampos p, int m)
78: {
79: return seekoff(p, ios::beg, m) ;
80: }
81:
82: streampos streambuf::seekoff(streampos,ios::seek_dir,int)
83: {
84: return EOF ;
85: }
86:
87: int streambuf::xsputn(register const char* s, int n)
88: {
89: register int req = n ;
90: if ( unbuffered() ) {
91: while( req-- > 0 ) {
92: if ( sputc(*s++) == EOF ) return n-req-1 ;
93: }
94: return n ;
95: }
96: register int avail = x_epptr-x_pptr ;
97: while ( avail < req ) {
98: memcpy(x_pptr,s,avail) ;
99: s += avail ;
100: pbump(avail) ;
101: req -= avail ;
102: if ( overflow(zapeof(*s++)) == EOF ) return n-req ;
103: --req ;
104: avail = x_epptr-x_pptr ;
105: }
106: memcpy(x_pptr,s,req ) ;
107: pbump(req) ;
108: return n ;
109: }
110:
111: int streambuf::xsgetn(register char* s, int n)
112: {
113: register char* p = s ;
114: register int req = n ;
115: if ( unbuffered() ) {
116: while (req-- > 0 ) {
117: register int c ;
118: if ( (c=sbumpc() ) != EOF ) *p++ = c ;
119: else return p-s ;
120: }
121: }
122:
123: if ( req <= 0 ) return 0 ;
124:
125: register int avail = x_egptr-x_gptr ;
126: while ( avail < req ) {
127: memcpy(p,x_gptr,avail) ;
128: p += avail ;
129: req -= avail ;
130: gbump(avail) ;
131: if ( underflow()==EOF ) return p-s ;
132: avail = x_egptr-x_gptr ;
133: }
134:
135: memcpy(p,x_gptr,req) ;
136: gbump(req) ;
137: return n ;
138: }
139:
140:
141: streambuf* streambuf::setbuf(char* p , int len)
142: {
143:
144: if ( x_base ) return 0 ;
145: if ( len <= 0 || p == 0 ) {
146: // make it unbuffered
147: setb(0,0,0) ;
148: setg(0,0,0) ;
149: setp(0,0);
150: unbuffered(1) ;
151: }
152: else {
153: setb(p,p+len,0) ;
154: setg(p,p,p) ;
155: setp(p,p+len) ;
156: unbuffered(0) ;
157: }
158: return this;
159: }
160:
161: streambuf* streambuf::setbuf(unsigned char* p, int len)
162: {
163: return setbuf((char*)p,len) ;
164: }
165:
166: streambuf::streambuf() :
167: x_unbuf(0), alloc(0)
168: {
169: setb(0,0,0);
170: setg(0,0,0);
171: setp(0,0);
172: }
173:
174: streambuf::streambuf(char* p, int l) :
175: x_unbuf(0), alloc(0)
176: {
177: setb(0,0,0);
178: setbuf(p,l) ;
179: }
180:
181: streambuf::~streambuf()
182: {
183: sync() ;
184: if (x_base && alloc) delete x_base;
185: }
186:
187: int streambuf::x_snextc()
188: {
189: // called by snextc to handle overflow
190: if ( x_egptr==0 || x_gptr != x_egptr ) {
191: // we stepped beyond x_gptr meaning snextc was called when
192: // x_gtr == x_egptr rather than when x_gptr+1=x_egptr.
193: underflow() ;
194: pbump(1) ;
195: }
196: return sgetc() ;
197: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.