|
|
1.1 root 1: /*ident "@(#)ctrans:lib/stream/out.c 1.1.2.1" */
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: out.c:
12:
13: *****************************************************************************/
14:
15: #include <iostream.h>
16: #include "streamdefs.h"
17: #include <string.h>
18:
19: #define OSTREAM ostream
20:
21: const int basebits = ios::dec|ios::oct|ios::hex ;
22:
23: // At the cost of 100 bytes of table we can measurably speed
24: // up conversion (at least on a VAX)
25:
26: static char digit1[] = {
27: '0','1','2','3','4','5','6','7','8','9',
28: '0','1','2','3','4','5','6','7','8','9',
29: '0','1','2','3','4','5','6','7','8','9',
30: '0','1','2','3','4','5','6','7','8','9',
31: '0','1','2','3','4','5','6','7','8','9',
32: '0','1','2','3','4','5','6','7','8','9',
33: '0','1','2','3','4','5','6','7','8','9',
34: '0','1','2','3','4','5','6','7','8','9',
35: '0','1','2','3','4','5','6','7','8','9',
36: '0','1','2','3','4','5','6','7','8','9',
37: } ;
38:
39: static char digit2[] = {
40: '0','0','0','0','0','0','0','0','0','0',
41: '1','1','1','1','1','1','1','1','1','1',
42: '2','2','2','2','2','2','2','2','2','2',
43: '3','3','3','3','3','3','3','3','3','3',
44: '4','4','4','4','4','4','4','4','4','4',
45: '5','5','5','5','5','5','5','5','5','5',
46: '6','6','6','6','6','6','6','6','6','6',
47: '7','7','7','7','7','7','7','7','7','7',
48: '8','8','8','8','8','8','8','8','8','8',
49: '9','9','9','9','9','9','9','9','9','9',
50: } ;
51:
52: static char* conv10(long i, char* bufend)
53: /* p points to right end of a buffer. Function function returns
54: * pointer to left end of converted number. Number is not 0 terminated.
55: *
56: * Special care with negatives to avoid problems with
57: * biggest negative number on 2's complement machines
58: */
59: {
60: register long j = i ;
61: register char* p = bufend ;
62:
63: /* Above entered low order digit or 0 if i is zero */
64:
65: if ( j >= 0 ) {
66: register int diff ;
67: do {
68: long register by100 = j/100 ;
69: diff = (int)(j-100*by100) ;
70: *p-- = digit1[diff] ;
71: *p-- = digit2[diff] ;
72: j = by100;
73: } while ( j > 0 ) ;
74: if ( diff<10 ) ++p ; //compensate for extra 0
75: } else { // j < 0
76: register int diff ;
77: do {
78: long register by100 = j/100 ;
79: diff = (int)(100*by100-j) ;
80: *p-- = digit1[diff] ;
81: *p-- = digit2[diff] ;
82: j = by100;
83: } while ( j < 0 ) ;
84: if ( diff<10 ) ++p ; //compensate for extra 0
85: }
86: return p+1 ;
87:
88: }
89:
90: static char* uconv10(unsigned long i, char* bufend)
91: /* Same interface as conv10 except unsigned so we don't have
92: * to worry about negatives */
93: {
94: register unsigned long j = i ;
95: register char* p = bufend ;
96: register int diff ;
97:
98: do {
99: long register by100 = j/100 ;
100: diff = (int)(j-100*by100) ;
101: *p-- = digit1[diff] ;
102: *p-- = digit2[diff] ;
103: j = by100;
104: } while ( j > 0 ) ;
105: if ( diff<10 ) ++p ; //compensate for extra 0
106:
107: return p+1 ;
108:
109: }
110:
111:
112: static char* conv8(register unsigned long i, register char* p)
113: {
114: do {
115: *p-- = (char)('0' + i%8) ;
116: } while ( (i >>= 3) > 0 ) ;
117: return p+1 ;
118: }
119:
120: static char* conv16(register unsigned long i, register char* p)
121: {
122: do {
123: register dig = (int)(i%16) ;
124: if ( dig < 10 ) *p-- = (char)('0' + i%16) ;
125: else *p-- = (char)('a'-10 + dig) ;
126:
127: } while ( (i >>= 4) > 0 ) ;
128: return p+1 ;
129: }
130:
131:
132: static char* conv16u(register unsigned long i, register char* p)
133: {
134: do {
135: register dig = (int)(i%16) ;
136: if ( dig < 10 ) *p-- = (char)('0' + i%16) ;
137: else *p-- = (char)('A'-10 + dig) ;
138:
139: } while ( (i >>= 4) > 0 ) ;
140: return p+1 ;
141: }
142: ostream& OSTREAM::operator<<(const char* s)
143: {
144: // I play some games so that if BREAKEVEN is <= 0 all
145: // tests get set the right way at compile time
146:
147: # if BREAKEVEN > 0
148: static int avglen = BREAKEVEN ;
149: // running average of the lengths
150: // of strings ;
151: # else
152: static const int avglen = BREAKEVEN ;
153: // fixed constant so all tests
154: // are fixed at compile time
155: # endif
156:
157: register int fwidth = width(0) ;
158:
159: if (!opfx() ) return *this ;
160: if ( s==0 ) return *this;
161: register streambuf* nbp = bp ;
162: register const char* p ;
163: register int len ;
164: register int pad ;
165:
166: register int leftjust = ( (flags()&left) != 0 ) ;
167: if ( BREAKEVEN<0
168: || BREAKEVEN>0 && avglen<=BREAKEVEN &&
169: (fwidth==0 || leftjust)){
170: p = s ;
171: while ( *p ) {
172: if ( nbp->sputc(*p++) == EOF ) {
173: setstate(badbit) ;
174: break ;
175: }
176: }
177: len = p-s ;
178: pad = fwidth-len ;
179: } else {
180: len = strlen(s) ;
181: pad = fwidth-len ;
182: if ( pad>0 && !leftjust ) {
183: while ( pad-- > 0 ) {
184: if ( nbp->sputc(fill()) == EOF ) {
185: setstate(badbit) ;
186: }
187: }
188: }
189: write(s,len) ;
190: }
191:
192: if ( pad > 0 ) {
193: while ( pad-- > 0 ) {
194: if ( nbp->sputc(fill()) == EOF ) setstate(badbit) ;
195: }
196: }
197:
198: if ( BREAKEVEN > 0 ) { // will be eliminated at compile time
199: avglen = (3*avglen + len) >> 2;
200: }
201: osfx() ;
202: return *this;
203: }
204:
205: static int dofield(
206: ostream* ios,
207: register char* pfx,
208: int pwidth,
209: register char* sfx,
210: int swidth)
211: {
212: register streambuf* b = ios->rdbuf() ;
213: register int w = ios->width(0)-(pwidth+swidth) ;
214: register int f = (int)ios->flags() ;
215: register int fchar = ios->fill() ;
216:
217: if ( (f&ios::right) || !(f&(ios::left|ios::internal)) ) {
218: while ( w-- > 0 ) {
219: if ( b->sputc(fchar) == EOF ) return ios::badbit ;
220: }
221: }
222:
223: while ( *pfx ) {
224: if ( b->sputc(*pfx++) == EOF ) return ios::badbit ;
225: }
226:
227: if ( f&ios::internal ) {
228: while ( w-- > 0 ) {
229: if ( b->sputc(fchar) == EOF ) return ios::badbit ;
230: }
231: }
232: while ( *sfx ) {
233: if ( b->sputc(*sfx++) == EOF ) return ios::badbit ;
234: }
235:
236: while ( w-- > 0 ) {
237: if ( b->sputc(fchar) == EOF ) return ios::badbit ;
238: }
239:
240: return 0 ;
241: }
242:
243: static const int dbufsize = 32 ;
244:
245: ostream& OSTREAM::operator<<(long i)
246: {
247: if (!opfx()) {
248: width(0) ;
249: return *this;
250: }
251: char buf[dbufsize];
252:
253: register char *p ;
254: register char* pfx = "" ;
255: register int pfxsize = 0 ;
256:
257: buf[dbufsize-1] = 0 ;
258: switch( flags()&basebits ) {
259: case ios::oct :
260: p = conv8(i,&buf[dbufsize-2]) ;
261: if ( (flags()&showbase) && i ) {
262: pfx = "0" ; pfxsize = 1 ;
263: }
264: break ;
265: case ios::hex :
266: if ( flags()&uppercase ) {
267: p=conv16u(i,&buf[dbufsize-2]);
268: if ( flags()&showbase ) {
269: pfx = "0X" ; pfxsize = 2 ;
270: }
271: }
272: else {
273: p=conv16(i,&buf[dbufsize-2]);
274: if ( flags()&showbase ) {
275: pfx = "0x" ; pfxsize = 2 ;
276: }
277: }
278: break ;
279: default:
280: p = conv10(i,&buf[dbufsize-2]) ;
281: if ( i < 0 ) {
282: pfx = "-" ; pfxsize = 1 ;
283: }
284: else if ( flags()&showpos ) {
285: pfx = "+" ; pfxsize = 1 ;
286: }
287: break ;
288: }
289: register int err ;
290: if ( err = dofield(this,pfx,pfxsize,p,&buf[dbufsize-1]-p) ) {
291: setstate(err) ;
292: }
293: osfx() ;
294: return *this ;
295: }
296:
297: ostream& OSTREAM::operator<<(unsigned long i)
298: {
299: if (!opfx()) {
300: width(0) ;
301: return *this;
302: }
303: char buf[dbufsize];
304: register char *p ;
305: register char* pfx = "" ;
306: register int pfxsize = 0 ;
307:
308:
309: buf[dbufsize-1] = 0 ;
310: switch( flags()&basebits ) {
311: case ios::oct :
312: p = conv8(i,&buf[dbufsize-2]) ;
313: if ( (flags()&showbase) && i ) {
314: pfx = "0" ; pfxsize = 1 ;
315: }
316: break ;
317: case ios::hex :
318: if ( flags()&uppercase ) {
319: p=conv16u(i,&buf[dbufsize-2]);
320: if ( flags()&showbase ) {
321: pfx = "0X" ; pfxsize = 2 ;
322: }
323: }
324: else {
325: p=conv16(i,&buf[dbufsize-2]);
326: if ( flags()&showbase ) {
327: pfx = "0x" ; pfxsize = 2 ;
328: }
329: }
330: break ;
331: default:
332: p = uconv10(i,&buf[dbufsize-2]) ;
333: break ;
334: }
335: register int err ;
336: if ( err = dofield(this,pfx,pfxsize,p,&buf[dbufsize-1]-p) ) {
337: setstate(err) ;
338: }
339: osfx() ;
340: return *this ;
341: }
342:
343: ostream& OSTREAM::operator<<(register streambuf* b)
344: {
345: register streambuf* nbp = bp;
346: register int c;
347:
348: if (!opfx()) return *this;
349: if ( !b ) {
350: setstate(failbit) ;
351: return *this ;
352: }
353: c = b->sgetc();
354: while (c != EOF) {
355: if (nbp->sputc(c) == EOF) {
356: setstate(badbit) ;
357: break;
358: }
359: c = b->snextc();
360: }
361:
362: osfx() ;
363: return *this;
364: }
365:
366: ostream& OSTREAM::operator<<( void* p)
367: {
368: long f = setf(ios::showbase|PTRBASE, basebits|ios::showbase) ;
369: *this << (long)p ;
370: setf(f,~0) ;
371: return *this ;
372: }
373:
374: ostream& OSTREAM::operator<<(int x)
375: {
376: *this << (long)x ;
377: return *this ;
378: }
379:
380: ostream& OSTREAM::operator<<(unsigned int x)
381: {
382: *this << (unsigned long)x ;
383: return *this ;
384: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.