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