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