@@ -834,40 +834,59 @@ typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>
834
834
*this ->pptr () = traits_type::to_char_type (__c);
835
835
this ->pbump (1 );
836
836
}
837
- if (this ->pptr () != this ->pbase ()) {
838
- if (__always_noconv_) {
839
- size_t __nmemb = static_cast <size_t >(this ->pptr () - this ->pbase ());
840
- if (std::fwrite (this ->pbase (), sizeof (char_type), __nmemb, __file_) != __nmemb)
837
+
838
+ // There is nothing to write, early return
839
+ if (this ->pptr () == this ->pbase ()) {
840
+ return traits_type::not_eof (__c);
841
+ }
842
+
843
+ if (__always_noconv_) {
844
+ size_t __n = static_cast <size_t >(this ->pptr () - this ->pbase ());
845
+ if (std::fwrite (this ->pbase (), sizeof (char_type), __n, __file_) != __n)
846
+ return traits_type::eof ();
847
+ } else {
848
+ if (!__cv_)
849
+ std::__throw_bad_cast ();
850
+
851
+ // See [filebuf.virtuals]
852
+ char_type* __b = this ->pbase ();
853
+ char_type* __p = this ->pptr ();
854
+ const char_type* __end;
855
+ char * __extbuf_end = __extbuf_;
856
+ do {
857
+ codecvt_base::result __r = __cv_->out (__st_, __b, __p, __end, __extbuf_, __extbuf_ + __ebs_, __extbuf_end);
858
+ if (__end == __b)
841
859
return traits_type::eof ();
842
- } else {
843
- char * __extbe = __extbuf_;
844
- codecvt_base::result __r;
845
- do {
846
- if (!__cv_)
847
- std::__throw_bad_cast ();
848
860
849
- const char_type* __e;
850
- __r = __cv_->out (__st_, this ->pbase (), this ->pptr (), __e, __extbuf_, __extbuf_ + __ebs_, __extbe);
851
- if (__e == this ->pbase ())
861
+ // No conversion needed: output characters directly to the file, done.
862
+ if (__r == codecvt_base::noconv) {
863
+ size_t __n = static_cast <size_t >(__p - __b);
864
+ if (std::fwrite (__b, 1 , __n, __file_) != __n)
852
865
return traits_type::eof ();
853
- if (__r == codecvt_base::noconv) {
854
- size_t __nmemb = static_cast <size_t >(this ->pptr () - this ->pbase ());
855
- if (std::fwrite (this ->pbase (), 1 , __nmemb, __file_) != __nmemb)
856
- return traits_type::eof ();
857
- } else if (__r == codecvt_base::ok || __r == codecvt_base::partial) {
858
- size_t __nmemb = static_cast <size_t >(__extbe - __extbuf_);
859
- if (std::fwrite (__extbuf_, 1 , __nmemb, __file_) != __nmemb)
860
- return traits_type::eof ();
861
- if (__r == codecvt_base::partial) {
862
- this ->setp (const_cast <char_type*>(__e), this ->pptr ());
863
- this ->__pbump (this ->epptr () - this ->pbase ());
864
- }
865
- } else
866
+ break ;
867
+
868
+ // Conversion successful: output the converted characters to the file, done.
869
+ } else if (__r == codecvt_base::ok) {
870
+ size_t __n = static_cast <size_t >(__extbuf_end - __extbuf_);
871
+ if (std::fwrite (__extbuf_, 1 , __n, __file_) != __n)
866
872
return traits_type::eof ();
867
- } while (__r == codecvt_base::partial);
868
- }
869
- this ->setp (__pb_save, __epb_save);
873
+ break ;
874
+
875
+ // Conversion partially successful: output converted characters to the file and repeat with the
876
+ // remaining characters.
877
+ } else if (__r == codecvt_base::partial) {
878
+ size_t __n = static_cast <size_t >(__extbuf_end - __extbuf_);
879
+ if (std::fwrite (__extbuf_, 1 , __n, __file_) != __n)
880
+ return traits_type::eof ();
881
+ __b = const_cast <char_type*>(__end);
882
+ continue ;
883
+
884
+ } else {
885
+ return traits_type::eof ();
886
+ }
887
+ } while (true );
870
888
}
889
+ this ->setp (__pb_save, __epb_save);
871
890
return traits_type::not_eof (__c);
872
891
}
873
892
0 commit comments