|
|
1.1 ! root 1: /*ident "@(#)ctrans:lib/stream/intin.c 1.1.1.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: intin.c: Input conversions of numbers ! 12: ! 13: *****************************************************************************/ ! 14: ! 15: ! 16: #include <ctype.h> ! 17: #include <iostream.h> ! 18: ! 19: /**************** ! 20: * ! 21: * This file contains the extraction operations for integer input. ! 22: * It suffers from several flaws that ought to be fixed. ! 23: * ! 24: * All other versions depend on the extractor for longs to ! 25: * do the real work. This is OK when int==long but on a machine ! 26: * where int!=long there will be a large performance penalty. ! 27: * ! 28: * Overflow detection is limited to cases where the long is ! 29: * shortened and changes its value. This misses a lot of cases. ! 30: * ! 31: ***************/ ! 32: ! 33: ! 34: #define ISTREAM istream ! 35: ! 36: static const int a10 = 'a'-10; ! 37: static const int A10 = 'A'-10; ! 38: ! 39: istream& ISTREAM::operator>>(long& i) ! 40: { ! 41: // This code ignores overflows. This ought to be fixed ! 42: // in some future version. ! 43: ! 44: if ( !ipfx() ) return *this ; ! 45: ! 46: register int c; ! 47: register int base ; ! 48: ! 49: switch ( flags()&(ios::dec|ios::hex|ios::oct) ) { ! 50: case ios::hex : base = 16 ; break ; ! 51: case ios::oct : base = 8 ; break ; ! 52: case ios::dec : base = 10 ; break ; ! 53: default : base = 0 ; break ; ! 54: } ! 55: ! 56: register streambuf *nbp = bp; // put bp in a reg for efficiency ! 57: register int x = 0 ; // how many chars are processed ! 58: register int neg = 0; // set to '-' for negative number ! 59: ! 60: switch (c = nbp->sgetc()) { ! 61: case '-': ! 62: neg = 1 ; ! 63: c = nbp->snextc(); ++x ; ! 64: break; ! 65: case '+': ! 66: c = nbp->snextc(); ++x ; ! 67: break; ! 68: case EOF: ! 69: setstate(failbit|eofbit) ; ! 70: break ; ! 71: } ! 72: ! 73: if ( base==0 && c=='0' ) { ! 74: c = nbp->snextc() ; ++x ; ! 75: ! 76: if ( c=='x' || c=='X' ) { ! 77: base = 16 ; ! 78: c = nbp->snextc() ; ++x ; ! 79: } ! 80: else { ! 81: base = 8 ; ! 82: } ! 83: } else if ( base==0 ) base = 10 ; ! 84: ! 85: // for efficiency we have similar loops ! 86: // Note that when we reach this point c has already been set to ! 87: // the first char of the string to be converted. ! 88: ! 89: if ( base==10 ) { ! 90: register long ii = 0; ! 91: for( ; isdigit(c) ; c=nbp->snextc(),++x ) { ! 92: ! 93: /* accumulate as negative to avoid problems ! 94: * with biggest negative integer on ! 95: * 2's complement machines ! 96: */ ! 97: ii = ii*10-(c-'0'); ! 98: } ! 99: i = neg ? ii : -ii; ! 100: } else if ( base < 10 ) { ! 101: register unsigned long ii = 0; ! 102: for( ; isdigit(c) ; c=nbp->snextc(),++x ) { ! 103: /* accumulate as unsigned */ ! 104: register int diff = c-'0' ; ! 105: if ( diff >= base ) break ; ! 106: ii = ii*base+diff ; ! 107: } ! 108: i = neg ? -(long)ii : (long)ii; ! 109: } else if ( base>10 ) { /* hex like base */ ! 110: register unsigned long ii = 0; ! 111: /* accumulate as unsigned */ ! 112: for( ; isxdigit(c) ; c=nbp->snextc(),++x ) { ! 113: register int diff ; ! 114: if ( isdigit(c) ) diff = (c-'0'); ! 115: else if ( isupper(c) ) diff = (c-A10); ! 116: else diff = (c-a10); ! 117: if ( diff >= base ) break ; ! 118: ii = ii*base+diff ; ! 119: } ! 120: i = neg ? -(long)ii : (long)ii; ! 121: } ! 122: ! 123: ! 124: if (x == 0 ) setstate(failbit) ; ! 125: // Correct treatment of this case ! 126: // (i.e. no correct digits) ! 127: // is unclear. Making it an error ! 128: // avoids certain infinite loops. ! 129: ! 130: return *this; ! 131: } ! 132: ! 133: istream& ISTREAM::operator>>(int& i) ! 134: { ! 135: long l; ! 136: ! 137: if ( !ipfx() ) return *this ; ! 138: ! 139: *this>>l ; ! 140: if ( good() ) { ! 141: i = (int)l ; ! 142: if ( i != l ) { ! 143: // overflow ! 144: setstate(failbit) ; ! 145: } ! 146: } ! 147: return *this; ! 148: } ! 149: ! 150: istream& ISTREAM::operator>>(short& i) ! 151: { ! 152: long l; ! 153: ! 154: if (!ipfx() ) return *this ; ! 155: ! 156: *this>>l ; ! 157: if ( good() ) { ! 158: i = (short)l ; ! 159: if ( i != l ) { ! 160: // overflow ! 161: setstate(failbit) ; ! 162: } ! 163: } ! 164: ! 165: return *this; ! 166: } ! 167: ! 168: ! 169: // The following routines deal with unsigned by reading a long and ! 170: // copying. This is certainly safe for "shorts", but is ! 171: // slightly problematic for ints and longs. It works on "common" ! 172: // machines. ! 173: ! 174: ! 175: istream& ISTREAM::operator>>(unsigned short& u) ! 176: { ! 177: long l ; ! 178: *this >> l ; ! 179: if ( good() ) { ! 180: u = (unsigned short)l ; ! 181: if ( u != l ) { ! 182: // overflow ! 183: setstate(failbit) ; ! 184: } ! 185: } ! 186: return *this ; ! 187: } ! 188: ! 189: istream& ISTREAM::operator>>(unsigned int& u) ! 190: { ! 191: long l ; ! 192: *this >> l ; ! 193: if ( good() ) { ! 194: u = (unsigned int)l ; ! 195: if ( u != l ) { ! 196: // overflow ! 197: setstate(failbit) ; ! 198: } ! 199: } ! 200: return *this ; ! 201: } ! 202: ! 203: istream& ISTREAM::operator>>(unsigned long& u) ! 204: { ! 205: long l ; ! 206: *this >> l ; ! 207: if ( good() ) { ! 208: u = (unsigned long)l ; ! 209: if ( u != l ) { ! 210: // overflow ! 211: setstate(failbit) ; ! 212: } ! 213: } ! 214: return *this ; ! 215: } ! 216:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.