diff --git a/include/fstream b/include/fstream index aa78d85f..7b6578f1 100644 --- a/include/fstream +++ b/include/fstream @@ -234,6 +234,7 @@ private: FILE* __file_; const codecvt<char_type, char, state_type>* __cv_; state_type __st_; + state_type __st_last_; ios_base::openmode __om_; ios_base::openmode __cm_; bool __owns_eb_; @@ -255,6 +256,7 @@ basic_filebuf<_CharT, _Traits>::basic_filebuf() __file_(0), __cv_(nullptr), __st_(), + __st_last_(), __om_(0), __cm_(0), __owns_eb_(false), @@ -293,6 +295,7 @@ basic_filebuf<_CharT, _Traits>::basic_filebuf(basic_filebuf&& __rhs) __file_ = __rhs.__file_; __cv_ = __rhs.__cv_; __st_ = __rhs.__st_; + __st_last_ = __rhs.__st_last_; __om_ = __rhs.__om_; __cm_ = __rhs.__cm_; __owns_eb_ = __rhs.__owns_eb_; @@ -325,6 +328,7 @@ basic_filebuf<_CharT, _Traits>::basic_filebuf(basic_filebuf&& __rhs) __rhs.__ibs_ = 0; __rhs.__file_ = 0; __rhs.__st_ = state_type(); + __rhs.__st_last_ = state_type(); __rhs.__om_ = 0; __rhs.__cm_ = 0; __rhs.__owns_eb_ = false; @@ -402,6 +406,7 @@ basic_filebuf<_CharT, _Traits>::swap(basic_filebuf& __rhs) _VSTD::swap(__file_, __rhs.__file_); _VSTD::swap(__cv_, __rhs.__cv_); _VSTD::swap(__st_, __rhs.__st_); + _VSTD::swap(__st_last_, __rhs.__st_last_); _VSTD::swap(__om_, __rhs.__om_); _VSTD::swap(__cm_, __rhs.__cm_); _VSTD::swap(__owns_eb_, __rhs.__owns_eb_); @@ -599,7 +604,7 @@ basic_filebuf<_CharT, _Traits>::underflow() size_t __nmemb = _VSTD::min(static_cast<size_t>(__ibs_ - __unget_sz), static_cast<size_t>(__extbufend_ - __extbufnext_)); codecvt_base::result __r; - state_type __svs = __st_; + __st_last_ = __st_; size_t __nr = fread((void*)__extbufnext_, 1, __nmemb, __file_); if (__nr != 0) { @@ -816,7 +821,7 @@ basic_filebuf<_CharT, _Traits>::seekpos(pos_type __sp, ios_base::openmode) return pos_type(off_type(-1)); if (fseeko(__file_, __sp, SEEK_SET)) return pos_type(off_type(-1)); - __st_ = __sp.state; + __st_ = __sp.state(); return __sp; } @@ -852,6 +857,8 @@ basic_filebuf<_CharT, _Traits>::sync() else if (__cm_ & ios_base::in) { off_type __c; + state_type __state = __st_last_; + bool __update_st = false; if (__always_noconv_) __c = this->egptr() - this->gptr(); else @@ -864,32 +871,19 @@ basic_filebuf<_CharT, _Traits>::sync() { if (this->gptr() != this->egptr()) { - reverse(this->gptr(), this->egptr()); - codecvt_base::result __r; - const char_type* __e = this->gptr(); - char* __extbe; - do - { - __r = __cv_->out(__st_, __e, this->egptr(), __e, - __extbuf_, __extbuf_ + __ebs_, __extbe); - switch (__r) - { - case codecvt_base::noconv: - __c += this->egptr() - this->gptr(); - break; - case codecvt_base::ok: - case codecvt_base::partial: - __c += __extbe - __extbuf_; - break; - default: - return -1; - } - } while (__r == codecvt_base::partial); + const int __off = __cv_->length(__state, __extbuf_, + __extbufnext_, + this->gptr() - this->eback()); + __c += __extbufnext_ - __extbuf_ - __off; + __update_st = true; } } } if (fseeko(__file_, -__c, SEEK_CUR)) return -1; + if (__update_st) + __st_ = __state; + __extbufnext_ = __extbufend_ = __extbuf_; this->setg(0, 0, 0); __cm_ = 0; }