Skip to content

Commit 0a34830

Browse files
committed
[libc++] Refactors fstream open.
This moves the duplicated code to one new function. This is a preparation to fix #60509
1 parent 81cedac commit 0a34830

File tree

1 file changed

+99
-121
lines changed

1 file changed

+99
-121
lines changed

libcxx/include/fstream

Lines changed: 99 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,9 @@ public:
247247
basic_filebuf* close();
248248

249249
_LIBCPP_HIDE_FROM_ABI inline static const char* __make_mdstring(ios_base::openmode __mode) _NOEXCEPT;
250+
# ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
251+
_LIBCPP_HIDE_FROM_ABI inline static const wchar_t* __make_mdwstring(ios_base::openmode __mode) _NOEXCEPT;
252+
# endif
250253

251254
protected:
252255
// 27.9.1.5 Overridden virtual functions:
@@ -282,6 +285,25 @@ private:
282285
void __write_mode();
283286

284287
_LIBCPP_EXPORTED_FROM_ABI friend FILE* __get_ostream_file(ostream&);
288+
289+
// There are multiple (__)open function, they use different C-API open
290+
// function. After that call these functions behave the same. This function
291+
// does that part and determines the final return value.
292+
_LIBCPP_HIDE_FROM_ABI basic_filebuf* __open_common_part(ios_base::openmode __mode) {
293+
if (!__file_)
294+
return nullptr;
295+
296+
__om_ = __mode;
297+
if (__mode & ios_base::ate) {
298+
if (fseek(__file_, 0, SEEK_END)) {
299+
fclose(__file_);
300+
__file_ = nullptr;
301+
return nullptr;
302+
}
303+
}
304+
305+
return this;
306+
}
285307
};
286308

287309
template <class _CharT, class _Traits>
@@ -516,140 +538,96 @@ const char* basic_filebuf<_CharT, _Traits>::__make_mdstring(ios_base::openmode _
516538
__libcpp_unreachable();
517539
}
518540

541+
# ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
519542
template <class _CharT, class _Traits>
520-
basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) {
521-
basic_filebuf<_CharT, _Traits>* __rt = nullptr;
522-
if (__file_ == nullptr) {
523-
if (const char* __mdstr = __make_mdstring(__mode)) {
524-
__rt = this;
525-
__file_ = fopen(__s, __mdstr);
526-
if (__file_) {
527-
__om_ = __mode;
528-
if (__mode & ios_base::ate) {
529-
if (fseek(__file_, 0, SEEK_END)) {
530-
fclose(__file_);
531-
__file_ = nullptr;
532-
__rt = nullptr;
533-
}
534-
}
535-
} else
536-
__rt = nullptr;
537-
}
543+
const wchar_t* basic_filebuf<_CharT, _Traits>::__make_mdwstring(ios_base::openmode __mode) _NOEXCEPT {
544+
switch (__mode & ~ios_base::ate) {
545+
case ios_base::out:
546+
case ios_base::out | ios_base::trunc:
547+
return L"w";
548+
case ios_base::out | ios_base::app:
549+
case ios_base::app:
550+
return L"a";
551+
case ios_base::in:
552+
return L"r";
553+
case ios_base::in | ios_base::out:
554+
return L"r+";
555+
case ios_base::in | ios_base::out | ios_base::trunc:
556+
return L"w+";
557+
case ios_base::in | ios_base::out | ios_base::app:
558+
case ios_base::in | ios_base::app:
559+
return L"a+";
560+
case ios_base::out | ios_base::binary:
561+
case ios_base::out | ios_base::trunc | ios_base::binary:
562+
return L"wb";
563+
case ios_base::out | ios_base::app | ios_base::binary:
564+
case ios_base::app | ios_base::binary:
565+
return L"ab";
566+
case ios_base::in | ios_base::binary:
567+
return L"rb";
568+
case ios_base::in | ios_base::out | ios_base::binary:
569+
return L"r+b";
570+
case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:
571+
return L"w+b";
572+
case ios_base::in | ios_base::out | ios_base::app | ios_base::binary:
573+
case ios_base::in | ios_base::app | ios_base::binary:
574+
return L"a+b";
575+
# if _LIBCPP_STD_VER >= 23
576+
case ios_base::out | ios_base::noreplace:
577+
case ios_base::out | ios_base::trunc | ios_base::noreplace:
578+
return L"wx";
579+
case ios_base::in | ios_base::out | ios_base::trunc | ios_base::noreplace:
580+
return L"w+x";
581+
case ios_base::out | ios_base::binary | ios_base::noreplace:
582+
case ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
583+
return L"wbx";
584+
case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
585+
return L"w+bx";
586+
# endif // _LIBCPP_STD_VER >= 23
587+
default:
588+
return nullptr;
538589
}
539-
return __rt;
590+
__libcpp_unreachable();
591+
}
592+
# endif
593+
594+
template <class _CharT, class _Traits>
595+
basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) {
596+
if (__file_)
597+
return nullptr;
598+
const char* __mdstr = __make_mdstring(__mode);
599+
if (!__mdstr)
600+
return nullptr;
601+
602+
__file_ = fopen(__s, __mdstr);
603+
return __open_common_part(__mode);
540604
}
541605

542606
template <class _CharT, class _Traits>
543607
inline basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::__open(int __fd, ios_base::openmode __mode) {
544-
basic_filebuf<_CharT, _Traits>* __rt = nullptr;
545-
if (__file_ == nullptr) {
546-
if (const char* __mdstr = __make_mdstring(__mode)) {
547-
__rt = this;
548-
__file_ = fdopen(__fd, __mdstr);
549-
if (__file_) {
550-
__om_ = __mode;
551-
if (__mode & ios_base::ate) {
552-
if (fseek(__file_, 0, SEEK_END)) {
553-
fclose(__file_);
554-
__file_ = nullptr;
555-
__rt = nullptr;
556-
}
557-
}
558-
} else
559-
__rt = nullptr;
560-
}
561-
}
562-
return __rt;
608+
if (__file_)
609+
return nullptr;
610+
const char* __mdstr = __make_mdstring(__mode);
611+
if (!__mdstr)
612+
return nullptr;
613+
614+
__file_ = fdopen(__fd, __mdstr);
615+
return __open_common_part(__mode);
563616
}
564617

565618
# ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
566619
// This is basically the same as the char* overload except that it uses _wfopen
567620
// and long mode strings.
568621
template <class _CharT, class _Traits>
569622
basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) {
570-
basic_filebuf<_CharT, _Traits>* __rt = nullptr;
571-
if (__file_ == nullptr) {
572-
__rt = this;
573-
const wchar_t* __mdstr;
574-
switch (__mode & ~ios_base::ate) {
575-
case ios_base::out:
576-
case ios_base::out | ios_base::trunc:
577-
__mdstr = L"w";
578-
break;
579-
case ios_base::out | ios_base::app:
580-
case ios_base::app:
581-
__mdstr = L"a";
582-
break;
583-
case ios_base::in:
584-
__mdstr = L"r";
585-
break;
586-
case ios_base::in | ios_base::out:
587-
__mdstr = L"r+";
588-
break;
589-
case ios_base::in | ios_base::out | ios_base::trunc:
590-
__mdstr = L"w+";
591-
break;
592-
case ios_base::in | ios_base::out | ios_base::app:
593-
case ios_base::in | ios_base::app:
594-
__mdstr = L"a+";
595-
break;
596-
case ios_base::out | ios_base::binary:
597-
case ios_base::out | ios_base::trunc | ios_base::binary:
598-
__mdstr = L"wb";
599-
break;
600-
case ios_base::out | ios_base::app | ios_base::binary:
601-
case ios_base::app | ios_base::binary:
602-
__mdstr = L"ab";
603-
break;
604-
case ios_base::in | ios_base::binary:
605-
__mdstr = L"rb";
606-
break;
607-
case ios_base::in | ios_base::out | ios_base::binary:
608-
__mdstr = L"r+b";
609-
break;
610-
case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:
611-
__mdstr = L"w+b";
612-
break;
613-
case ios_base::in | ios_base::out | ios_base::app | ios_base::binary:
614-
case ios_base::in | ios_base::app | ios_base::binary:
615-
__mdstr = L"a+b";
616-
break;
617-
# if _LIBCPP_STD_VER >= 23
618-
case ios_base::out | ios_base::noreplace:
619-
case ios_base::out | ios_base::trunc | ios_base::noreplace:
620-
__mdstr = L"wx";
621-
break;
622-
case ios_base::in | ios_base::out | ios_base::trunc | ios_base::noreplace:
623-
__mdstr = L"w+x";
624-
break;
625-
case ios_base::out | ios_base::binary | ios_base::noreplace:
626-
case ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
627-
__mdstr = L"wbx";
628-
break;
629-
case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
630-
__mdstr = L"w+bx";
631-
break;
632-
# endif // _LIBCPP_STD_VER >= 23
633-
default:
634-
__rt = nullptr;
635-
break;
636-
}
637-
if (__rt) {
638-
__file_ = _wfopen(__s, __mdstr);
639-
if (__file_) {
640-
__om_ = __mode;
641-
if (__mode & ios_base::ate) {
642-
if (fseek(__file_, 0, SEEK_END)) {
643-
fclose(__file_);
644-
__file_ = nullptr;
645-
__rt = nullptr;
646-
}
647-
}
648-
} else
649-
__rt = nullptr;
650-
}
651-
}
652-
return __rt;
623+
if (__file_)
624+
return nullptr;
625+
const char* __mdstr = __make_mdwstring(__mode);
626+
if (!__mdstr)
627+
return nullptr;
628+
629+
__file_ = _wfopen(__s, __mdstr);
630+
return __open_common_part(__mode);
653631
}
654632
# endif
655633

0 commit comments

Comments
 (0)