|
|
1.1 root 1: /*ident "@(#)ctrans:lib/stream/strstream.c 1.1.4.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: strstream.c:
12:
13: *****************************************************************************/
14:
15: #include <iostream.h>
16: #include <string.h>
17: #include <strstream.h>
18: #include <memory.h>
19:
20: typedef unsigned int Size_t ;
21: // Some day <memory.h> will be ANSIfied and
22: // this will be declared there.
23: // Until then make it compatible with declaration
24: // of third argument of memcpy.
25:
26: static const int initsize = 16*sizeof(int) ;
27: static const int increment = 2 ;
28:
29: static const int arbitrary = 1024 ; // used by ignore_oflow.
30:
31: static const int ios_atend = ios::ate ;
32: static const int ios_input = ios::in ;
33: static const int ios_output = ios::out ;
34: static const int ios_append = ios::app ;
35: static const int seek_cur = ios::cur ;
36: static const int seek_end = ios::end ;
37: static const int seek_beg = ios::beg ;
38:
39: strstreambuf::strstreambuf(void* (*a)(long), void (*f)(void*)) :
40: afct(a),
41: ffct(f),
42: froozen(1),
43: auto_extend(initsize),
44: ignore_oflow(0)
45: {
46: }
47:
48: void strstreambuf::init(char* b, int size, char* pstart)
49: {
50: if ( b && size > 0 ) {
51: setb(b,b+size) ;
52: }
53: else if ( b && size == 0 ) {
54: setb(b,b+strlen(b) ) ;
55: }
56: else if ( b && size < 0 ) {
57: ignore_oflow = 1 ;
58: setb(b,b+arbitrary) ;
59: }
60: else if ( !b && size > initsize ) {
61: auto_extend = size ;
62: setb(0,0) ;
63: }
64: else {
65: setb(0,0) ;
66: }
67:
68: if ( pstart && base() && base() <= pstart && pstart <= ebuf() ) {
69: setp(pstart,ebuf()) ;
70: }
71: else {
72: setp(0,0) ;
73: }
74:
75: if ( base() ) {
76: setg(base(),base(),ebuf()) ;
77: auto_extend = 0 ;
78: froozen = 1 ;
79: }
80: else {
81: setg(0,0,0) ;
82: }
83: }
84:
85: strstreambuf::strstreambuf(char* b, int size, char* pstart) :
86: afct(0),
87: ffct(0),
88: froozen(0),
89: auto_extend(0),
90: ignore_oflow(0)
91: {
92: init(b,size,pstart) ;
93: }
94:
95: strstreambuf::strstreambuf(unsigned char* b, int size, unsigned char* pstart) :
96: afct(0),
97: ffct(0),
98: froozen(0),
99: auto_extend(0),
100: ignore_oflow(0)
101: {
102: init((char*)b,size,(char*)pstart) ;
103: }
104:
105:
106: strstreambuf::strstreambuf(int ae) :
107: afct(0),
108: ffct(0),
109: froozen(1),
110: auto_extend(ae>0?ae:initsize),
111: ignore_oflow(0)
112: {
113: }
114:
115: strstreambuf::strstreambuf() :
116: afct(0),
117: ffct(0),
118: froozen(1),
119: auto_extend(initsize),
120: ignore_oflow(0)
121: {
122: }
123:
124:
125: int strstreambuf::doallocate()
126: {
127: if ( auto_extend < initsize ) auto_extend = initsize ;
128: char* newspace = afct ? (char*)(*afct)(auto_extend)
129: : new char[auto_extend] ;
130:
131: if ( !newspace ) return EOF ;
132:
133: froozen = 0 ;
134: setb(newspace,newspace+auto_extend,0) ;
135: // Will free this space ourselves if neccessary
136:
137: setp(newspace,newspace+auto_extend) ;
138: setg(newspace,newspace,newspace) ;
139:
140: return 0 ;
141: }
142:
143: int strstreambuf::overflow(int c)
144: {
145: if ( !base() ) {
146: allocate() ;
147: if ( !base() ) return EOF ;
148: }
149: else if ( auto_extend && !froozen ) {
150: Size_t inserted=pptr()-base() ; // number of chars previously
151: // inserted into buffer
152:
153: Size_t extracted=gptr()-base() ;
154: // number of chars previously
155: // extracted from buffer
156:
157: // after we copy chars from current space to a new
158: // (larger) area we have to adjust pointers to take into
159: // acount previous activities.
160:
161: Size_t newsize = (Size_t)increment*blen() + 4 ;
162: if ( newsize < auto_extend ) newsize = auto_extend ;
163: char* newspace = afct ? (char*)(*afct)(newsize)
164: : new char[newsize] ;
165:
166: if ( !newspace ) return EOF ;
167:
168: memcpy(newspace,base(),inserted) ;
169:
170: if ( ffct ) (*ffct)(base()) ;
171: else delete base() ;
172:
173: setb(newspace,newspace+newsize,0) ;
174: setp(base()+inserted,ebuf()) ;
175: setg(base(),base()+extracted,pptr()) ;
176: }
177: else if ( ignore_oflow ) {
178: setp(pptr(),pptr()+arbitrary) ;
179: }
180: else {
181: return EOF ;
182: }
183: if ( c!=EOF ) return sputc(c) ;
184: }
185:
186: int strstreambuf::underflow()
187: {
188: if ( !pptr() ) return EOF ;
189: if ( !egptr() ) return EOF ;
190:
191: setg(base(),egptr(),pptr()) ;
192:
193: if ( egptr() <= gptr() ) return EOF ;
194: else return *gptr() ;
195: }
196:
197: void strstreambuf::freeze(int n)
198: {
199: froozen = n ;
200: }
201:
202:
203: char* strstreambuf::str()
204: {
205: freeze() ;
206: return base() ;
207: }
208:
209: strstreambuf::~strstreambuf()
210: {
211: if ( !froozen && base() ) {
212: if ( ffct ) ffct(base()) ;
213: else delete base() ;
214: }
215: }
216:
217: streambuf* strstreambuf::setbuf(char* p, int size)
218: {
219: if ( p == 0 && ( base()==0 || auto_extend ) ) {
220: auto_extend = size ;
221: return this ;
222: }
223: else {
224: return 0 ;
225: }
226: }
227:
228: streampos strstreambuf::seekoff(streamoff o, ios::seek_dir d, int m)
229: {
230: switch (d) {
231: case seek_beg : break ;
232: case seek_cur : {
233: if ( (m&ios_input) ) {
234: o += gptr()-base() ;
235: }
236: else {
237: o += pptr()-base() ;
238: }
239: } break ;
240: case seek_end : {
241: if ( gptr()<egptr() && egptr()>pptr() ) {
242: o += egptr()-base() ;
243: }
244: else if ( pptr()<epptr() ) {
245: o += pptr()-base();
246: }
247: } break ;
248: } // end switch
249: if ( o < 0 ) return streampos(EOF) ;
250: if ( o >= blen() && !ignore_oflow ) return streampos(EOF) ;
251: if ( m&ios_input ) setg(base(), base()+o, egptr() ) ;
252: if ( m&ios_output) setp(base()+o, epptr() ) ;
253: return o ;
254: }
255:
256: strstreambase::strstreambase(char* str, int size, char* pstart)
257: : buf(str,size,pstart) { init(&buf) ; }
258:
259: strstreambase::strstreambase() : buf() { init(&buf) ; }
260:
261: strstreambase::~strstreambase() { }
262:
263: strstreambuf* strstreambase::rdbuf() { return &buf ; }
264:
265: istrstream::istrstream(char* str)
266: : strstreambase(str,strlen(str),0) { }
267:
268: istrstream::istrstream(char* str, int size)
269: : strstreambase(str, size , 0) { }
270:
271: istrstream::~istrstream() { }
272:
273:
274: static char* pstart(char* str, int size, int m)
275: {
276: if ( (m&(ios_append|ios_output)) == 0 ) return str+size ;
277: else if ( (m&(ios_append|ios_atend)) ) return str+strlen(str) ;
278: else return str ;
279: }
280:
281: ostrstream::ostrstream(char* str, int size, int m)
282: : strstreambase(str, size, pstart(str,size, (m|ios_output)) )
283: { }
284:
285: ostrstream::ostrstream() : strstreambase() { }
286:
287:
288: ostrstream::~ostrstream()
289: {
290: ios::rdbuf()->sputc(0) ;
291: }
292:
293: char* ostrstream::str()
294: {
295: return strstreambase::rdbuf()->str() ;
296: }
297:
298: int ostrstream::pcount() {
299: return ios::rdbuf()->out_waiting() ;
300: }
301:
302: strstream::strstream() : strstreambase() { }
303:
304: strstream::strstream(char* str, int size, int m)
305: : strstreambase(str,size,pstart(str,size,m))
306: { }
307:
308: char* strstream::str()
309: {
310: return strstreambase::rdbuf()->str() ;
311: }
312:
313:
314: strstream::~strstream() { }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.