YSTest: yftext.cpp 源文件

YSTest PreAlpha_b400_20130424 The YSLib Test Project

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

- 文件列表
- 文件成员

全部 类 命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 宏定义 组 页
yftext.cpp
浏览该文件的文档.
1 ﻿/*
2 Copyright by FrankHB 2009 - 2013.
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/yftext.h"
29
30 YSL_BEGIN
31
32 using namespace Text;
33
34 namespace
35 {
36
37 bool
38 CheckUTF8(const char* s, const char* g)
39 {
40 while(s < g && *s != 0
41 && MBCToUC(s, CharSet::UTF_8) == ConversionResult::OK);
42 return s == g || *s == 0;
43 }
44
45 // TODO: More accurate encoding checking for text stream without BOM.
46 Encoding
47 CheckEncoding(const char* s, size_t n)
48 {
49 return CheckUTF8(s, s + n) ? CharSet::UTF_8 : CharSet::GBK;
50 }
51
52 void
53 InitializeTextFile(TextFile& tf, size_t& bl)
54 {
55 if(tf)
56 {
57 tf.Seek(0, SEEK_END);
58 bl = tf.CheckBOM(tf.Encoding);
59 tf.Rewind();
60 }
61 if(bl == 0)
62 {
63 #define YSL_TXT_CHECK_ENCODING_N 64U
64 char s[YSL_TXT_CHECK_ENCODING_N + 6];
65 const auto n(min(tf.GetTextSize(), YSL_TXT_CHECK_ENCODING_N));
66 #undef YSL_TXT_CHECK_ENCODING_N
67
68 std::char_traits<char>::assign(s + n, arrlen(s) - n, 0);
69 tf.Read(s, 1, n);
70 tf.Rewind();
71 tf.Encoding = CheckEncoding(s, n);
72 }
73 }
74
75 } // unnamed namespace;
76
77
78 TextFile::TextFile(const_path_t filename, std::ios_base::openmode mode,
79 Text::Encoding enc)
80 : File(filename, mode),
81 bl(0), Encoding(enc)
82 {
83 if(GetSize() == 0 && mode & std::ios_base::out)
84 switch(enc)
85 {
86 case CharSet::UTF_16LE:
87 yunseq(*this << BOM_UTF_16LE, bl = 2);
88 break;
89 case CharSet::UTF_16BE:
90 yunseq(*this << BOM_UTF_16BE, bl = 2);
91 break;
92 case CharSet::UTF_8:
93 yunseq(*this << BOM_UTF_8, bl = 3);
94 break;
95 case CharSet::UTF_32LE:
96 yunseq(*this << BOM_UTF_32LE, bl = 4);
97 break;
98 case CharSet::UTF_32BE:
99 yunseq(*this << BOM_UTF_32BE, bl = 4);
100 default:
101 break;
102 }
103 else
104 InitializeTextFile(*this, bl);
105 }
106 TextFile::TextFile(const String& filename)
107 : File(filename, u"r"),
108 bl(0), Encoding(CharSet::Null)
109 {
110 InitializeTextFile(*this, bl);
111 }
112
113 string
114 TextFile::GetBOM() const
115 {
116 const size_t s(GetBOMSize());
117 string str(s, char());
118
119 File::Rewind();
120 for(size_t i(0); i != s; ++i)
121 str[i] = std::fgetc(GetPtr());
122 return std::move(str);
123 }
124
125 size_t
126 TextFile::CheckBOM(Text::Encoding& cp)
127 {
128 using std::char_traits;
129
130 Rewind();
131 if(GetSize() < 2)
132 return 0;
133 char tmp[4];
134 Read(tmp, 1, 4);
135
136 if(char_traits<char>::compare(tmp, BOM_UTF_16LE, 2) == 0)
137 {
138 cp = CharSet::UTF_16LE;
139 return 2;
140 }
141 if(char_traits<char>::compare(tmp, BOM_UTF_16BE, 2) == 0)
142 {
143 cp = CharSet::UTF_16BE;
144 return 2;
145 }
146 if(char_traits<char>::compare(tmp, BOM_UTF_8, 3) == 0)
147 {
148 cp = CharSet::UTF_8;
149 return 3;
150 }
151 if(char_traits<char>::compare(tmp, BOM_UTF_32LE, 4) == 0)
152 {
153 cp = CharSet::UTF_32LE;
154 return 4;
155 }
156 if(char_traits<char>::compare(tmp, BOM_UTF_32BE, 4) == 0)
157 {
158 cp = CharSet::UTF_32BE;
159 return 4;
160 }
161 return 0;
162 }
163
164 void
165 TextFile::Locate(u32 pos) const
166 {
167 Seek(bl + pos, SEEK_SET);
168 }
169
170 void
171 TextFile::Rewind() const
172 {
173 Seek(bl, SEEK_SET);
174 }
175
176 bool
177 TextFile::Truncate(size_t size) const
178 {
179 return File::Truncate(GetBOMSize() + size);
180 }
181
182 YSL_END
183