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 
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.
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
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
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
166 {
167  Seek(bl + pos, SEEK_SET);
168 }
169 
170 void
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