TextFile.cpp
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:10k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. /* 
  2.  * Copyright (C) 2003-2005 Gabest
  3.  * http://www.gabest.org
  4.  *
  5.  *  This Program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2, or (at your option)
  8.  *  any later version.
  9.  *   
  10.  *  This Program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13.  *  GNU General Public License for more details.
  14.  *   
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with GNU Make; see the file COPYING.  If not, write to
  17.  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
  18.  *  http://www.gnu.org/copyleft/gpl.html
  19.  *
  20.  */
  21. #include "stdafx.h"
  22. #include <atlbase.h>
  23. #include <afxinet.h>
  24. #include "TextFile.h"
  25. CTextFile::CTextFile()
  26. {
  27. m_encoding = ASCII;
  28. m_offset = 0;
  29. }
  30. bool CTextFile::Open(LPCTSTR lpszFileName)
  31. {
  32. if(!__super::Open(lpszFileName, modeRead|typeBinary|shareDenyWrite))
  33. return(false);
  34. m_encoding = ASCII;
  35. m_offset = 0;
  36. if(__super::GetLength() >= 2)
  37. {
  38. WORD w;
  39. if(sizeof(w) != Read(&w, sizeof(w)))
  40. return Close(), false;
  41. if(w == 0xfeff)
  42. {
  43. m_encoding = LE16;
  44. m_offset = 2;
  45. }
  46. else if(w == 0xfffe)
  47. {
  48. m_encoding = BE16;
  49. m_offset = 2;
  50. }
  51. else if(w == 0xbbef && __super::GetLength() >= 3)
  52. {
  53. BYTE b;
  54. if(sizeof(b) != Read(&b, sizeof(b)))
  55. return Close(), false;
  56. if(b == 0xbf)
  57. {
  58. m_encoding = UTF8;
  59. m_offset = 3;
  60. }
  61. }
  62. }
  63. if(m_encoding == ASCII)
  64. {
  65. __super::Close(); // CWebTextFile::Close() would delete the temp file if we called it...
  66. if(!__super::Open(lpszFileName, modeRead|typeText|shareDenyWrite))
  67. return(false);
  68. }
  69. return(true);
  70. }
  71. bool CTextFile::Save(LPCTSTR lpszFileName, enc e)
  72. {
  73. if(!__super::Open(lpszFileName, modeCreate|modeWrite|shareDenyWrite|(e==ASCII?typeText:typeBinary)))
  74. return(false);
  75. if(e == UTF8)
  76. {
  77. BYTE b[3] = {0xef,0xbb,0xbf};
  78. Write(b, sizeof(b));
  79. }
  80. else if(e == LE16)
  81. {
  82. BYTE b[2] = {0xff,0xfe};
  83. Write(b, sizeof(b));
  84. }
  85. else if(e == BE16)
  86. {
  87. BYTE b[2] = {0xfe,0xff};
  88. Write(b, sizeof(b));
  89. }
  90. m_encoding = e;
  91. return(true);
  92. }
  93. CTextFile::enc CTextFile::GetEncoding()
  94. {
  95. return(m_encoding);
  96. }
  97. bool CTextFile::IsUnicode()
  98. {
  99. return(m_encoding == UTF8 || m_encoding == LE16 || m_encoding == BE16);
  100. }
  101. // CFile
  102. CString CTextFile::GetFilePath() const
  103. {
  104. // to avoid a CException coming from CTime
  105. return m_strFileName; // __super::GetFilePath();
  106. }
  107. // CStdioFile
  108. ULONGLONG CTextFile::GetPosition() const
  109. {
  110. return(CStdioFile::GetPosition() - m_offset);
  111. }
  112. ULONGLONG CTextFile::GetLength() const
  113. {
  114. return(CStdioFile::GetLength() - m_offset);
  115. }
  116. ULONGLONG CTextFile::Seek(LONGLONG lOff, UINT nFrom)
  117. {
  118. ULONGLONG pos = GetPosition();
  119. ULONGLONG len = GetLength();
  120. switch(nFrom)
  121. {
  122. default:
  123. case begin: lOff = lOff; break;
  124. case current: lOff = pos + lOff; break;
  125. case end: lOff = len - lOff; break;
  126. }
  127. lOff = max(min(lOff, len), 0) + m_offset;
  128. pos = CStdioFile::Seek(lOff, begin) - m_offset;
  129. return(pos);
  130. }
  131. void CTextFile::WriteString(LPCSTR lpsz/*CStringA str*/)
  132. {
  133. CStringA str(lpsz);
  134. if(m_encoding == ASCII)
  135. {
  136. __super::WriteString(AToT(str));
  137. }
  138. else if(m_encoding == UTF8)
  139. {
  140. WriteString(AToW(str));
  141. }
  142. else if(m_encoding == LE16)
  143. {
  144. WriteString(AToW(str));
  145. }
  146. else if(m_encoding == BE16)
  147. {
  148. WriteString(AToW(str));
  149. }
  150. }
  151. void CTextFile::WriteString(LPCWSTR lpsz/*CStringW str*/)
  152. {
  153. CStringW str(lpsz);
  154. if(m_encoding == ASCII)
  155. {
  156. __super::WriteString(WToT(str));
  157. }
  158. else if(m_encoding == UTF8)
  159. {
  160. str.Replace(L"n", L"rn");
  161. for(int i = 0; i < str.GetLength(); i++)
  162. {
  163. DWORD c = (WORD)str[i];
  164. if(0 <= c && c < 0x80) // 0xxxxxxx
  165. {
  166. Write(&c, 1);
  167. }
  168. else if(0x80 <= c && c < 0x800) // 110xxxxx 10xxxxxx
  169. {
  170. c = 0xc080|((c<<2)&0x1f00)|(c&0x003f);
  171. Write((BYTE*)&c+1, 1);
  172. Write(&c, 1);
  173. }
  174. else if(0x800 <= c && c < 0xFFFF) // 1110xxxx 10xxxxxx 10xxxxxx
  175. {
  176. c = 0xe08080|((c<<4)&0x0f0000)|((c<<2)&0x3f00)|(c&0x003f);
  177. Write((BYTE*)&c+2, 1);
  178. Write((BYTE*)&c+1, 1);
  179. Write(&c, 1);
  180. }
  181. else
  182. {
  183. c = '?';
  184. Write(&c, 1);
  185. }
  186. }
  187. }
  188. else if(m_encoding == LE16)
  189. {
  190. str.Replace(L"n", L"rn");
  191. Write((LPCWSTR)str, str.GetLength()*2);
  192. }
  193. else if(m_encoding == BE16)
  194. {
  195. str.Replace(L"n", L"rn");
  196. for(int i = 0; i < str.GetLength(); i++)
  197. str.SetAt(i, ((str[i]>>8)&0x00ff)|((str[i]<<8)&0xff00));
  198. Write((LPCWSTR)str, str.GetLength()*2);
  199. }
  200. }
  201. BOOL CTextFile::ReadString(CStringA& str)
  202. {
  203. bool fEOF = true;
  204. str.Empty();
  205. if(m_encoding == ASCII)
  206. {
  207. CString s;
  208. fEOF = !__super::ReadString(s);
  209. str = TToA(s);
  210. }
  211. else if(m_encoding == UTF8)
  212. {
  213. BYTE b;
  214. while(Read(&b, sizeof(b)) == sizeof(b))
  215. {
  216. fEOF = false;
  217. char c = '?';
  218. if(!(b&0x80)) // 0xxxxxxx
  219. {
  220. c = b&0x7f;
  221. }
  222. else if((b&0xe0) == 0xc0) // 110xxxxx 10xxxxxx
  223. {
  224. if(Read(&b, sizeof(b)) != sizeof(b)) break;
  225. }
  226. else if((b&0xf0) == 0xe0) // 1110xxxx 10xxxxxx 10xxxxxx
  227. {
  228. if(Read(&b, sizeof(b)) != sizeof(b)) break;
  229. if(Read(&b, sizeof(b)) != sizeof(b)) break;
  230. }
  231. if(c == 'r') continue;
  232. if(c == 'n') break;
  233. str += c;
  234. }
  235. }
  236. else if(m_encoding == LE16)
  237. {
  238. WORD w;
  239. while(Read(&w, sizeof(w)) == sizeof(w))
  240. {
  241. fEOF = false;
  242. char c = '?';
  243. if(!(w&0xff00)) c = w&0xff;
  244. if(c == 'r') continue;
  245. if(c == 'n') break;
  246. str += c;
  247. }
  248. }
  249. else if(m_encoding == BE16)
  250. {
  251. WORD w;
  252. while(Read(&w, sizeof(w)) == sizeof(w))
  253. {
  254. fEOF = false;
  255. char c = '?';
  256. if(!(w&0xff)) c = w>>8;
  257. if(c == 'r') continue;
  258. if(c == 'n') break;
  259. str += c;
  260. }
  261. }
  262. return(!fEOF);
  263. }
  264. BOOL CTextFile::ReadString(CStringW& str)
  265. {
  266. bool fEOF = true;
  267. str.Empty();
  268. if(m_encoding == ASCII)
  269. {
  270. CString s;
  271. fEOF = !__super::ReadString(s);
  272. str = TToW(s);
  273. }
  274. else if(m_encoding == UTF8)
  275. {
  276. BYTE b;
  277. while(Read(&b, sizeof(b)) == sizeof(b))
  278. {
  279. fEOF = false;
  280. WCHAR c = '?';
  281. if(!(b&0x80)) // 0xxxxxxx
  282. {
  283. c = b&0x7f;
  284. }
  285. else if((b&0xe0) == 0xc0) // 110xxxxx 10xxxxxx
  286. {
  287. c = (b&0x1f)<<6;
  288. if(Read(&b, sizeof(b)) != sizeof(b)) break;
  289. c |= (b&0x3f);
  290. }
  291. else if((b&0xf0) == 0xe0) // 1110xxxx 10xxxxxx 10xxxxxx
  292. {
  293. c = (b&0x0f)<<12;
  294. if(Read(&b, sizeof(b)) != sizeof(b)) break;
  295. c |= (b&0x3f)<<6;
  296. if(Read(&b, sizeof(b)) != sizeof(b)) break;
  297. c |= (b&0x3f);
  298. }
  299. if(c == 'r') continue;
  300. if(c == 'n') break;
  301. str += c;
  302. }
  303. }
  304. else if(m_encoding == LE16)
  305. {
  306. WCHAR wc;
  307. while(Read(&wc, sizeof(wc)) == sizeof(wc))
  308. {
  309. fEOF = false;
  310. if(wc == 'r') continue;
  311. if(wc == 'n') break;
  312. str += wc;
  313. }
  314. }
  315. else if(m_encoding == BE16)
  316. {
  317. WCHAR wc;
  318. while(Read(&wc, sizeof(wc)) == sizeof(wc))
  319. {
  320. fEOF = false;
  321. wc = ((wc>>8)&0x00ff)|((wc<<8)&0xff00);
  322. if(wc == 'r') continue;
  323. if(wc == 'n') break;
  324. str += wc;
  325. }
  326. }
  327. return(!fEOF);
  328. }
  329. //
  330. // CWebTextFile
  331. //
  332. CWebTextFile::CWebTextFile(LONGLONG llMaxSize)
  333. : m_llMaxSize(llMaxSize)
  334. {
  335. }
  336. bool CWebTextFile::Open(LPCTSTR lpszFileName)
  337. {
  338. CString fn(lpszFileName);
  339. if(fn.Find(_T("http://")) != 0)
  340. return __super::Open(lpszFileName);
  341. try
  342. {
  343. CInternetSession is;
  344. CAutoPtr<CStdioFile> f(is.OpenURL(fn, 1, INTERNET_FLAG_TRANSFER_BINARY|INTERNET_FLAG_EXISTING_CONNECT));
  345. if(!f) return(false);
  346. TCHAR path[MAX_PATH];
  347. GetTempPath(MAX_PATH, path);
  348. fn = path + fn.Mid(fn.ReverseFind('/')+1);
  349. int i = fn.Find(_T("?"));
  350. if(i > 0) fn = fn.Left(i);
  351. CFile temp;
  352. if(!temp.Open(fn, modeCreate|modeWrite|typeBinary|shareDenyWrite))
  353. {
  354. f->Close();
  355. return(false);
  356. }
  357. BYTE buff[1024];
  358. int len, total = 0;
  359. while((len = f->Read(buff, 1024)) == 1024 && (m_llMaxSize < 0 || (total+=1024) < m_llMaxSize))
  360. temp.Write(buff, len);
  361. if(len > 0) temp.Write(buff, len);
  362. m_tempfn = fn;
  363. f->Close(); // must close it because the desctructor doesn't seem to do it and we will get an exception when "is" is destroying
  364. }
  365. catch(CInternetException* ie)
  366. {
  367. ie->Delete();
  368. return(false);
  369. }
  370. return __super::Open(m_tempfn);
  371. }
  372. bool CWebTextFile::Save(LPCTSTR lpszFileName, enc e)
  373. {
  374. // CWebTextFile is read-only...
  375. ASSERT(0);
  376. return(false);
  377. }
  378. void CWebTextFile::Close()
  379. {
  380. __super::Close();
  381. if(!m_tempfn.IsEmpty())
  382. {
  383. _tremove(m_tempfn);
  384. m_tempfn.Empty();
  385. }
  386. }
  387. ///////////////////////////////////////////////////////////////
  388. CStringW AToW(CStringA str)
  389. {
  390. CStringW ret;
  391. for(int i = 0, j = str.GetLength(); i < j; i++)
  392. ret += (WCHAR)(BYTE)str[i];
  393. return(ret);
  394. }
  395. CStringA WToA(CStringW str)
  396. {
  397. CStringA ret;
  398. for(int i = 0, j = str.GetLength(); i < j; i++)
  399. ret += (CHAR)(WORD)str[i];
  400. return(ret);
  401. }
  402. CString AToT(CStringA str)
  403. {
  404. CString ret;
  405. for(int i = 0, j = str.GetLength(); i < j; i++)
  406. ret += (TCHAR)(BYTE)str[i];
  407. return(ret);
  408. }
  409. CString WToT(CStringW str)
  410. {
  411. CString ret;
  412. for(int i = 0, j = str.GetLength(); i < j; i++)
  413. ret += (TCHAR)(WORD)str[i];
  414. return(ret);
  415. }
  416. CStringA TToA(CString str)
  417. {
  418. CStringA ret;
  419. #ifdef UNICODE
  420. for(int i = 0, j = str.GetLength(); i < j; i++)
  421. ret += (CHAR)(BYTE)str[i];
  422. #else
  423. ret = str;
  424. #endif
  425. return(ret);
  426. }
  427. CStringW TToW(CString str)
  428. {
  429. CStringW ret;
  430. #ifdef UNICODE
  431. ret = str;
  432. #else
  433. for(int i = 0, j = str.GetLength(); i < j; i++)
  434. ret += (WCHAR)(BYTE)str[i];
  435. #endif
  436. return(ret);
  437. }