Skip to content

Commit a5d3a1d

Browse files
authored
[libc++] Refactors fstream open. (#76617)
This moves the duplicated code to one new function. This is a preparation to fix #60509
1 parent 22f34ea commit a5d3a1d

File tree

1 file changed

+97
-121
lines changed

1 file changed

+97
-121
lines changed

libcxx/include/fstream

Lines changed: 97 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,9 @@ public:
279279
# endif // _LIBCPP_STD_VER >= 26
280280

281281
_LIBCPP_HIDE_FROM_ABI inline static const char* __make_mdstring(ios_base::openmode __mode) _NOEXCEPT;
282+
# ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
283+
_LIBCPP_HIDE_FROM_ABI inline static const wchar_t* __make_mdwstring(ios_base::openmode __mode) _NOEXCEPT;
284+
# endif
282285

283286
protected:
284287
// 27.9.1.5 Overridden virtual functions:
@@ -314,6 +317,26 @@ private:
314317
void __write_mode();
315318

316319
_LIBCPP_EXPORTED_FROM_ABI friend FILE* __get_ostream_file(ostream&);
320+
321+
// There are multiple (__)open function, they use different C-API open
322+
// function. After that call these functions behave the same. This function
323+
// does that part and determines the final return value.
324+
_LIBCPP_HIDE_FROM_ABI basic_filebuf* __do_open(FILE* __file, ios_base::openmode __mode) {
325+
__file_ = __file;
326+
if (!__file_)
327+
return nullptr;
328+
329+
__om_ = __mode;
330+
if (__mode & ios_base::ate) {
331+
if (fseek(__file_, 0, SEEK_END)) {
332+
fclose(__file_);
333+
__file_ = nullptr;
334+
return nullptr;
335+
}
336+
}
337+
338+
return this;
339+
}
317340
};
318341

319342
template <class _CharT, class _Traits>
@@ -548,140 +571,93 @@ const char* basic_filebuf<_CharT, _Traits>::__make_mdstring(ios_base::openmode _
548571
__libcpp_unreachable();
549572
}
550573

574+
# ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
551575
template <class _CharT, class _Traits>
552-
basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) {
553-
basic_filebuf<_CharT, _Traits>* __rt = nullptr;
554-
if (__file_ == nullptr) {
555-
if (const char* __mdstr = __make_mdstring(__mode)) {
556-
__rt = this;
557-
__file_ = fopen(__s, __mdstr);
558-
if (__file_) {
559-
__om_ = __mode;
560-
if (__mode & ios_base::ate) {
561-
if (fseek(__file_, 0, SEEK_END)) {
562-
fclose(__file_);
563-
__file_ = nullptr;
564-
__rt = nullptr;
565-
}
566-
}
567-
} else
568-
__rt = nullptr;
569-
}
576+
const wchar_t* basic_filebuf<_CharT, _Traits>::__make_mdwstring(ios_base::openmode __mode) _NOEXCEPT {
577+
switch (__mode & ~ios_base::ate) {
578+
case ios_base::out:
579+
case ios_base::out | ios_base::trunc:
580+
return L"w";
581+
case ios_base::out | ios_base::app:
582+
case ios_base::app:
583+
return L"a";
584+
case ios_base::in:
585+
return L"r";
586+
case ios_base::in | ios_base::out:
587+
return L"r+";
588+
case ios_base::in | ios_base::out | ios_base::trunc:
589+
return L"w+";
590+
case ios_base::in | ios_base::out | ios_base::app:
591+
case ios_base::in | ios_base::app:
592+
return L"a+";
593+
case ios_base::out | ios_base::binary:
594+
case ios_base::out | ios_base::trunc | ios_base::binary:
595+
return L"wb";
596+
case ios_base::out | ios_base::app | ios_base::binary:
597+
case ios_base::app | ios_base::binary:
598+
return L"ab";
599+
case ios_base::in | ios_base::binary:
600+
return L"rb";
601+
case ios_base::in | ios_base::out | ios_base::binary:
602+
return L"r+b";
603+
case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:
604+
return L"w+b";
605+
case ios_base::in | ios_base::out | ios_base::app | ios_base::binary:
606+
case ios_base::in | ios_base::app | ios_base::binary:
607+
return L"a+b";
608+
# if _LIBCPP_STD_VER >= 23
609+
case ios_base::out | ios_base::noreplace:
610+
case ios_base::out | ios_base::trunc | ios_base::noreplace:
611+
return L"wx";
612+
case ios_base::in | ios_base::out | ios_base::trunc | ios_base::noreplace:
613+
return L"w+x";
614+
case ios_base::out | ios_base::binary | ios_base::noreplace:
615+
case ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
616+
return L"wbx";
617+
case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
618+
return L"w+bx";
619+
# endif // _LIBCPP_STD_VER >= 23
620+
default:
621+
return nullptr;
570622
}
571-
return __rt;
623+
__libcpp_unreachable();
624+
}
625+
# endif
626+
627+
template <class _CharT, class _Traits>
628+
basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) {
629+
if (__file_)
630+
return nullptr;
631+
const char* __mdstr = __make_mdstring(__mode);
632+
if (!__mdstr)
633+
return nullptr;
634+
635+
return __do_open(fopen(__s, __mdstr), __mode);
572636
}
573637

574638
template <class _CharT, class _Traits>
575639
inline basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::__open(int __fd, ios_base::openmode __mode) {
576-
basic_filebuf<_CharT, _Traits>* __rt = nullptr;
577-
if (__file_ == nullptr) {
578-
if (const char* __mdstr = __make_mdstring(__mode)) {
579-
__rt = this;
580-
__file_ = fdopen(__fd, __mdstr);
581-
if (__file_) {
582-
__om_ = __mode;
583-
if (__mode & ios_base::ate) {
584-
if (fseek(__file_, 0, SEEK_END)) {
585-
fclose(__file_);
586-
__file_ = nullptr;
587-
__rt = nullptr;
588-
}
589-
}
590-
} else
591-
__rt = nullptr;
592-
}
593-
}
594-
return __rt;
640+
if (__file_)
641+
return nullptr;
642+
const char* __mdstr = __make_mdstring(__mode);
643+
if (!__mdstr)
644+
return nullptr;
645+
646+
return __do_open(fdopen(__fd, __mdstr), __mode);
595647
}
596648

597649
# ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
598650
// This is basically the same as the char* overload except that it uses _wfopen
599651
// and long mode strings.
600652
template <class _CharT, class _Traits>
601653
basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) {
602-
basic_filebuf<_CharT, _Traits>* __rt = nullptr;
603-
if (__file_ == nullptr) {
604-
__rt = this;
605-
const wchar_t* __mdstr;
606-
switch (__mode & ~ios_base::ate) {
607-
case ios_base::out:
608-
case ios_base::out | ios_base::trunc:
609-
__mdstr = L"w";
610-
break;
611-
case ios_base::out | ios_base::app:
612-
case ios_base::app:
613-
__mdstr = L"a";
614-
break;
615-
case ios_base::in:
616-
__mdstr = L"r";
617-
break;
618-
case ios_base::in | ios_base::out:
619-
__mdstr = L"r+";
620-
break;
621-
case ios_base::in | ios_base::out | ios_base::trunc:
622-
__mdstr = L"w+";
623-
break;
624-
case ios_base::in | ios_base::out | ios_base::app:
625-
case ios_base::in | ios_base::app:
626-
__mdstr = L"a+";
627-
break;
628-
case ios_base::out | ios_base::binary:
629-
case ios_base::out | ios_base::trunc | ios_base::binary:
630-
__mdstr = L"wb";
631-
break;
632-
case ios_base::out | ios_base::app | ios_base::binary:
633-
case ios_base::app | ios_base::binary:
634-
__mdstr = L"ab";
635-
break;
636-
case ios_base::in | ios_base::binary:
637-
__mdstr = L"rb";
638-
break;
639-
case ios_base::in | ios_base::out | ios_base::binary:
640-
__mdstr = L"r+b";
641-
break;
642-
case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:
643-
__mdstr = L"w+b";
644-
break;
645-
case ios_base::in | ios_base::out | ios_base::app | ios_base::binary:
646-
case ios_base::in | ios_base::app | ios_base::binary:
647-
__mdstr = L"a+b";
648-
break;
649-
# if _LIBCPP_STD_VER >= 23
650-
case ios_base::out | ios_base::noreplace:
651-
case ios_base::out | ios_base::trunc | ios_base::noreplace:
652-
__mdstr = L"wx";
653-
break;
654-
case ios_base::in | ios_base::out | ios_base::trunc | ios_base::noreplace:
655-
__mdstr = L"w+x";
656-
break;
657-
case ios_base::out | ios_base::binary | ios_base::noreplace:
658-
case ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
659-
__mdstr = L"wbx";
660-
break;
661-
case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
662-
__mdstr = L"w+bx";
663-
break;
664-
# endif // _LIBCPP_STD_VER >= 23
665-
default:
666-
__rt = nullptr;
667-
break;
668-
}
669-
if (__rt) {
670-
__file_ = _wfopen(__s, __mdstr);
671-
if (__file_) {
672-
__om_ = __mode;
673-
if (__mode & ios_base::ate) {
674-
if (fseek(__file_, 0, SEEK_END)) {
675-
fclose(__file_);
676-
__file_ = nullptr;
677-
__rt = nullptr;
678-
}
679-
}
680-
} else
681-
__rt = nullptr;
682-
}
683-
}
684-
return __rt;
654+
if (__file_)
655+
return nullptr;
656+
const wchar_t* __mdstr = __make_mdwstring(__mode);
657+
if (!__mdstr)
658+
return nullptr;
659+
660+
return __do_open(_wfopen(__s, __mdstr), __mode);
685661
}
686662
# endif
687663

0 commit comments

Comments
 (0)