1 #ifndef GENESIS_UTILS_IO_INPUT_STREAM_H_ 2 #define GENESIS_UTILS_IO_INPUT_STREAM_H_ 105 : source_name_(
"invalid source" )
114 explicit InputStream( std::shared_ptr<BaseInputSource> input_source )
118 init_( input_source );
132 *
this = std::move( other );
139 if(
this == &other ) {
143 input_reader_ = std::move( other.input_reader_ );
144 source_name_ = std::move( other.source_name_ );
152 buffer_ = other.buffer_;
153 data_pos_ = other.data_pos_;
154 data_end_ = other.data_end_;
155 current_ = other.current_;
157 column_ = other.column_;
160 other.buffer_ =
nullptr;
163 other.current_ =
'\0';
198 if( data_pos_ >= data_end_ ) {
199 throw std::runtime_error(
204 throw std::domain_error(
205 "Invalid input char in " +
source_name() +
" at " +
at() +
"." 217 if( data_pos_ >= data_end_ ) {
224 assert( data_pos_ < BlockLength );
227 if( current_ ==
'\n' ) {
278 if( data_pos_ >= data_end_ ) {
287 assert( data_pos_ < BlockLength );
290 size_t const start = data_pos_;
295 auto const stop = std::min( data_end_, start + BlockLength );
302 data_pos_ + 7 < stop &&
303 buffer_[ data_pos_ + 0 ] !=
'\n' &&
304 buffer_[ data_pos_ + 0 ] !=
'\r' &&
305 buffer_[ data_pos_ + 1 ] !=
'\n' &&
306 buffer_[ data_pos_ + 1 ] !=
'\r' &&
307 buffer_[ data_pos_ + 2 ] !=
'\n' &&
308 buffer_[ data_pos_ + 2 ] !=
'\r' &&
309 buffer_[ data_pos_ + 3 ] !=
'\n' &&
310 buffer_[ data_pos_ + 3 ] !=
'\r' &&
311 buffer_[ data_pos_ + 4 ] !=
'\n' &&
312 buffer_[ data_pos_ + 4 ] !=
'\r' &&
313 buffer_[ data_pos_ + 5 ] !=
'\n' &&
314 buffer_[ data_pos_ + 5 ] !=
'\r' &&
315 buffer_[ data_pos_ + 6 ] !=
'\n' &&
316 buffer_[ data_pos_ + 6 ] !=
'\r' &&
317 buffer_[ data_pos_ + 7 ] !=
'\n' &&
318 buffer_[ data_pos_ + 7 ] !=
'\r' 383 buffer_[ data_pos_ ] !=
'\n' &&
384 buffer_[ data_pos_ ] !=
'\r' 390 target.append( buffer_ + start, data_pos_ - start );
393 assert( data_pos_ >= start );
394 if( data_pos_ - start >= BlockLength ) {
403 assert( data_pos_ <= data_end_ );
404 assert( data_pos_ < 2 * BlockLength );
407 if( data_pos_ == data_end_ ) {
414 }
else if( buffer_[ data_pos_ ] ==
'\n' ) {
417 }
else if( buffer_[ data_pos_ ] ==
'\r' ) {
422 if( data_pos_ < data_end_ && buffer_[ data_pos_ ] ==
'\n' ) {
481 std::string
at()
const 491 return data_pos_ < data_end_;
498 explicit operator bool()
const 500 return data_pos_ < data_end_;
508 return data_pos_ >= data_end_;
546 void update_blocks_()
551 assert( data_pos_ < data_end_ );
554 assert( data_end_ <= BlockLength * 2 );
557 if( data_pos_ >= BlockLength ) {
560 std::memcpy( buffer_, buffer_ + BlockLength, BlockLength );
566 if( input_reader_ && input_reader_->valid() ) {
567 data_end_ += input_reader_->finish_reading();
568 std::memcpy( buffer_ + BlockLength, buffer_ + 2 * BlockLength, BlockLength );
569 input_reader_->start_reading( buffer_ + 2 * BlockLength, BlockLength );
574 assert( data_pos_ < BlockLength );
581 void set_current_char_()
583 if( data_pos_ >= data_end_ ) {
592 if( buffer_[ data_pos_ ] ==
'\r' ) {
593 buffer_[ data_pos_ ] =
'\n';
597 if( data_pos_ + 1 < data_end_ && buffer_[ data_pos_ + 1 ] ==
'\n' ) {
603 if( data_pos_ + 1 == data_end_ && buffer_[ data_pos_ ] !=
'\n' ) {
605 buffer_[ data_pos_ + 1 ] =
'\n';
609 current_ = buffer_[ data_pos_ ];
615 void init_( std::shared_ptr<BaseInputSource> input_source )
618 if( input_source ==
nullptr ) {
619 source_name_ =
"invalid source";
639 source_name_ = input_source->source_name();
643 data_end_ = input_source->read( buffer_, 2 * BlockLength );
646 if( data_end_ >= 3 &&
647 buffer_[0] ==
'\xEF' &&
648 buffer_[1] ==
'\xBB' &&
655 if( data_pos_ == data_end_ ) {
665 if( data_end_ == 2 * BlockLength ) {
669 input_reader_ = utils::make_unique<InputReader>();
671 input_reader_->init( input_source );
672 input_reader_->start_reading( buffer_ + 2 * BlockLength, BlockLength );
689 std::unique_ptr<InputReader> input_reader_ =
nullptr;
690 std::string source_name_;
706 #endif // include guard
Container namespace for all symbols of genesis in order to keep them separate when used as a library...
Provides some valuable additions to STD.
std::shared_ptr< BaseOutputTarget > to_string(std::string &target_string)
Obtain an output target for writing to a string.