/* 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 #include #include #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 _UCXXEXPORT basic_string _readToken(basic_istream& stream) { basic_string 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 _UCXXEXPORT basic_string _readTokenDecimal(basic_istream& stream) { basic_string temp; typename traits::int_type c; while(true){ c = stream.rdbuf()->sgetc(); if(c != traits::eof() && isspace(c) == false && (isdigit(c) || c == '.' || c == ',' )){ 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 >(istream & stream); #endif template class _UCXXEXPORT __istream_readin{ public: static void readin(basic_istream& stream, dataType & var); }; template class _UCXXEXPORT __istream_readin{ public: inline static void readin(basic_istream& stream, bool & var) { basic_string temp; temp = _readToken( stream); if(temp == "true" || temp == "True" || temp == "TRUE" || temp == "1"){ var = true; }else{ var = false; } } }; template class _UCXXEXPORT __istream_readin{ public: inline static void readin(basic_istream& stream, short & var) { basic_string 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 _UCXXEXPORT __istream_readin{ public: inline static void readin(basic_istream& stream, unsigned short & var) { basic_string 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 _UCXXEXPORT __istream_readin{ public: inline static void readin(basic_istream& stream, int & var) { basic_string 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 _UCXXEXPORT __istream_readin{ public: inline static void readin(basic_istream& stream, unsigned int & var) { basic_string 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 _UCXXEXPORT __istream_readin{ public: inline static void readin(basic_istream& stream, long int & var) { basic_string 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 _UCXXEXPORT __istream_readin{ public: inline static void readin(basic_istream& stream, unsigned long int & var) { basic_string 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 _UCXXEXPORT __istream_readin{ public: inline static void readin(basic_istream& stream, float & var) { basic_string temp; temp = _readTokenDecimal( stream); sscanf(temp.c_str(), "%g", &var); } }; template class _UCXXEXPORT __istream_readin{ public: inline static void readin(basic_istream& stream, double & var) { basic_string temp; temp = _readTokenDecimal( stream); sscanf(temp.c_str(), "%lg", &var); } }; template class _UCXXEXPORT __istream_readin{ public: inline static void readin(basic_istream& stream, long double & var) { basic_string temp; temp = _readTokenDecimal( stream); sscanf(temp.c_str(), "%Lg", &var); } }; #endif // ifdef __UCLIBCXX_HAS_FLOATS__ template class _UCXXEXPORT __istream_readin{ public: inline static void readin(basic_istream& stream, void* & var) { basic_string temp; temp = _readToken( stream); sscanf(temp.c_str(), "%p", &var); } }; template void __skipws(basic_istream& is){ const typename basic_istream::int_type eof = traits::eof(); typename basic_istream::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