YSTest: FileIO.h 源文件

YSTest PreAlpha_b800_20170810 The YSLib Test Project

- 首页
- 相关页面
- 模块
- 命名空间
- 类
- 文件

- 文件列表
- 文件成员

FileIO.h
浏览该文件的文档.
1 /*
2 © 2011-2016 FrankHB.
3
4 This file is part of the YSLib project, and may only be used,
5 modified, and distributed under the terms of the YSLib project
6 license, LICENSE.TXT. By continuing to use, modify, or distribute
7 this file you indicate that you have read the license and
8 understand and accept it fully.
9 */
10
28 #ifndef YCL_INC_FileIO_h_
29 #define YCL_INC_FileIO_h_ 1
30
31 #include "YModules.h"
32 #include YFM_YCLib_Platform
33 #include YFM_YBaseMacro
34 #include YFM_YCLib_Debug // for YB_NONNULL, string, Nonnull, u16string_view,
35 // std::uint32_t, std::uint64_t, ynothrow, ystdex::totally_ordered, std::FILE,
36 // ystdex::enable_for_string_class_t, ystdex::retry_for_vector, errno,
37 // ystdex::throw_error, u16string, std::system_error, YTraceDe, array, wstring,
38 // string_view;
39 #include <chrono> // for std::chrono::nanoseconds;
40 #include YFM_YCLib_Reference // for unique_ptr_from;
41 #include <ios> // for std::ios_base::sync_with_stdio;
42 #include <fstream> // for std::filebuf;
43 #if __GLIBCXX__
44 # include <ext/stdio_filebuf.h> // for __gnu_cxx::stdio_filebuf;
45 # include <ystdex/utility.hpp> // for ystdex::swap_underlying,
46 // ystdex::exchange;
47 #elif YB_IMPL_MSCPP
48 # include <ystdex/cstdio.h> // for ystdex::openmode_conv;
49 # include <locale> // for std::use_facet, std::codecvt;
50 #endif
51
52 namespace platform
53 {
54
61 inline YB_NONNULL(1) PDefH(string, MakePathString, const char* s)
63 ImplRet(Nonnull(s))
64 inline PDefH(const string&, MakePathString, const string& s)
65 ImplRet(s)
67
68 YF_API YB_NONNULL(1) string
70 MakePathString(const char16_t*);
72 inline PDefH(string, MakePathString, u16string_view sv)
73 ImplRet(MakePathString(sv.data()))
75
76
77
79
80
82 #if YCL_Win32
83 using FileNodeID = pair<std::uint32_t, std::uint64_t>;
84 #else
85 using FileNodeID = pair<std::uint64_t, std::uint64_t>;
86 #endif
87
88
94 yconstfn PDefHOp(bool, ==, const FileNodeID& x, const FileNodeID& y)
95 ImplRet(x.first == y.first && x.second == y.second)
96 yconstfn PDefHOp(bool, !=, const FileNodeID& x, const FileNodeID& y)
97 ImplRet(!(x == y))
99
100
101
103 using FileTime = std::chrono::nanoseconds;
104
105
111 #if YCL_Win32
112 using mode_t = unsigned short;
113 #else
114 using mode_t = ::mode_t;
115 #endif
116
117
118
123 enum class NodeCategory : std::uint_least32_t;
124
125 /*
126 \brief 取指定模式对应的文件节点类型。
127 \relates NodeCategory
128 \since build 658
129 */
130 YF_API NodeCategory
131 CategorizeNode(mode_t) ynothrow;
132
133
146 class YF_API FileDescriptor : private ystdex::totally_ordered<FileDescriptor>
147 {
148 public:
153 struct YF_API Deleter
154 {
155 using pointer = FileDescriptor;
156
158 void
159 operator()(pointer) const ynothrow;
160 };
161
162 private:
164 int desc = -1;
165
166 public:
167 yconstfn DefDeCtor(FileDescriptor)
168 yconstfn
169 FileDescriptor(int fd) ynothrow
170 : desc(fd)
171 {}
173 yconstfn
174 FileDescriptor(nullptr_t) ynothrow
175 {}
182 FileDescriptor(std::FILE*) ynothrow;
183
188 PDefHOp(int, *, ) const ynothrow
189 ImplRet(desc)
190
192 PDefHOp(FileDescriptor*, ->, ) ynothrow
193 ImplRet(this)
195 PDefHOp(const FileDescriptor*, ->, ) const ynothrow
196 ImplRet(this)
197
198 explicit DefCvt(const ynothrow, bool, desc != -1)
199
201 friend yconstfn YB_PURE PDefHOp(bool,
202 ==, const FileDescriptor& x, const FileDescriptor& y) ynothrow
203 ImplRet(x.desc == y.desc)
204
206 friend yconstfn YB_PURE PDefHOp(bool,
207 <, const FileDescriptor& x, const FileDescriptor& y) ynothrow
208 ImplRet(x.desc < y.desc)
209
211
212
218 FileTime
219 GetAccessTime() const;
225 NodeCategory
226 GetCategory() const ynothrow;
228
229
233 int
234 GetFlags() const;
236 mode_t
237 GetMode() const;
239
245 FileTime
247 GetModificationTime() const;
249 array<FileTime, 2>
250 GetModificationAndAccessTime() const;
252
253
258 FileNodeID
260 GetNodeID() const ynothrow;
262 size_t
263 GetNumberOfLinks() const ynothrow;
265
273 std::uint64_t
274 GetSize() const;
275
282 void
283 SetAccessTime(FileTime) const;
295 bool
296 SetBlocking() const;
298 void
299 SetFlags(int) const;
301 void
302 SetMode(mode_t) const;
304
311 void
313 SetModificationTime(FileTime) const;
315 void
316 SetModificationAndAccessTime(array<FileTime, 2>) const;
318
327 bool
328 SetNonblocking() const;
330
331
338 bool
339 SetSize(size_t) ynothrow;
346 int
347 SetTranslationMode(int) const ynothrow;
348
354 void
355 Flush();
356
371 YB_NONNULL(2) size_t
372 FullRead(void*, size_t) ynothrowv;
373
378 YB_NONNULL(2) size_t
379 FullWrite(const void*, size_t) ynothrowv;
381
389 YB_NONNULL(2) size_t
390 Read(void*, size_t) ynothrowv;
391
392 YB_NONNULL(2) size_t
393 Write(const void*, size_t) ynothrowv;
395
396
397
406 static YB_NONNULL(3) void
408 WriteContent(FileDescriptor, FileDescriptor, byte*, size_t);
413 static void
414 WriteContent(FileDescriptor, FileDescriptor,
415 size_t = yimpl(size_t(BUFSIZ << 4)));
417
432
434 void
435 lock();
436
437 void
438 lock_shared();
440
442
443 bool
444 try_lock() ynothrowv;
445
446 bool
447 try_lock_shared() ynothrowv;
449
450
452
453 void
454 unlock() ynothrowv;
455
456 void
457 unlock_shared() ynothrowv;
459
460 };
461
462
464 using UniqueFile = unique_ptr_from<FileDescriptor::Deleter>;
465
466
471 YF_API YB_STATELESS mode_t
472 DefaultPMode() ynothrow;
473
480 YF_API void
481 SetBinaryIO(std::FILE*) ynothrowv;
482
489 inline PDefH(void, SetupBinaryStdIO, std::FILE* in = stdin,
490 std::FILE* out = stdout, bool sync = {}) ynothrowv
491 ImplExpr(SetBinaryIO(in), SetBinaryIO(out),
492 std::ios_base::sync_with_stdio(sync))
494
495
502 YF_API YB_STATELESS int
504 omode_conv(std::ios_base::openmode) ynothrow;
505
510 YF_API YB_STATELESS int
511 omode_convb(std::ios_base::openmode) ynothrow;
513
527 YF_API YB_NONNULL(1) int
528 uaccess(const char* path, int amode) ynothrowv;
529 YF_API YB_NONNULL(1) int
530 uaccess(const char16_t* path, int amode) ynothrowv;
532
540 YF_API YB_NONNULL(1) int
542 uopen(const char* filename, int oflag, mode_t pmode = DefaultPMode())
543 ynothrowv;
545 YF_API YB_NONNULL(1) int
546 uopen(const char16_t* filename, int oflag, mode_t pmode = DefaultPMode())
547 ynothrowv;
549
551
552
557 YF_API YB_NONNULL(1, 2) std::FILE*
559 ufopen(const char* filename, const char* mode) ynothrowv;
561 YF_API YB_NONNULL(1, 2) std::FILE*
562 ufopen(const char16_t* filename, const char16_t* mode) ynothrowv;
564
566 YF_API YB_NONNULL(1) std::FILE*
568 ufopen(const char* filename, std::ios_base::openmode mode) ynothrowv;
570 YF_API YB_NONNULL(1) std::FILE*
571 ufopen(const char16_t* filename, std::ios_base::openmode mode) ynothrowv;
573
575
576 YF_API YB_NONNULL(1) bool
578 ufexists(const char*) ynothrowv;
580 YF_API YB_NONNULL(1) bool
581 ufexists(const char16_t*) ynothrowv;
583
584
595 YF_API YB_NONNULL(1) char*
597 ugetcwd(char* buf, size_t size) ynothrowv;
599 YF_API YB_NONNULL(1) char16_t*
600 ugetcwd(char16_t* buf, size_t size) ynothrowv;
602
616 YF_API YB_NONNULL(1) bool
617 uchdir(const char*) ynothrowv;
618
623 YF_API YB_NONNULL(1) bool
624 umkdir(const char*) ynothrowv;
625
630 YF_API YB_NONNULL(1) bool
631 urmdir(const char*) ynothrowv;
632
638 YF_API YB_NONNULL(1) bool
639 uunlink(const char*) ynothrowv;
640
647 YF_API YB_NONNULL(1) bool
648 uremove(const char*) ynothrowv;
650
651
652
653
659 #if __GLIBCXX__ || YB_IMPL_MSCPP
660
665 # if __GLIBCXX__
666 yconstexpr const auto ios_nocreate(
668 std::ios_base::openmode(std::_Ios_Openmode::yimpl(_S_trunc << 1)));
673 yconstexpr const auto ios_noreplace(
674 std::ios_base::openmode(std::_Ios_Openmode::yimpl(_S_trunc << 2)));
675 # else
676 yconstexpr const auto ios_nocreate(std::ios::_Nocreate);
677 yconstexpr const auto ios_noreplace(std::ios::_Noreplace);
678 # endif
679
680
681
682 template<typename _tChar, class _tTraits = std::char_traits<_tChar>>
683 class basic_filebuf
684 # if __GLIBCXX__
685 : public yimpl(__gnu_cxx::stdio_filebuf<_tChar, _tTraits>)
686 # else
687 : public yimpl(std::basic_filebuf<_tChar, _tTraits>)
688 # endif
689 {
690 public:
691 using char_type = _tChar;
692 using int_type = typename _tTraits::int_type;
693 using pos_type = typename _tTraits::pos_type;
694 using off_type = typename _tTraits::off_type;
695 using traits = _tTraits;
696
698 DefDeCtor(basic_filebuf)
699 # if __GLIBCXX__
700 using yimpl(__gnu_cxx::stdio_filebuf<_tChar, _tTraits>::stdio_filebuf);
701 # else
702 using yimpl(std::basic_filebuf<_tChar, _tTraits>::basic_filebuf);
704 # endif
705 DefDeCopyMoveCtorAssignment(basic_filebuf)
706
707 public:
712 basic_filebuf<_tChar, _tTraits>*
713 open(UniqueFile p, std::ios_base::openmode mode)
714 {
715 if(p)
716 {
717 mode &= ~(ios_nocreate | ios_noreplace);
718 # if __GLIBCXX__
719 this->_M_file.sys_open(*p.get(), mode);
720 if(open_check(mode))
721 {
722 p.release();
723 return this;
724 }
725 # else
726 if(!this->is_open())
727 if(const auto mode_str = ystdex::openmode_conv(mode))
728 return open_file_ptr(::_fdopen(*p.get(), mode_str));
729 # endif
730 }
731 return {};
732 }
733 template<typename _tPathChar>
734 std::basic_filebuf<_tChar, _tTraits>*
735 open(const _tPathChar* s, std::ios_base::openmode mode)
736 {
737 if(!this->is_open())
738 {
739 # if __GLIBCXX__
740 this->_M_file.sys_open(uopen(s, omode_convb(mode)), mode);
741 if(open_check(mode))
742 return this;
743 # else
744 return open_file_ptr(std::_Fiopen(s, mode,
745 int(std::ios_base::_Openprot)));
746 # endif
747 }
748 return {};
749 }
751 template<class _tString,
752 yimpl(typename = ystdex::enable_for_string_class_t<_tString>)>
753 std::basic_filebuf<_tChar, _tTraits>*
754 open(const _tString& s, std::ios_base::openmode mode)
755 {
756 return open(s.c_str(), mode);
757 }
758
759 private:
760 # if __GLIBCXX__
761 bool
763 open_check(std::ios_base::openmode mode)
764 {
765 if(this->is_open())
766 {
767 this->_M_allocate_internal_buffer();
768 this->_M_mode = mode;
769 yunseq(this->_M_reading = {}, this->_M_writing = {});
770 this->_M_set_buffer(-1);
771 yunseq(this->_M_state_cur = this->_M_state_beg,
772 this->_M_state_last = this->_M_state_beg);
773 if((mode & std::ios_base::ate) && this->seekoff(0,
774 std::ios_base::end) == pos_type(off_type(-1)))
775 this->close();
776 else
777 return true;
778 return true;
779 }
780 return {};
781 }
782 # else
783 YB_NONNULL(1) basic_filebuf<_tChar, _tTraits>*
785 open_file_ptr(::_Filet* p_file)
786 {
787 if(p_file)
788 {
789 this->_Init(p_file, std::basic_filebuf<_tChar, _tTraits>::_Openfl);
790 this->_Initcvt(&std::use_facet<std::codecvt<_tChar, char,
791 typename _tTraits::state_type>>(
792 std::basic_streambuf<_tChar, _tTraits>::getloc()));
793 return this;
794 }
795 return {};
796 }
797 # endif
798 };
799
800
801 //extern template class YF_API basic_filebuf<char>;
802 //extern template class YF_API basic_filebuf<wchar_t>;
803
804 using filebuf = basic_filebuf<char>;
805 using wfilebuf = basic_filebuf<wchar_t>;
806
807
809
810 template<typename _tChar, class _tTraits = std::char_traits<_tChar>>
811 class basic_ifstream : public std::basic_istream<_tChar, _tTraits>
812 {
813 public:
814 using char_type = _tChar;
815 using int_type = typename _tTraits::int_type;
816 using pos_type = typename _tTraits::pos_type;
817 using off_type = typename _tTraits::off_type;
818 using traits_type = _tTraits;
819
820 private:
821 using base_type = std::basic_istream<char_type, traits_type>;
822
823 mutable basic_filebuf<_tChar, _tTraits> fbuf{};
824
825 public:
826 basic_ifstream()
827 : base_type(nullptr)
828 {
829 this->init(&fbuf);
830 }
832 template<typename _tParam,
833 yimpl(typename = ystdex::exclude_self_t<basic_ifstream, _tParam>)>
834 explicit
835 basic_ifstream(_tParam&& s,
836 std::ios_base::openmode mode = std::ios_base::in)
837 : base_type(nullptr)
838 {
839 this->init(&fbuf);
840 this->open(yforward(s), mode);
841 }
842 DefDelCopyCtor(basic_ifstream)
843 basic_ifstream(basic_ifstream&& rhs)
844 : base_type(std::move(rhs)),
845 fbuf(std::move(rhs.fbuf))
846 {
847 base_type::set_rdbuf(&fbuf);
848 }
849 DefDeDtor(basic_ifstream)
850
851 DefDelCopyAssignment(basic_ifstream)
852 basic_ifstream&
853 operator=(basic_ifstream&& rhs)
854 {
855 base_type::operator=(std::move(rhs));
856 fbuf = std::move(rhs.fbuf);
857 return *this;
858 }
859
860 void
861 swap(basic_ifstream& rhs)
862 {
863 base_type::swap(rhs),
864 fbuf.swap(rhs.fbuf);
865 }
866
867 void
868 close()
869 {
870 if(!fbuf.close())
871 this->setstate(std::ios_base::failbit);
872 }
873
874 bool
875 is_open() const
876 {
877 return fbuf.is_open();
878 }
879
881 template<typename _tParam>
882 void
883 open(_tParam&& s,
884 std::ios_base::openmode mode = std::ios_base::in)
885 {
886 if(fbuf.open(yforward(s), mode))
887 this->clear();
888 else
889 this->setstate(std::ios_base::failbit);
890 }
891
892 YB_ATTR_returns_nonnull std::basic_filebuf<_tChar, _tTraits>*
893 rdbuf() const
894 {
895 return &fbuf;
896 }
897 };
898
899 template<typename _tChar, class _tTraits>
900 inline DefSwap(, basic_ifstream<_tChar YPP_Comma _tTraits>)
901
902
903 template<typename _tChar, class _tTraits = std::char_traits<_tChar>>
904 class basic_ofstream : public std::basic_ostream<_tChar, _tTraits>
905 {
906 public:
907 using char_type = _tChar;
908 using int_type = typename _tTraits::int_type;
909 using pos_type = typename _tTraits::pos_type;
910 using off_type = typename _tTraits::off_type;
911 using traits_type = _tTraits;
912
913 private:
914 using base_type = std::basic_ostream<char_type, traits_type>;
915
917 mutable basic_filebuf<_tChar, _tTraits> fbuf{};
918
919 public:
920 basic_ofstream()
921 : base_type(nullptr)
922 {
923 this->init(&fbuf);
924 }
926 template<typename _tParam,
927 yimpl(typename = ystdex::exclude_self_t<basic_ofstream, _tParam>)>
928 explicit
929 basic_ofstream(_tParam&& s,
930 std::ios_base::openmode mode = std::ios_base::out)
931 : base_type(nullptr)
932 {
933 this->init(&fbuf);
934 this->open(yforward(s), mode);
935 }
936 DefDelCopyCtor(basic_ofstream)
937 basic_ofstream(basic_ofstream&& rhs)
938 : base_type(std::move(rhs)),
939 fbuf(std::move(rhs.fbuf))
940 {
941 base_type::set_rdbuf(&fbuf);
942 }
943 DefDeDtor(basic_ofstream)
944
945 DefDelCopyAssignment(basic_ofstream)
946 basic_ofstream&
947 operator=(basic_ofstream&& rhs)
948 {
949 base_type::operator=(std::move(rhs));
950 fbuf = std::move(rhs.fbuf);
951 return *this;
952 }
953
954 void
955 swap(basic_ofstream& rhs)
956 {
957 base_type::swap(rhs),
958 fbuf.swap(rhs.fbuf);
959 }
960
961 void
962 close()
963 {
964 if(!fbuf.close())
965 this->setstate(std::ios_base::failbit);
966 }
967
968 bool
969 is_open() const
970 {
971 return fbuf.is_open();
972 }
973
975 template<typename _tParam>
976 void
977 open(_tParam&& s, std::ios_base::openmode mode = std::ios_base::out)
978 {
979 if(fbuf.open(yforward(s), mode))
980 this->clear();
981 else
982 this->setstate(std::ios_base::failbit);
983 }
984
985 YB_ATTR_returns_nonnull std::basic_filebuf<_tChar, _tTraits>*
986 rdbuf() const
987 {
988 return &fbuf;
989 }
990 };
991
992 template<typename _tChar, class _tTraits>
993 inline DefSwap(, basic_ofstream<_tChar YPP_Comma _tTraits>)
995
996
997 template<typename _tChar, class _tTraits = std::char_traits<_tChar>>
998 class basic_fstream : public std::basic_iostream<_tChar, _tTraits>
999 {
1000 public:
1001 using char_type = _tChar;
1002 using int_type = typename _tTraits::int_type;
1003 using pos_type = typename _tTraits::pos_type;
1004 using off_type = typename _tTraits::off_type;
1005 using traits_type = _tTraits;
1006
1007 private:
1008 using base_type = std::basic_iostream<char_type, traits_type>;
1009
1011 mutable basic_filebuf<_tChar, _tTraits> fbuf{};
1012
1013 public:
1014 basic_fstream()
1015 : base_type(nullptr)
1016 {
1017 this->init(&fbuf);
1018 }
1019 template<typename _tParam,
1020 yimpl(typename = ystdex::exclude_self_t<basic_fstream, _tParam>)>
1021 explicit
1022 basic_fstream(_tParam&& s,
1023 std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out)
1024 : base_type(nullptr)
1025 {
1026 this->init(&fbuf);
1027 this->open(yforward(s), mode);
1028 }
1029 DefDelCopyCtor(basic_fstream)
1030 basic_fstream(basic_fstream&& rhs)
1031 : base_type(std::move(rhs)),
1032 fbuf(std::move(rhs.fbuf))
1033 {
1034 base_type::set_rdbuf(&fbuf);
1035 }
1036 DefDeDtor(basic_fstream)
1037
1038 DefDelCopyAssignment(basic_fstream)
1039 basic_fstream&
1040 operator=(basic_fstream&& rhs)
1041 {
1042 base_type::operator=(std::move(rhs));
1043 fbuf = std::move(rhs.fbuf);
1044 return *this;
1045 }
1046
1047 void
1048 swap(basic_fstream& rhs)
1049 {
1050 base_type::swap(rhs),
1051 fbuf.swap(rhs.fbuf);
1052 }
1053
1054 void
1055 close()
1056 {
1057 if(!fbuf.close())
1058 this->setstate(std::ios_base::failbit);
1059 }
1060
1061 bool
1062 is_open() const
1063 {
1064 return fbuf.is_open();
1065 }
1066
1068 template<typename _tParam>
1069 void
1070 open(_tParam&& s,
1071 std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out)
1072 {
1073 if(fbuf.open(yforward(s), mode))
1074 this->clear();
1075 else
1076 this->setstate(std::ios_base::failbit);
1077 }
1078
1079 YB_ATTR_returns_nonnull std::basic_filebuf<_tChar, _tTraits>*
1080 rdbuf() const
1081 {
1082 return &fbuf;
1083 }
1084 };
1085
1086 template<typename _tChar, class _tTraits>
1087 inline DefSwap(, basic_fstream<_tChar YPP_Comma _tTraits>)
1088
1089
1090 //extern template class YF_API basic_fstream<char>;
1091 //extern template class YF_API basic_fstream<wchar_t>;
1092
1093
1095 using ifstream = basic_ifstream<char>;
1096 using ofstream = basic_ofstream<char>;
1098 using fstream = basic_fstream<char>;
1099 using wifstream = basic_ifstream<wchar_t>;
1100 using wofstream = basic_ofstream<wchar_t>;
1102 using wfstream = basic_fstream<wchar_t>;
1103 #else
1104 // TODO: Use VC++ extensions to support %char16_t path initialization.
1105 using std::basic_filebuf;
1106 using std::filebuf;
1107 using std::wfilebuf;
1109
1110 using std::basic_ifstream;
1111 using std::basic_ofstream;
1113 using std::basic_fstream;
1114 using std::ifstream;
1115 using std::ofstream;
1117 using std::fstream;
1118 using std::wifstream;
1119 using std::wofstream;
1121 using std::wfstream;
1122 #endif
1123
1124
1125
1127
1128
1133 template<typename _tChar>
1134 basic_string<_tChar>
1135 FetchCurrentWorkingDirectory(size_t init)
1136 {
1137 return ystdex::retry_for_vector<basic_string<_tChar>>(init,
1138 [](basic_string<_tChar>& res, size_t) -> bool{
1139 const auto r(platform::ugetcwd(&res[0], res.length()));
1140
1141 if(r)
1142 {
1143 res = r;
1144 return {};
1145 }
1146
1147 const int err(errno);
1148
1149 if(err != ERANGE)
1150 ystdex::throw_error(err, yfsig);
1151 return true;
1152 });
1153 }
1154 #if YCL_Win32
1155
1157 template<>
1158 YF_API string
1159 FetchCurrentWorkingDirectory(size_t);
1160 template<>
1161 YF_API u16string
1162 FetchCurrentWorkingDirectory(size_t);
1164 #endif
1165
1166
1167
1169
1170
1178 #define YCL_Raise_SysE(_t, _msg, _sig) \
1179 do \
1180 { \
1181 const auto err_(errno); \
1182 \
1183 ystdex::throw_error<_t>(err_, \
1184 platform::ComposeMessageWithSignature(_msg YPP_Comma _sig)); \
1185 }while(false)
1186
1188 #define YCL_RaiseZ_SysE(_t, _expr, _msg, _sig) \
1189 do \
1190 { \
1191 const auto err_(_expr); \
1192 \
1193 if(err_ != decltype(err_)()) \
1194 ystdex::throw_error<_t>(err_, \
1195 platform::ComposeMessageWithSignature(_msg YPP_Comma _sig)); \
1196 }while(false)
1197
1198
1203 #define YCL_Trace_SysE(_lv, _fn, _sig) \
1204 do \
1205 { \
1206 const int err_(errno); \
1207 \
1208 YTraceDe(_lv, "Failed calling " #_fn " @ %s with error %d: %s.", \
1209 _sig, err_, std::strerror(err_)); \
1210 }while(false)
1211
1225 #define YCL_WrapCall_CAPI(_t, _fn, ...) \
1226 [&](const char* sig_) YB_NONNULL(1){ \
1227 const auto res_(_fn(__VA_ARGS__)); \
1228 \
1229 if(YB_UNLIKELY(res_ < decltype(res_)())) \
1230 YCL_Raise_SysE(_t, #_fn, sig_); \
1231 return res_; \
1232 }
1233
1234 #define YCL_Call_CAPI(_t, _fn, _sig, ...) \
1235 YCL_WrapCall_CAPI(_t, _fn, __VA_ARGS__)(_sig)
1236
1237 #define YCL_CallF_CAPI(_t, _fn, ...) YCL_Call_CAPI(_t, _fn, yfsig, __VA_ARGS__)
1238
1239
1246 #define YCL_TraceWrapCall_CAPI(_fn, ...) \
1247 [&](const char* sig_) YB_NONNULL(1){ \
1248 const auto res_(_fn(__VA_ARGS__)); \
1249 \
1250 if(YB_UNLIKELY(res_ < decltype(res_)())) \
1251 YCL_Trace_SysE(platform::Descriptions::Warning, _fn, sig_); \
1252 return res_; \
1253 }
1254
1255 #define YCL_TraceCall_CAPI(_fn, _sig, ...) \
1256 YCL_TraceWrapCall_CAPI(_fn, __VA_ARGS__)(_sig)
1257
1258 #define YCL_TraceCallF_CAPI(_fn, ...) \
1259 YCL_TraceCall_CAPI(_fn, yfsig, __VA_ARGS__)
1260
1261
1262
1263
1264
1266
1267
1272 inline YB_NONNULL(1) PDefH(FileTime, GetFileAccessTimeOf, std::FILE* fp)
1273 ImplRet(FileDescriptor(fp).GetAccessTime())
1279 YF_API YB_NONNULL(1) FileTime
1280 GetFileAccessTimeOf(const char*, bool = {});
1281 YF_API YB_NONNULL(1) FileTime
1282 GetFileAccessTimeOf(const char16_t*, bool = {});
1284
1285
1291 inline YB_NONNULL(1) PDefH(FileTime, GetFileModificationTimeOf, std::FILE* fp)
1292 ImplRet(FileDescriptor(fp).GetModificationTime())
1293
1299 YF_API YB_NONNULL(1) FileTime
1300 GetFileModificationTimeOf(const char*, bool = {});
1301 YF_API YB_NONNULL(1) FileTime
1302 GetFileModificationTimeOf(const char16_t*, bool = {});
1304
1305
1311 inline YB_NONNULL(1) PDefH(array<FileTime YPP_Comma 2>,
1312 GetFileModificationAndAccessTimeOf, std::FILE* fp)
1313 ImplRet(FileDescriptor(fp).GetModificationAndAccessTime())
1319 YF_API YB_NONNULL(1) array<FileTime, 2>
1320 GetFileModificationAndAccessTimeOf(const char*, bool = {});
1321 YF_API YB_NONNULL(1) array<FileTime, 2>
1322 GetFileModificationAndAccessTimeOf(const char16_t*, bool = {});
1324
1325
1326
1334 YB_NONNULL(1) size_t
1335 FetchNumberOfLinks(const char*, bool = {});
1336 YB_NONNULL(1) size_t
1337 FetchNumberOfLinks(const char16_t*, bool = {});
1339
1340
1352 YF_API YB_NONNULL(1) UniqueFile
1353 EnsureUniqueFile(const char*, mode_t = DefaultPMode(), size_t = 1, bool = {});
1355
1366
1368 YF_API YB_NONNULL(1, 2) bool
1369 HaveSameContents(const char*, const char*, mode_t = DefaultPMode());
1371 YF_API YB_NONNULL(1, 2) bool
1372 HaveSameContents(const char16_t*, const char16_t*, mode_t = DefaultPMode());
1374
1380 YF_API bool
1381 HaveSameContents(UniqueFile, UniqueFile, const char*, const char*);
1383
1390 yconstfn YB_PURE PDefH(bool, IsNodeShared, const FileNodeID& x,
1391 const FileNodeID& y) ynothrow
1392 ImplRet(x != FileNodeID() && x == y)
1399 YF_API YB_NONNULL(1, 2) bool
1400 IsNodeShared(const char*, const char*, bool = true) ynothrowv;
1401 YF_API YB_NONNULL(1, 2) bool
1402 IsNodeShared(const char16_t*, const char16_t*, bool = true) ynothrowv;
1404
1408 bool
1409 IsNodeShared(FileDescriptor, FileDescriptor) ynothrow;
1411
1412 } // namespace platform;
1413
1414 namespace platform_ex
1415 {
1416
1418
1419 #if YCL_Win32
1420
1425 inline YB_NONNULL(1) PDefH(wstring, MakePathStringW, const wchar_t* s)
1427 ImplRet(platform::Nonnull(s))
1428 inline PDefH(const wstring&, MakePathStringW, const wstring& s)
1429 ImplRet(s)
1431 YF_API YB_NONNULL(1) wstring
1432 MakePathStringW(const char*);
1433 inline PDefH(wstring, MakePathStringW, string_view sv)
1434 ImplRet(MakePathStringW(sv.data()))
1436 #else
1437
1442 inline YB_NONNULL(1) PDefH(u16string, MakePathStringU, const char16_t* s)
1444 ImplRet(platform::Nonnull(s))
1445 inline PDefH(const u16string&, MakePathStringU, const u16string& s)
1446 ImplRet(s)
1448 YF_API YB_NONNULL(1) u16string
1449 MakePathStringU(const char*);
1450 inline PDefH(u16string, MakePathStringU, string_view sv)
1451 ImplRet(MakePathStringU(sv.data()))
1453 #endif
1454
1455
1456 } // namespace platform_ex;
1457
1458 #endif
1459
platform::path
_tString && path
Definition: YCLib/FileSystem.h:285
platform::containers::wstring
basic_string< wchar_t > wstring
Definition: Container.h:108
platform::FileDescriptor
文件描述符包装类。
Definition: FileIO.h:146
yconstfn
#define yconstfn
指定编译时常量函数。
Definition: ydef.h:680
platform::containers::u16string
basic_string< char16_t > u16string
Definition: Container.h:103
platform::HaveSameContents
YF_API bool HaveSameContents(UniqueFile, UniqueFile, const char *, const char *)
Definition: FileIO.cpp:1242
ystdex::dep_ops::totally_ordered
details::flat_ops< _type, _type2, _tOpt, less_than_comparable, equality_comparable > totally_ordered
Definition: operators.hpp:367
DefDelCopyAssignment
#define DefDelCopyAssignment(_t)
Definition: YBaseMacro.h:188
platform
默认平台命名空间。
Definition: Container.h:47
YSLib::UI::y
SPos SPos y
Definition: YWidget.cpp:44
NPL::x
const TermNode &term ynothrow const TermNode &term ynothrow const TermNode &term ynothrow TermNode &term const TermNode &term ValueNode &node const ValueNode &node const _type & x
Definition: SContext.h:94
platform::size_t
YF_API size_t
Definition: FileIO.h:1353
yfsig
#define yfsig
展开为表示函数签名的预定义变量的宏。
Definition: ydef.h:728
YSLib::Drawing::r
The boundary is out of the const Graphics const Rect const Point const Point Color c const Rect const Rect & r
Definition: YDraw.h:174
ystdex::u16string_view
basic_string_view< char16_t > u16string_view
Definition: string_view.hpp:416
platform::omode_conv
int omode_conv(std::ios_base::openmode mode) ynothrow
Definition: FileIO.cpp:796
DefSwap
#define DefSwap(_q, _t)
交换成员。
Definition: YBaseMacro.h:304
platform::uunlink
bool uunlink(const char *path) ynothrowv
Definition: FileIO.cpp:1073
platform::MakePathString
MakePathString
Definition: FileIO.h:62
platform::ugetcwd
char * ugetcwd(char *buf, size_t size) ynothrowv
Definition: FileIO.cpp:965
yimpl
#define yimpl(...)
实现标签。
Definition: ydef.h:262
platform::PDefH
const string const char *sig PDefH(string, ComposeMessageWithSignature, const char *msg, const char *sig) ImplRet(string(Nonnull(msg))+" @ "+Nonnull(sig)) template< class _type > inline YB_NONNULL(2) string ComposeMessageWithSignature(const _type &msg
platform::UniqueFile
unique_ptr_from< FileDescriptor::Deleter > UniqueFile
Definition: FileIO.h:464
platform::omode_convb
std::ios_base::sync_with_stdio(sync)) YF_API YB_STATELESS int omode_conv(std YF_API YB_STATELESS int omode_convb(std::ios_base::openmode) ynothrow
ISO C++ 标准输入输出接口打开模式转换为 POSIX 文件打开模式。
Definition: FileIO.cpp:840
platform::FetchCurrentWorkingDirectory
basic_string< _tChar > FetchCurrentWorkingDirectory(size_t init)
尝试按指定的起始缓冲区大小取当前工作目录的路径。
Definition: FileIO.h:1135
DefDeCopyMoveCtorAssignment
#define DefDeCopyMoveCtorAssignment(_t)
Definition: YBaseMacro.h:202
yconstexpr
#define yconstexpr
指定编译时常量表达式。
Definition: ydef.h:679
ystdex::nullptr
const class ystdex::nullptr_t nullptr
YSLib::Text::buf
const char * buf
Definition: TextFile.h:81
YSLib::IO::FileDescriptor
YF_API const char *YF_API FileDescriptor
Definition: YSLib/Service/FileSystem.h:740
ystdex::data
auto data(_tRange &c) -> decltype(c.data())
Definition: range.hpp:280
platform::FileDescriptor::FileDescriptor
yconstfn FileDescriptor(nullptr_t) ynothrow
Definition: FileIO.h:174
platform::ImplRet
const string const char *sig ImplRet(msg+" @ "+Nonnull(sig)) inline YB_NONNULL(1
ystdex::enable_for_string_class_t
enable_if_t< is_string_class< decay_t< _tParam >>::value, _type > enable_for_string_class_t
选择字符串类类型的特定重载避免和其它非字符串类型冲突。
Definition: string.hpp:274
ystdex::cpp2011::end
_type * end(_type(&&array)[_vN])
Definition: range.hpp:54
yunseq
#define yunseq
无序列依赖表达式组求值。
Definition: ydef.h:1022
YB_PURE
#define YB_PURE
指示函数或函数模板实例为纯函数。
Definition: ydef.h:527
platform::uopen
int uopen(const char *filename, int oflag, mode_t pmode) ynothrowv
Definition: FileIO.cpp:873
platform::EnsureUniqueFile
UniqueFile EnsureUniqueFile(const char *dst, mode_t mode, size_t allowed_links, bool share)
Definition: FileIO.cpp:1201
YB_ATTR_returns_nonnull
#define YB_ATTR_returns_nonnull
指示返回非空属性。
Definition: ydef.h:413
ystdex::throw_error
void throw_error(std::error_code ec, _tParams &&...args)
抛出错误： std::system_error 或允许相同构造函数参数的异常。
Definition: ystdex/exception.h:206
platform::urmdir
bool urmdir(const char *path) ynothrowv
Definition: FileIO.cpp:1071
DefDeCtor
#define DefDeCtor(_t)
简单通用成员函数定义。
Definition: YBaseMacro.h:157
DefDelCopyCtor
#define DefDelCopyCtor(_t)
Definition: YBaseMacro.h:164
CHRLib::s
_tDst const _tSrc * s
Definition: CharacterProcessing.h:140
platform::if
if(!p) p
DefDeDtor
#define DefDeDtor(_t)
Definition: YBaseMacro.h:177
platform::ynothrowv
YF_API int amode ynothrowv
Definition: FileIO.h:528
YF_API
#define YF_API
Definition: Platform.h:56
platform::YB_NONNULL
YB_NONNULL(2) PDefH(string
组合消息和函数签名字符串。
YModules.h
platform::oflag
YF_API int oflag
Definition: FileIO.h:542
platform::SetBinaryIO
YF_API void SetBinaryIO(std::FILE *) ynothrowv
设置标准库流二进制输入/输出模式。
Definition: FileIO.cpp:784
platform::GetFileModificationAndAccessTimeOf
GetFileModificationAndAccessTimeOf
Definition: FileIO.h:1312
ystdex::setstate
void setstate(std::basic_ios< _tChar, _tTraits > &ios, std::ios_base::iostate state)
设置流状态。
Definition: ios.hpp:44
platform::ufopen
std::FILE * ufopen(const char *filename, const char *mode) ynothrowv
Definition: FileIO.cpp:898
platform::uremove
bool uremove(const char *path) ynothrowv
Definition: FileIO.cpp:1083
ystdex::swap
void swap(container_adaptor< _tSeqCon > &x, container_adaptor< _tSeqCon > &y)
Definition: container.hpp:179
ystdex::exclude_self_t
enable_if_t<!is_same< _tClass &, decay_t< _tParam > & >::value, _type > exclude_self_t
移除选择类类型的特定重载避免构造模板和复制/转移特殊成员函数冲突。
Definition: type_traits.hpp:748
std
Definition: memory.hpp:1183
platform::FileDescriptor::Deleter
删除器。
Definition: FileIO.h:153
ystdex::byte
unsigned char byte
字节类型。
Definition: ydef.h:834
cstdio.h
platform::pmode
YF_API int mode_t pmode
Definition: FileIO.h:542
platform::Nonnull
_type && Nonnull(_type &&p) ynothrowv
断言并返回非空参数。
Definition: Debug.h:422
DefCvt
#define DefCvt(_q, _t,...)
Definition: YBaseMacro.h:206
ystdex::single_thread::try_lock
int try_lock(_tLock1 &&, _tLock2 &&, _tLocks &&...)
Definition: pseudo_mutex.h:983
utility.hpp
实用设施。
platform_ex
平台扩展命名空间。
Definition: Android.h:45
platform::umkdir
bool umkdir(const char *path) ynothrowv
Definition: FileIO.cpp:1063
yforward
#define yforward(_expr)
根据参数类型使用 std::forward 传递对应参数。
Definition: ydef.h:995
platform::GetFileAccessTimeOf
GetFileAccessTimeOf
Definition: FileIO.h:1272
platform::uchdir
bool uchdir(const char *path) ynothrowv
Definition: FileIO.cpp:1061
YPP_Comma
#define YPP_Comma
替换为逗号的预处理记号。
Definition: ydef.h:225
ystdex::single_thread::lock
void lock(_tLock1 &&, _tLock2 &&, _tLocks &&...)
Definition: pseudo_mutex.h:990
CHRLib::char16_t
char16_t((*c_ptr<< CHAR_BIT)|c_ptr[1])) inline PDefH(char16_t
取 c_ptr 指向的小端序双字节字符。
platform::CategorizeNode
enum NodeCategory std::uint_least32_t YF_API NodeCategory CategorizeNode(mode_t) ynothrow
文件节点类别。
Definition: FileIO.cpp:388
platform::ufexists
bool ufexists(const char *filename) ynothrowv
Definition: FileIO.cpp:948
ystdex::size
auto size(const _tRange &c) -> decltype(c.size())
类容器访问。
Definition: range.hpp:233
platform::GetFileModificationTimeOf
GetFileModificationTimeOf
Definition: FileIO.h:1291
platform::references::unique_ptr_from
unique_ptr< ystdex::defer_element< ystdex::unique_ptr_pointer< void, _tDeleter >, _tDefault >, _tDeleter > unique_ptr_from
取删除器对应的 unique_ptr 实例。
Definition: Reference.h:99
platform_ex::MakePathStringU
MakePathStringU
Definition: FileIO.h:1443
platform::mode_t
::mode_t mode_t
文件模式类型。
Definition: FileIO.h:114
ystdex::openmode_conv
const char * openmode_conv(std::ios_base::openmode)
ISO C/C++ 标准输入输出接口打开模式转换。
Definition: cstdio.cpp:68
platform::DefaultPMode
YF_API YB_STATELESS mode_t DefaultPMode() ynothrow
取默认权限。
Definition: FileIO.cpp:772
platform::uaccess
int uaccess(const char *path, int amode) ynothrowv
Definition: FileIO.cpp:848
ystdex::string_view
basic_string_view< char > string_view
Definition: string_view.hpp:415
platform::IsNodeShared
bool IsNodeShared(FileDescriptor, FileDescriptor) ynothrow
Definition: FileIO.cpp:1285
CHRLib::p
const auto p(d)
fp
tidy_ptr< std::streambuf > fp
Definition: TextManager.cpp:93
platform::ynothrow
const _tString &path ynothrow
Definition: YCLib/FileSystem.h:274
YB_STATELESS
#define YB_STATELESS
指示函数或函数模板实例为无状态函数。
Definition: ydef.h:548