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