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