]> git.saurik.com Git - wxWidgets.git/blame - src/common/ffile.cpp
Add wxUSE_ARCSTREAM so that other archive classes can be used without wxZip
[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
14f355c2 20#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
a1b82138
VZ
21 #pragma implementation "ffile.h"
22#endif
23
24// For compilers that support precompilation, includes "wx.h".
25#include "wx/wxprec.h"
26
27#ifdef __BORLANDC__
28 #pragma hdrstop
29#endif
30
1e6feb95 31#if wxUSE_FFILE
a1b82138
VZ
32
33#ifndef WX_PRECOMP
0efe5ba7
VZ
34 #include "wx/intl.h"
35 #include "wx/log.h"
a1b82138
VZ
36#endif
37
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
90e2cbf7 60wxFFile::wxFFile(const wxChar *filename, const wxChar *mode)
a1b82138
VZ
61{
62 Detach();
63
64 (void)Open(filename, mode);
65}
66
90e2cbf7 67bool wxFFile::Open(const wxChar *filename, const wxChar *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
106bool wxFFile::ReadAll(wxString *str)
107{
a62848fd
WS
108 wxCHECK_MSG( str, false, wxT("invalid parameter") );
109 wxCHECK_MSG( IsOpened(), false, wxT("can't read from closed file") );
11846af3
WS
110 wxCHECK_MSG( Length() >= 0, false, wxT("invalid length") );
111 size_t length = (size_t)Length();
c3816108 112 wxCHECK_MSG( (wxFileOffset)length == Length(), false, wxT("huge file not supported") );
a1b82138
VZ
113
114 clearerr(m_fp);
115
116 str->Empty();
11846af3 117 str->Alloc(length);
a1b82138
VZ
118
119 wxChar buf[1024];
120 static const size_t nSize = WXSIZEOF(buf) - 1; // -1 for trailing '\0'
121 while ( !Eof() )
122 {
123 size_t nRead = fread(buf, sizeof(wxChar), nSize, m_fp);
124 if ( (nRead < nSize) && Error() )
125 {
126 wxLogSysError(_("Read error on file '%s'"), m_name.c_str());
127
a62848fd 128 return false;
a1b82138
VZ
129 }
130 //else: just EOF
131
132 buf[nRead] = 0;
133 *str += buf;
134 }
135
a62848fd 136 return true;
a1b82138
VZ
137}
138
139size_t wxFFile::Read(void *pBuf, size_t nCount)
140{
223d09f6
KB
141 wxCHECK_MSG( pBuf, FALSE, wxT("invalid parameter") );
142 wxCHECK_MSG( IsOpened(), FALSE, wxT("can't read from closed file") );
a1b82138
VZ
143
144 size_t nRead = fread(pBuf, 1, nCount, m_fp);
145 if ( (nRead < nCount) && Error() )
146 {
147 wxLogSysError(_("Read error on file '%s'"), m_name.c_str());
148 }
149
150 return nRead;
151}
152
153size_t wxFFile::Write(const void *pBuf, size_t nCount)
154{
223d09f6
KB
155 wxCHECK_MSG( pBuf, FALSE, wxT("invalid parameter") );
156 wxCHECK_MSG( IsOpened(), FALSE, wxT("can't write to closed file") );
a1b82138
VZ
157
158 size_t nWritten = fwrite(pBuf, 1, nCount, m_fp);
159 if ( nWritten < nCount )
160 {
161 wxLogSysError(_("Write error on file '%s'"), m_name.c_str());
162 }
163
164 return nWritten;
165}
166
167bool wxFFile::Flush()
168{
169 if ( IsOpened() )
170 {
5b96c684
MB
171 // fflush returns non-zero on error
172 //
173 if ( fflush(m_fp) )
a1b82138
VZ
174 {
175 wxLogSysError(_("failed to flush the file '%s'"), m_name.c_str());
176
a62848fd 177 return false;
a1b82138
VZ
178 }
179 }
180
a62848fd 181 return true;
a1b82138
VZ
182}
183
184// ----------------------------------------------------------------------------
185// seeking
186// ----------------------------------------------------------------------------
187
70a7bd90 188bool wxFFile::Seek(wxFileOffset ofs, wxSeekMode mode)
a1b82138 189{
a62848fd 190 wxCHECK_MSG( IsOpened(), false, wxT("can't seek on closed file") );
a1b82138
VZ
191
192 int origin;
193 switch ( mode )
194 {
195 default:
223d09f6 196 wxFAIL_MSG(wxT("unknown seek mode"));
a1b82138
VZ
197 // still fall through
198
199 case wxFromStart:
200 origin = SEEK_SET;
201 break;
202
203 case wxFromCurrent:
204 origin = SEEK_CUR;
205 break;
206
207 case wxFromEnd:
208 origin = SEEK_END;
209 break;
210 }
211
11846af3 212#ifndef HAVE_FSEEKO
70a7bd90
VZ
213 if ((long)ofs != ofs)
214 {
215 wxLogError(_("Seek error on file '%s' (large files not supported by stdio)"), m_name.c_str());
216
217 return false;
218 }
70a7bd90 219
11846af3
WS
220 if ( wxFseek(m_fp, (long)ofs, origin) != 0 )
221#else
70a7bd90 222 if ( wxFseek(m_fp, ofs, origin) != 0 )
11846af3 223#endif
a1b82138
VZ
224 {
225 wxLogSysError(_("Seek error on file '%s'"), m_name.c_str());
226
a62848fd 227 return false;
a1b82138
VZ
228 }
229
a62848fd 230 return true;
a1b82138
VZ
231}
232
70a7bd90 233wxFileOffset wxFFile::Tell() const
a1b82138 234{
70a7bd90 235 wxCHECK_MSG( IsOpened(), wxInvalidOffset,
de2ce07c
VZ
236 _T("wxFFile::Tell(): file is closed!") );
237
70a7bd90
VZ
238 wxFileOffset rc = wxFtell(m_fp);
239 if ( rc == wxInvalidOffset )
a1b82138
VZ
240 {
241 wxLogSysError(_("Can't find current position in file '%s'"),
242 m_name.c_str());
243 }
244
70a7bd90 245 return rc;
a1b82138
VZ
246}
247
70a7bd90 248wxFileOffset wxFFile::Length() const
a1b82138 249{
70a7bd90 250 wxCHECK_MSG( IsOpened(), wxInvalidOffset,
de2ce07c
VZ
251 _T("wxFFile::Length(): file is closed!") );
252
a1b82138
VZ
253 wxFFile& self = *(wxFFile *)this; // const_cast
254
70a7bd90
VZ
255 wxFileOffset posOld = Tell();
256 if ( posOld != wxInvalidOffset )
a1b82138
VZ
257 {
258 if ( self.SeekEnd() )
259 {
70a7bd90 260 wxFileOffset len = Tell();
a1b82138
VZ
261
262 (void)self.Seek(posOld);
263
264 return len;
265 }
266 }
267
11846af3 268 return wxInvalidOffset;
a1b82138
VZ
269}
270
1e6feb95 271#endif // wxUSE_FFILE