1 /*=========================================================================
3 Program: KWSys - Kitware System Library
4 Module: $RCSfile: IOStream.cxx,v $
6 Copyright (c) Kitware, Inc., Insight Consortium. All rights reserved.
7 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 This software is distributed WITHOUT ANY WARRANTY; without even
10 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11 PURPOSE. See the above copyright notices for more information.
13 =========================================================================*/
14 #include "kwsysPrivate.h"
15 #include KWSYS_HEADER(Configure.hxx)
17 // Configure the implementation for the current streams library.
18 #if !KWSYS_IOS_USE_ANSI
20 # if defined(__HP_aCC)
21 # define protected public
22 # include <iostream.h> // Hack access to some private stream methods.
27 // Include the streams library.
28 #include KWSYS_HEADER(ios/iostream)
29 #include KWSYS_HEADER(IOStream.hxx)
31 // Work-around CMake dependency scanning limitation. This must
32 // duplicate the above list of headers.
34 # include "Configure.hxx.in"
35 # include "kwsys_ios_iostream.hxx.in"
36 # include "IOStream.hxx.in"
39 // Implement the rest of this file only if it is needed.
40 #if KWSYS_IOS_NEED_OPERATORS_LL
42 # include <stdio.h> // sscanf, sprintf
43 # include <string.h> // memchr
45 # if defined(_MAX_INT_DIG)
46 # define KWSYS_IOS_INT64_MAX_DIG _MAX_INT_DIG
48 # define KWSYS_IOS_INT64_MAX_DIG 32
51 namespace KWSYS_NAMESPACE
54 // Scan an input stream for an integer value.
55 static int IOStreamScanStream(kwsys_ios::istream
& is
, char* buffer
)
57 // Prepare to write to buffer.
59 char* end
= buffer
+ KWSYS_IOS_INT64_MAX_DIG
- 1;
61 // Look for leading sign.
62 if(is
.peek() == '+') { *out
++ = '+'; is
.ignore(); }
63 else if(is
.peek() == '-') { *out
++ = '-'; is
.ignore(); }
65 // Determine the base. If not specified in the stream, try to
66 // detect it from the input. A leading 0x means hex, and a leading
67 // 0 alone means octal.
69 int flags
= is
.flags() & kwsys_ios::ios_base::basefield
;
70 if(flags
== kwsys_ios::ios_base::oct
) { base
= 8; }
71 else if(flags
== kwsys_ios::ios_base::dec
) { base
= 10; }
72 else if(flags
== kwsys_ios::ios_base::hex
) { base
= 16; }
73 bool foundDigit
= false;
74 bool foundNonZero
= false;
79 if((is
.peek() == 'x' || is
.peek() == 'X') && (base
== 0 || base
== 16))
91 // Determine the range of digits allowed for this number.
92 const char* digits
= "0123456789abcdefABCDEF";
93 int maxDigitIndex
= 10;
100 maxDigitIndex
= 10+6+6;
103 // Scan until an invalid digit is found.
104 for(;is
.peek() != EOF
; is
.ignore())
106 if(memchr(digits
, *out
= (char)is
.peek(), maxDigitIndex
) != 0)
108 if((foundNonZero
|| *out
!= '0') && out
< end
)
121 // Correct the buffer contents for degenerate cases.
122 if(foundDigit
&& !foundNonZero
)
126 else if (!foundDigit
)
131 // Terminate the string in the buffer.
137 // Read an integer value from an input stream.
140 IOStreamScanTemplate(kwsys_ios::istream
& is
, T
& value
, char type
)
142 int state
= kwsys_ios::ios_base::goodbit
;
144 // Skip leading whitespace.
145 # if KWSYS_IOS_USE_ANSI
146 kwsys_ios::istream::sentry
okay(is
);
149 kwsys_ios::istream
& okay
= is
;
154 # if KWSYS_IOS_USE_ANSI
157 // Copy the string to a buffer and construct the format string.
158 char buffer
[KWSYS_IOS_INT64_MAX_DIG
];
159 # if defined(_MSC_VER)
160 char format
[] = "%I64_";
161 const int typeIndex
= 4;
163 char format
[] = "%ll_";
164 const int typeIndex
= 3;
166 switch(IOStreamScanStream(is
, buffer
))
168 case 8: format
[typeIndex
] = 'o'; break;
169 case 0: // Default to decimal if not told otherwise.
170 case 10: format
[typeIndex
] = type
; break;
171 case 16: format
[typeIndex
] = 'x'; break;
174 // Use sscanf to parse the number from the buffer.
176 int success
= (sscanf(buffer
, format
, &result
) == 1)?1:0;
178 // Set flags for resulting state.
179 if(is
.peek() == EOF
) { state
|= kwsys_ios::ios_base::eofbit
; }
180 if(!success
) { state
|= kwsys_ios::ios_base::failbit
; }
181 else { value
= result
; }
182 # if KWSYS_IOS_USE_ANSI
183 } catch(...) { state
|= kwsys_ios::ios_base::badbit
; }
187 # if KWSYS_IOS_USE_ANSI
188 is
.setstate(kwsys_ios::ios_base::iostate(state
));
195 // Print an integer value to an output stream.
198 IOStreamPrintTemplate(kwsys_ios::ostream
& os
, T value
, char type
)
200 # if KWSYS_IOS_USE_ANSI
201 kwsys_ios::ostream::sentry
okay(os
);
203 kwsys_ios::ostream
& okay
= os
;
207 # if KWSYS_IOS_USE_ANSI
210 // Construct the format string.
214 if(os
.flags() & kwsys_ios::ios_base::showpos
) { *f
++ = '+'; }
215 if(os
.flags() & kwsys_ios::ios_base::showbase
) { *f
++ = '#'; }
216 # if defined(_MSC_VER)
217 *f
++ = 'I'; *f
++ = '6'; *f
++ = '4';
219 *f
++ = 'l'; *f
++ = 'l';
221 long bflags
= os
.flags() & kwsys_ios::ios_base::basefield
;
222 if(bflags
== kwsys_ios::ios_base::oct
) { *f
++ = 'o'; }
223 else if(bflags
!= kwsys_ios::ios_base::hex
) { *f
++ = type
; }
224 else if(os
.flags() & kwsys_ios::ios_base::uppercase
) { *f
++ = 'X'; }
228 // Use sprintf to print to a buffer and then write the
229 // buffer to the stream.
230 char buffer
[2*KWSYS_IOS_INT64_MAX_DIG
];
231 sprintf(buffer
, format
, value
);
233 # if KWSYS_IOS_USE_ANSI
234 } catch(...) { os
.clear(os
.rdstate() | kwsys_ios::ios_base::badbit
); }
240 # if !KWSYS_IOS_HAS_ISTREAM_LONG_LONG
241 // Implement input stream operator for IOStreamSLL.
242 kwsys_ios::istream
& IOStreamScan(kwsys_ios::istream
& is
, IOStreamSLL
& value
)
244 return IOStreamScanTemplate(is
, value
, 'd');
247 // Implement input stream operator for IOStreamULL.
248 kwsys_ios::istream
& IOStreamScan(kwsys_ios::istream
& is
, IOStreamULL
& value
)
250 return IOStreamScanTemplate(is
, value
, 'u');
254 # if !KWSYS_IOS_HAS_OSTREAM_LONG_LONG
255 // Implement output stream operator for IOStreamSLL.
256 kwsys_ios::ostream
& IOStreamPrint(kwsys_ios::ostream
& os
, IOStreamSLL value
)
258 return IOStreamPrintTemplate(os
, value
, 'd');
261 // Implement output stream operator for IOStreamULL.
262 kwsys_ios::ostream
& IOStreamPrint(kwsys_ios::ostream
& os
, IOStreamULL value
)
264 return IOStreamPrintTemplate(os
, value
, 'u');
268 } // namespace KWSYS_NAMESPACE
272 namespace KWSYS_NAMESPACE
275 // Create one public symbol in this object file to avoid warnings from
277 void IOStreamSymbolToAvoidWarning()
281 } // namespace KWSYS_NAMESPACE
283 #endif // KWSYS_IOS_NEED_OPERATORS_LL