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