15 #ifndef ECL_STREAMS_INPUT_TEXT_STREAM_HPP_ 16 #define ECL_STREAMS_INPUT_TEXT_STREAM_HPP_ 25 #include <ecl/config/macros.hpp> 26 #include <ecl/config/portable_types.hpp> 27 #include <ecl/exceptions/standard_exception.hpp> 28 #include <ecl/concepts/devices.hpp> 29 #include <ecl/type_traits/numeric_limits.hpp> 31 #include "../macros.hpp" 38 namespace interfaces {
56 template <
typename Device,
bool InputDevice = true >
86 template <
typename Device>
87 class ECL_PUBLIC InputTextStream<Device,true> :
public virtual BaseTextStream<Device> {
93 virtual ~InputTextStream() {}
116 void enableRawCharReads();
117 void disableRawCharReads();
125 bool skipLeadingWhiteSpace(
char &c);
126 template <
typename Number>
127 bool getIntegerFromStream(Number &i);
128 template <
typename Number>
129 bool parseHexInteger(Number &i);
130 template <
typename Number>
131 bool getFloatFromStream(Number &f);
147 template <
typename Device>
165 template <
typename Device>
170 if ( !raw_char_reads ) {
171 if( skipLeadingWhiteSpace(c) ) {
177 if ( this->io_device.read(c) == 1 ) {
197 template <
typename Device>
203 if ( skipLeadingWhiteSpace(c) ) {
207 if( this->io_device.read(c) < 1 ) {
211 }
while ( ( c !=
' ' ) && ( c !=
'\n' ) );
232 template <
typename Device>
237 if ( getIntegerFromStream(i) ) {
252 template <
typename Device>
256 if ( getIntegerFromStream(i) ) {
270 template <
typename Device>
274 if ( getIntegerFromStream(i) ) {
287 template <
typename Device>
291 if ( getIntegerFromStream(i) ) {
306 template <
typename Device>
310 if ( getIntegerFromStream(uc) ) {
324 template <
typename Device>
328 if ( getIntegerFromStream(i) ) {
342 template <
typename Device>
346 if ( getIntegerFromStream(i) ) {
360 template <
typename Device>
364 if ( getIntegerFromStream(i) ) {
378 template <
typename Device>
382 if ( getIntegerFromStream(i) ) {
397 template <
typename Device>
401 if ( getFloatFromStream(f) ) {
415 template <
typename Device>
419 if ( getFloatFromStream(d) ) {
435 template <
typename Device>
442 if ( this->fail() ) {
446 if ( ( s ==
"true" ) || ( s ==
"TRUE" ) || ( s ==
"True" ) ) {
449 }
else if ( ( s ==
"false" ) || ( s ==
"FALSE" ) || ( s ==
"False" ) ) {
474 template <
typename Device>
475 void InputTextStream<Device,true>::enableRawCharReads() { raw_char_reads =
true; }
485 template <
typename Device>
486 void InputTextStream<Device,true>::disableRawCharReads() { raw_char_reads =
false; }
502 template <
typename Device>
503 bool InputTextStream<Device,true>::skipLeadingWhiteSpace(
char &c)
506 if( this->io_device.read(c) < 1 ) {
510 }
while ( ( c ==
' ' ) || ( c ==
'\n' ) );
518 template <
typename Device>
519 template <
typename Number>
520 bool InputTextStream<Device,true>::parseHexInteger(Number &i)
523 static int digits[25];
529 long n = this->io_device.read(c);
533 }
else if ( n == 0 ) {
536 if ( ( c >=
'0' ) && ( c <=
'9') ) {
538 }
else if ( ( c >=
'a' ) && ( c <=
'f') ) {
539 digits[j] = 10 + c -
'a';
540 }
else if ( ( c >=
'A' ) && ( c <=
'F') ) {
541 digits[j] = 10 + c -
'A';
553 for (
int k = 0; k < j; ++k ) {
554 if ( number < ceiling ) {
555 number = 16*number + (digits[k]);
570 template <
typename Device>
571 template <
typename Number>
572 bool InputTextStream<Device,true>::getIntegerFromStream(Number &i) {
574 static char digits[25];
577 Number sign_multiplier = 1;
580 if ( !skipLeadingWhiteSpace(c) ) {
return false; }
583 if ( std::numeric_limits<Number>::min() != 0 ) {
584 sign_multiplier = -1;
585 if ( this->io_device.read(c) < 1 ) {
590 }
else if ( c ==
'+' ) {
591 if ( this->io_device.read(c) < 1 ) {
595 }
else if ( c ==
'0' ) {
596 long n = this->io_device.read(c);
597 if ( ( n == 0 ) || ( c ==
' ' ) || ( c ==
'\n' ) ) {
600 }
else if ( n < 0 ) {
603 }
else if ( c ==
'x' ) {
604 return parseHexInteger(i);
608 }
else if ( c ==
'x' ) {
609 return parseHexInteger(i);
616 while ( ( c >=
'0' ) && ( c <=
'9') && ( j < 25 ) ) {
619 long n = this->io_device.read(c);
623 }
else if ( n == 0 ) {
633 for (
int k = 0; k < j; ++k )
635 if ( number < ceiling )
637 number = 10*number + (digits[k] -
'0');
643 i = sign_multiplier*number;
648 template <
typename Device>
649 template <
typename Number>
650 bool InputTextStream<Device,true>::getFloatFromStream(Number &f) {
651 static const int bufferSize = 25;
652 static char digits[bufferSize];
654 int integral_length = 0;
655 int decimal_length = 0;
656 Number sign_multiplier = 1;
659 if ( !skipLeadingWhiteSpace(c) ) {
return false; }
662 sign_multiplier = -1;
663 if ( this->io_device.read(c) < 1 ) { this->error =
ReadError;
return false; }
664 }
else if ( c ==
'+' ) {
665 if ( this->io_device.read(c) < 1 ) { this->error =
ReadError;
return false; }
671 while ( ( c >=
'0' ) && ( c <=
'9') && ( integral_length < bufferSize ) ) {
672 digits[integral_length] = c;
673 long n = this->io_device.read(c);
676 }
else if ( n == 0 ) {
682 for (
int k = 0; k < integral_length; ++k ) {
683 number = 10*number + (digits[k] -
'0');
687 float frac_multiplier = 1;
688 if ( this->io_device.read(c) < 1 ) { this->error =
ReadError;
return false; }
692 while ( ( c >=
'0' ) && ( c <=
'9') && ( decimal_length < bufferSize ) ) {
693 digits[decimal_length] = c;
694 long n = this->io_device.read(c);
697 }
else if ( n == 0 ) {
703 for (
int k = 0; k < decimal_length; ++k ) {
704 frac_multiplier *= 0.1f;
705 number = number + frac_multiplier*(digits[k] -
'0');
709 if ( (integral_length+decimal_length) == 0 ) {
714 f = sign_multiplier*number;
static const short maximum
InputTextStream()
Connects the stream to an input device.
#define LOC
Stringify the line of code you are at.
#define ecl_assert_throw(expression, exception)
Debug mode throw with a logical condition check.
Standard exception type, provides code location and error string.
Expands the std numeric_limits class.
#define ecl_assert_throw_decl(exception)
Assure throw exception declaration.
#define ecl_compile_time_concept_check(Model)
Compile time concept checking assertion.