diff options
Diffstat (limited to 'misc/uClibc++/include/uClibc++/istream_helpers')
-rw-r--r-- | misc/uClibc++/include/uClibc++/istream_helpers | 374 |
1 files changed, 374 insertions, 0 deletions
diff --git a/misc/uClibc++/include/uClibc++/istream_helpers b/misc/uClibc++/include/uClibc++/istream_helpers new file mode 100644 index 000000000..0bdca7d21 --- /dev/null +++ b/misc/uClibc++/include/uClibc++/istream_helpers @@ -0,0 +1,374 @@ +/* Copyright (C) 2004 Garrett A. Kajmowicz + + This file is part of the uClibc++ Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include <ios> +#include <cctype> +#include <ctype.h> + +#include <string> + +#ifndef __STD_HEADER_ISTREAM_HELPERS +#define __STD_HEADER_ISTREAM_HELPERS 1 + +#pragma GCC visibility push(default) + +namespace std{ + + + /* We are making the following template class for serveral reasons. Firstly, + * we want to keep the main istream code neat and tidy. Secondly, we want it + * to be easy to do partial specialization of the istream code so that it can + * be expanded and put into the library. This will allow us to make application + * code smaller at the expense of increased library size. This is a fair + * trade-off when there are multiple applications being compiled. Also, this + * feature will be used optionally via configuration options. It will also + * allow us to keep the code bases in sync, dramatically simplifying the + * maintenance required. We specialized for char because wchar and others + * require different scanf functions + */ + + template <class C, class traits> _UCXXEXPORT + basic_string<C, traits> _readToken(basic_istream<C, traits>& stream) + { + basic_string<C, traits> temp; + typename traits::int_type c; + while(true){ + c = stream.rdbuf()->sgetc(); + if(c != traits::eof() && isspace(c) == false){ + stream.rdbuf()->sbumpc(); + temp.append(1, traits::to_char_type(c)); + }else{ + break; + } + } + if (temp.size() == 0) + stream.setstate(ios_base::eofbit|ios_base::failbit); + + return temp; + } + + template <class C, class traits> _UCXXEXPORT + basic_string<C, traits> _readTokenDecimal(basic_istream<C, traits>& stream) + { + basic_string<C, traits> temp; + typename traits::int_type c; + while(true){ + c = stream.rdbuf()->sgetc(); + if(c != traits::eof() && isspace(c) == false && ( + isdigit(c) || + c == '.' || + c == ',' || + ((c == '-' || c == '+') && temp.size() == 0) ) + ){ + stream.rdbuf()->sbumpc(); + temp.append(1, traits::to_char_type(c)); + }else{ + break; + } + } + if (temp.size() == 0) + stream.setstate(ios_base::eofbit|ios_base::failbit); + + return temp; + } + +#ifdef __UCLIBCXX_EXPAND_ISTREAM_CHAR__ + + template <> _UCXXEXPORT string _readToken<char, char_traits<char> >(istream & stream); + +#endif + + + template <class traits, class charT, class dataType> class _UCXXEXPORT __istream_readin{ + public: + static void readin(basic_istream<charT,traits>& stream, dataType & var); + }; + + template <class traits> class _UCXXEXPORT __istream_readin<traits, char, bool>{ + public: + inline static void readin(basic_istream<char, traits >& stream, bool & var) + { + /* 22.4.2.1.2.4 */ + basic_string<char, traits > temp; + temp = _readToken( stream); + if (stream.flags() & ios_base::boolalpha) { + if (temp == "true") // truename() + var = true; + else { + var = false; + if (temp != "false") // falsename() + stream.setstate(ios_base::failbit); + } + } else { + long int i = 0; + int ret; + if (stream.flags() & ios_base::dec) { + ret = sscanf(temp.c_str(), "%ld", &i ); + } else { + if (stream.flags() & ios_base::oct) { + ret = sscanf(temp.c_str(), "%lo", (unsigned long int *)(&i)); + } else if (stream.flags() & ios_base::hex) { + if (stream.flags() & ios_base::uppercase) { + ret = sscanf(temp.c_str(), "%lX", (unsigned long int *)(&i)); + } else { + ret = sscanf(temp.c_str(), "%lx", (unsigned long int *)(&i)); + } + } else { + ret = sscanf(temp.c_str(), "%li", &i); + } + } + if (ret != 1 || i >> 1) + stream.setstate(ios_base::failbit); + var = ret == 1 && bool(i); + } + } + }; + + + template <class traits> class _UCXXEXPORT __istream_readin<traits, char, short>{ + public: + inline static void readin(basic_istream<char, traits >& stream, short & var) + { + basic_string<char, traits > temp; + + if(stream.flags() & ios_base::dec){ + temp = _readTokenDecimal( stream); + sscanf(temp.c_str(), "%hd", &var ); + }else{ + temp = _readToken( stream); + if( stream.flags() & ios_base::oct){ + sscanf(temp.c_str(), "%ho", (unsigned short int *)(&var) ); + }else if(stream.flags() & ios_base::hex){ + if(stream.flags() & ios_base::uppercase){ + sscanf(temp.c_str(), "%hX", (unsigned short int *)(&var) ); + }else{ + sscanf(temp.c_str(), "%hx", (unsigned short int *)(&var) ); + } + }else{ + sscanf(temp.c_str(), "%hi", &var); + } + } + } + }; + + template <class traits> class _UCXXEXPORT __istream_readin<traits, char, unsigned short>{ + public: + inline static void readin(basic_istream<char, traits >& stream, unsigned short & var) + { + basic_string<char, traits > temp; + + if(stream.flags() & ios_base::dec){ + temp = _readTokenDecimal( stream); + sscanf(temp.c_str(), "%hu", &var ); + }else{ + temp = _readToken( stream); + if( stream.flags() & ios_base::oct){ + sscanf(temp.c_str(), "%ho", &var); + }else if(stream.flags() & ios_base::hex){ + if(stream.flags() & ios_base::uppercase){ + sscanf(temp.c_str(), "%hX", &var ); + }else{ + sscanf(temp.c_str(), "%hx", &var); + } + }else{ + sscanf(temp.c_str(), "%hi", (signed short int*)(&var) ); + } + } + } + }; + + template <class traits> class _UCXXEXPORT __istream_readin<traits, char, int>{ + public: + inline static void readin(basic_istream<char, traits >& stream, int & var) + { + basic_string<char, traits > temp; + + if(stream.flags() & ios_base::dec){ + temp = _readTokenDecimal( stream); + sscanf(temp.c_str(), "%d", &var ); + }else{ + temp = _readToken( stream); + if( stream.flags() & ios_base::oct){ + sscanf(temp.c_str(), "%o", (unsigned int *)(&var) ); + }else if(stream.flags() & ios_base::hex){ + if(stream.flags() & ios_base::uppercase){ + sscanf(temp.c_str(), "%X", (unsigned int *)(&var) ); + }else{ + sscanf(temp.c_str(), "%x", (unsigned int *)(&var) ); + } + }else{ + sscanf(temp.c_str(), "%i", &var); + } + } + } + }; + + template <class traits> class _UCXXEXPORT __istream_readin<traits, char, unsigned int>{ + public: + inline static void readin(basic_istream<char, traits >& stream, unsigned int & var) + { + basic_string<char, traits > temp; + + if(stream.flags() & ios_base::dec){ + temp = _readTokenDecimal( stream); + sscanf(temp.c_str(), "%u", &var ); + }else{ + temp = _readToken( stream); + if( stream.flags() & ios_base::oct){ + sscanf(temp.c_str(), "%o", (unsigned int *)(&var) ); + }else if(stream.flags() & ios_base::hex){ + if(stream.flags() & ios_base::uppercase){ + sscanf(temp.c_str(), "%X", (unsigned int *)(&var) ); + }else{ + sscanf(temp.c_str(), "%x", (unsigned int *)(&var) ); + } + }else{ + sscanf(temp.c_str(), "%i", (int *)(&var) ); + } + } + + } + }; + + + template <class traits> class _UCXXEXPORT __istream_readin<traits, char, long int>{ + public: + inline static void readin(basic_istream<char, traits >& stream, long int & var) + { + basic_string<char, traits > temp; + + if(stream.flags() & ios_base::dec){ + temp = _readTokenDecimal( stream); + sscanf(temp.c_str(), "%ld", &var ); + }else{ + temp = _readToken( stream); + if( stream.flags() & ios_base::oct){ + sscanf(temp.c_str(), "%lo", (unsigned long int *)(&var) ); + }else if(stream.flags() & ios_base::hex){ + if(stream.flags() & ios_base::uppercase){ + sscanf(temp.c_str(), "%lX", (unsigned long int *)(&var) ); + }else{ + sscanf(temp.c_str(), "%lx", (unsigned long int *)(&var) ); + } + }else{ + sscanf(temp.c_str(), "%li", (long int *)(&var) ); + } + } + + } + }; + + + template <class traits> class _UCXXEXPORT __istream_readin<traits, char, unsigned long int>{ + public: + inline static void readin(basic_istream<char, traits >& stream, unsigned long int & var) + { + basic_string<char, traits > temp; + + if(stream.flags() & ios_base::dec){ + temp = _readTokenDecimal( stream); + sscanf(temp.c_str(), "%lu", &var ); + }else{ + temp = _readToken( stream); + if( stream.flags() & ios_base::oct){ + sscanf(temp.c_str(), "%lo", &var ); + }else if(stream.flags() & ios_base::hex){ + if(stream.flags() & ios_base::uppercase){ + sscanf(temp.c_str(), "%lX", &var ); + }else{ + sscanf(temp.c_str(), "%lx", &var); + } + }else{ + sscanf(temp.c_str(), "%li", (long int *)(&var) ); + } + } + } + }; + + +#ifdef __UCLIBCXX_HAS_FLOATS__ + + template <class traits> class _UCXXEXPORT __istream_readin<traits, char, float>{ + public: + inline static void readin(basic_istream<char, traits >& stream, float & var) + { + basic_string<char, traits > temp; + temp = _readTokenDecimal( stream); + + sscanf(temp.c_str(), "%g", &var); + } + }; + + template <class traits> class _UCXXEXPORT __istream_readin<traits, char, double>{ + public: + inline static void readin(basic_istream<char, traits >& stream, double & var) + { + basic_string<char, traits > temp; + temp = _readTokenDecimal( stream); + sscanf(temp.c_str(), "%lg", &var); + } + }; + + template <class traits> class _UCXXEXPORT __istream_readin<traits, char, long double>{ + public: + inline static void readin(basic_istream<char, traits >& stream, long double & var) + { + basic_string<char, traits > temp; + temp = _readTokenDecimal( stream); + sscanf(temp.c_str(), "%Lg", &var); + } + }; + +#endif // ifdef __UCLIBCXX_HAS_FLOATS__ + + template <class traits> class _UCXXEXPORT __istream_readin<traits, char, void*>{ + public: + inline static void readin(basic_istream<char, traits >& stream, void* & var) + { + basic_string<char, traits > temp; + temp = _readToken( stream); + sscanf(temp.c_str(), "%p", &var); + } + }; + + + template<class charT, class traits> void __skipws(basic_istream<charT,traits>& is){ + const typename basic_istream<charT,traits>::int_type eof = traits::eof(); + typename basic_istream<charT,traits>::int_type c; + //While the next character normally read doesn't equal eof + //and that character is a space, advance to the next read position + //Thus itterating through all whitespace until we get to the meaty stuff + while ( + !traits::eq_int_type((c = is.rdbuf()->sgetc()), eof) + && isspace(c) + ) { + is.rdbuf()->sbumpc(); + } + if(traits::eq_int_type(c, eof)){ + is.setstate(ios_base::eofbit); + } + } +} + +#pragma GCC visibility pop + +#endif + + + |