]> git.saurik.com Git - wxWidgets.git/blob - src/common/ffile.cpp
wxLaunchDefaultBrowser() now supports wxBROWSER_NEW_WINDOW flag (and it actually...
[wxWidgets.git] / src / common / ffile.cpp
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
56 wxFFile::wxFFile(const wxChar *filename, const wxChar *mode)
57 {
58 Detach();
59
60 (void)Open(filename, mode);
61 }
62
63 bool 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
81 bool 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
102 bool 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
132 size_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
146 size_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
160 bool 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
181 bool 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
226 wxFileOffset 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
241 wxFileOffset 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