]> git.saurik.com Git - wxWidgets.git/blob - src/common/ffile.cpp
fixed memory allocation code of wxStreamBuffer to not realloc() new[]ed memory any...
[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 license
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #ifdef __GNUG__
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
31 #if wxUSE_FILE
32
33 #ifndef WX_PRECOMP
34 #include "wx/intl.h"
35 #include "wx/log.h"
36 #endif
37
38 #include "wx/ffile.h"
39
40 // ============================================================================
41 // implementation
42 // ============================================================================
43
44 // ----------------------------------------------------------------------------
45 // opening the file
46 // ----------------------------------------------------------------------------
47
48 wxFFile::wxFFile(const wxChar *filename, const char *mode)
49 {
50 Detach();
51
52 (void)Open(filename, mode);
53 }
54
55 bool wxFFile::Open(const wxChar *filename, const char *mode)
56 {
57 wxASSERT_MSG( !m_fp, wxT("should close or detach the old file first") );
58
59 #if wxUSE_UNICODE
60 char *tmp_fname;
61 size_t fname_len;
62
63 fname_len = wxStrlen(filename)+1;
64 tmp_fname = new char[fname_len];
65 wxWX2MB(tmp_fname, filename, fname_len);
66
67 #ifdef __WXMAC__
68 m_fp = fopen(wxUnix2MacFilename( tmp_fname ), mode);
69 #else
70 m_fp = fopen(tmp_fname, mode);
71 #endif
72
73 delete tmp_fname;
74 #else
75 #ifdef __WXMAC__
76 m_fp = fopen(wxUnix2MacFilename( filename ), mode);
77 #else
78 m_fp = fopen(filename, mode);
79 #endif
80 #endif
81
82
83 if ( !m_fp )
84 {
85 wxLogSysError(_("can't open file '%s'"), filename);
86
87 return FALSE;
88 }
89
90 m_name = filename;
91
92 return TRUE;
93 }
94
95 bool wxFFile::Close()
96 {
97 if ( IsOpened() )
98 {
99 if ( fclose(m_fp) != 0 )
100 {
101 wxLogSysError(_("can't close file '%s'"), m_name.c_str());
102
103 return FALSE;
104 }
105
106 Detach();
107 }
108
109 return TRUE;
110 }
111
112 // ----------------------------------------------------------------------------
113 // read/write
114 // ----------------------------------------------------------------------------
115
116 bool wxFFile::ReadAll(wxString *str)
117 {
118 wxCHECK_MSG( str, FALSE, wxT("invalid parameter") );
119 wxCHECK_MSG( IsOpened(), FALSE, wxT("can't read from closed file") );
120
121 clearerr(m_fp);
122
123 str->Empty();
124 str->Alloc(Length());
125
126 wxChar buf[1024];
127 static const size_t nSize = WXSIZEOF(buf) - 1; // -1 for trailing '\0'
128 while ( !Eof() )
129 {
130 size_t nRead = fread(buf, sizeof(wxChar), nSize, m_fp);
131 if ( (nRead < nSize) && Error() )
132 {
133 wxLogSysError(_("Read error on file '%s'"), m_name.c_str());
134
135 return FALSE;
136 }
137 //else: just EOF
138
139 buf[nRead] = 0;
140 *str += buf;
141 }
142
143 return TRUE;
144 }
145
146 size_t wxFFile::Read(void *pBuf, size_t nCount)
147 {
148 wxCHECK_MSG( pBuf, FALSE, wxT("invalid parameter") );
149 wxCHECK_MSG( IsOpened(), FALSE, wxT("can't read from closed file") );
150
151 size_t nRead = fread(pBuf, 1, nCount, m_fp);
152 if ( (nRead < nCount) && Error() )
153 {
154 wxLogSysError(_("Read error on file '%s'"), m_name.c_str());
155 }
156
157 return nRead;
158 }
159
160 size_t wxFFile::Write(const void *pBuf, size_t nCount)
161 {
162 wxCHECK_MSG( pBuf, FALSE, wxT("invalid parameter") );
163 wxCHECK_MSG( IsOpened(), FALSE, wxT("can't write to closed file") );
164
165 size_t nWritten = fwrite(pBuf, 1, nCount, m_fp);
166 if ( nWritten < nCount )
167 {
168 wxLogSysError(_("Write error on file '%s'"), m_name.c_str());
169 }
170
171 return nWritten;
172 }
173
174 bool wxFFile::Flush()
175 {
176 if ( IsOpened() )
177 {
178 // fflush returns non-zero on error
179 //
180 if ( fflush(m_fp) )
181 {
182 wxLogSysError(_("failed to flush the file '%s'"), m_name.c_str());
183
184 return FALSE;
185 }
186 }
187
188 return TRUE;
189 }
190
191 // ----------------------------------------------------------------------------
192 // seeking
193 // ----------------------------------------------------------------------------
194
195 bool wxFFile::Seek(long ofs, wxSeekMode mode)
196 {
197 wxCHECK_MSG( IsOpened(), FALSE, wxT("can't seek on closed file") );
198
199 int origin;
200 switch ( mode )
201 {
202 default:
203 wxFAIL_MSG(wxT("unknown seek mode"));
204 // still fall through
205
206 case wxFromStart:
207 origin = SEEK_SET;
208 break;
209
210 case wxFromCurrent:
211 origin = SEEK_CUR;
212 break;
213
214 case wxFromEnd:
215 origin = SEEK_END;
216 break;
217 }
218
219 if ( fseek(m_fp, ofs, origin) != 0 )
220 {
221 wxLogSysError(_("Seek error on file '%s'"), m_name.c_str());
222
223 return FALSE;
224 }
225
226 return TRUE;
227 }
228
229 size_t wxFFile::Tell() const
230 {
231 long rc = ftell(m_fp);
232 if ( rc == -1 )
233 {
234 wxLogSysError(_("Can't find current position in file '%s'"),
235 m_name.c_str());
236 }
237
238 return (size_t)rc;
239 }
240
241 size_t wxFFile::Length() const
242 {
243 wxFFile& self = *(wxFFile *)this; // const_cast
244
245 size_t posOld = Tell();
246 if ( posOld != (size_t)-1 )
247 {
248 if ( self.SeekEnd() )
249 {
250 size_t len = Tell();
251
252 (void)self.Seek(posOld);
253
254 return len;
255 }
256 }
257
258 return (size_t)-1;
259 }
260
261 #endif // wxUSE_FILE