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