YSTest: textmgr.cpp 源文件

YSTest PreAlpha_b500_20140530 The YSLib Test Project

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

- 文件列表
- 文件成员

全部 类 命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 宏定义 组 页
textmgr.cpp
浏览该文件的文档.
1 /*
2 © 2010-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 #include "YSLib/Service/YModules.h"
29 #include YFM_YSLib_Service_TextManager
30 #include YFM_CHRLib_MappingEx
31 #include <ystdex/any_iterator.hpp>
32 #include YFM_CHRLib_Convert
33
34 namespace YSLib
35 {
36
37 namespace Text
38 {
39
40 namespace
41 {
42
44 yconstexpr auto& FetchMapperFunc(FetchMapperPtr<ConversionResult(ucs2_t&,
45 ystdex::input_monomorphic_iterator&&, ConversionState&&)>);
47 yconstexpr auto& FetchSkipMapperFunc(FetchMapperPtr<ConversionResult(
48 ystdex::input_monomorphic_iterator&&, ConversionState&&)>);
49
50 } // unnamed namespace;
51
52
53 TextFileBuffer::iterator::iterator(TextFileBuffer* p_buf, size_t b, size_t idx)
54 ynothrow
55 : p_buffer(p_buf), block(b), index(idx)
56 {}
57
58 TextFileBuffer::iterator&
59 TextFileBuffer::iterator::operator++() ynothrow
60 {
61 YAssertNonnull(p_buffer);
62 YAssert(block < p_buffer->nBlock, "End iterator found.");
63
64 auto& vec((*p_buffer)[block].first);
65
66 YAssert(index < vec.size(), "Invalid index found.");
67 if(YB_UNLIKELY(++index == vec.size()))
68 yunseq(++block, index = 0);
69 return *this;
70 }
71
72 TextFileBuffer::iterator&
73 TextFileBuffer::iterator::operator--() ynothrow
74 {
75 YAssert(p_buffer, "Null buffer pointer found.");
76 YAssert(block != 0 || index != 0, "Begin iterator found."),
77 YAssert(block < p_buffer->nBlock || *this == p_buffer->end(),
78 "Invalid iterator found.");
79 if(index == 0)
80 {
81 index = (*p_buffer)[--block].first.size();
82
83 YAssert(index != 0, "Invalid index found.");
84 }
85 else
86 YAssert(index < (*p_buffer)[block].first.size(),
87 "Invalid index found.");
88 --index;
89 return *this;
90 }
91
92 TextFileBuffer::iterator::reference
93 TextFileBuffer::iterator::operator*() const
94 {
95 YAssertNonnull(p_buffer);
96
97 auto& vec((*p_buffer)[block].first);
98
99 YAssert(!vec.empty(), "Empty block found.");
100 YAssert(index < vec.size(), "Invalid index found.");
101 return vec[index];
102 }
103
104 bool
105 operator==(const TextFileBuffer::iterator& x, const TextFileBuffer::iterator& y)
106 ynothrow
107 {
108 YAssert(x.p_buffer == y.p_buffer, "Iterators to different buffer are not"
109 " comparable.");
110
111 return x.block == y.block && x.index == y.index;
112 }
113
114
115 TextFileBuffer::TextFileBuffer(TextFile& file)
116 : File(file), nTextSize(File.GetTextSize()),
117 nBlock((nTextSize + BlockSize - 1) / BlockSize), Map(),
118 fixed_width(FetchFixedCharWidth(File.Encoding)), max_width(fixed_width
119 == 0 ? FetchMaxVariantCharWidth(File.Encoding) : fixed_width)
120 {
121 YAssert(max_width != 0, "Unknown encoding found.");
122
123 if(fixed_width == 0)
124 ++fixed_width;
125 // TODO: Implementation for non-fixed-width char streams.
126 }
127
128 TextFileBuffer::BlockType&
129 TextFileBuffer::operator[](size_t idx)
130 {
131 YAssert(idx < nBlock, "Invalid index found.");
132
133 auto& b(Map[idx]);
134 auto& vec(b.first);
135
136 if(YB_UNLIKELY(vec.empty() && bool(File)))
137 if(const auto pfun = FetchMapperFunc(File.Encoding))
138 {
139 File.Locate(idx * BlockSize);
140
141 size_t len(idx == nBlock - 1 && nTextSize % BlockSize != 0
142 ? nTextSize % BlockSize : BlockSize);
143
144 vec.reserve(len / fixed_width);
145
146 size_t n_byte(0);
147 ucs2_t c;
148 ystdex::ifile_iterator i(File.GetPtr());
149
150 while(n_byte < len)
151 {
152 ConversionState st;
153
154 if(YB_LIKELY(ConvertCharacter(pfun, c, i, std::move(st))
155 == ConversionResult::OK))
156 vec.push_back(c);
157 n_byte += GetCountOf(st);
158 }
159 std::ungetc(*i, File.GetPtr()),
160 vec.shrink_to_fit();
161 }
162 return b;
163 }
164
165 TextFileBuffer::iterator
166 TextFileBuffer::begin() ynothrow
167 {
168 return TextFileBuffer::iterator(this);
169 }
170 TextFileBuffer::iterator
171 TextFileBuffer::end() ynothrow
172 {
173 return TextFileBuffer::iterator(this, nBlock);
174 }
175 TextFileBuffer::iterator
176 TextFileBuffer::GetIterator(size_t pos)
177 {
178 if(pos < nTextSize)
179 {
180 const size_t idx(pos / BlockSize);
181
182 pos %= BlockSize;
183 if(fixed_width == max_width)
184 return TextFileBuffer::iterator(this, idx, pos / max_width);
185
186 YAssert(bool(File), "Invalid file found.");
187
188 if(const auto pfun = FetchSkipMapperFunc(File.Encoding))
189 {
190 File.Locate(idx * BlockSize);
191
192 size_t n_byte(0), n_char(0);
193 ystdex::ifile_iterator i(File.GetPtr());
194
195 while(n_byte < pos)
196 {
197 ConversionState st;
198
199 if(YB_LIKELY(ConvertCharacter(pfun, i, std::move(st))
200 == ConversionResult::OK))
201 ++n_char;
202 n_byte += GetCountOf(st);
203 }
204 std::ungetc(*i, File.GetPtr());
205 return TextFileBuffer::iterator(this, idx, n_char);
206 }
207 return TextFileBuffer::iterator(this, idx, 0);
208 }
209 return end();
210 }
211 size_t
212 TextFileBuffer::GetPosition(TextFileBuffer::iterator i)
213 {
214 if(i == end())
215 return nTextSize;
216
217 auto idx(i.GetBlockN());
218 const auto pos(i.GetIndexN());
219
220 if(fixed_width == max_width)
221 return idx * BlockSize + pos * max_width;
222
223 if(const auto pfun = FetchSkipMapperFunc(File.Encoding))
224 {
225 const auto& vec((*this)[idx].first);
226
227 YAssert(!vec.empty() && bool(File), "Block loading failed.");
228
229 File.Locate(idx *= BlockSize);
230
231 const auto mid(vec.cbegin() + pos);
232
233 YAssert(mid <= vec.cend(), "Wrong iterator found.");
234
235 auto it(vec.begin());
236
237 YAssert(it <= mid, "Wrong iterator found.");
238
239 ystdex::ifile_iterator i(File.GetPtr());
240 size_t n_byte(0);
241
242 while(it != mid)
243 {
244 ConversionState st;
245
246 if(YB_LIKELY(ConvertCharacter(pfun, i, std::move(st))
247 == ConversionResult::OK))
248 ++it;
249 n_byte += GetCountOf(st);
250 }
251 return idx + n_byte;
252 }
253 return idx;
254 }
255
256
257 string
258 CopySliceFrom(TextFileBuffer& buf, size_t pos, size_t len)
259 ythrow(std::out_of_range)
260 {
261 const auto i_end(buf.end());
262 auto i_beg(buf.GetIterator(pos));
263
264 if(i_beg == i_end)
265 throw std::out_of_range("Wrong offset found.");
266 if(len == 0)
267 return {};
268
269 YAssert(pos < pos + len, "Unexpected unsigned integer round up.");
270
271 string str;
272
273 str.reserve(len * 2);
274 while(len != 0 && i_beg != i_end)
275 {
276 str.push_back(*i_beg);
277 yunseq(++i_beg, --len);
278 }
279 return str;
280 }
281
282 } // namespace Text;
283
284 } // namespace YSLib;
285
YSLib::Text::TextFileBuffer::TextFileBuffer
TextFileBuffer(TextFile &)
构造：使用文本文件。
Definition: textmgr.cpp:115
YSLib::Text::TextFileBuffer::nBlock
size_t nBlock
区块数。
Definition: textmgr.h:137
CHRLib::ConversionResult
ConversionResult
编码转换结果。
Definition: chrmap.h:75
YSLib::Text::TextFileBuffer::iterator
目标编码迭代器类型。
Definition: textmgr.h:68
ystdex::iterator_transformation::first
static auto first(const _tIterator &i) -> decltype((i->first))
Definition: iterator.hpp:759
YSLib::Text::TextFileBuffer::GetPosition
size_t GetPosition(iterator)
取迭代器对应的文本字节位置。
Definition: textmgr.cpp:212
CHRLib::ConvertCharacter
ConversionResult ConvertCharacter(_fConv f, ucs2_t &uc, _tIn &&i, ConversionState &&st)
Definition: Convert.hpp:40
CHRLib::ConversionState
编码转换状态。
Definition: chrmap.h:89
ystdex::ifile_iterator
基于 ISO C 标准库的流只读迭代器。
Definition: cstdio.h:73
YSLib::TextFile
文本文件类。
Definition: TextFile.h:56
YSLib::Text::TextFileBuffer::iterator::operator++
iterator & operator++() ynothrow
迭代：循环向后遍历。
Definition: textmgr.cpp:59
YSLib::File
文件基类。
Definition: File.h:43
YSLib::Text::TextFileBuffer::iterator::block
size_t block
Definition: textmgr.h:78
YSLib::Text::TextFileBuffer::end
iterator end() ynothrow
取文本缓冲区终止迭代器。
Definition: textmgr.cpp:171
YSLib::Text::TextFileBuffer::max_width
size_t max_width
最大编码每字符的字节数。
Definition: textmgr.h:155
YB_UNLIKELY
#define YB_UNLIKELY(expr)
分支预测提示。
Definition: ydef.h:298
YSLib::Text::TextFileBuffer::fixed_width
size_t fixed_width
固定编码每字符的字节数。
Definition: textmgr.h:150
yunseq
#define yunseq
无序列依赖表达式组求值。
Definition: ydef.h:748
ynothrow
#define ynothrow
YSLib 无异常抛出保证：若支持 noexcept 关键字， 指定特定的 noexcept 异常规范。
Definition: ydef.h:514
YSLib::Text::TextFileBuffer::iterator::p_buffer
TextFileBuffer * p_buffer
Definition: textmgr.h:76
ythrow
#define ythrow(...)
YSLib 动态异常规范：根据是否使用异常规范宏指定或忽略动态异常规范。
Definition: ydef.h:476
CHRLib::FetchMaxVariantCharWidth
YF_API size_t FetchMaxVariantCharWidth(Encoding)
取指定变长编码的最大字符宽度。
Definition: chrmap.cpp:67
YSLib::Text::TextFileBuffer::iterator::operator--
iterator & operator--() ynothrow
迭代：循环向前遍历。
Definition: textmgr.cpp:73
YAssertNonnull
#define YAssertNonnull(_expr)
Definition: cassert.h:81
YSLib::Text::TextFileBuffer::iterator::operator*
reference operator*() const
Definition: textmgr.cpp:93
YSLib::Text::TextFileBuffer::begin
iterator begin() ynothrow
取文本缓冲区起始迭代器。
Definition: textmgr.cpp:166
CHRLib::FetchFixedCharWidth
YF_API size_t FetchFixedCharWidth(Encoding)
取指定固定编码的固定字符宽度。
Definition: chrmap.cpp:37
ystdex::any_input_iterator
动态泛型输入迭代器。
Definition: any_iterator.hpp:236
CHRLib::ucs2_t
char16_t ucs2_t
UCS-2 字符类型。
Definition: chrdef.h:44
yconstexpr
#define yconstexpr
指定编译时常量表达式。
Definition: ydef.h:462
YSLib::Text::TextFileBuffer::nTextSize
size_t nTextSize
文本大小。
Definition: textmgr.h:132
CHRLib::CharSet::Encoding
Encoding
Definition: encoding.h:53
YSLib::Text::operator==
bool operator==(const TextFileBuffer::iterator &x, const TextFileBuffer::iterator &y) ynothrow
Definition: textmgr.cpp:105
YSLib::Text::TextFileBuffer
Definition: textmgr.h:46
YB_LIKELY
#define YB_LIKELY(expr)
Definition: ydef.h:297
YSLib::Text::TextFileBuffer::BlockSize
static yconstexpr size_t BlockSize
默认文本区块大小。
Definition: textmgr.h:120
YSLib::Text::TextFileBuffer::GetIterator
File Encoding nTextSize iterator GetIterator(size_t)
取文本字节位置对应的迭代器。
Definition: textmgr.cpp:176
CHRLib::c
c
Definition: chrproc.h:76
YSLib::Text::TextFileBuffer::Map
MapType Map
缓冲映射。
Definition: textmgr.h:142
any_iterator.hpp
动态泛型迭代器。
YModules.h
YSLib::Text::TextFileBuffer::iterator::index
size_t index
Definition: textmgr.h:79
CHRLib::FetchMapperPtr
_fCodemapTransform * FetchMapperPtr(Encoding enc)
取指定编码映射的转换函数指针。
Definition: MapEx.h:217
YSLib::Text::CopySliceFrom
string CopySliceFrom(TextFileBuffer &buf, size_t pos, size_t len) ythrow(std
Definition: textmgr.cpp:258
YSLib::Text::TextFileBuffer::iterator::iterator
iterator(TextFileBuffer *={}, size_t=0, size_t=0) ynothrow
构造：指定文本读取位置。
Definition: textmgr.cpp:53
YAssert
#define YAssert(_expr, _msg)
Definition: cassert.h:73
YSLib::Text::TextFileBuffer::BlockType
pair< vector< ucs2_t >, size_t > BlockType
缓冲区块类型。
Definition: textmgr.h:55