YSTest: cstdio.cpp 源文件

YSTest PreAlpha_b700_20160611 The YSLib Test Project

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

- 文件列表
- 文件成员

cstdio.cpp
浏览该文件的文档.
1 /*
2 © 2009-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 #include "ystdex/cstdio.h" // for ystdex::call_value_or;
29 #include "ystdex/cassert.h"
30 #include <libdefect/string.h> // for std::char_traits<char>::length and
31 // possible fix for std::vsnprintf;
32 #include "ystdex/functional.hpp" // for ystdex::compose, addrof;
33 #include "ystdex/algorithm.hpp" // for ystdex::trivially_copy_n;
34
35 namespace ystdex
36 {
37
38 size_t
39 vfmtlen(const char* fmt, std::va_list args) ynothrow
40 {
41 yconstraint(fmt);
42
43 const int l(std::vsnprintf({}, 0, fmt, args));
44
45 return size_t(l < 0 ? -1 : l);
46 }
47 size_t
48 vfmtlen(const wchar_t* fmt, std::va_list args) ynothrow
49 {
50 yconstraint(fmt);
51
52 const int l(std::vswprintf({}, 0, fmt, args));
53
54 return size_t(l < 0 ? -1 : l);
55 }
56
57
58 bool
59 fexists(const char* path) ynothrow
60 {
61 yconstraint(path);
62 return ystdex::call_value_or(ystdex::compose(std::fclose, addrof<>()),
63 std::fopen(path, "rb"), yimpl(1)) == 0;
64 }
65
66
67 const char*
68 openmode_conv(std::ios_base::openmode mode) ynothrow
69 {
70 using namespace std;
71
72 switch(unsigned((mode &= ~ios_base::ate) & ~ios_base::binary))
73 {
74 case ios_base::out:
75 case ios_base::out | ios_base::trunc:
76 return mode & ios_base::binary ? "wb" : "w";
77 case ios_base::out | ios_base::app:
78 case ios_base::app:
79 return mode & ios_base::binary ? "ab" : "a";
80 case ios_base::in:
81 return mode & ios_base::binary ? "rb" : "r";
82 case ios_base::in | ios_base::out:
83 return mode & ios_base::binary ? "r+b" : "r+";
84 case ios_base::in | ios_base::out | ios_base::trunc:
85 return mode & ios_base::binary ? "w+b" : "w+";
86 case ios_base::in | ios_base::out | ios_base::app:
87 case ios_base::in | ios_base::app:
88 return mode & ios_base::binary ? "a+b" : "a+";
89 default:
90 break;
91 }
92 return {};
93 }
94 std::ios_base::openmode
95 openmode_conv(const char* str) ynothrow
96 {
97 using namespace std;
98
99 if(str)
100 {
101 ios_base::openmode mode;
102
103 switch(*str)
104 {
105 case 'w':
106 mode = ios_base::out | ios_base::trunc;
107 break;
108 case 'r':
109 mode = ios_base::in;
110 break;
111 case 'a':
112 mode = ios_base::app;
113 break;
114 default:
115 goto invalid;
116 }
117 if(str[1] != char())
118 {
119 auto l(char_traits<char>::length(str));
120
121 if(str[l - 1] == 'x')
122 {
123 if(mode & ios_base::out)
124 mode &= ~ios_base::out;
125 else
126 goto invalid;
127 --l;
128 }
129
130 bool b(str[1] == 'b'), p(str[1] == '+');
131
132 switch(l)
133 {
134 case 2:
135 if(b != p)
136 break;
137 goto invalid;
138 case 3:
139 yunseq(b = b != (str[2] == 'b'), p = p != (str[2] == '+'));
140 if(b && p)
141 break;
142 default:
143 goto invalid;
144 }
145 if(p)
146 mode |= *str == 'r' ? ios::out : ios::in;
147 if(b)
148 mode |= ios::binary;
149 }
150 return mode;
151 }
152 invalid:
153 return ios_base::openmode();
154 }
155
156
157 ifile_iterator&
158 ifile_iterator::operator++()
159 {
160 yassume(stream);
161
162 const auto val(std::fgetc(stream));
163
164 if(YB_UNLIKELY(val == EOF))
165 stream = {};
166 else
167 {
168 yassume(byte(val) == val);
169 value = byte(val);
170 }
171 return *this;
172 }
173
174
175 void
176 block_buffer::fill(size_t offset, size_t n, byte value) ynothrowv
177 {
178 yconstraint(get());
179
180 yunseq(ystdex::trivially_fill_n(get() + offset, n, value),
181 need_flush = true);
182 }
183
184 void
185 block_buffer::read(void* dst, size_t offset, size_t n) const ynothrowv
186 {
187 yunseq((yconstraint(get()), 0), (yconstraint(dst), 0));
188
189 ystdex::trivially_copy_n(get() + offset, n, static_cast<byte*>(dst));
190 }
191
192 void
193 block_buffer::write(size_t offset, const void* src, size_t n) ynothrowv
194 {
195 yunseq((yconstraint(get()), 0), (yconstraint(src), 0));
196
197 yunseq(ystdex::trivially_copy_n(static_cast<const byte*>(src), n,
198 get() + offset), need_flush = true);
199 }
200
201 } // namespace ystdex;
202
yassume
#define yassume(_expr)
假定：环境语义。
Definition: cassert.h:99
platform::p
while p p
Definition: YCLib/FileSystem.h:225
ystdex::trivially_fill_n
_type * trivially_fill_n(_type *first, size_t n=1, byte value={})
填充字节序列。
Definition: algorithm.hpp:363
ystdex::block_buffer::write
void write(size_t offset, const void *src, size_t n)
写入外部字节序列的内容到缓冲区。
Definition: cstdio.cpp:193
ynothrow
#define ynothrow
YSLib 无异常抛出保证：若支持 noexcept 关键字， 指定特定的 noexcept 异常规范。
Definition: ydef.h:740
yconstraint
#define yconstraint(_expr)
约束：接口语义。
Definition: cassert.h:82
ystdex::ifile_iterator::operator++
ifile_iterator & operator++()
前置自增。
Definition: cstdio.cpp:158
cassert.h
ISO C 断言/调试跟踪扩展。
cstdio.h
ynothrowv
#define ynothrowv
YSLib 无异常抛出保证验证：有条件地使用无异常抛出规范。
Definition: ydef.h:760
platform::size_t
YF_API size_t
Definition: FileIO.h:1262
ystdex::ifile_iterator::stream
std::FILE * stream
流指针。
Definition: ystdex/cstdio.h:139
yimpl
#define yimpl(...)
实现标签。
Definition: ydef.h:256
ystdex::fexists
bool fexists(const char *)
判断指定路径的文件是否存在。
Definition: cstdio.cpp:59
YB_UNLIKELY
#define YB_UNLIKELY(_expr)
分支预测提示。
Definition: ydef.h:438
ystdex::block_buffer::read
void read(void *dst, size_t offset, size_t n) const
读取缓冲区内容到外部存储。
Definition: cstdio.cpp:185
NPL::dst
YF_API const char src const string const char * dst
Definition: Dependency.h:93
functional.hpp
函数和可调用对象。
std
Definition: memory.hpp:1100
ystdex::block_buffer::fill
void fill(size_t offset, size_t n=1, byte value={})
填充字节到缓冲区。
Definition: cstdio.cpp:176
yunseq
#define yunseq
无序列依赖表达式组求值。
Definition: ydef.h:996
ystdex::path
一般路径模板。
Definition: path.hpp:123
ystdex
特性测试宏。
Definition: ydef.h:796
YSLib::Text::str
const char const char * str
Definition: TextFile.h:77
string.h
标准库实现 修正。
ystdex::byte
unsigned char byte
字节类型。
Definition: ydef.h:808
ystdex::openmode_conv
const char * openmode_conv(std::ios_base::openmode)
ISO C/C++ 标准输入输出接口打开模式转换。
Definition: cstdio.cpp:68
ystdex::call_value_or
auto call_value_or(_func f, _type p, _tOther &&other={}) -> decltype(p?f(*p):other)
调用非空值或取默认值。
Definition: deref_op.hpp:100
ystdex::trivially_copy_n
_type * trivially_copy_n(const _type *first, size_t n, _type *result)
复制不覆盖的序列。
Definition: algorithm.hpp:388
ystdex::addrof
一元 & 操作。
Definition: functor.hpp:416
ystdex::compose
auto compose(_func1 f, _func2 g, _funcs...args) -> decltype(ystdex::compose(ystdex::compose(f, g), args...))
Definition: functional.hpp:646
ystdex::ifile_iterator::value
char_type value
Definition: ystdex/cstdio.h:140
CHRLib::args
_tParams && args
Definition: CharacterProcessing.h:538
ystdex::vfmtlen
size_t vfmtlen(const char *, std::va_list)
计算指定格式字符串输出的占用的字节数。
Definition: cstdio.cpp:39
algorithm.hpp
泛型算法。
platform::n
size_t n
Definition: YCLib/FileSystem.cpp:321