|
|
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: return *this;
202: }
203:
204: static int dofield(
205: ostream* ios,
206: register char* pfx,
207: int pwidth,
208: register char* sfx,
209: int swidth)
210: {
211: register streambuf* b = ios->rdbuf() ;
212: register int w = ios->width(0)-(pwidth+swidth) ;
213: register int f = (int)ios->flags() ;
214: register int fchar = ios->fill() ;
215:
216: if ( (f&ios::right) || !(f&(ios::left|ios::internal)) ) {
217: while ( w-- > 0 ) {
218: if ( b->sputc(fchar) == EOF ) return ios::badbit ;
219: }
220: }
221:
222: while ( *pfx ) {
223: if ( b->sputc(*pfx++) == EOF ) return ios::badbit ;
224: }
225:
226: if ( f&ios::internal ) {
227: while ( w-- > 0 ) {
228: if ( b->sputc(fchar) == EOF ) return ios::badbit ;
229: }
230: }
231: while ( *sfx ) {
232: if ( b->sputc(*sfx++) == EOF ) return ios::badbit ;
233: }
234:
235: while ( w-- > 0 ) {
236: if ( b->sputc(fchar) == EOF ) return ios::badbit ;
237: }
238:
239: return 0 ;
240: }
241:
242: static const int dbufsize = 32 ;
243:
244: ostream& OSTREAM::operator<<(long i)
245: {
246: if (!opfx()) {
247: width(0) ;
248: return *this;
249: }
250: char buf[dbufsize];
251:
252: register char *p ;
253: register char* pfx = "" ;
254: register int pfxsize = 0 ;
255:
256: buf[dbufsize-1] = 0 ;
257: switch( flags()&basebits ) {
258: case ios::oct :
259: p = conv8(i,&buf[dbufsize-2]) ;
260: if ( (flags()&showbase) && i ) {
261: pfx = "0" ; pfxsize = 1 ;
262: }
263: break ;
264: case ios::hex :
265: if ( flags()&uppercase ) {
266: p=conv16u(i,&buf[dbufsize-2]);
267: if ( flags()&showbase ) {
268: pfx = "0X" ; pfxsize = 2 ;
269: }
270: }
271: else {
272: p=conv16(i,&buf[dbufsize-2]);
273: if ( flags()&showbase ) {
274: pfx = "0x" ; pfxsize = 2 ;
275: }
276: }
277: break ;
278: default:
279: p = conv10(i,&buf[dbufsize-2]) ;
280: if ( i < 0 ) {
281: pfx = "-" ; pfxsize = 1 ;
282: }
283: else if ( flags()&showpos ) {
284: pfx = "+" ; pfxsize = 1 ;
285: }
286: break ;
287: }
288: register int err ;
289: if ( err = dofield(this,pfx,pfxsize,p,&buf[dbufsize-1]-p) ) {
290: setstate(err) ;
291: }
292: return *this ;
293: }
294:
295: ostream& OSTREAM::operator<<(unsigned long i)
296: {
297: if (!opfx()) {
298: width(0) ;
299: return *this;
300: }
301: char buf[dbufsize];
302: register char *p ;
303: register char* pfx = "" ;
304: register int pfxsize = 0 ;
305:
306:
307: buf[dbufsize-1] = 0 ;
308: switch( flags()&basebits ) {
309: case ios::oct :
310: p = conv8(i,&buf[dbufsize-2]) ;
311: if ( (flags()&showbase) && i ) {
312: pfx = "0" ; pfxsize = 1 ;
313: }
314: break ;
315: case ios::hex :
316: if ( flags()&uppercase ) {
317: p=conv16u(i,&buf[dbufsize-2]);
318: if ( flags()&showbase ) {
319: pfx = "0X" ; pfxsize = 2 ;
320: }
321: }
322: else {
323: p=conv16(i,&buf[dbufsize-2]);
324: if ( flags()&showbase ) {
325: pfx = "0x" ; pfxsize = 2 ;
326: }
327: }
328: break ;
329: default:
330: p = uconv10(i,&buf[dbufsize-2]) ;
331: break ;
332: }
333: register int err ;
334: if ( err = dofield(this,pfx,pfxsize,p,&buf[dbufsize-1]-p) ) {
335: setstate(err) ;
336: }
337: return *this ;
338: }
339:
340: ostream& OSTREAM::operator<<(register streambuf* b)
341: {
342: register streambuf* nbp = bp;
343: register int c;
344:
345: if (!opfx()) return *this;
346:
347: c = b->sgetc();
348: while (c != EOF) {
349: if (nbp->sputc(c) == EOF) {
350: setstate(failbit) ;
351: break;
352: }
353: c = b->snextc();
354: }
355:
356: return *this;
357: }
358:
359: ostream& OSTREAM::operator<<( void* p)
360: {
361: long f = setf(ios::showbase|PTRBASE, basebits|ios::showbase) ;
362: *this << (long)p ;
363: setf(f,~0) ;
364: return *this ;
365: }
366:
367: ostream& OSTREAM::operator<<(int x)
368: {
369: *this << (long)x ;
370: return *this ;
371: }
372:
373: ostream& OSTREAM::operator<<(unsigned int x)
374: {
375: *this << (unsigned long)x ;
376: return *this ;
377: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.