]> git.saurik.com Git - wxWidgets.git/blame - src/common/textfile.cpp
Improved size handling.
[wxWidgets.git] / src / common / textfile.cpp
CommitLineData
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
43wxTextFile::wxTextFile(const wxString& strFileName)
44 : wxTextBuffer(strFileName)
a1b82138 45{
a1b82138
VZ
46}
47
c801d85f
KB
48
49// ----------------------------------------------------------------------------
50// file operations
51// ----------------------------------------------------------------------------
52
a3a584a7 53bool wxTextFile::OnExists() const
ef8d96c2 54{
a3a584a7 55 return wxFile::Exists(m_strBufferName);
ef8d96c2
VZ
56}
57
1b6dea5d 58
a3a584a7 59bool 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 82bool wxTextFile::OnClose()
c801d85f 83{
a3a584a7 84 return m_file.Close();
c801d85f
KB
85}
86
a3a584a7
VZ
87
88bool wxTextFile::OnRead(wxMBConv& conv)
c801d85f 89{
d9ade1df
VS
90 // file should be opened and we must be in it's beginning
91 wxASSERT( m_file.IsOpened() && m_file.Tell() == 0 );
adfed1ca 92
d9ade1df
VS
93 char *strBuf, *strPtr, *strEnd;
94 char ch, chLast = '\0';
95 char buf[1024];
30984dea 96 size_t nRead;
c801d85f 97
d9ade1df
VS
98 strPtr = strBuf = new char[1024];
99 strEnd = strBuf + 1024;
ba7f9a90 100
cb719f2e 101 do
d9ade1df
VS
102 {
103 nRead = m_file.Read(buf, WXSIZEOF(buf));
30984dea 104 if ( nRead == (size_t)wxInvalidOffset )
d9ade1df
VS
105 {
106 // read error (error message already given in wxFile::Read)
107 delete[] strBuf;
cb719f2e 108 return false;
d9ade1df
VS
109 }
110
30984dea 111 for (size_t n = 0; n < nRead; n++)
d9ade1df
VS
112 {
113 ch = buf[n];
cb719f2e 114 switch ( ch )
d9ade1df
VS
115 {
116 case '\n':
117 // Dos/Unix line termination
118 *strPtr = '\0';
cb719f2e 119 AddLine(wxString(strBuf, conv),
d9ade1df
VS
120 chLast == '\r' ? wxTextFileType_Dos
121 : wxTextFileType_Unix);
122 strPtr = strBuf;
123 chLast = '\n';
124 break;
125
126 case '\r':
cb719f2e 127 if ( chLast == '\r' )
d9ade1df
VS
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 }
cb719f2e 146 else
d9ade1df
VS
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?
cb719f2e 167 if ( strPtr != strBuf )
d9ade1df
VS
168 {
169 *strPtr = '\0';
cb719f2e 170 AddLine(wxString(strBuf, conv),
d9ade1df 171 wxTextFileType_None); // no line terminator
c801d85f 172 }
c801d85f 173
d9ade1df 174 delete[] strBuf;
cb719f2e 175 return true;
c801d85f
KB
176}
177
f42d2aba 178
a3a584a7 179bool wxTextFile::OnWrite(wxTextFileType typeNew, wxMBConv& conv)
c801d85f 180{
68c97af3 181 wxFileName fn = m_strBufferName;
baed1077
JS
182
183 // We do NOT want wxPATH_NORM_CASE here, or the case will not
184 // be preserved.
68c97af3 185 if ( !fn.IsAbsolute() )
32a0d013
VS
186 fn.Normalize(wxPATH_NORM_ENV_VARS | wxPATH_NORM_DOTS | wxPATH_NORM_TILDE |
187 wxPATH_NORM_ABSOLUTE | wxPATH_NORM_LONG);
68c97af3 188
deab4540 189 wxTempFile fileTmp(fn.GetFullPath());
c801d85f 190
a3a584a7
VZ
191 if ( !fileTmp.IsOpened() ) {
192 wxLogError(_("can't write buffer '%s' to disk."), m_strBufferName.c_str());
cb719f2e 193 return false;
a3a584a7 194 }
c801d85f 195
a3a584a7
VZ
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 }
c801d85f 203
a3a584a7
VZ
204 // replace the old file with this one
205 return fileTmp.Commit();
ba7f9a90 206}
6164d85e 207
a1b82138 208#endif // wxUSE_TEXTFILE
6164d85e 209