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)
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
27 CTextFile::CTextFile(enc e
)
29 m_encoding
= m_defaultencoding
= e
;
33 bool CTextFile::Open(LPCTSTR lpszFileName
)
35 if(!__super::Open(lpszFileName
, modeRead
|typeBinary
|shareDenyWrite
))
38 m_encoding
= m_defaultencoding
;
41 if(__super::GetLength() >= 2)
44 if(sizeof(w
) != Read(&w
, sizeof(w
)))
45 return Close(), false;
57 else if(w
== 0xbbef && __super::GetLength() >= 3)
60 if(sizeof(b
) != Read(&b
, sizeof(b
)))
61 return Close(), false;
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
))
81 bool CTextFile::Save(LPCTSTR lpszFileName
, enc e
)
83 if(!__super::Open(lpszFileName
, modeCreate
|modeWrite
|shareDenyWrite
|(e
==ASCII
?typeText
:typeBinary
)))
88 BYTE b
[3] = {0xef,0xbb,0xbf};
93 BYTE b
[2] = {0xff,0xfe};
98 BYTE b
[2] = {0xfe,0xff};
107 void CTextFile::SetEncoding(enc e
)
112 CTextFile::enc
CTextFile::GetEncoding()
117 bool CTextFile::IsUnicode()
119 return m_encoding
== UTF8
|| m_encoding
== LE16
|| m_encoding
== BE16
;
124 CString
CTextFile::GetFilePath() const
126 // to avoid a CException coming from CTime
127 return m_strFileName
; // __super::GetFilePath();
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();
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
;
162 void CTextFile::WriteString(LPCSTR lpsz
/*CStringA str*/)
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*/)
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
214 else if(0x80 <= c
&& c
< 0x800) // 110xxxxx 10xxxxxx
216 c
= 0xc080|((c
<<2)&0x1f00)|(c
&0x003f);
217 Write((BYTE
*)&c
+1, 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);
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
)
254 if(m_encoding
== ASCII
)
257 fEOF
= !__super::ReadString(s
);
260 else if(m_encoding
== ANSI
)
263 while(Read(&c
, sizeof(c
)) == sizeof(c
))
266 if(c
== '\r') continue;
271 else if(m_encoding
== UTF8
)
274 while(Read(&b
, sizeof(b
)) == sizeof(b
))
278 if(!(b
&0x80)) // 0xxxxxxx
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;
296 else if(m_encoding
== LE16
)
299 while(Read(&w
, sizeof(w
)) == sizeof(w
))
303 if(!(w
&0xff00)) c
= w
&0xff;
304 if(c
== '\r') continue;
309 else if(m_encoding
== BE16
)
312 while(Read(&w
, sizeof(w
)) == sizeof(w
))
316 if(!(w
&0xff)) c
= w
>>8;
317 if(c
== '\r') continue;
326 BOOL
CTextFile::ReadString(CStringW
& str
)
332 if(m_encoding
== ASCII
)
335 fEOF
= !__super::ReadString(s
);
338 else if(m_encoding
== ANSI
)
342 while(Read(&c
, sizeof(c
)) == sizeof(c
))
345 if(c
== '\r') continue;
349 str
= CStringW(CString(stra
)); // TODO: codepage
351 else if(m_encoding
== UTF8
)
354 while(Read(&b
, sizeof(b
)) == sizeof(b
))
358 if(!(b
&0x80)) // 0xxxxxxx
362 else if((b
&0xe0) == 0xc0) // 110xxxxx 10xxxxxx
365 if(Read(&b
, sizeof(b
)) != sizeof(b
)) break;
368 else if((b
&0xf0) == 0xe0) // 1110xxxx 10xxxxxx 10xxxxxx
371 if(Read(&b
, sizeof(b
)) != sizeof(b
)) break;
373 if(Read(&b
, sizeof(b
)) != sizeof(b
)) break;
376 if(c
== '\r') continue;
381 else if(m_encoding
== LE16
)
384 while(Read(&wc
, sizeof(wc
)) == sizeof(wc
))
387 if(wc
== '\r') continue;
388 if(wc
== '\n') break;
392 else if(m_encoding
== BE16
)
395 while(Read(&wc
, sizeof(wc
)) == sizeof(wc
))
398 wc
= ((wc
>>8)&0x00ff)|((wc
<<8)&0xff00);
399 if(wc
== '\r') continue;
400 if(wc
== '\n') break;
408 UINT
CTextFile::Read( void* lpBuf
, UINT nCount
)
410 return __super::Read(lpBuf
,nCount
);
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
);
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
);
442 if(!temp
.Open(fn
, modeCreate
|modeWrite
|typeBinary
|shareDenyWrite
))
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
);
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
)
464 return __super::Open(m_tempfn
);
467 bool CWebTextFile::Save(LPCTSTR lpszFileName
, enc e
)
469 // CWebTextFile is read-only...
474 void CWebTextFile::Close()
478 if(!m_tempfn
.IsEmpty())
485 ///////////////////////////////////////////////////////////////
487 CStringW
AToW(const CStringA
& str
)
490 for(int i
= 0, j
= str
.GetLength(); i
< j
; i
++)
491 ret
+= (WCHAR
)(BYTE
)str
[i
];
495 CStringA
WToA(const CStringW
& str
)
498 for(int i
= 0, j
= str
.GetLength(); i
< j
; i
++)
499 ret
+= (CHAR
)(WORD
)str
[i
];
503 CString
AToT(const CStringA
& str
)
506 for(int i
= 0, j
= str
.GetLength(); i
< j
; i
++)
507 ret
+= (TCHAR
)(BYTE
)str
[i
];
511 CString
WToT(const CStringW
& str
)
517 for(int i
= 0, j
= str
.GetLength(); i
< j
; i
++)
518 ret
+= (TCHAR
)(WORD
)str
[i
];
525 CStringA
TToA(const CString
& str
)
529 for(int i
= 0, j
= str
.GetLength(); i
< j
; i
++)
530 ret
+= (CHAR
)(BYTE
)str
[i
];
537 CStringW
TToW(const CString
& str
)
543 for(int i
= 0, j
= str
.GetLength(); i
< j
; i
++)
544 ret
+= (WCHAR
)(BYTE
)str
[i
];