1
/* Copyright (C) 2004 Garrett A. Kajmowicz
3
This file is part of the uClibc++ Library.
5
This library is free software; you can redistribute it and/or
6
modify it under the terms of the GNU Lesser General Public
7
License as published by the Free Software Foundation; either
8
version 2.1 of the License, or (at your option) any later version.
10
This library is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
Lesser General Public License for more details.
15
You should have received a copy of the GNU Lesser General Public
16
License along with this library; if not, write to the Free Software
17
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
#ifndef __STD_HEADER_ISTREAM_HELPERS
26
#define __STD_HEADER_ISTREAM_HELPERS 1
28
#pragma GCC visibility push(default)
33
/* We are making the following template class for serveral reasons. Firstly,
34
* we want to keep the main istream code neat and tidy. Secondly, we want it
35
* to be easy to do partial specialization of the istream code so that it can
36
* be expanded and put into the library. This will allow us to make application
37
* code smaller at the expense of increased library size. This is a fair
38
* trade-off when there are multiple applications being compiled. Also, this
39
* feature will be used optionally via configuration options. It will also
40
* allow us to keep the code bases in sync, dramatically simplifying the
41
* maintenance required. We specialized for char because wchar and others
42
* require different scanf functions
45
template <class C, class traits> _UCXXEXPORT
46
basic_string<C, traits> _readToken(basic_istream<C, traits>& stream)
48
basic_string<C, traits> temp;
49
typename traits::int_type c;
51
c = stream.rdbuf()->sgetc();
52
if(c != traits::eof() && isspace(c) == false){
53
stream.rdbuf()->sbumpc();
54
temp.append(1, traits::to_char_type(c));
60
stream.setstate(ios_base::eofbit|ios_base::failbit);
65
template <class C, class traits> _UCXXEXPORT
66
basic_string<C, traits> _readTokenDecimal(basic_istream<C, traits>& stream)
68
basic_string<C, traits> temp;
69
typename traits::int_type c;
71
c = stream.rdbuf()->sgetc();
72
if(c != traits::eof() && isspace(c) == false && (
76
((c == '-' || c == '+') && temp.size() == 0) )
78
stream.rdbuf()->sbumpc();
79
temp.append(1, traits::to_char_type(c));
85
stream.setstate(ios_base::eofbit|ios_base::failbit);
90
#ifdef __UCLIBCXX_EXPAND_ISTREAM_CHAR__
92
template <> _UCXXEXPORT string _readToken<char, char_traits<char> >(istream & stream);
97
template <class traits, class charT, class dataType> class _UCXXEXPORT __istream_readin{
99
static void readin(basic_istream<charT,traits>& stream, dataType & var);
102
template <class traits> class _UCXXEXPORT __istream_readin<traits, char, bool>{
104
inline static void readin(basic_istream<char, traits >& stream, bool & var)
106
basic_string<char, traits > temp;
107
temp = _readToken( stream);
108
if(temp == "true" || temp == "True" || temp == "TRUE" || temp == "1"){
117
template <class traits> class _UCXXEXPORT __istream_readin<traits, char, short>{
119
inline static void readin(basic_istream<char, traits >& stream, short & var)
121
basic_string<char, traits > temp;
123
if(stream.flags() & ios_base::dec){
124
temp = _readTokenDecimal( stream);
125
sscanf(temp.c_str(), "%hd", &var );
127
temp = _readToken( stream);
128
if( stream.flags() & ios_base::oct){
129
sscanf(temp.c_str(), "%ho", (unsigned short int *)(&var) );
130
}else if(stream.flags() & ios_base::hex){
131
if(stream.flags() & ios_base::uppercase){
132
sscanf(temp.c_str(), "%hX", (unsigned short int *)(&var) );
134
sscanf(temp.c_str(), "%hx", (unsigned short int *)(&var) );
137
sscanf(temp.c_str(), "%hi", &var);
144
template <class traits> class _UCXXEXPORT __istream_readin<traits, char, unsigned short>{
146
inline static void readin(basic_istream<char, traits >& stream, unsigned short & var)
148
basic_string<char, traits > temp;
150
if(stream.flags() & ios_base::dec){
151
temp = _readTokenDecimal( stream);
152
sscanf(temp.c_str(), "%hu", &var );
154
temp = _readToken( stream);
155
if( stream.flags() & ios_base::oct){
156
sscanf(temp.c_str(), "%ho", &var);
157
}else if(stream.flags() & ios_base::hex){
158
if(stream.flags() & ios_base::uppercase){
159
sscanf(temp.c_str(), "%hX", &var );
161
sscanf(temp.c_str(), "%hx", &var);
164
sscanf(temp.c_str(), "%hi", (signed short int*)(&var) );
170
template <class traits> class _UCXXEXPORT __istream_readin<traits, char, int>{
172
inline static void readin(basic_istream<char, traits >& stream, int & var)
174
basic_string<char, traits > temp;
176
if(stream.flags() & ios_base::dec){
177
temp = _readTokenDecimal( stream);
178
sscanf(temp.c_str(), "%d", &var );
180
temp = _readToken( stream);
181
if( stream.flags() & ios_base::oct){
182
sscanf(temp.c_str(), "%o", (unsigned int *)(&var) );
183
}else if(stream.flags() & ios_base::hex){
184
if(stream.flags() & ios_base::uppercase){
185
sscanf(temp.c_str(), "%X", (unsigned int *)(&var) );
187
sscanf(temp.c_str(), "%x", (unsigned int *)(&var) );
190
sscanf(temp.c_str(), "%i", &var);
196
template <class traits> class _UCXXEXPORT __istream_readin<traits, char, unsigned int>{
198
inline static void readin(basic_istream<char, traits >& stream, unsigned int & var)
200
basic_string<char, traits > temp;
202
if(stream.flags() & ios_base::dec){
203
temp = _readTokenDecimal( stream);
204
sscanf(temp.c_str(), "%u", &var );
206
temp = _readToken( stream);
207
if( stream.flags() & ios_base::oct){
208
sscanf(temp.c_str(), "%o", (unsigned int *)(&var) );
209
}else if(stream.flags() & ios_base::hex){
210
if(stream.flags() & ios_base::uppercase){
211
sscanf(temp.c_str(), "%X", (unsigned int *)(&var) );
213
sscanf(temp.c_str(), "%x", (unsigned int *)(&var) );
216
sscanf(temp.c_str(), "%i", (int *)(&var) );
224
template <class traits> class _UCXXEXPORT __istream_readin<traits, char, long int>{
226
inline static void readin(basic_istream<char, traits >& stream, long int & var)
228
basic_string<char, traits > temp;
230
if(stream.flags() & ios_base::dec){
231
temp = _readTokenDecimal( stream);
232
sscanf(temp.c_str(), "%ld", &var );
234
temp = _readToken( stream);
235
if( stream.flags() & ios_base::oct){
236
sscanf(temp.c_str(), "%lo", (unsigned long int *)(&var) );
237
}else if(stream.flags() & ios_base::hex){
238
if(stream.flags() & ios_base::uppercase){
239
sscanf(temp.c_str(), "%lX", (unsigned long int *)(&var) );
241
sscanf(temp.c_str(), "%lx", (unsigned long int *)(&var) );
244
sscanf(temp.c_str(), "%li", (long int *)(&var) );
252
template <class traits> class _UCXXEXPORT __istream_readin<traits, char, unsigned long int>{
254
inline static void readin(basic_istream<char, traits >& stream, unsigned long int & var)
256
basic_string<char, traits > temp;
258
if(stream.flags() & ios_base::dec){
259
temp = _readTokenDecimal( stream);
260
sscanf(temp.c_str(), "%lu", &var );
262
temp = _readToken( stream);
263
if( stream.flags() & ios_base::oct){
264
sscanf(temp.c_str(), "%lo", &var );
265
}else if(stream.flags() & ios_base::hex){
266
if(stream.flags() & ios_base::uppercase){
267
sscanf(temp.c_str(), "%lX", &var );
269
sscanf(temp.c_str(), "%lx", &var);
272
sscanf(temp.c_str(), "%li", (long int *)(&var) );
279
#ifdef __UCLIBCXX_HAS_FLOATS__
281
template <class traits> class _UCXXEXPORT __istream_readin<traits, char, float>{
283
inline static void readin(basic_istream<char, traits >& stream, float & var)
285
basic_string<char, traits > temp;
286
temp = _readTokenDecimal( stream);
287
#if defined (__AVR__)
288
var = strtod(temp.c_str(), NULL);
290
sscanf(temp.c_str(), "%g", &var);
296
template <class traits> class _UCXXEXPORT __istream_readin<traits, char, double>{
298
inline static void readin(basic_istream<char, traits >& stream, double & var)
300
basic_string<char, traits > temp;
301
temp = _readTokenDecimal( stream);
302
#if defined (__AVR__)
303
var = strtod(temp.c_str(), NULL);
305
sscanf(temp.c_str(), "%lg", &var);
310
template <class traits> class _UCXXEXPORT __istream_readin<traits, char, long double>{
312
inline static void readin(basic_istream<char, traits >& stream, long double & var)
314
basic_string<char, traits > temp;
315
temp = _readTokenDecimal( stream);
316
#if defined (__AVR__)
317
var = strtod(temp.c_str(), NULL);
319
sscanf(temp.c_str(), "%Lg", &var);
324
#endif // ifdef __UCLIBCXX_HAS_FLOATS__
326
template <class traits> class _UCXXEXPORT __istream_readin<traits, char, void*>{
328
inline static void readin(basic_istream<char, traits >& stream, void* & var)
330
basic_string<char, traits > temp;
331
temp = _readToken( stream);
332
sscanf(temp.c_str(), "%p", &var);
337
template<class charT, class traits> void __skipws(basic_istream<charT,traits>& is){
338
const typename basic_istream<charT,traits>::int_type eof = traits::eof();
339
typename basic_istream<charT,traits>::int_type c;
340
//While the next character normally read doesn't equal eof
341
//and that character is a space, advance to the next read position
342
//Thus itterating through all whitespace until we get to the meaty stuff
344
!traits::eq_int_type((c = is.rdbuf()->sgetc()), eof)
348
is.rdbuf()->sbumpc();
350
if(traits::eq_int_type(c, eof)){
351
is.setstate(ios_base::eofbit);
356
#pragma GCC visibility pop