]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/common/ffile.cpp
reuse Clear() instead of duplicating its code in Close()
[wxWidgets.git] / src / common / ffile.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: ffile.cpp
3// Purpose: wxFFile encapsulates "FILE *" IO stream
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 14.07.99
7// RCS-ID: $Id$
8// Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
24 #pragma hdrstop
25#endif
26
27#if wxUSE_FFILE
28
29#ifndef WX_PRECOMP
30 #include "wx/intl.h"
31 #include "wx/log.h"
32#endif
33
34#ifdef __WINDOWS__
35#include "wx/msw/mslu.h"
36#endif
37
38#include "wx/ffile.h"
39
40// ============================================================================
41// implementation
42// ============================================================================
43
44// ----------------------------------------------------------------------------
45// seek and tell with large file support if available
46// ----------------------------------------------------------------------------
47
48#ifdef HAVE_FSEEKO
49# define wxFseek fseeko
50# define wxFtell ftello
51#else
52# define wxFseek fseek
53# define wxFtell ftell
54#endif
55
56// ----------------------------------------------------------------------------
57// opening the file
58// ----------------------------------------------------------------------------
59
60wxFFile::wxFFile(const wxChar *filename, const wxChar *mode)
61{
62 Detach();
63
64 (void)Open(filename, mode);
65}
66
67bool wxFFile::Open(const wxChar *filename, const wxChar *mode)
68{
69 wxASSERT_MSG( !m_fp, wxT("should close or detach the old file first") );
70
71 m_fp = wxFopen(filename, mode);
72
73 if ( !m_fp )
74 {
75 wxLogSysError(_("can't open file '%s'"), filename);
76
77 return false;
78 }
79
80 m_name = filename;
81
82 return true;
83}
84
85bool wxFFile::Close()
86{
87 if ( IsOpened() )
88 {
89 if ( fclose(m_fp) != 0 )
90 {
91 wxLogSysError(_("can't close file '%s'"), m_name.c_str());
92
93 return false;
94 }
95
96 Detach();
97 }
98
99 return true;
100}
101
102// ----------------------------------------------------------------------------
103// read/write
104// ----------------------------------------------------------------------------
105
106bool wxFFile::ReadAll(wxString *str, wxMBConv& conv)
107{
108 wxCHECK_MSG( str, false, wxT("invalid parameter") );
109 wxCHECK_MSG( IsOpened(), false, wxT("can't read from closed file") );
110 wxCHECK_MSG( Length() >= 0, false, wxT("invalid length") );
111 size_t length = wx_truncate_cast(size_t, Length());
112 wxCHECK_MSG( (wxFileOffset)length == Length(), false, wxT("huge file not supported") );
113
114 clearerr(m_fp);
115
116 wxCharBuffer buf(length + 1);
117
118 // note that real length may be less than file length for text files with DOS EOLs
119 // ('\r's get dropped by CRT when reading which means that we have
120 // realLen = fileLen - numOfLinesInTheFile)
121 length = fread(buf.data(), sizeof(char), length, m_fp);
122
123 if ( Error() )
124 {
125 wxLogSysError(_("Read error on file '%s'"), m_name.c_str());
126
127 return false;
128 }
129
130 buf.data()[length] = 0;
131 *str = wxString(buf, conv);
132
133 return true;
134}
135
136size_t wxFFile::Read(void *pBuf, size_t nCount)
137{
138 wxCHECK_MSG( pBuf, 0, wxT("invalid parameter") );
139 wxCHECK_MSG( IsOpened(), 0, wxT("can't read from closed file") );
140
141 size_t nRead = fread(pBuf, 1, nCount, m_fp);
142 if ( (nRead < nCount) && Error() )
143 {
144 wxLogSysError(_("Read error on file '%s'"), m_name.c_str());
145 }
146
147 return nRead;
148}
149
150size_t wxFFile::Write(const void *pBuf, size_t nCount)
151{
152 wxCHECK_MSG( pBuf, 0, wxT("invalid parameter") );
153 wxCHECK_MSG( IsOpened(), 0, wxT("can't write to closed file") );
154
155 size_t nWritten = fwrite(pBuf, 1, nCount, m_fp);
156 if ( nWritten < nCount )
157 {
158 wxLogSysError(_("Write error on file '%s'"), m_name.c_str());
159 }
160
161 return nWritten;
162}
163
164bool wxFFile::Flush()
165{
166 if ( IsOpened() )
167 {
168 // fflush returns non-zero on error
169 //
170 if ( fflush(m_fp) )
171 {
172 wxLogSysError(_("failed to flush the file '%s'"), m_name.c_str());
173
174 return false;
175 }
176 }
177
178 return true;
179}
180
181// ----------------------------------------------------------------------------
182// seeking
183// ----------------------------------------------------------------------------
184
185bool wxFFile::Seek(wxFileOffset ofs, wxSeekMode mode)
186{
187 wxCHECK_MSG( IsOpened(), false, wxT("can't seek on closed file") );
188
189 int origin;
190 switch ( mode )
191 {
192 default:
193 wxFAIL_MSG(wxT("unknown seek mode"));
194 // still fall through
195
196 case wxFromStart:
197 origin = SEEK_SET;
198 break;
199
200 case wxFromCurrent:
201 origin = SEEK_CUR;
202 break;
203
204 case wxFromEnd:
205 origin = SEEK_END;
206 break;
207 }
208
209#ifndef HAVE_FSEEKO
210 if ((long)ofs != ofs)
211 {
212 wxLogError(_("Seek error on file '%s' (large files not supported by stdio)"), m_name.c_str());
213
214 return false;
215 }
216
217 if ( wxFseek(m_fp, (long)ofs, origin) != 0 )
218#else
219 if ( wxFseek(m_fp, ofs, origin) != 0 )
220#endif
221 {
222 wxLogSysError(_("Seek error on file '%s'"), m_name.c_str());
223
224 return false;
225 }
226
227 return true;
228}
229
230wxFileOffset wxFFile::Tell() const
231{
232 wxCHECK_MSG( IsOpened(), wxInvalidOffset,
233 _T("wxFFile::Tell(): file is closed!") );
234
235 wxFileOffset rc = wxFtell(m_fp);
236 if ( rc == wxInvalidOffset )
237 {
238 wxLogSysError(_("Can't find current position in file '%s'"),
239 m_name.c_str());
240 }
241
242 return rc;
243}
244
245wxFileOffset wxFFile::Length() const
246{
247 wxCHECK_MSG( IsOpened(), wxInvalidOffset,
248 _T("wxFFile::Length(): file is closed!") );
249
250 wxFFile& self = *(wxFFile *)this; // const_cast
251
252 wxFileOffset posOld = Tell();
253 if ( posOld != wxInvalidOffset )
254 {
255 if ( self.SeekEnd() )
256 {
257 wxFileOffset len = Tell();
258
259 (void)self.Seek(posOld);
260
261 return len;
262 }
263 }
264
265 return wxInvalidOffset;
266}
267
268#endif // wxUSE_FFILE