YSTest: smap.hpp 源文件

YSTest PreAlpha_b500_20140530 The YSLib Test Project

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

- 文件列表
- 文件成员

全部 类 命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 宏定义 组 页
smap.hpp
浏览该文件的文档.
1 /*
2 © 2009-2014 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 INC_CHRLib_smap_hpp_
29 #define INC_CHRLib_smap_hpp_ 1
30
31 #include "YModules.h"
32 #include YFM_CHRLib_CharacterMapping
33 #include <ystdex/cstdio.h>
34 #include <ystdex/any.h> // for ystdex::pseudo_object;
35
36 namespace CHRLib
37 {
38
43 template<typename _tIn, typename _tState>
44 inline bool
45 FillByte(_tIn& i, _tState& st)
46 {
47 static_assert(std::is_constructible<const byte, decltype(*i)>::value,
48 "Invalid mapping source type found.");
49 static_assert(!std::is_volatile<ystdex::remove_reference_t<_tState>>::value,
50 "Volatile state is not supported.");
51
52 if(YB_UNLIKELY(is_undereferenceable(i)))
53 return false;
54
55 const byte r(*i);
56
57 yunseq(++i, GetSequenceOf(st)[GetCountOf(st)++] = r);
58 return true;
59 }
60
61
67 template<Encoding>
68 class GUCS2Mapper
69 {};
70
71 template<>
72 struct GUCS2Mapper<CharSet::UTF_8>
73 {
78 static yconstfn bool
79 IsInvalid(byte b)
80 {
81 return b == 0xC0 || b == 0xC1 || b > 0xF4;
82 }
83
92 template<typename _tObj, typename _tIn, typename _tState>
93 static ConversionResult
94 Map(_tObj& uc, _tIn&& i, _tState&& st)
95 {
96 const auto seq(GetSequenceOf(st));
97
98 switch(GetCountOf(st))
99 {
100 case 0:
101 if(YB_UNLIKELY(!FillByte(i, st)))
102 return ConversionResult::BadSource;
103 if(seq[0] < 0x80)
104 {
105 uc = seq[0];
106 break;
107 }
108 if(YB_UNLIKELY(IsInvalid(seq[0]) || ((seq[0] & 0xC0) != 0xC0)))
109 return ConversionResult::Invalid;
110 case 1:
111 if(YB_UNLIKELY(!FillByte(i, st)))
112 return ConversionResult::BadSource;
113 if(YB_UNLIKELY(IsInvalid(seq[1]) || ((seq[1] & 0xC0) != 0x80)))
114 return ConversionResult::Invalid;
115 if(((seq[0] ^ 0xC0) & 0xE0) == 0)
116 {
117 uc = ((seq[0] & 0x1C) >> 2 << 8)
118 | ((seq[0] & 0x03) << 6)
119 | (seq[1] & 0x3F);
120 break;
121 }
122 case 2:
123 if(YB_UNLIKELY(!FillByte(i, st)))
124 return ConversionResult::BadSource;
125 if(YB_UNLIKELY(IsInvalid(seq[2]) || ((seq[2] & 0xC0) != 0x80)))
126 return ConversionResult::Invalid;
127 if(((seq[0] ^ 0xE0) & 0xF0) == 0)
128 {
129 uc = (((seq[0] & 0x0F) << 4 | (seq[1] & 0x3C) >> 2) << 8)
130 | ((seq[1] & 0x3) << 6) | (seq[2] & 0x3F);
131 break;
132 }
133 case 3:
134 if(YB_UNLIKELY(!FillByte(i, st)))
135 return ConversionResult::BadSource;
136 if(YB_UNLIKELY(IsInvalid(seq[3]) || ((seq[3] & 0xC0) != 0x80)))
137 return ConversionResult::Invalid;
138 if(YB_LIKELY(((seq[0] ^ 0xF0) & 0xF8) == 0))
139 {
140 uc = (((seq[0] & 0x0F) << 4 | (seq[1] & 0x3C) >> 2) << 8)
141 | ((seq[1] & 0x3) << 6) | (seq[2] & 0x3F);
142 break;
143 }
144 return ConversionResult::Unhandled;
145 default:
146 return ConversionResult::BadState;
147 }
148 return ConversionResult::OK;
149 }
150
151 template<typename _tOut>
152 static byte
153 InverseMap(_tOut d, const ucs2_t& s)
154 {
155 size_t l(0);
156
157 if(s < 0x80)
158 {
159 *d = s;
160 return 1;
161 }
162 if(s < 0x800)
163 l = 2;
164 else
165 {
166 *d = 0xE0 | s >> 12;
167 ++d;
168 l = 3;
169 }
170 *d = 0x80 | (s >> 6 & 0x3F);
171 *++d = 0x80 | (s & 0x3F);
172 return l;
173 }
174 };
175
176 template<>
177 struct GUCS2Mapper<CharSet::UTF_16BE>
178 {
179 template<typename _tObj, typename _tIn, typename _tState>
180 static ConversionResult
181 Map(_tObj& uc, _tIn&& i, _tState&& st)
182 {
183 const auto seq(GetSequenceOf(st));
184
185 switch(GetCountOf(st))
186 {
187 case 0:
188 if(YB_UNLIKELY(!FillByte(i, st)))
189 return ConversionResult::BadSource;
190 case 1:
191 if(YB_UNLIKELY(!FillByte(i, st)))
192 return ConversionResult::BadSource;
193 uc = seq[0] << 8 | seq[1];
194 break;
195 default:
196 return ConversionResult::BadState;
197 }
198 return ConversionResult::OK;
199 }
200 };
201
202 template<>
203 struct GUCS2Mapper<CharSet::UTF_16LE>
204 {
205 template<typename _tObj, typename _tIn, typename _tState>
206 static ConversionResult
207 Map(_tObj& uc, _tIn&& i, _tState&& st)
208 {
209 const auto seq(GetSequenceOf(st));
210
211 switch(GetCountOf(st))
212 {
213 case 0:
214 if(YB_UNLIKELY(!FillByte(i, st)))
215 return ConversionResult::BadSource;
216 case 1:
217 if(YB_UNLIKELY(!FillByte(i, st)))
218 return ConversionResult::BadSource;
219 uc = seq[0] | seq[1] << 8;
220 break;
221 default:
222 return ConversionResult::BadState;
223 }
224 return ConversionResult::OK;
225 }
226 };
228
229
235 template<Encoding, typename... _tParams>
236 yconstfn ConversionResult
237 UCS2Mapper_Map(_tParams&&...)
238 {
239 return ConversionResult::Unhandled;
240 }
241 template<Encoding _vEnc, typename _tDst, typename _tSrc, typename _tState>
242 yconstfn ConversionResult
243 UCS2Mapper_Map(_tDst&& d, _tSrc&& s, _tState&& st, decltype(
244 &GUCS2Mapper<_vEnc>::template Map<_tDst, _tSrc, _tState>) = {})
245 {
246 return GUCS2Mapper<_vEnc>::Map(d, s, st);
247 }
248
249 template<Encoding _vEnc, typename _tDst, typename _tSrc>
250 yconstfn byte
251 UCS2Mapper_InverseMap(_tDst, _tSrc)
252 {
253 return 0;
254 }
255 template<Encoding _vEnc, typename _tDst>
256 yconstfn byte
257 UCS2Mapper_InverseMap(_tDst&& d, const ucs2_t& s,
258 decltype(&GUCS2Mapper<_vEnc>::template InverseMap<_tDst>) = {})
259 {
260 return GUCS2Mapper<_vEnc>::InverseMap(d, s);
261 }
262
263
264 template<Encoding _vEnc, typename _tIn, typename _tState>
265 yconstexpr ConversionResult
266 UCS2Mapper(ucs2_t& uc, _tIn&& i, _tState&& st)
267 {
268 return UCS2Mapper_Map<_vEnc>(uc, i, std::move(st));
269 }
270 template<Encoding _vEnc, typename _tIn, typename _tState>
271 yconstexpr ConversionResult
272 UCS2Mapper(_tIn&& i, _tState&& st)
273 {
274 return UCS2Mapper_Map<_vEnc>(ystdex::pseudo_output(), i, st);
275 }
276 template<Encoding _vEnc>
277 byte
278 UCS2Mapper(char* d, const ucs2_t& s)
279 {
280 yconstraint(d);
281 return UCS2Mapper_InverseMap<_vEnc>(d, s);
282 }
284
285 } // namespace CHRLib;
286
287 #endif
288
CHRLib::UCS2Mapper_Map
yconstfn ConversionResult UCS2Mapper_Map(_tParams &&...)
取映射函数。
Definition: smap.hpp:237
CHRLib::ConversionResult
ConversionResult
编码转换结果。
Definition: chrmap.h:75
CHRLib::GUCS2Mapper< CharSet::UTF_16LE >::Map
static ConversionResult Map(_tObj &uc, _tIn &&i, _tState &&st)
Definition: smap.hpp:207
cstdio.h
ISO C 标准输入/输出扩展。
CHRLib::CharSet::UTF_16LE
yconstexpr Encoding UTF_16LE(csUTF16LE)
CHRLib::FillByte
bool FillByte(_tIn &i, _tState &st)
以输入迭代器指向内容填充有效输入迭代器指定的字节。
Definition: smap.hpp:45
CHRLib::CharSet::UTF_16BE
yconstexpr Encoding UTF_16BE(csUTF16BE)
CHRLib::GUCS2Mapper
静态编码映射模板及 Unicode 编码特化。
Definition: smap.hpp:68
CHRLib::GUCS2Mapper< CharSet::UTF_8 >::IsInvalid
static yconstfn bool IsInvalid(byte b)
检查 UTF-8 文本序列中非法字节。
Definition: smap.hpp:79
ystdex::remove_reference_t
typename remove_reference< _type >::type remove_reference_t
Definition: type_op.hpp:234
platform_ex::Windows::l
l
Definition: MinGW32.cpp:50
CHRLib::GUCS2Mapper< CharSet::UTF_8 >::Map
static ConversionResult Map(_tObj &uc, _tIn &&i, _tState &&st)
映射： UTF-8 。
Definition: smap.hpp:94
ystdex::byte
unsigned char byte
字节类型。
Definition: ydef.h:555
CHRLib::ConversionResult::Invalid
数据校验失败（如不构成代码点的字节序列）。
CHRLib::GUCS2Mapper< CharSet::UTF_16BE >::Map
static ConversionResult Map(_tObj &uc, _tIn &&i, _tState &&st)
Definition: smap.hpp:181
CHRLib::ConversionResult::OK
转换成功。
YB_UNLIKELY
#define YB_UNLIKELY(expr)
分支预测提示。
Definition: ydef.h:298
yunseq
#define yunseq
无序列依赖表达式组求值。
Definition: ydef.h:748
CHRLib::ConversionResult::BadSource
源数据不可达（如越界）。
yconstraint
#define yconstraint
约束：接口语义。
Definition: cassert.h:47
yconstfn
#define yconstfn
指定编译时常量函数。
Definition: ydef.h:463
CHRLib::GUCS2Mapper< CharSet::UTF_8 >::InverseMap
static byte InverseMap(_tOut d, const ucs2_t &s)
Definition: smap.hpp:153
CHRLib::ConversionResult::BadState
转换状态错误。
any.h
动态泛型类型。
platform_ex::Windows::s
return s
Definition: MinGW32.cpp:49
CHRLib::ucs2_t
char16_t ucs2_t
UCS-2 字符类型。
Definition: chrdef.h:44
yconstexpr
#define yconstexpr
指定编译时常量表达式。
Definition: ydef.h:462
ystdex::is_undereferenceable
bool is_undereferenceable(const any_input_iterator< _type, _tDifference, _tPointer, _tReference > &i)
Definition: any_iterator.hpp:364
CHRLib::Encoding
std::FILE Encoding
Definition: chrproc.h:85
CHRLib::UCS2Mapper
yconstexpr ConversionResult UCS2Mapper(ucs2_t &uc, _tIn &&i, _tState &&st)
Definition: smap.hpp:266
YSLib::Drawing::r
bounds & r
Definition: ydraw.h:220
YB_LIKELY
#define YB_LIKELY(expr)
Definition: ydef.h:297
CHRLib::CharSet::UTF_8
yconstexpr Encoding UTF_8(csUTF8)
CHRLib::ConversionResult::Unhandled
未处理（超过被处理的界限）。
YModules.h
ystdex::pseudo_output
伪输出对象。
Definition: any.h:865
CHRLib::UCS2Mapper_InverseMap
yconstfn byte UCS2Mapper_InverseMap(_tDst, _tSrc)
Definition: smap.hpp:251