first commit
This commit is contained in:
465
libraries/ArduinoSTL/src/istream_helpers
Normal file
465
libraries/ArduinoSTL/src/istream_helpers
Normal file
@@ -0,0 +1,465 @@
|
||||
/* 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 "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) );
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#if !defined(__STRICT_ANSI__) || (__cplusplus >= 201103L)
|
||||
template <class traits> class _UCXXEXPORT __istream_readin<traits, char, long long>{
|
||||
public:
|
||||
inline static void readin(basic_istream<char, traits >& stream, long long & var)
|
||||
{
|
||||
basic_string<char, traits > temp;
|
||||
|
||||
if(stream.flags() & ios_base::dec){
|
||||
temp = _readTokenDecimal( stream);
|
||||
sscanf(temp.c_str(), "%lld", &var );
|
||||
}else{
|
||||
temp = _readToken( stream);
|
||||
if( stream.flags() & ios_base::oct){
|
||||
sscanf(temp.c_str(), "%llo", (unsigned long long *)&var );
|
||||
}else if(stream.flags() & ios_base::hex){
|
||||
if(stream.flags() & ios_base::uppercase){
|
||||
scanf(temp.c_str(), "%llX", (unsigned long long *)&var );
|
||||
}else{
|
||||
sscanf(temp.c_str(), "%llx", (unsigned long long *)&var);
|
||||
}
|
||||
}else{
|
||||
sscanf(temp.c_str(), "%lli", (&var) );
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <class traits> class _UCXXEXPORT __istream_readin<traits, char, unsigned long long>{
|
||||
public:
|
||||
inline static void readin(basic_istream<char, traits >& stream, unsigned long long & var)
|
||||
{
|
||||
basic_string<char, traits > temp;
|
||||
|
||||
if(stream.flags() & ios_base::dec){
|
||||
temp = _readTokenDecimal( stream);
|
||||
sscanf(temp.c_str(), "%llu", &var );
|
||||
}else{
|
||||
temp = _readToken( stream);
|
||||
if( stream.flags() & ios_base::oct){
|
||||
sscanf(temp.c_str(), "%llo", &var );
|
||||
}else if(stream.flags() & ios_base::hex){
|
||||
if(stream.flags() & ios_base::uppercase){
|
||||
scanf(temp.c_str(), "%llX", &var );
|
||||
}else{
|
||||
sscanf(temp.c_str(), "%llx", &var);
|
||||
}
|
||||
}else{
|
||||
sscanf(temp.c_str(), "%lli", (long long *)(&var) );
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef __UCLIBCXX_HAS_FLOATS__
|
||||
|
||||
// NB: The Arduino AVR compiler contains an implementation of printf() and scanf()
|
||||
// that lacks support for floating point numbers. Also, the AVR C library doesn't
|
||||
// support the double datatype. In AVR it's the same as float.
|
||||
|
||||
|
||||
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);
|
||||
bool isneg=false;
|
||||
if (temp[0] == '-') {
|
||||
isneg=true;
|
||||
temp.erase(0,1);
|
||||
}else if (temp[0] == '+') {
|
||||
isneg=false;
|
||||
temp.erase(0,1);
|
||||
}
|
||||
unsigned int dec = temp.find('.', 0);
|
||||
if (dec == string::npos) {
|
||||
var = atol(temp.c_str());
|
||||
}else{
|
||||
var = atol(temp.substr(0,dec).c_str());
|
||||
var += ((double) atoi(temp.substr(dec+1).c_str())) / pow(10.0,temp.size()-dec-1);
|
||||
}
|
||||
if (isneg)
|
||||
var = -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);
|
||||
bool isneg=false;
|
||||
if (temp[0] == '-') {
|
||||
isneg=true;
|
||||
temp.erase(0,1);
|
||||
}else if (temp[0] == '+') {
|
||||
isneg=false;
|
||||
temp.erase(0,1);
|
||||
}
|
||||
unsigned int dec = temp.find('.', 0);
|
||||
if (dec == string::npos) {
|
||||
var = atol(temp.c_str());
|
||||
}else{
|
||||
var = atol(temp.substr(0,dec).c_str());
|
||||
var += ((double) atoi(temp.substr(dec+1).c_str())) / pow(10.0,temp.size()-dec-1);
|
||||
}
|
||||
if (isneg)
|
||||
var = -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
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user