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.
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,
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
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
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 
void assign(_tCon &c, _tParams &&...args)
插入参数指定的元素到容器。
Definition: container.hpp:289
TextFile(const char *, std::ios_base::openmode=std::ios_base::in, Text::Encoding=Text::CS_Default)
构造:使用指定文件名、编码和模式初始化文本文件对象。
Definition: TextFile.cpp:80
yconstexpr char BOM_UTF_32LE[]
Definition: TextFile.h:50
string GetBOM() const
取 BOM 字符串。
Definition: TextFile.cpp:116
yconstexpr Encoding UTF_16LE(csUTF16LE)
yconstexpr Encoding UTF_16BE(csUTF16BE)
std::uint32_t u32
Definition: yadaptor.h:69
size_t arrlen(_type(&)[_vN])
计算指定数组类型对象的长度。
Definition: utility.hpp:196
yconstexpr Encoding UTF_32BE(csUTF32BE)
yconstexpr char BOM_UTF_16LE[]
Unicode 编码模式标记。
Definition: TextFile.h:47
文件基类。
Definition: File.h:43
GetSize()-GetBOMSize()) DefGetter(const ynothrow
< 取文本区段大小。
YF_API ConversionResult MBCToUC(ucs2_t &, const char *&, Encoding, ConversionState &&={})
按指定编码和转换状态转换字符串中字符为 UCS-2 字符,返回转换的字节数。
Definition: chrproc.cpp:52
yconstexpr char BOM_UTF_32BE[]
Definition: TextFile.h:51
#define YSL_TXT_CHECK_ENCODING_N
yconstexpr char BOM_UTF_16BE[]
Definition: TextFile.h:48
YSLib 标准字符串(使用 UCS-2 作为内部编码)。
Definition: ystring.h:47
fp fsize Seek
Definition: File.h:104
#define yunseq
无序列依赖表达式组求值。
Definition: ydef.h:748
bool Truncate(size_t) const override
截断文本。
Definition: TextFile.cpp:179
yconstexpr char BOM_UTF_8[]
Definition: TextFile.h:49
void Rewind() const
设置文件读位置为文本区段头。
Definition: TextFile.cpp:173
空字符集。
Definition: encoding.h:56
yconstexpr Encoding UTF_32LE(csUTF32LE)
yconstexpr Encoding GBK(csGBK)
c yconstfn g
Definition: ystyle.h:104
yconstexpr Encoding UTF_8(csUTF8)