00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "stdafx.h"
00023 #include <atlbase.h>
00024 #include <afxinet.h>
00025 #include "TextFile.h"
00026
00027 CTextFile::CTextFile()
00028 {
00029 m_encoding = ASCII;
00030 m_offset = 0;
00031 }
00032
00033 bool CTextFile::Open(LPCTSTR lpszFileName)
00034 {
00035 if(!__super::Open(lpszFileName, modeRead|typeBinary|shareDenyWrite))
00036 return(false);
00037
00038 m_encoding = ASCII;
00039 m_offset = 0;
00040
00041 if(__super::GetLength() >= 2)
00042 {
00043 WORD w;
00044 if(sizeof(w) != Read(&w, sizeof(w)))
00045 return Close(), false;
00046
00047 if(w == 0xfeff)
00048 {
00049 m_encoding = LE16;
00050 m_offset = 2;
00051 }
00052 else if(w == 0xfffe)
00053 {
00054 m_encoding = BE16;
00055 m_offset = 2;
00056 }
00057 else if(w == 0xbbef && __super::GetLength() >= 3)
00058 {
00059 BYTE b;
00060 if(sizeof(b) != Read(&b, sizeof(b)))
00061 return Close(), false;
00062
00063 if(b == 0xbf)
00064 {
00065 m_encoding = UTF8;
00066 m_offset = 3;
00067 }
00068 }
00069 }
00070
00071 if(m_encoding == ASCII)
00072 {
00073 __super::Close();
00074 if(!__super::Open(lpszFileName, modeRead|typeText|shareDenyWrite))
00075 return(false);
00076 }
00077
00078 return(true);
00079 }
00080
00081 bool CTextFile::Save(LPCTSTR lpszFileName, enc e)
00082 {
00083 if(!__super::Open(lpszFileName, modeCreate|modeWrite|shareDenyWrite|(e==ASCII?typeText:typeBinary)))
00084 return(false);
00085
00086 if(e == UTF8)
00087 {
00088 BYTE b[3] = {0xef,0xbb,0xbf};
00089 Write(b, sizeof(b));
00090 }
00091 else if(e == LE16)
00092 {
00093 BYTE b[2] = {0xff,0xfe};
00094 Write(b, sizeof(b));
00095 }
00096 else if(e == BE16)
00097 {
00098 BYTE b[2] = {0xfe,0xff};
00099 Write(b, sizeof(b));
00100 }
00101
00102 m_encoding = e;
00103
00104 return(true);
00105 }
00106
00107 CTextFile::enc CTextFile::GetEncoding()
00108 {
00109 return(m_encoding);
00110 }
00111
00112 bool CTextFile::IsUnicode()
00113 {
00114 return(m_encoding == UTF8 || m_encoding == LE16 || m_encoding == BE16);
00115 }
00116
00117
00118
00119 CString CTextFile::GetFilePath() const
00120 {
00121
00122 return m_strFileName;
00123 }
00124
00125
00126
00127 ULONGLONG CTextFile::GetPosition() const
00128 {
00129 return(CStdioFile::GetPosition() - m_offset);
00130 }
00131
00132 ULONGLONG CTextFile::GetLength() const
00133 {
00134 return(CStdioFile::GetLength() - m_offset);
00135 }
00136
00137 ULONGLONG CTextFile::Seek(LONGLONG lOff, UINT nFrom)
00138 {
00139 ULONGLONG pos = GetPosition();
00140 ULONGLONG len = GetLength();
00141
00142 switch(nFrom)
00143 {
00144 default:
00145 case begin: lOff = lOff; break;
00146 case current: lOff = pos + lOff; break;
00147 case end: lOff = len - lOff; break;
00148 }
00149
00150 lOff = max(min(lOff, len), 0) + m_offset;
00151
00152 pos = CStdioFile::Seek(lOff, begin) - m_offset;
00153
00154 return(pos);
00155 }
00156
00157 void CTextFile::WriteString(LPCSTR lpsz)
00158 {
00159 CStringA str(lpsz);
00160
00161 if(m_encoding == ASCII)
00162 {
00163 __super::WriteString(AToT(str));
00164 }
00165 else if(m_encoding == UTF8)
00166 {
00167 WriteString(AToW(str));
00168 }
00169 else if(m_encoding == LE16)
00170 {
00171 WriteString(AToW(str));
00172 }
00173 else if(m_encoding == BE16)
00174 {
00175 WriteString(AToW(str));
00176 }
00177 }
00178
00179 void CTextFile::WriteString(LPCWSTR lpsz)
00180 {
00181 CStringW str(lpsz);
00182
00183 if(m_encoding == ASCII)
00184 {
00185 __super::WriteString(WToT(str));
00186 }
00187 else if(m_encoding == UTF8)
00188 {
00189 str.Replace(L"\n", L"\r\n");
00190 for(int i = 0; i < str.GetLength(); i++)
00191 {
00192 DWORD c = (WORD)str[i];
00193
00194 if(0 <= c && c < 0x80)
00195 {
00196 Write(&c, 1);
00197 }
00198 else if(0x80 <= c && c < 0x800)
00199 {
00200 c = 0xc080|((c<<2)&0x1f00)|(c&0x003f);
00201 Write((BYTE*)&c+1, 1);
00202 Write(&c, 1);
00203 }
00204 else if(0x800 <= c && c < 0xFFFF)
00205 {
00206 c = 0xe08080|((c<<4)&0x0f0000)|((c<<2)&0x3f00)|(c&0x003f);
00207 Write((BYTE*)&c+2, 1);
00208 Write((BYTE*)&c+1, 1);
00209 Write(&c, 1);
00210 }
00211 else
00212 {
00213 c = '?';
00214 Write(&c, 1);
00215 }
00216 }
00217 }
00218 else if(m_encoding == LE16)
00219 {
00220 str.Replace(L"\n", L"\r\n");
00221 Write((LPCWSTR)str, str.GetLength()*2);
00222 }
00223 else if(m_encoding == BE16)
00224 {
00225 str.Replace(L"\n", L"\r\n");
00226 for(int i = 0; i < str.GetLength(); i++)
00227 str.SetAt(i, ((str[i]>>8)&0x00ff)|((str[i]<<8)&0xff00));
00228 Write((LPCWSTR)str, str.GetLength()*2);
00229 }
00230 }
00231
00232 BOOL CTextFile::ReadString(CStringA& str)
00233 {
00234 bool fEOF = true;
00235
00236 str.Empty();
00237
00238 if(m_encoding == ASCII)
00239 {
00240 CString s;
00241 fEOF = !__super::ReadString(s);
00242 str = TToA(s);
00243 }
00244 else if(m_encoding == UTF8)
00245 {
00246 BYTE b;
00247 while(Read(&b, sizeof(b)) == sizeof(b))
00248 {
00249 fEOF = false;
00250 char c = '?';
00251 if(!(b&0x80))
00252 {
00253 c = b&0x7f;
00254 }
00255 else if((b&0xe0) == 0xc0)
00256 {
00257 if(Read(&b, sizeof(b)) != sizeof(b)) break;
00258 }
00259 else if((b&0xf0) == 0xe0)
00260 {
00261 if(Read(&b, sizeof(b)) != sizeof(b)) break;
00262 if(Read(&b, sizeof(b)) != sizeof(b)) break;
00263 }
00264 if(c == '\r') continue;
00265 if(c == '\n') break;
00266 str += c;
00267 }
00268 }
00269 else if(m_encoding == LE16)
00270 {
00271 WORD w;
00272 while(Read(&w, sizeof(w)) == sizeof(w))
00273 {
00274 fEOF = false;
00275 char c = '?';
00276 if(!(w&0xff00)) c = w&0xff;
00277 if(c == '\r') continue;
00278 if(c == '\n') break;
00279 str += c;
00280 }
00281 }
00282 else if(m_encoding == BE16)
00283 {
00284 WORD w;
00285 while(Read(&w, sizeof(w)) == sizeof(w))
00286 {
00287 fEOF = false;
00288 char c = '?';
00289 if(!(w&0xff)) c = w>>8;
00290 if(c == '\r') continue;
00291 if(c == '\n') break;
00292 str += c;
00293 }
00294 }
00295
00296 return(!fEOF);
00297 }
00298
00299 BOOL CTextFile::ReadString(CStringW& str)
00300 {
00301 bool fEOF = true;
00302
00303 str.Empty();
00304
00305 if(m_encoding == ASCII)
00306 {
00307 CString s;
00308 fEOF = !__super::ReadString(s);
00309 str = TToW(s);
00310 }
00311 else if(m_encoding == UTF8)
00312 {
00313 BYTE b;
00314 while(Read(&b, sizeof(b)) == sizeof(b))
00315 {
00316 fEOF = false;
00317 WCHAR c = '?';
00318 if(!(b&0x80))
00319 {
00320 c = b&0x7f;
00321 }
00322 else if((b&0xe0) == 0xc0)
00323 {
00324 c = (b&0x1f)<<6;
00325 if(Read(&b, sizeof(b)) != sizeof(b)) break;
00326 c |= (b&0x3f);
00327 }
00328 else if((b&0xf0) == 0xe0)
00329 {
00330 c = (b&0x0f)<<12;
00331 if(Read(&b, sizeof(b)) != sizeof(b)) break;
00332 c |= (b&0x3f)<<6;
00333 if(Read(&b, sizeof(b)) != sizeof(b)) break;
00334 c |= (b&0x3f);
00335 }
00336 if(c == '\r') continue;
00337 if(c == '\n') break;
00338 str += c;
00339 }
00340 }
00341 else if(m_encoding == LE16)
00342 {
00343 WCHAR wc;
00344 while(Read(&wc, sizeof(wc)) == sizeof(wc))
00345 {
00346 fEOF = false;
00347 if(wc == '\r') continue;
00348 if(wc == '\n') break;
00349 str += wc;
00350 }
00351 }
00352 else if(m_encoding == BE16)
00353 {
00354 WCHAR wc;
00355 while(Read(&wc, sizeof(wc)) == sizeof(wc))
00356 {
00357 fEOF = false;
00358 wc = ((wc>>8)&0x00ff)|((wc<<8)&0xff00);
00359 if(wc == '\r') continue;
00360 if(wc == '\n') break;
00361 str += wc;
00362 }
00363 }
00364
00365 return(!fEOF);
00366 }
00367
00368
00369
00370
00371
00372 CWebTextFile::CWebTextFile(LONGLONG llMaxSize)
00373 : m_llMaxSize(llMaxSize)
00374 {
00375 }
00376
00377 bool CWebTextFile::Open(LPCTSTR lpszFileName)
00378 {
00379 CString fn(lpszFileName);
00380
00381 if(fn.Find(_T("http://")) != 0)
00382 return __super::Open(lpszFileName);
00383
00384 try
00385 {
00386 CInternetSession is;
00387
00388 CAutoPtr<CStdioFile> f(is.OpenURL(fn, 1, INTERNET_FLAG_TRANSFER_BINARY|INTERNET_FLAG_EXISTING_CONNECT));
00389 if(!f) return(false);
00390
00391 TCHAR path[MAX_PATH];
00392 GetTempPath(MAX_PATH, path);
00393
00394 fn = path + fn.Mid(fn.ReverseFind('/')+1);
00395 int i = fn.Find(_T("?"));
00396 if(i > 0) fn = fn.Left(i);
00397 CFile temp;
00398 if(!temp.Open(fn, modeCreate|modeWrite|typeBinary|shareDenyWrite))
00399 {
00400 f->Close();
00401 return(false);
00402 }
00403
00404 BYTE buff[1024];
00405 int len, total = 0;
00406 while((len = f->Read(buff, 1024)) == 1024 && (m_llMaxSize < 0 || (total+=1024) < m_llMaxSize))
00407 temp.Write(buff, len);
00408 if(len > 0) temp.Write(buff, len);
00409
00410 m_tempfn = fn;
00411
00412 f->Close();
00413 }
00414 catch(CInternetException* ie)
00415 {
00416 ie->Delete();
00417 return(false);
00418 }
00419
00420 return __super::Open(m_tempfn);
00421 }
00422
00423 bool CWebTextFile::Save(LPCTSTR lpszFileName, enc e)
00424 {
00425
00426 ASSERT(0);
00427 return(false);
00428 }
00429
00430 void CWebTextFile::Close()
00431 {
00432 __super::Close();
00433
00434 if(!m_tempfn.IsEmpty())
00435 {
00436 _tremove(m_tempfn);
00437 m_tempfn.Empty();
00438 }
00439 }
00440
00442
00443 CStringW AToW(CStringA str)
00444 {
00445 CStringW ret;
00446 for(int i = 0, j = str.GetLength(); i < j; i++)
00447 ret += (WCHAR)(BYTE)str[i];
00448 return(ret);
00449 }
00450
00451 CStringA WToA(CStringW str)
00452 {
00453 CStringA ret;
00454 for(int i = 0, j = str.GetLength(); i < j; i++)
00455 ret += (CHAR)(WORD)str[i];
00456 return(ret);
00457 }
00458
00459 CString AToT(CStringA str)
00460 {
00461 CString ret;
00462 for(int i = 0, j = str.GetLength(); i < j; i++)
00463 ret += (TCHAR)(BYTE)str[i];
00464 return(ret);
00465 }
00466
00467 CString WToT(CStringW str)
00468 {
00469 CString ret;
00470 for(int i = 0, j = str.GetLength(); i < j; i++)
00471 ret += (TCHAR)(WORD)str[i];
00472 return(ret);
00473 }
00474
00475 CStringA TToA(CString str)
00476 {
00477 CStringA ret;
00478 #ifdef UNICODE
00479 for(int i = 0, j = str.GetLength(); i < j; i++)
00480 ret += (CHAR)(BYTE)str[i];
00481 #else
00482 ret = str;
00483 #endif
00484 return(ret);
00485 }
00486
00487 CStringW TToW(CString str)
00488 {
00489 CStringW ret;
00490 #ifdef UNICODE
00491 ret = str;
00492 #else
00493 for(int i = 0, j = str.GetLength(); i < j; i++)
00494 ret += (WCHAR)(BYTE)str[i];
00495 #endif
00496 return(ret);
00497 }