]>
Commit | Line | Data |
---|---|---|
c801d85f | 1 | /////////////////////////////////////////////////////////////////////////////// |
a3a584a7 | 2 | // Name: src/common/textfile.cpp |
c801d85f KB |
3 | // Purpose: implementation of wxTextFile class |
4 | // Author: Vadim Zeitlin | |
ba7f9a90 | 5 | // Modified by: |
c801d85f KB |
6 | // Created: 03.04.98 |
7 | // RCS-ID: $Id$ | |
8 | // Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr> | |
65571936 | 9 | // Licence: wxWindows licence |
c801d85f KB |
10 | /////////////////////////////////////////////////////////////////////////////// |
11 | ||
12 | // ============================================================================ | |
13 | // headers | |
14 | // ============================================================================ | |
15 | ||
c801d85f KB |
16 | #include "wx/wxprec.h" |
17 | ||
18 | #ifdef __BORLANDC__ | |
a1b82138 | 19 | #pragma hdrstop |
c801d85f KB |
20 | #endif //__BORLANDC__ |
21 | ||
a3a584a7 | 22 | #if !wxUSE_FILE || !wxUSE_TEXTBUFFER |
a1b82138 VZ |
23 | #undef wxUSE_TEXTFILE |
24 | #define wxUSE_TEXTFILE 0 | |
25 | #endif // wxUSE_FILE | |
26 | ||
a3a584a7 VZ |
27 | #if wxUSE_TEXTFILE |
28 | ||
ce4169a4 | 29 | #ifndef WX_PRECOMP |
68c97af3 VZ |
30 | #include "wx/string.h" |
31 | #include "wx/intl.h" | |
32 | #include "wx/file.h" | |
33 | #include "wx/log.h" | |
ce4169a4 RR |
34 | #endif |
35 | ||
a3a584a7 | 36 | #include "wx/textfile.h" |
68c97af3 | 37 | #include "wx/filename.h" |
c801d85f KB |
38 | |
39 | // ============================================================================ | |
40 | // wxTextFile class implementation | |
41 | // ============================================================================ | |
42 | ||
a3a584a7 VZ |
43 | wxTextFile::wxTextFile(const wxString& strFileName) |
44 | : wxTextBuffer(strFileName) | |
a1b82138 | 45 | { |
a1b82138 VZ |
46 | } |
47 | ||
c801d85f KB |
48 | |
49 | // ---------------------------------------------------------------------------- | |
50 | // file operations | |
51 | // ---------------------------------------------------------------------------- | |
52 | ||
a3a584a7 | 53 | bool wxTextFile::OnExists() const |
ef8d96c2 | 54 | { |
a3a584a7 | 55 | return wxFile::Exists(m_strBufferName); |
ef8d96c2 VZ |
56 | } |
57 | ||
1b6dea5d | 58 | |
a3a584a7 | 59 | bool wxTextFile::OnOpen(const wxString &strBufferName, wxTextBufferOpenMode OpenMode) |
1b6dea5d | 60 | { |
77f859c3 VZ |
61 | wxFile::OpenMode FileOpenMode; |
62 | ||
63 | switch ( OpenMode ) | |
64 | { | |
65 | default: | |
66 | wxFAIL_MSG( _T("unknown open mode in wxTextFile::Open") ); | |
67 | // fall through | |
27752aab | 68 | |
a3a584a7 VZ |
69 | case ReadAccess : |
70 | FileOpenMode = wxFile::read; | |
71 | break; | |
77f859c3 | 72 | |
a3a584a7 VZ |
73 | case WriteAccess : |
74 | FileOpenMode = wxFile::write; | |
75 | break; | |
77f859c3 | 76 | } |
1b6dea5d | 77 | |
a3a584a7 | 78 | return m_file.Open(strBufferName.c_str(), FileOpenMode); |
c801d85f KB |
79 | } |
80 | ||
c801d85f | 81 | |
a3a584a7 | 82 | bool wxTextFile::OnClose() |
c801d85f | 83 | { |
a3a584a7 | 84 | return m_file.Close(); |
c801d85f KB |
85 | } |
86 | ||
a3a584a7 VZ |
87 | |
88 | bool wxTextFile::OnRead(wxMBConv& conv) | |
c801d85f | 89 | { |
d9ade1df | 90 | // file should be opened and we must be in it's beginning |
86948c99 VZ |
91 | wxASSERT( m_file.IsOpened() && |
92 | (m_file.GetKind() != wxFILE_KIND_DISK || m_file.Tell() == 0) ); | |
adfed1ca | 93 | |
b260e323 VZ |
94 | static const size_t BUF_SIZE = 1024; |
95 | #if wxUSE_UNICODE | |
96 | static const size_t NUL_SIZE = 4; | |
97 | #else | |
98 | static const size_t NUL_SIZE = 1; | |
99 | #endif | |
100 | ||
101 | char buf[BUF_SIZE + NUL_SIZE]; | |
86948c99 VZ |
102 | wxChar chLast = '\0'; |
103 | wxString str; | |
c801d85f | 104 | |
86948c99 | 105 | for ( ;; ) |
d9ade1df | 106 | { |
86948c99 | 107 | // leave space for trailing NUL |
b260e323 | 108 | ssize_t nRead = m_file.Read(buf, BUF_SIZE); |
86948c99 VZ |
109 | |
110 | if ( nRead == wxInvalidOffset ) | |
d9ade1df VS |
111 | { |
112 | // read error (error message already given in wxFile::Read) | |
cb719f2e | 113 | return false; |
d9ade1df VS |
114 | } |
115 | ||
86948c99 VZ |
116 | if ( nRead == 0 ) |
117 | break; | |
118 | ||
b260e323 VZ |
119 | #if wxUSE_UNICODE |
120 | // we have to properly NUL-terminate the string for any encoding it may | |
121 | // use -- 4 NULs should be enough for everyone (this is why we add 4 | |
122 | // extra bytes to the buffer) | |
123 | buf[nRead] = | |
124 | buf[nRead + 1] = | |
125 | buf[nRead + 2] = | |
126 | buf[nRead + 3] = '\0'; | |
86948c99 VZ |
127 | |
128 | // append to the remains of the last block, don't overwrite | |
b260e323 VZ |
129 | wxString strbuf(buf, conv); |
130 | if ( strbuf.empty() ) | |
131 | { | |
132 | // conversion failed | |
133 | return false; | |
134 | } | |
135 | ||
136 | str += strbuf; | |
137 | #else // ANSI | |
39987096 | 138 | wxUnusedVar(conv); |
b260e323 VZ |
139 | buf[nRead] = '\0'; |
140 | str += buf; | |
141 | #endif // wxUSE_UNICODE/!wxUSE_UNICODE | |
142 | ||
86948c99 VZ |
143 | |
144 | // the beginning of the current line, changes inside the loop | |
0cc88b4b VZ |
145 | wxString::const_iterator lineStart = str.begin(); |
146 | const wxString::const_iterator end = str.end(); | |
147 | for ( wxString::const_iterator p = lineStart; p != end; p++ ) | |
d9ade1df | 148 | { |
86948c99 | 149 | const wxChar ch = *p; |
cb719f2e | 150 | switch ( ch ) |
d9ade1df VS |
151 | { |
152 | case '\n': | |
86948c99 VZ |
153 | // could be a DOS or Unix EOL |
154 | if ( chLast == '\r' ) | |
155 | { | |
156 | AddLine(wxString(lineStart, p - 1), wxTextFileType_Dos); | |
157 | } | |
158 | else // bare '\n', Unix style | |
159 | { | |
160 | AddLine(wxString(lineStart, p), wxTextFileType_Unix); | |
161 | } | |
162 | ||
163 | lineStart = p + 1; | |
d9ade1df VS |
164 | break; |
165 | ||
166 | case '\r': | |
cb719f2e | 167 | if ( chLast == '\r' ) |
d9ade1df VS |
168 | { |
169 | // Mac empty line | |
170 | AddLine(wxEmptyString, wxTextFileType_Mac); | |
86948c99 | 171 | lineStart = p + 1; |
d9ade1df | 172 | } |
86948c99 VZ |
173 | //else: we don't what this is yet -- could be a Mac EOL or |
174 | // start of DOS EOL so wait for next char | |
d9ade1df VS |
175 | break; |
176 | ||
177 | default: | |
178 | if ( chLast == '\r' ) | |
179 | { | |
180 | // Mac line termination | |
86948c99 VZ |
181 | AddLine(wxString(lineStart, p - 1), wxTextFileType_Mac); |
182 | lineStart = p; | |
d9ade1df VS |
183 | } |
184 | } | |
86948c99 VZ |
185 | |
186 | chLast = ch; | |
d9ade1df | 187 | } |
86948c99 VZ |
188 | |
189 | // remove the part we already processed | |
190 | str.erase(0, lineStart - str.begin()); | |
191 | } | |
d9ade1df VS |
192 | |
193 | // anything in the last line? | |
86948c99 | 194 | if ( !str.empty() ) |
d9ade1df | 195 | { |
86948c99 | 196 | AddLine(str, wxTextFileType_None); // no line terminator |
c801d85f | 197 | } |
c801d85f | 198 | |
cb719f2e | 199 | return true; |
c801d85f KB |
200 | } |
201 | ||
f42d2aba | 202 | |
a3a584a7 | 203 | bool wxTextFile::OnWrite(wxTextFileType typeNew, wxMBConv& conv) |
c801d85f | 204 | { |
68c97af3 | 205 | wxFileName fn = m_strBufferName; |
baed1077 JS |
206 | |
207 | // We do NOT want wxPATH_NORM_CASE here, or the case will not | |
208 | // be preserved. | |
68c97af3 | 209 | if ( !fn.IsAbsolute() ) |
32a0d013 VS |
210 | fn.Normalize(wxPATH_NORM_ENV_VARS | wxPATH_NORM_DOTS | wxPATH_NORM_TILDE | |
211 | wxPATH_NORM_ABSOLUTE | wxPATH_NORM_LONG); | |
68c97af3 | 212 | |
deab4540 | 213 | wxTempFile fileTmp(fn.GetFullPath()); |
c801d85f | 214 | |
a3a584a7 VZ |
215 | if ( !fileTmp.IsOpened() ) { |
216 | wxLogError(_("can't write buffer '%s' to disk."), m_strBufferName.c_str()); | |
cb719f2e | 217 | return false; |
a3a584a7 | 218 | } |
c801d85f | 219 | |
a3a584a7 VZ |
220 | size_t nCount = GetLineCount(); |
221 | for ( size_t n = 0; n < nCount; n++ ) { | |
222 | fileTmp.Write(GetLine(n) + | |
223 | GetEOL(typeNew == wxTextFileType_None ? GetLineType(n) | |
224 | : typeNew), | |
225 | conv); | |
226 | } | |
c801d85f | 227 | |
a3a584a7 VZ |
228 | // replace the old file with this one |
229 | return fileTmp.Commit(); | |
ba7f9a90 | 230 | } |
6164d85e | 231 | |
a1b82138 | 232 | #endif // wxUSE_TEXTFILE |
6164d85e | 233 |