/elec/propeller-clock

To get this branch, use:
bzr branch http://bzr.ed.am/elec/propeller-clock

« back to all changes in this revision

Viewing changes to src/utility/istream_helpers

  • Committer: Dan
  • Date: 2011-11-02 22:15:18 UTC
  • Revision ID: dan@waxworlds.org-20111102221518-b5j2m5l2pd71f4t1
Added Test whilst testing

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*      Copyright (C) 2004 Garrett A. Kajmowicz
2
 
 
3
 
        This file is part of the uClibc++ Library.
4
 
 
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.
9
 
 
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.
14
 
 
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
18
 
*/
19
 
 
20
 
#include <ios>
21
 
#include <cctype>
22
 
 
23
 
#include <string>
24
 
 
25
 
#ifndef __STD_HEADER_ISTREAM_HELPERS
26
 
#define __STD_HEADER_ISTREAM_HELPERS 1
27
 
 
28
 
#pragma GCC visibility push(default)
29
 
 
30
 
namespace std{
31
 
 
32
 
 
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
43
 
         */
44
 
 
45
 
        template <class C, class traits> _UCXXEXPORT 
46
 
                basic_string<C, traits> _readToken(basic_istream<C, traits>& stream)
47
 
        {
48
 
                basic_string<C, traits> temp;
49
 
                typename traits::int_type c;
50
 
                while(true){
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));
55
 
                        }else{
56
 
                                break;
57
 
                        }
58
 
                }
59
 
                if (temp.size() == 0)
60
 
                        stream.setstate(ios_base::eofbit|ios_base::failbit);
61
 
 
62
 
                return temp;
63
 
        }
64
 
 
65
 
        template <class C, class traits> _UCXXEXPORT 
66
 
                basic_string<C, traits> _readTokenDecimal(basic_istream<C, traits>& stream)
67
 
        {
68
 
                basic_string<C, traits> temp;
69
 
                typename traits::int_type c;
70
 
                while(true){
71
 
                        c = stream.rdbuf()->sgetc();
72
 
                        if(c != traits::eof() && isspace(c) == false && (
73
 
                                isdigit(c) ||
74
 
                                c == '.' ||
75
 
                                c == ',' ||
76
 
                                ((c == '-' || c == '+') && temp.size() == 0) )
77
 
                        ){
78
 
                                stream.rdbuf()->sbumpc();
79
 
                                temp.append(1, traits::to_char_type(c));
80
 
                        }else{
81
 
                                break;
82
 
                        }
83
 
                }
84
 
                if (temp.size() == 0)
85
 
                        stream.setstate(ios_base::eofbit|ios_base::failbit);
86
 
 
87
 
                return temp;
88
 
        }
89
 
 
90
 
#ifdef __UCLIBCXX_EXPAND_ISTREAM_CHAR__
91
 
 
92
 
        template <> _UCXXEXPORT string _readToken<char, char_traits<char> >(istream & stream);
93
 
 
94
 
#endif
95
 
 
96
 
 
97
 
        template <class traits, class charT, class dataType> class _UCXXEXPORT __istream_readin{
98
 
        public:
99
 
                static void readin(basic_istream<charT,traits>& stream, dataType & var);
100
 
        };
101
 
 
102
 
        template <class traits> class _UCXXEXPORT __istream_readin<traits, char, bool>{
103
 
        public:
104
 
                inline static void readin(basic_istream<char, traits >& stream, bool & var)
105
 
                {
106
 
                        basic_string<char, traits > temp;
107
 
                        temp = _readToken( stream);
108
 
                        if(temp == "true" || temp == "True" || temp == "TRUE" || temp == "1"){
109
 
                                var = true;
110
 
                        }else{
111
 
                                var = false;
112
 
                        }
113
 
                }
114
 
        };
115
 
 
116
 
 
117
 
        template <class traits> class _UCXXEXPORT __istream_readin<traits, char, short>{
118
 
        public:
119
 
                inline static void readin(basic_istream<char, traits >& stream, short & var)
120
 
                {
121
 
                        basic_string<char, traits > temp;
122
 
 
123
 
                        if(stream.flags() & ios_base::dec){
124
 
                                temp = _readTokenDecimal( stream);
125
 
                                sscanf(temp.c_str(), "%hd", &var );
126
 
                        }else{
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) );
133
 
                                        }else{
134
 
                                                sscanf(temp.c_str(), "%hx", (unsigned short int *)(&var) );
135
 
                                        }
136
 
                                }else{
137
 
                                        sscanf(temp.c_str(), "%hi", &var);
138
 
                
139
 
                                }
140
 
                        }
141
 
                }
142
 
        };
143
 
 
144
 
        template <class traits> class _UCXXEXPORT __istream_readin<traits, char, unsigned short>{
145
 
        public:
146
 
                inline static void readin(basic_istream<char, traits >& stream, unsigned short & var)
147
 
                {
148
 
                        basic_string<char, traits > temp;
149
 
 
150
 
                        if(stream.flags() & ios_base::dec){
151
 
                                temp = _readTokenDecimal( stream);
152
 
                                sscanf(temp.c_str(), "%hu", &var );
153
 
                        }else{
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 );
160
 
                                        }else{
161
 
                                                sscanf(temp.c_str(), "%hx", &var);
162
 
                                        }
163
 
                                }else{
164
 
                                        sscanf(temp.c_str(), "%hi", (signed short int*)(&var) );
165
 
                                }
166
 
                        }
167
 
                }
168
 
        };
169
 
 
170
 
        template <class traits> class _UCXXEXPORT __istream_readin<traits, char, int>{
171
 
        public:
172
 
                inline static void readin(basic_istream<char, traits >& stream, int & var)
173
 
                {
174
 
                        basic_string<char, traits > temp;
175
 
 
176
 
                        if(stream.flags() & ios_base::dec){
177
 
                                temp = _readTokenDecimal( stream);
178
 
                                sscanf(temp.c_str(), "%d", &var );
179
 
                        }else{
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) );
186
 
                                        }else{
187
 
                                                sscanf(temp.c_str(), "%x", (unsigned int *)(&var) );
188
 
                                        }
189
 
                                }else{
190
 
                                        sscanf(temp.c_str(), "%i", &var);
191
 
                                }
192
 
                        }
193
 
                }
194
 
        };
195
 
 
196
 
        template <class traits> class _UCXXEXPORT __istream_readin<traits, char, unsigned int>{
197
 
        public:
198
 
                inline static void readin(basic_istream<char, traits >& stream, unsigned int & var)
199
 
                {
200
 
                        basic_string<char, traits > temp;
201
 
 
202
 
                        if(stream.flags() & ios_base::dec){
203
 
                                temp = _readTokenDecimal( stream);
204
 
                                sscanf(temp.c_str(), "%u", &var );
205
 
                        }else{
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) );
212
 
                                        }else{
213
 
                                                sscanf(temp.c_str(), "%x", (unsigned int *)(&var) );
214
 
                                        }
215
 
                                }else{
216
 
                                        sscanf(temp.c_str(), "%i", (int *)(&var) );
217
 
                                }
218
 
                        }       
219
 
 
220
 
                }
221
 
        };
222
 
 
223
 
 
224
 
        template <class traits> class _UCXXEXPORT __istream_readin<traits, char, long int>{
225
 
        public:
226
 
                inline static void readin(basic_istream<char, traits >& stream, long int & var)
227
 
                {
228
 
                        basic_string<char, traits > temp;
229
 
 
230
 
                        if(stream.flags() & ios_base::dec){
231
 
                                temp = _readTokenDecimal( stream);
232
 
                                sscanf(temp.c_str(), "%ld", &var );
233
 
                        }else{
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) );
240
 
                                        }else{
241
 
                                                sscanf(temp.c_str(), "%lx", (unsigned long int *)(&var) );
242
 
                                        }
243
 
                                }else{
244
 
                                        sscanf(temp.c_str(), "%li", (long int *)(&var) );
245
 
                                }
246
 
                        }
247
 
 
248
 
                }
249
 
        };
250
 
 
251
 
 
252
 
        template <class traits> class _UCXXEXPORT __istream_readin<traits, char, unsigned long int>{
253
 
        public:
254
 
                inline static void readin(basic_istream<char, traits >& stream, unsigned long int & var)
255
 
                {
256
 
                        basic_string<char, traits > temp;
257
 
 
258
 
                        if(stream.flags() & ios_base::dec){
259
 
                                temp = _readTokenDecimal( stream);
260
 
                                sscanf(temp.c_str(), "%lu", &var );
261
 
                        }else{
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 );
268
 
                                        }else{
269
 
                                                sscanf(temp.c_str(), "%lx", &var);
270
 
                                        }
271
 
                                }else{
272
 
                                        sscanf(temp.c_str(), "%li", (long int *)(&var) );
273
 
                                }
274
 
                        }
275
 
                }
276
 
        };
277
 
 
278
 
 
279
 
#ifdef __UCLIBCXX_HAS_FLOATS__
280
 
 
281
 
        template <class traits> class _UCXXEXPORT __istream_readin<traits, char, float>{
282
 
        public:
283
 
                inline static void readin(basic_istream<char, traits >& stream, float & var)
284
 
                {
285
 
                        basic_string<char, traits > temp;
286
 
                        temp = _readTokenDecimal( stream);
287
 
#if defined (__AVR__) 
288
 
                        var = strtod(temp.c_str(), NULL);
289
 
#else
290
 
                        sscanf(temp.c_str(), "%g", &var);
291
 
#endif
292
 
                        
293
 
                }
294
 
        };
295
 
 
296
 
        template <class traits> class _UCXXEXPORT __istream_readin<traits, char, double>{
297
 
        public:
298
 
                inline static void readin(basic_istream<char, traits >& stream, double & var)
299
 
                {
300
 
                        basic_string<char, traits > temp;
301
 
                        temp = _readTokenDecimal( stream);
302
 
#if defined (__AVR__)
303
 
                        var = strtod(temp.c_str(), NULL);
304
 
#else                   
305
 
                        sscanf(temp.c_str(), "%lg", &var);
306
 
#endif                  
307
 
                }
308
 
        };
309
 
 
310
 
        template <class traits> class _UCXXEXPORT __istream_readin<traits, char, long double>{
311
 
        public:
312
 
                inline static void readin(basic_istream<char, traits >& stream, long double & var)
313
 
                {
314
 
                        basic_string<char, traits > temp;
315
 
                        temp = _readTokenDecimal( stream);
316
 
#if defined (__AVR__)
317
 
                        var = strtod(temp.c_str(), NULL);
318
 
#else                   
319
 
                        sscanf(temp.c_str(), "%Lg", &var);
320
 
#endif                  
321
 
                }
322
 
        };
323
 
 
324
 
#endif  // ifdef __UCLIBCXX_HAS_FLOATS__
325
 
 
326
 
        template <class traits> class _UCXXEXPORT __istream_readin<traits, char, void*>{
327
 
        public:
328
 
                inline static void readin(basic_istream<char, traits >& stream, void* & var)
329
 
                {
330
 
                        basic_string<char, traits > temp;
331
 
                        temp = _readToken( stream);
332
 
                        sscanf(temp.c_str(), "%p", &var);
333
 
                }
334
 
        };
335
 
 
336
 
 
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
343
 
                while (
344
 
                        !traits::eq_int_type((c = is.rdbuf()->sgetc()), eof)
345
 
                        && isspace(c)
346
 
                      )
347
 
                {
348
 
                        is.rdbuf()->sbumpc();
349
 
                }
350
 
                if(traits::eq_int_type(c, eof)){
351
 
                        is.setstate(ios_base::eofbit);
352
 
                }
353
 
        }
354
 
}
355
 
 
356
 
#pragma GCC visibility pop
357
 
 
358
 
#endif
359
 
 
360
 
 
361