]> git.saurik.com Git - wxWidgets.git/blame - src/common/ffile.cpp
use wx/crt.h as the 'official' header for wxCRT wrappers instead of wxchar.h; add...
[wxWidgets.git] / src / common / ffile.cpp
CommitLineData
a1b82138
VZ
1/////////////////////////////////////////////////////////////////////////////
2// Name: ffile.cpp
90e2cbf7 3// Purpose: wxFFile encapsulates "FILE *" IO stream
a1b82138
VZ
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>
65571936 9// Licence: wxWindows licence
a1b82138
VZ
10/////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
a1b82138
VZ
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
24 #pragma hdrstop
25#endif
26
1e6feb95 27#if wxUSE_FFILE
a1b82138
VZ
28
29#ifndef WX_PRECOMP
0efe5ba7
VZ
30 #include "wx/intl.h"
31 #include "wx/log.h"
a1b82138
VZ
32#endif
33
89220a94
CE
34#ifdef __WINDOWS__
35#include "wx/msw/mslu.h"
36#endif
37
a1b82138
VZ
38#include "wx/ffile.h"
39
40// ============================================================================
41// implementation
42// ============================================================================
43
70a7bd90
VZ
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
a1b82138
VZ
56// ----------------------------------------------------------------------------
57// opening the file
58// ----------------------------------------------------------------------------
59
6626de90 60wxFFile::wxFFile(const wxString& filename, const wxString& mode)
a1b82138
VZ
61{
62 Detach();
63
64 (void)Open(filename, mode);
65}
66
6626de90 67bool wxFFile::Open(const wxString& filename, const wxString& mode)
a1b82138 68{
223d09f6 69 wxASSERT_MSG( !m_fp, wxT("should close or detach the old file first") );
a1b82138 70
90e2cbf7 71 m_fp = wxFopen(filename, mode);
a1b82138
VZ
72
73 if ( !m_fp )
74 {
75 wxLogSysError(_("can't open file '%s'"), filename);
76
a62848fd 77 return false;
a1b82138
VZ
78 }
79
80 m_name = filename;
81
a62848fd 82 return true;
a1b82138
VZ
83}
84
85bool wxFFile::Close()
86{
87 if ( IsOpened() )
88 {
d2e1ef19 89 if ( fclose(m_fp) != 0 )
a1b82138
VZ
90 {
91 wxLogSysError(_("can't close file '%s'"), m_name.c_str());
92
a62848fd 93 return false;
a1b82138
VZ
94 }
95
96 Detach();
97 }
98
a62848fd 99 return true;
a1b82138
VZ
100}
101
102// ----------------------------------------------------------------------------
103// read/write
104// ----------------------------------------------------------------------------
105
830f8f11 106bool wxFFile::ReadAll(wxString *str, const wxMBConv& conv)
a1b82138 107{
a62848fd
WS
108 wxCHECK_MSG( str, false, wxT("invalid parameter") );
109 wxCHECK_MSG( IsOpened(), false, wxT("can't read from closed file") );
11846af3 110 wxCHECK_MSG( Length() >= 0, false, wxT("invalid length") );
17a1ebd1 111 size_t length = wx_truncate_cast(size_t, Length());
c3816108 112 wxCHECK_MSG( (wxFileOffset)length == Length(), false, wxT("huge file not supported") );
a1b82138
VZ
113
114 clearerr(m_fp);
115
2a9c0905 116 wxCharBuffer buf(length + 1);
f281f29f 117
2a9c0905 118 // note that real length may be less than file length for text files with DOS EOLs
f281f29f
VZ
119 // ('\r's get dropped by CRT when reading which means that we have
120 // realLen = fileLen - numOfLinesInTheFile)
2a9c0905 121 length = fread(buf.data(), sizeof(char), length, m_fp);
f281f29f
VZ
122
123 if ( Error() )
a1b82138 124 {
3e15dde3 125 wxLogSysError(_("Read error on file '%s'"), m_name.c_str());
a1b82138 126
3e15dde3 127 return false;
a1b82138
VZ
128 }
129
2a9c0905 130 buf.data()[length] = 0;
3e15dde3
VZ
131 *str = wxString(buf, conv);
132
a62848fd 133 return true;
a1b82138
VZ
134}
135
136size_t wxFFile::Read(void *pBuf, size_t nCount)
137{
2a9c0905
WS
138 wxCHECK_MSG( pBuf, 0, wxT("invalid parameter") );
139 wxCHECK_MSG( IsOpened(), 0, wxT("can't read from closed file") );
a1b82138
VZ
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{
2a9c0905
WS
152 wxCHECK_MSG( pBuf, 0, wxT("invalid parameter") );
153 wxCHECK_MSG( IsOpened(), 0, wxT("can't write to closed file") );
a1b82138
VZ
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
b1c67394
VZ
164bool wxFFile::Write(const wxString& s, const wxMBConv& conv)
165{
166 const wxWX2MBbuf buf = s.mb_str(conv);
167 if ( !buf )
168 return false;
169
170 const size_t size = strlen(buf); // FIXME: use buf.length() when available
171 return Write(buf, size) == size;
172}
173
a1b82138
VZ
174bool wxFFile::Flush()
175{
176 if ( IsOpened() )
177 {
b1c67394 178 if ( fflush(m_fp) != 0 )
a1b82138
VZ
179 {
180 wxLogSysError(_("failed to flush the file '%s'"), m_name.c_str());
181
a62848fd 182 return false;
a1b82138
VZ
183 }
184 }
185
a62848fd 186 return true;
a1b82138
VZ
187}
188
189// ----------------------------------------------------------------------------
190// seeking
191// ----------------------------------------------------------------------------
192
70a7bd90 193bool wxFFile::Seek(wxFileOffset ofs, wxSeekMode mode)
a1b82138 194{
a62848fd 195 wxCHECK_MSG( IsOpened(), false, wxT("can't seek on closed file") );
a1b82138
VZ
196
197 int origin;
198 switch ( mode )
199 {
200 default:
223d09f6 201 wxFAIL_MSG(wxT("unknown seek mode"));
a1b82138
VZ
202 // still fall through
203
204 case wxFromStart:
205 origin = SEEK_SET;
206 break;
207
208 case wxFromCurrent:
209 origin = SEEK_CUR;
210 break;
211
212 case wxFromEnd:
213 origin = SEEK_END;
214 break;
215 }
216
11846af3 217#ifndef HAVE_FSEEKO
70a7bd90
VZ
218 if ((long)ofs != ofs)
219 {
220 wxLogError(_("Seek error on file '%s' (large files not supported by stdio)"), m_name.c_str());
221
222 return false;
223 }
70a7bd90 224
11846af3
WS
225 if ( wxFseek(m_fp, (long)ofs, origin) != 0 )
226#else
70a7bd90 227 if ( wxFseek(m_fp, ofs, origin) != 0 )
11846af3 228#endif
a1b82138
VZ
229 {
230 wxLogSysError(_("Seek error on file '%s'"), m_name.c_str());
231
a62848fd 232 return false;
a1b82138
VZ
233 }
234
a62848fd 235 return true;
a1b82138
VZ
236}
237
70a7bd90 238wxFileOffset wxFFile::Tell() const
a1b82138 239{
70a7bd90 240 wxCHECK_MSG( IsOpened(), wxInvalidOffset,
de2ce07c
VZ
241 _T("wxFFile::Tell(): file is closed!") );
242
70a7bd90
VZ
243 wxFileOffset rc = wxFtell(m_fp);
244 if ( rc == wxInvalidOffset )
a1b82138
VZ
245 {
246 wxLogSysError(_("Can't find current position in file '%s'"),
247 m_name.c_str());
248 }
249
70a7bd90 250 return rc;
a1b82138
VZ
251}
252
70a7bd90 253wxFileOffset wxFFile::Length() const
a1b82138 254{
70a7bd90 255 wxCHECK_MSG( IsOpened(), wxInvalidOffset,
de2ce07c
VZ
256 _T("wxFFile::Length(): file is closed!") );
257
a1b82138
VZ
258 wxFFile& self = *(wxFFile *)this; // const_cast
259
70a7bd90
VZ
260 wxFileOffset posOld = Tell();
261 if ( posOld != wxInvalidOffset )
a1b82138
VZ
262 {
263 if ( self.SeekEnd() )
264 {
70a7bd90 265 wxFileOffset len = Tell();
a1b82138
VZ
266
267 (void)self.Seek(posOld);
268
269 return len;
270 }
271 }
272
11846af3 273 return wxInvalidOffset;
a1b82138
VZ
274}
275
1e6feb95 276#endif // wxUSE_FFILE