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