Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5496 leency 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 
21
#include 
22
 
23
#include 
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  _UCXXEXPORT
46
		basic_string _readToken(basic_istream& stream)
47
	{
48
		basic_string 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  _UCXXEXPORT
66
		basic_string _readTokenDecimal(basic_istream& stream)
67
	{
68
		basic_string 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 >(istream & stream);
93
 
94
#endif
95
 
96
 
97
	template  class _UCXXEXPORT __istream_readin{
98
	public:
99
		static void readin(basic_istream& stream, dataType & var);
100
	};
101
 
102
	template  class _UCXXEXPORT __istream_readin{
103
	public:
104
		inline static void readin(basic_istream& stream, bool & var)
105
		{
106
			/* 22.4.2.1.2.4 */
107
			basic_string temp;
108
			temp = _readToken( stream);
109
			if (stream.flags() & ios_base::boolalpha) {
110
				if (temp == "true") // truename()
111
					var = true;
112
				else {
113
					var = false;
114
					if (temp != "false") // falsename()
115
						stream.setstate(ios_base::failbit);
116
				}
117
			} else {
118
				long int i = 0;
119
				int ret;
120
				if (stream.flags() & ios_base::dec) {
121
					ret = sscanf(temp.c_str(), "%ld", &i );
122
				} else {
123
					if (stream.flags() & ios_base::oct) {
124
						ret = sscanf(temp.c_str(), "%lo", (unsigned long int *)(&i));
125
					} else if (stream.flags() & ios_base::hex) {
126
						if (stream.flags() & ios_base::uppercase) {
127
							ret = sscanf(temp.c_str(), "%lX", (unsigned long int *)(&i));
128
						} else {
129
							ret = sscanf(temp.c_str(), "%lx", (unsigned long int *)(&i));
130
						}
131
					} else {
132
						ret = sscanf(temp.c_str(), "%li", &i);
133
					}
134
				}
135
				if (ret != 1 || i >> 1)
136
					stream.setstate(ios_base::failbit);
137
				var = ret == 1 && bool(i);
138
			}
139
		}
140
	};
141
 
142
 
143
	template  class _UCXXEXPORT __istream_readin{
144
	public:
145
		inline static void readin(basic_istream& stream, short & var)
146
		{
147
			basic_string temp;
148
 
149
			if(stream.flags() & ios_base::dec){
150
				temp = _readTokenDecimal( stream);
151
				sscanf(temp.c_str(), "%hd", &var );
152
			}else{
153
				temp = _readToken( stream);
154
				if( stream.flags() & ios_base::oct){
155
					sscanf(temp.c_str(), "%ho", (unsigned short int *)(&var) );
156
				}else if(stream.flags() & ios_base::hex){
157
					if(stream.flags() & ios_base::uppercase){
158
						sscanf(temp.c_str(), "%hX", (unsigned short int *)(&var) );
159
					}else{
160
						sscanf(temp.c_str(), "%hx", (unsigned short int *)(&var) );
161
					}
162
				}else{
163
					sscanf(temp.c_str(), "%hi", &var);
164
				}
165
			}
166
		}
167
	};
168
 
169
	template  class _UCXXEXPORT __istream_readin{
170
	public:
171
		inline static void readin(basic_istream& stream, unsigned short & var)
172
		{
173
			basic_string temp;
174
 
175
			if(stream.flags() & ios_base::dec){
176
				temp = _readTokenDecimal( stream);
177
				sscanf(temp.c_str(), "%hu", &var );
178
			}else{
179
				temp = _readToken( stream);
180
				if( stream.flags() & ios_base::oct){
181
					sscanf(temp.c_str(), "%ho", &var);
182
				}else if(stream.flags() & ios_base::hex){
183
					if(stream.flags() & ios_base::uppercase){
184
						sscanf(temp.c_str(), "%hX", &var );
185
					}else{
186
						sscanf(temp.c_str(), "%hx", &var);
187
					}
188
				}else{
189
					sscanf(temp.c_str(), "%hi", (signed short int*)(&var) );
190
				}
191
			}
192
		}
193
	};
194
 
195
	template  class _UCXXEXPORT __istream_readin{
196
	public:
197
		inline static void readin(basic_istream& stream, int & var)
198
		{
199
			basic_string temp;
200
 
201
			if(stream.flags() & ios_base::dec){
202
				temp = _readTokenDecimal( stream);
203
				sscanf(temp.c_str(), "%d", &var );
204
			}else{
205
				temp = _readToken( stream);
206
				if( stream.flags() & ios_base::oct){
207
					sscanf(temp.c_str(), "%o", (unsigned int *)(&var) );
208
				}else if(stream.flags() & ios_base::hex){
209
					if(stream.flags() & ios_base::uppercase){
210
						sscanf(temp.c_str(), "%X", (unsigned int *)(&var) );
211
					}else{
212
						sscanf(temp.c_str(), "%x", (unsigned int *)(&var) );
213
					}
214
				}else{
215
					sscanf(temp.c_str(), "%i", &var);
216
				}
217
			}
218
		}
219
	};
220
 
221
	template  class _UCXXEXPORT __istream_readin{
222
	public:
223
		inline static void readin(basic_istream& stream, unsigned int & var)
224
		{
225
			basic_string temp;
226
 
227
			if(stream.flags() & ios_base::dec){
228
				temp = _readTokenDecimal( stream);
229
				sscanf(temp.c_str(), "%u", &var );
230
			}else{
231
				temp = _readToken( stream);
232
				if( stream.flags() & ios_base::oct){
233
					sscanf(temp.c_str(), "%o", (unsigned int *)(&var) );
234
				}else if(stream.flags() & ios_base::hex){
235
					if(stream.flags() & ios_base::uppercase){
236
						sscanf(temp.c_str(), "%X", (unsigned int *)(&var) );
237
					}else{
238
						sscanf(temp.c_str(), "%x", (unsigned int *)(&var) );
239
					}
240
				}else{
241
					sscanf(temp.c_str(), "%i", (int *)(&var) );
242
				}
243
			}
244
 
245
		}
246
	};
247
 
248
 
249
	template  class _UCXXEXPORT __istream_readin{
250
	public:
251
		inline static void readin(basic_istream& stream, long int & var)
252
		{
253
			basic_string temp;
254
 
255
			if(stream.flags() & ios_base::dec){
256
				temp = _readTokenDecimal( stream);
257
				sscanf(temp.c_str(), "%ld", &var );
258
			}else{
259
				temp = _readToken( stream);
260
				if( stream.flags() & ios_base::oct){
261
					sscanf(temp.c_str(), "%lo", (unsigned long int *)(&var) );
262
				}else if(stream.flags() & ios_base::hex){
263
					if(stream.flags() & ios_base::uppercase){
264
						sscanf(temp.c_str(), "%lX", (unsigned long int *)(&var) );
265
					}else{
266
						sscanf(temp.c_str(), "%lx", (unsigned long int *)(&var) );
267
					}
268
				}else{
269
					sscanf(temp.c_str(), "%li", (long int *)(&var) );
270
				}
271
			}
272
 
273
		}
274
	};
275
 
276
 
277
	template  class _UCXXEXPORT __istream_readin{
278
	public:
279
		inline static void readin(basic_istream& stream, unsigned long int & var)
280
		{
281
			basic_string temp;
282
 
283
			if(stream.flags() & ios_base::dec){
284
				temp = _readTokenDecimal( stream);
285
				sscanf(temp.c_str(), "%lu", &var );
286
			}else{
287
				temp = _readToken( stream);
288
				if( stream.flags() & ios_base::oct){
289
					sscanf(temp.c_str(), "%lo", &var );
290
				}else if(stream.flags() & ios_base::hex){
291
					if(stream.flags() & ios_base::uppercase){
292
						sscanf(temp.c_str(), "%lX", &var );
293
					}else{
294
						sscanf(temp.c_str(), "%lx", &var);
295
					}
296
				}else{
297
					sscanf(temp.c_str(), "%li", (long int *)(&var) );
298
				}
299
			}
300
		}
301
	};
302
 
303
 
304
#ifdef __UCLIBCXX_HAS_FLOATS__
305
 
306
	template  class _UCXXEXPORT __istream_readin{
307
	public:
308
		inline static void readin(basic_istream& stream, float & var)
309
		{
310
			basic_string temp;
311
			temp = _readTokenDecimal( stream);
312
 
313
			sscanf(temp.c_str(), "%g", &var);
314
		}
315
	};
316
 
317
	template  class _UCXXEXPORT __istream_readin{
318
	public:
319
		inline static void readin(basic_istream& stream, double & var)
320
		{
321
			basic_string temp;
322
			temp = _readTokenDecimal( stream);
323
			sscanf(temp.c_str(), "%lg", &var);
324
		}
325
	};
326
 
327
	template  class _UCXXEXPORT __istream_readin{
328
	public:
329
		inline static void readin(basic_istream& stream, long double & var)
330
		{
331
			basic_string temp;
332
			temp = _readTokenDecimal( stream);
333
			sscanf(temp.c_str(), "%Lg", &var);
334
		}
335
	};
336
 
337
#endif	// ifdef __UCLIBCXX_HAS_FLOATS__
338
 
339
	template  class _UCXXEXPORT __istream_readin{
340
	public:
341
		inline static void readin(basic_istream& stream, void* & var)
342
		{
343
			basic_string temp;
344
			temp = _readToken( stream);
345
			sscanf(temp.c_str(), "%p", &var);
346
		}
347
	};
348
 
349
 
350
	template void __skipws(basic_istream& is){
351
		const typename basic_istream::int_type eof = traits::eof();
352
		typename basic_istream::int_type c;
353
		//While the next character normally read doesn't equal eof
354
		//and that character is a space, advance to the next read position
355
		//Thus itterating through all whitespace until we get to the meaty stuff
356
		while (
357
			!traits::eq_int_type((c = is.rdbuf()->sgetc()),	eof)
358
			&& isspace(c)
359
		) {
360
			is.rdbuf()->sbumpc();
361
		}
362
		if(traits::eq_int_type(c, eof)){
363
			is.setstate(ios_base::eofbit);
364
		}
365
	}
366
}
367
 
368
#pragma GCC visibility pop
369
 
370
#endif
371