]> git.saurik.com Git - wxWidgets.git/blob - src/common/textfile.cpp
Merge #3 from the 2.6 branch, containing last set of changes before
[wxWidgets.git] / src / common / textfile.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/textfile.cpp
3 // Purpose: implementation of wxTextFile class
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 03.04.98
7 // RCS-ID: $Id$
8 // Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // headers
14 // ============================================================================
15
16 #include "wx/wxprec.h"
17
18 #ifdef __BORLANDC__
19 #pragma hdrstop
20 #endif //__BORLANDC__
21
22 #if !wxUSE_FILE || !wxUSE_TEXTBUFFER
23 #undef wxUSE_TEXTFILE
24 #define wxUSE_TEXTFILE 0
25 #endif // wxUSE_FILE
26
27 #if wxUSE_TEXTFILE
28
29 #ifndef WX_PRECOMP
30 #include "wx/string.h"
31 #include "wx/intl.h"
32 #include "wx/file.h"
33 #include "wx/log.h"
34 #endif
35
36 #include "wx/textfile.h"
37 #include "wx/filename.h"
38
39 // ============================================================================
40 // wxTextFile class implementation
41 // ============================================================================
42
43 wxTextFile::wxTextFile(const wxString& strFileName)
44 : wxTextBuffer(strFileName)
45 {
46 }
47
48
49 // ----------------------------------------------------------------------------
50 // file operations
51 // ----------------------------------------------------------------------------
52
53 bool wxTextFile::OnExists() const
54 {
55 return wxFile::Exists(m_strBufferName);
56 }
57
58
59 bool wxTextFile::OnOpen(const wxString &strBufferName, wxTextBufferOpenMode OpenMode)
60 {
61 wxFile::OpenMode FileOpenMode;
62
63 switch ( OpenMode )
64 {
65 default:
66 wxFAIL_MSG( _T("unknown open mode in wxTextFile::Open") );
67 // fall through
68
69 case ReadAccess :
70 FileOpenMode = wxFile::read;
71 break;
72
73 case WriteAccess :
74 FileOpenMode = wxFile::write;
75 break;
76 }
77
78 return m_file.Open(strBufferName.c_str(), FileOpenMode);
79 }
80
81
82 bool wxTextFile::OnClose()
83 {
84 return m_file.Close();
85 }
86
87
88 bool wxTextFile::OnRead(wxMBConv& conv)
89 {
90 // file should be opened and we must be in it's beginning
91 wxASSERT( m_file.IsOpened() && m_file.Tell() == 0 );
92
93 char *strBuf, *strPtr, *strEnd;
94 char ch, chLast = '\0';
95 char buf[1024];
96 size_t nRead;
97
98 strPtr = strBuf = new char[1024];
99 strEnd = strBuf + 1024;
100
101 do
102 {
103 nRead = m_file.Read(buf, WXSIZEOF(buf));
104 if ( nRead == (size_t)wxInvalidOffset )
105 {
106 // read error (error message already given in wxFile::Read)
107 delete[] strBuf;
108 return false;
109 }
110
111 for (size_t n = 0; n < nRead; n++)
112 {
113 ch = buf[n];
114 switch ( ch )
115 {
116 case '\n':
117 // Dos/Unix line termination
118 *strPtr = '\0';
119 AddLine(wxString(strBuf, conv),
120 chLast == '\r' ? wxTextFileType_Dos
121 : wxTextFileType_Unix);
122 strPtr = strBuf;
123 chLast = '\n';
124 break;
125
126 case '\r':
127 if ( chLast == '\r' )
128 {
129 // Mac empty line
130 AddLine(wxEmptyString, wxTextFileType_Mac);
131 }
132 else
133 chLast = '\r';
134 break;
135
136 default:
137 if ( chLast == '\r' )
138 {
139 // Mac line termination
140 *strPtr = '\0';
141 AddLine(wxString(strBuf, conv), wxTextFileType_Mac);
142 chLast = ch;
143 strPtr = strBuf;
144 *(strPtr++) = ch;
145 }
146 else
147 {
148 // add to the current line
149 *(strPtr++) = ch;
150 if ( strPtr == strEnd )
151 {
152 // we must allocate more memory
153 size_t size = strEnd - strBuf;
154 char *newBuf = new char[size + 1024];
155 memcpy(newBuf, strBuf, size);
156 delete[] strBuf;
157 strBuf = newBuf;
158 strEnd = strBuf + size + 1024;
159 strPtr = strBuf + size;
160 }
161 }
162 }
163 }
164 } while ( nRead == WXSIZEOF(buf) );
165
166 // anything in the last line?
167 if ( strPtr != strBuf )
168 {
169 *strPtr = '\0';
170 AddLine(wxString(strBuf, conv),
171 wxTextFileType_None); // no line terminator
172 }
173
174 delete[] strBuf;
175 return true;
176 }
177
178
179 bool wxTextFile::OnWrite(wxTextFileType typeNew, wxMBConv& conv)
180 {
181 wxFileName fn = m_strBufferName;
182
183 // We do NOT want wxPATH_NORM_CASE here, or the case will not
184 // be preserved.
185 if ( !fn.IsAbsolute() )
186 fn.Normalize(wxPATH_NORM_ENV_VARS | wxPATH_NORM_DOTS | wxPATH_NORM_TILDE |
187 wxPATH_NORM_ABSOLUTE | wxPATH_NORM_LONG);
188
189 wxTempFile fileTmp(fn.GetFullPath());
190
191 if ( !fileTmp.IsOpened() ) {
192 wxLogError(_("can't write buffer '%s' to disk."), m_strBufferName.c_str());
193 return false;
194 }
195
196 size_t nCount = GetLineCount();
197 for ( size_t n = 0; n < nCount; n++ ) {
198 fileTmp.Write(GetLine(n) +
199 GetEOL(typeNew == wxTextFileType_None ? GetLineType(n)
200 : typeNew),
201 conv);
202 }
203
204 // replace the old file with this one
205 return fileTmp.Commit();
206 }
207
208 #endif // wxUSE_TEXTFILE
209