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