YSTest: TextFile.cpp 源文件

YSTest PreAlpha_b500_20140530 The YSLib Test Project

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

- 文件列表
- 文件成员

全部 类 命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 宏定义 组 页
TextFile.cpp
浏览该文件的文档.
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 #include "YSLib/Service/YModules.h"
29 #include YFM_YSLib_Service_TextFile
30
31 namespace YSLib
32 {
33
34 using namespace Text;
35
36 namespace
37 {
38
39 bool
40 CheckUTF8(const char* s, const char* g)
41 {
42 while(s < g && *s != 0
43 && MBCToUC(s, CharSet::UTF_8) == ConversionResult::OK);
44 return s == g || *s == 0;
45 }
46
47 // TODO: More accurate encoding checking for text stream without BOM.
48 Encoding
49 CheckEncoding(const char* s, size_t n)
50 {
51 return CheckUTF8(s, s + n) ? CharSet::UTF_8 : CharSet::GBK;
52 }
53
54 void
55 InitializeTextFile(TextFile& tf, size_t& bl)
56 {
57 if(tf)
58 {
59 tf.Seek(0, SEEK_END);
60 bl = tf.CheckBOM(tf.Encoding);
61 tf.Rewind();
62 }
63 if(bl == 0)
64 {
65 #define YSL_TXT_CHECK_ENCODING_N 64U
66 char s[YSL_TXT_CHECK_ENCODING_N + 6];
67 const auto n(min(tf.GetTextSize(), YSL_TXT_CHECK_ENCODING_N));
68 #undef YSL_TXT_CHECK_ENCODING_N
69
70 std::char_traits<char>::assign(s + n, arrlen(s) - n, 0);
71 tf.Read(s, 1, n);
72 tf.Rewind();
73 tf.Encoding = CheckEncoding(s, n);
74 }
75 }
76
77 } // unnamed namespace;
78
79
80 TextFile::TextFile(const char* filename, std::ios_base::openmode mode,
81 Text::Encoding enc)
82 : File(filename, mode),
83 bl(0), Encoding(enc)
84 {
85 if(GetSize() == 0 && mode & std::ios_base::out)
86 switch(enc)
87 {
88 case CharSet::UTF_16LE:
89 yunseq(*this << BOM_UTF_16LE, bl = 2);
90 break;
91 case CharSet::UTF_16BE:
92 yunseq(*this << BOM_UTF_16BE, bl = 2);
93 break;
94 case CharSet::UTF_8:
95 yunseq(*this << BOM_UTF_8, bl = 3);
96 break;
97 case CharSet::UTF_32LE:
98 yunseq(*this << BOM_UTF_32LE, bl = 4);
99 break;
100 case CharSet::UTF_32BE:
101 yunseq(*this << BOM_UTF_32BE, bl = 4);
102 default:
103 break;
104 }
105 else
106 InitializeTextFile(*this, bl);
107 }
108 TextFile::TextFile(const String& filename)
109 : File(filename, u"r"),
110 bl(0), Encoding(CharSet::Null)
111 {
112 InitializeTextFile(*this, bl);
113 }
114
115 string
116 TextFile::GetBOM() const
117 {
118 const size_t s(GetBOMSize());
119 string str(s, char());
120
121 File::Rewind();
122 for(size_t i(0); i != s; ++i)
123 str[i] = std::fgetc(GetPtr());
124 return str;
125 }
126
127 size_t
128 TextFile::CheckBOM(Text::Encoding& cp)
129 {
130 using std::char_traits;
131
132 Rewind();
133 if(GetSize() < 2)
134 return 0;
135 char tmp[4];
136 Read(tmp, 1, 4);
137
138 if(char_traits<char>::compare(tmp, BOM_UTF_16LE, 2) == 0)
139 {
140 cp = CharSet::UTF_16LE;
141 return 2;
142 }
143 if(char_traits<char>::compare(tmp, BOM_UTF_16BE, 2) == 0)
144 {
145 cp = CharSet::UTF_16BE;
146 return 2;
147 }
148 if(char_traits<char>::compare(tmp, BOM_UTF_8, 3) == 0)
149 {
150 cp = CharSet::UTF_8;
151 return 3;
152 }
153 if(char_traits<char>::compare(tmp, BOM_UTF_32LE, 4) == 0)
154 {
155 cp = CharSet::UTF_32LE;
156 return 4;
157 }
158 if(char_traits<char>::compare(tmp, BOM_UTF_32BE, 4) == 0)
159 {
160 cp = CharSet::UTF_32BE;
161 return 4;
162 }
163 return 0;
164 }
165
166 void
167 TextFile::Locate(u32 pos) const
168 {
169 Seek(bl + pos, SEEK_SET);
170 }
171
172 void
173 TextFile::Rewind() const
174 {
175 Seek(bl, SEEK_SET);
176 }
177
178 bool
179 TextFile::Truncate(size_t size) const
180 {
181 return File::Truncate(GetBOMSize() + size);
182 }
183
184 } // namespace YSLib;
185
ystdex::assign
void assign(_tCon &c, _tParams &&...args)
插入参数指定的元素到容器。
Definition: container.hpp:289
YSLib::TextFile::TextFile
TextFile(const char *, std::ios_base::openmode=std::ios_base::in, Text::Encoding=Text::CS_Default)
构造：使用指定文件名、编码和模式初始化文本文件对象。
Definition: TextFile.cpp:80
YSLib::BOM_UTF_32LE
yconstexpr char BOM_UTF_32LE[]
Definition: TextFile.h:50
YSLib::TextFile::GetBOM
string GetBOM() const
取 BOM 字符串。
Definition: TextFile.cpp:116
CHRLib::CharSet::UTF_16LE
yconstexpr Encoding UTF_16LE(csUTF16LE)
CHRLib::CharSet::UTF_16BE
yconstexpr Encoding UTF_16BE(csUTF16BE)
YSLib::u32
std::uint32_t u32
Definition: yadaptor.h:69
CHRLib::enc
enc
Definition: chrproc.h:76
ystdex::arrlen
size_t arrlen(_type(&)[_vN])
计算指定数组类型对象的长度。
Definition: utility.hpp:196
CHRLib::CharSet::UTF_32BE
yconstexpr Encoding UTF_32BE(csUTF32BE)
YSLib::BOM_UTF_16LE
yconstexpr char BOM_UTF_16LE[]
Unicode 编码模式标记。
Definition: TextFile.h:47
YSLib::File
文件基类。
Definition: File.h:43
YSLib::TextFile::GetSize
GetSize()-GetBOMSize()) DefGetter(const ynothrow
< 取文本区段大小。
CHRLib::MBCToUC
YF_API ConversionResult MBCToUC(ucs2_t &, const char *&, Encoding, ConversionState &&={})
按指定编码和转换状态转换字符串中字符为 UCS-2 字符，返回转换的字节数。
Definition: chrproc.cpp:52
YSLib::BOM_UTF_32BE
yconstexpr char BOM_UTF_32BE[]
Definition: TextFile.h:51
YSL_TXT_CHECK_ENCODING_N
#define YSL_TXT_CHECK_ENCODING_N
YSLib::BOM_UTF_16BE
yconstexpr char BOM_UTF_16BE[]
Definition: TextFile.h:48
YSLib::Text::String
YSLib 标准字符串（使用 UCS-2 作为内部编码）。
Definition: ystring.h:47
YSLib::File::Seek
fp fsize Seek
Definition: File.h:104
yunseq
#define yunseq
无序列依赖表达式组求值。
Definition: ydef.h:748
YSLib::TextFile::Truncate
bool Truncate(size_t) const override
截断文本。
Definition: TextFile.cpp:179
YSLib::BOM_UTF_8
yconstexpr char BOM_UTF_8[]
Definition: TextFile.h:49
YSLib::TextFile::Rewind
void Rewind() const
设置文件读位置为文本区段头。
Definition: TextFile.cpp:173
CHRLib::CharSet::Null
空字符集。
Definition: encoding.h:56
CHRLib::CharSet::UTF_32LE
yconstexpr Encoding UTF_32LE(csUTF32LE)
CHRLib::CharSet::GBK
yconstexpr Encoding GBK(csGBK)
platform_ex::Windows::s
return s
Definition: MinGW32.cpp:49
CHRLib::CharSet::Encoding
Encoding
Definition: encoding.h:53
YSLib::Drawing::g
c yconstfn g
Definition: ystyle.h:104
CHRLib::CharSet::UTF_8
yconstexpr Encoding UTF_8(csUTF8)
YModules.h