|
|
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.