Remove unused ProjectConfiguration
[xy_vsfilter.git] / src / subtitles / TextFile.cpp
blob46683ac1421539d4748a18c89f7a1f0caf65d6c0
1 /*
2 * Copyright (C) 2003-2006 Gabest
3 * http://www.gabest.org
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.
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
22 #include "stdafx.h"
23 #include <atlbase.h>
24 #include <afxinet.h>
25 #include "TextFile.h"
27 CTextFile::CTextFile(enc e)
29 m_encoding = m_defaultencoding = e;
30 m_offset = 0;
33 bool CTextFile::Open(LPCTSTR lpszFileName)
35 if(!__super::Open(lpszFileName, modeRead|typeBinary|shareDenyWrite))
36 return(false);
38 m_encoding = m_defaultencoding;
39 m_offset = 0;
41 if(__super::GetLength() >= 2)
43 WORD w;
44 if(sizeof(w) != Read(&w, sizeof(w)))
45 return Close(), false;
47 if(w == 0xfeff)
49 m_encoding = LE16;
50 m_offset = 2;
52 else if(w == 0xfffe)
54 m_encoding = BE16;
55 m_offset = 2;
57 else if(w == 0xbbef && __super::GetLength() >= 3)
59 BYTE b;
60 if(sizeof(b) != Read(&b, sizeof(b)))
61 return Close(), false;
63 if(b == 0xbf)
65 m_encoding = UTF8;
66 m_offset = 3;
71 if(m_encoding == m_defaultencoding)
73 __super::Close(); // CWebTextFile::Close() would delete the temp file if we called it...
74 if(!__super::Open(lpszFileName, modeRead|typeText|shareDenyWrite))
75 return(false);
78 return(true);
81 bool CTextFile::Save(LPCTSTR lpszFileName, enc e)
83 if(!__super::Open(lpszFileName, modeCreate|modeWrite|shareDenyWrite|(e==ASCII?typeText:typeBinary)))
84 return(false);
86 if(e == UTF8)
88 BYTE b[3] = {0xef,0xbb,0xbf};
89 Write(b, sizeof(b));
91 else if(e == LE16)
93 BYTE b[2] = {0xff,0xfe};
94 Write(b, sizeof(b));
96 else if(e == BE16)
98 BYTE b[2] = {0xfe,0xff};
99 Write(b, sizeof(b));
102 m_encoding = e;
104 return true;
107 void CTextFile::SetEncoding(enc e)
109 m_encoding = e;
112 CTextFile::enc CTextFile::GetEncoding()
114 return m_encoding;
117 bool CTextFile::IsUnicode()
119 return m_encoding == UTF8 || m_encoding == LE16 || m_encoding == BE16;
122 // CFile
124 CString CTextFile::GetFilePath() const
126 // to avoid a CException coming from CTime
127 return m_strFileName; // __super::GetFilePath();
130 // CStdioFile
132 ULONGLONG CTextFile::GetPosition() const
134 return(CStdioFile::GetPosition() - m_offset);
137 ULONGLONG CTextFile::GetLength() const
139 return(CStdioFile::GetLength() - m_offset);
142 ULONGLONG CTextFile::Seek(LONGLONG lOff, UINT nFrom)
144 ULONGLONG pos = GetPosition();
145 ULONGLONG len = GetLength();
147 switch(nFrom)
149 default:
150 case begin: lOff = lOff; break;
151 case current: lOff = pos + lOff; break;
152 case end: lOff = len - lOff; break;
155 lOff = max(min(lOff, len), 0) + m_offset;
157 pos = CStdioFile::Seek(lOff, begin) - m_offset;
159 return(pos);
162 void CTextFile::WriteString(LPCSTR lpsz/*CStringA str*/)
164 CStringA str(lpsz);
166 if(m_encoding == ASCII)
168 __super::WriteString(AToT(str));
170 else if(m_encoding == ANSI)
172 str.Replace("\n", "\r\n");
173 Write((LPCSTR)str, str.GetLength());
175 else if(m_encoding == UTF8)
177 WriteString(AToW(str));
179 else if(m_encoding == LE16)
181 WriteString(AToW(str));
183 else if(m_encoding == BE16)
185 WriteString(AToW(str));
189 void CTextFile::WriteString(LPCWSTR lpsz/*CStringW str*/)
191 CStringW str(lpsz);
193 if(m_encoding == ASCII)
195 __super::WriteString(WToT(str));
197 else if(m_encoding == ANSI)
199 str.Replace(L"\n", L"\r\n");
200 CStringA stra = CStringA(CString(str)); // TODO: codepage
201 Write((LPCSTR)stra, stra.GetLength());
203 else if(m_encoding == UTF8)
205 str.Replace(L"\n", L"\r\n");
206 for(int i = 0; i < str.GetLength(); i++)
208 DWORD c = (WORD)str[i];
210 if(0 <= c && c < 0x80) // 0xxxxxxx
212 Write(&c, 1);
214 else if(0x80 <= c && c < 0x800) // 110xxxxx 10xxxxxx
216 c = 0xc080|((c<<2)&0x1f00)|(c&0x003f);
217 Write((BYTE*)&c+1, 1);
218 Write(&c, 1);
220 else if(0x800 <= c && c < 0xFFFF) // 1110xxxx 10xxxxxx 10xxxxxx
222 c = 0xe08080|((c<<4)&0x0f0000)|((c<<2)&0x3f00)|(c&0x003f);
223 Write((BYTE*)&c+2, 1);
224 Write((BYTE*)&c+1, 1);
225 Write(&c, 1);
227 else
229 c = '?';
230 Write(&c, 1);
234 else if(m_encoding == LE16)
236 str.Replace(L"\n", L"\r\n");
237 Write((LPCWSTR)str, str.GetLength()*2);
239 else if(m_encoding == BE16)
241 str.Replace(L"\n", L"\r\n");
242 for(int i = 0; i < str.GetLength(); i++)
243 str.SetAt(i, ((str[i]>>8)&0x00ff)|((str[i]<<8)&0xff00));
244 Write((LPCWSTR)str, str.GetLength()*2);
248 BOOL CTextFile::ReadString(CStringA& str)
250 bool fEOF = true;
252 str.Empty();
254 if(m_encoding == ASCII)
256 CString s;
257 fEOF = !__super::ReadString(s);
258 str = TToA(s);
260 else if(m_encoding == ANSI)
262 char c;
263 while(Read(&c, sizeof(c)) == sizeof(c))
265 fEOF = false;
266 if(c == '\r') continue;
267 if(c == '\n') break;
268 str += c;
271 else if(m_encoding == UTF8)
273 BYTE b;
274 while(Read(&b, sizeof(b)) == sizeof(b))
276 fEOF = false;
277 char c = '?';
278 if(!(b&0x80)) // 0xxxxxxx
280 c = b&0x7f;
282 else if((b&0xe0) == 0xc0) // 110xxxxx 10xxxxxx
284 if(Read(&b, sizeof(b)) != sizeof(b)) break;
286 else if((b&0xf0) == 0xe0) // 1110xxxx 10xxxxxx 10xxxxxx
288 if(Read(&b, sizeof(b)) != sizeof(b)) break;
289 if(Read(&b, sizeof(b)) != sizeof(b)) break;
291 if(c == '\r') continue;
292 if(c == '\n') break;
293 str += c;
296 else if(m_encoding == LE16)
298 WORD w;
299 while(Read(&w, sizeof(w)) == sizeof(w))
301 fEOF = false;
302 char c = '?';
303 if(!(w&0xff00)) c = w&0xff;
304 if(c == '\r') continue;
305 if(c == '\n') break;
306 str += c;
309 else if(m_encoding == BE16)
311 WORD w;
312 while(Read(&w, sizeof(w)) == sizeof(w))
314 fEOF = false;
315 char c = '?';
316 if(!(w&0xff)) c = w>>8;
317 if(c == '\r') continue;
318 if(c == '\n') break;
319 str += c;
323 return(!fEOF);
326 BOOL CTextFile::ReadString(CStringW& str)
328 bool fEOF = true;
330 str.Empty();
332 if(m_encoding == ASCII)
334 CString s;
335 fEOF = !__super::ReadString(s);
336 str = TToW(s);
338 else if(m_encoding == ANSI)
340 CStringA stra;
341 char c;
342 while(Read(&c, sizeof(c)) == sizeof(c))
344 fEOF = false;
345 if(c == '\r') continue;
346 if(c == '\n') break;
347 stra += c;
349 str = CStringW(CString(stra)); // TODO: codepage
351 else if(m_encoding == UTF8)
353 BYTE b;
354 while(Read(&b, sizeof(b)) == sizeof(b))
356 fEOF = false;
357 WCHAR c = '?';
358 if(!(b&0x80)) // 0xxxxxxx
360 c = b&0x7f;
362 else if((b&0xe0) == 0xc0) // 110xxxxx 10xxxxxx
364 c = (b&0x1f)<<6;
365 if(Read(&b, sizeof(b)) != sizeof(b)) break;
366 c |= (b&0x3f);
368 else if((b&0xf0) == 0xe0) // 1110xxxx 10xxxxxx 10xxxxxx
370 c = (b&0x0f)<<12;
371 if(Read(&b, sizeof(b)) != sizeof(b)) break;
372 c |= (b&0x3f)<<6;
373 if(Read(&b, sizeof(b)) != sizeof(b)) break;
374 c |= (b&0x3f);
376 if(c == '\r') continue;
377 if(c == '\n') break;
378 str += c;
381 else if(m_encoding == LE16)
383 WCHAR wc;
384 while(Read(&wc, sizeof(wc)) == sizeof(wc))
386 fEOF = false;
387 if(wc == '\r') continue;
388 if(wc == '\n') break;
389 str += wc;
392 else if(m_encoding == BE16)
394 WCHAR wc;
395 while(Read(&wc, sizeof(wc)) == sizeof(wc))
397 fEOF = false;
398 wc = ((wc>>8)&0x00ff)|((wc<<8)&0xff00);
399 if(wc == '\r') continue;
400 if(wc == '\n') break;
401 str += wc;
405 return(!fEOF);
408 UINT CTextFile::Read( void* lpBuf, UINT nCount )
410 return __super::Read(lpBuf,nCount);
413 // CWebTextFile
416 CWebTextFile::CWebTextFile(LONGLONG llMaxSize)
417 : m_llMaxSize(llMaxSize)
421 bool CWebTextFile::Open(LPCTSTR lpszFileName)
423 CString fn(lpszFileName);
425 if(fn.Find(_T("http://")) != 0)
426 return __super::Open(lpszFileName);
430 CInternetSession is;
432 CAutoPtr<CStdioFile> f(is.OpenURL(fn, 1, INTERNET_FLAG_TRANSFER_BINARY|INTERNET_FLAG_EXISTING_CONNECT));
433 if(!f) return(false);
435 TCHAR path[MAX_PATH];
436 GetTempPath(MAX_PATH, path);
438 fn = path + fn.Mid(fn.ReverseFind('/')+1);
439 int i = fn.Find(_T("?"));
440 if(i > 0) fn = fn.Left(i);
441 CFile temp;
442 if(!temp.Open(fn, modeCreate|modeWrite|typeBinary|shareDenyWrite))
444 f->Close();
445 return(false);
448 BYTE buff[1024];
449 int len, total = 0;
450 while((len = f->Read(buff, 1024)) == 1024 && (m_llMaxSize < 0 || (total+=1024) < m_llMaxSize))
451 temp.Write(buff, len);
452 if(len > 0) temp.Write(buff, len);
454 m_tempfn = fn;
456 f->Close(); // must close it because the desctructor doesn't seem to do it and we will get an exception when "is" is destroying
458 catch(CInternetException* ie)
460 ie->Delete();
461 return(false);
464 return __super::Open(m_tempfn);
467 bool CWebTextFile::Save(LPCTSTR lpszFileName, enc e)
469 // CWebTextFile is read-only...
470 ASSERT(0);
471 return(false);
474 void CWebTextFile::Close()
476 __super::Close();
478 if(!m_tempfn.IsEmpty())
480 _tremove(m_tempfn);
481 m_tempfn.Empty();
485 ///////////////////////////////////////////////////////////////
487 CStringW AToW(const CStringA& str)
489 CStringW ret;
490 for(int i = 0, j = str.GetLength(); i < j; i++)
491 ret += (WCHAR)(BYTE)str[i];
492 return(ret);
495 CStringA WToA(const CStringW& str)
497 CStringA ret;
498 for(int i = 0, j = str.GetLength(); i < j; i++)
499 ret += (CHAR)(WORD)str[i];
500 return(ret);
503 CString AToT(const CStringA& str)
505 CString ret;
506 for(int i = 0, j = str.GetLength(); i < j; i++)
507 ret += (TCHAR)(BYTE)str[i];
508 return(ret);
511 CString WToT(const CStringW& str)
513 #ifdef UNICODE
514 return str;
515 #else
516 CString ret;
517 for(int i = 0, j = str.GetLength(); i < j; i++)
518 ret += (TCHAR)(WORD)str[i];
519 return(ret);
520 ret = str;
521 return(ret);
522 #endif
525 CStringA TToA(const CString& str)
527 CStringA ret;
528 #ifdef UNICODE
529 for(int i = 0, j = str.GetLength(); i < j; i++)
530 ret += (CHAR)(BYTE)str[i];
531 #else
532 ret = str;
533 #endif
534 return(ret);
537 CStringW TToW(const CString& str)
539 CStringW ret;
540 #ifdef UNICODE
541 ret = str;
542 #else
543 for(int i = 0, j = str.GetLength(); i < j; i++)
544 ret += (WCHAR)(BYTE)str[i];
545 #endif
546 return(ret);