Skip to content

Commit 916bdde

Browse files
[libcxx] Fix xsgetn in basic_filebuf
The optimized version of xsgetn for basic_filebuf added in #165223 has an issue where if the reads come from both the buffer and the filesystem it returns the wrong number of characters. This patch should address the issue.
1 parent 79d9ae7 commit 916bdde

File tree

1 file changed

+9
-3
lines changed

1 file changed

+9
-3
lines changed

libcxx/include/fstream

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -310,13 +310,19 @@ protected:
310310

311311
_LIBCPP_HIDE_FROM_ABI_VIRTUAL streamsize xsgetn(char_type* __str, streamsize __len) override {
312312
if (__always_noconv_) {
313-
const streamsize __n = std::min(this->egptr() - this->gptr(), __len);
313+
const streamsize __n = std::min( this->egptr() - this->gptr(), __len);
314314
if (__n != 0) {
315315
traits_type::copy(__str, this->gptr(), __n);
316316
this->__gbump_ptrdiff(__n);
317317
}
318-
if (__len - __n >= this->egptr() - this->eback())
319-
return std::fread(__str + __n, sizeof(char_type), __len - __n, __file_);
318+
const streamsize __remainder = __len - __n;
319+
const streamsize __buffer_space = this->egptr() - this->eback();
320+
321+
if (__remainder >= __buffer_space)
322+
return std::fread(__str + __n, sizeof(char_type), __remainder, __file_) + __n;
323+
else if( __remainder > 0)
324+
return basic_streambuf<_CharT, _Traits>::xsgetn(__str + __n, __remainder) + __n;
325+
return __n;
320326
}
321327
return basic_streambuf<_CharT, _Traits>::xsgetn(__str, __len);
322328
}

0 commit comments

Comments
 (0)