]>
git.saurik.com Git - wxWidgets.git/blob - src/common/textfile.cpp
1 ///////////////////////////////////////////////////////////////////////////////
3 // Purpose: implementation of wxTextFile class
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence: wxWindows license
10 ///////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
17 #pragma implementation "textfile.h"
20 #include "wx/wxprec.h"
30 #if wxUSE_TEXTFILE && wxUSE_FILE
32 #include <wx/string.h>
36 #include <wx/textfile.h>
38 // ============================================================================
39 // wxTextFile class implementation
40 // ============================================================================
42 // ----------------------------------------------------------------------------
44 // ----------------------------------------------------------------------------
46 // default type is the native one
47 const wxTextFileType
wxTextFile::typeDefault
=
48 #if defined(__WINDOWS__)
50 #elif defined(__UNIX__)
52 #elif defined(__WXMAC__)
56 #error "wxTextFile: unsupported platform."
60 // ----------------------------------------------------------------------------
62 // ----------------------------------------------------------------------------
64 wxTextFile::wxTextFile(const wxString
& strFile
) : m_strFile(strFile
)
70 wxTextFile::~wxTextFile()
72 // m_file dtor called automatically
75 // ----------------------------------------------------------------------------
77 // ----------------------------------------------------------------------------
79 bool wxTextFile::Open(const wxString
& strFile
)
86 bool wxTextFile::Open()
88 // file name must be either given in ctor or in Open(const wxString&)
89 wxASSERT( !m_strFile
.IsEmpty() );
91 // open file in read-only mode
92 if ( !m_file
.Open(m_strFile
) )
95 // read file into memory
103 // analyse some lines of the file trying to guess it's type.
104 // if it fails, it assumes the native type for our platform.
105 wxTextFileType
wxTextFile::GuessType() const
107 // file should be opened and we must be in it's beginning
108 wxASSERT( m_file
.IsOpened() && m_file
.Tell() == 0 );
110 // scan the file lines
111 size_t nUnix
= 0, // number of '\n's alone
112 nDos
= 0, // number of '\r\n'
113 nMac
= 0; // number of '\r's
115 // we take MAX_LINES_SCAN in the beginning, middle and the end of file
116 #define MAX_LINES_SCAN (10)
117 size_t nCount
= m_aLines
.Count() / 3,
118 nScan
= nCount
> 3*MAX_LINES_SCAN
? MAX_LINES_SCAN
: nCount
/ 3;
120 #define AnalyseLine(n) \
121 switch ( m_aTypes[n] ) { \
122 case wxTextFileType_Unix: nUnix++; break; \
123 case wxTextFileType_Dos: nDos++; break; \
124 case wxTextFileType_Mac: nMac++; break; \
125 default: wxFAIL_MSG(_("unknown line terminator")); \
129 for ( n
= 0; n
< nScan
; n
++ ) // the beginning
131 for ( n
= (nCount
- nScan
)/2; n
< (nCount
+ nScan
)/2; n
++ )
133 for ( n
= nCount
- nScan
; n
< nCount
; n
++ )
138 // interpret the results (@@ far from being even 50% fool proof)
139 if ( nDos
+ nUnix
+ nMac
== 0 ) {
140 // no newlines at all
141 wxLogWarning(_("'%s' is probably a binary file."), m_strFile
.c_str());
144 #define GREATER_OF(t1, t2) n##t1 == n##t2 ? typeDefault \
146 ? wxTextFileType_##t1 \
147 : wxTextFileType_##t2
149 // Watcom C++ doesn't seem to be able to handle the macro
150 #if !defined(__WATCOMC__)
152 return GREATER_OF(Dos
, Mac
);
153 else if ( nDos
< nUnix
)
154 return GREATER_OF(Unix
, Mac
);
157 return nMac
> nDos
? wxTextFileType_Mac
: typeDefault
;
159 #endif // __WATCOMC__
167 bool wxTextFile::Read()
169 // file should be opened and we must be in it's beginning
170 wxASSERT( m_file
.IsOpened() && m_file
.Tell() == 0 );
173 char ch
, chLast
= '\0';
176 while ( !m_file
.Eof() ) {
177 nRead
= m_file
.Read(buf
, WXSIZEOF(buf
));
178 if ( nRead
== wxInvalidOffset
) {
179 // read error (error message already given in wxFile::Read)
183 for ( n
= 0; n
< nRead
; n
++ ) {
187 // Dos/Unix line termination
189 m_aTypes
.Add(chLast
== '\r' ? wxTextFileType_Dos
190 : wxTextFileType_Unix
);
196 if ( chLast
== '\r' ) {
199 m_aTypes
.Add(wxTextFileType_Mac
);
206 if ( chLast
== '\r' ) {
207 // Mac line termination
209 m_aTypes
.Add(wxTextFileType_Mac
);
214 // add to the current line
221 // anything in the last line?
222 if ( !str
.IsEmpty() ) {
223 m_aTypes
.Add(wxTextFileType_None
); // no line terminator
230 bool wxTextFile::Close()
240 bool wxTextFile::Write(wxTextFileType typeNew
)
242 wxTempFile
fileTmp(m_strFile
);
244 if ( !fileTmp
.IsOpened() ) {
245 wxLogError(_("can't write file '%s' to disk."), m_strFile
.c_str());
249 size_t nCount
= m_aLines
.Count();
250 for ( size_t n
= 0; n
< nCount
; n
++ ) {
251 fileTmp
.Write(m_aLines
[n
] +
252 GetEOL(typeNew
== wxTextFileType_None
? m_aTypes
[n
]
256 // replace the old file with this one
257 return fileTmp
.Commit();
260 const wxChar
*wxTextFile::GetEOL(wxTextFileType type
)
263 case wxTextFileType_None
: return _T("");
264 case wxTextFileType_Unix
: return _T("\n");
265 case wxTextFileType_Dos
: return _T("\r\n");
266 case wxTextFileType_Mac
: return _T("\r");
269 wxFAIL_MSG(_T("bad file type in wxTextFile::GetEOL."));
270 return (const wxChar
*) NULL
;