@@ -835,35 +835,50 @@ typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>
835835 }
836836 if (this ->pptr () != this ->pbase ()) {
837837 if (__always_noconv_) {
838- size_t __nmemb = static_cast <size_t >(this ->pptr () - this ->pbase ());
839- if (std::fwrite (this ->pbase (), sizeof (char_type), __nmemb , __file_) != __nmemb )
838+ size_t __n = static_cast <size_t >(this ->pptr () - this ->pbase ());
839+ if (std::fwrite (this ->pbase (), sizeof (char_type), __n , __file_) != __n )
840840 return traits_type::eof ();
841841 } else {
842- char * __extbe = __extbuf_;
843- codecvt_base::result __r;
842+ if (!__cv_)
843+ std::__throw_bad_cast ();
844+
845+ // See [filebuf.virtuals]
846+ char_type* __b = this ->pbase ();
847+ char_type* __p = this ->pptr ();
848+ const char_type* __end;
849+ char * __extbuf_end = __extbuf_;
844850 do {
845- if (!__cv_)
846- std::__throw_bad_cast ();
847-
848- const char_type* __e;
849- __r = __cv_->out (__st_, this ->pbase (), this ->pptr (), __e, __extbuf_, __extbuf_ + __ebs_, __extbe);
850- if (__e == this ->pbase ())
851+ codecvt_base::result __r = __cv_->out (__st_, __b, __p, __end, __extbuf_, __extbuf_ + __ebs_, __extbuf_end);
852+ if (__end == __b)
851853 return traits_type::eof ();
854+
855+ // No conversion needed: output characters directly to the file, done.
852856 if (__r == codecvt_base::noconv) {
853- size_t __nmemb = static_cast <size_t >(this -> pptr () - this -> pbase () );
854- if (std::fwrite (this -> pbase () , 1 , __nmemb , __file_) != __nmemb )
857+ size_t __n = static_cast <size_t >(__p - __b );
858+ if (std::fwrite (__b , 1 , __n , __file_) != __n )
855859 return traits_type::eof ();
856- } else if (__r == codecvt_base::ok || __r == codecvt_base::partial) {
857- size_t __nmemb = static_cast <size_t >(__extbe - __extbuf_);
858- if (std::fwrite (__extbuf_, 1 , __nmemb, __file_) != __nmemb)
860+ break ;
861+
862+ // Conversion successful: output the converted characters to the file, done.
863+ } else if (__r == codecvt_base::ok) {
864+ size_t __n = static_cast <size_t >(__extbuf_end - __extbuf_);
865+ if (std::fwrite (__extbuf_, 1 , __n, __file_) != __n)
866+ return traits_type::eof ();
867+ break ;
868+
869+ // Conversion partially successful: output converted characters to the file and repeat with the
870+ // remaining characters.
871+ } else if (__r == codecvt_base::partial) {
872+ size_t __n = static_cast <size_t >(__extbuf_end - __extbuf_);
873+ if (std::fwrite (__extbuf_, 1 , __n, __file_) != __n)
859874 return traits_type::eof ();
860- if (__r == codecvt_base::partial) {
861- this ->setp (const_cast <char_type*>(__e), this ->pptr ());
862- this ->__pbump (this ->epptr () - this ->pbase ());
863- }
864- } else
875+ __b = const_cast <char_type*>(__end);
876+ continue ;
877+
878+ } else {
865879 return traits_type::eof ();
866- } while (__r == codecvt_base::partial);
880+ }
881+ } while (true );
867882 }
868883 this ->setp (__pb_save, __epb_save);
869884 }
0 commit comments