The rounded corners look really dumb at this size.
[wxWidgets.git] / src / common / ffile.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/ffile.cpp
3 // Purpose: wxFFile encapsulates "FILE *" IO stream
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 14.07.99
7 // Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 // ============================================================================
12 // declarations
13 // ============================================================================
14
15 // ----------------------------------------------------------------------------
16 // headers
17 // ----------------------------------------------------------------------------
18
19 // For compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
21
22 #ifdef __BORLANDC__
23 #pragma hdrstop
24 #endif
25
26 #if wxUSE_FFILE
27
28 #ifndef WX_PRECOMP
29 #include "wx/intl.h"
30 #include "wx/log.h"
31 #include "wx/crt.h"
32 #endif
33
34 #ifdef __WINDOWS__
35 #include "wx/msw/mslu.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 wxString& filename, const wxString& mode)
49 {
50 m_fp = NULL;
51
52 (void)Open(filename, mode);
53 }
54
55 bool wxFFile::Open(const wxString& filename, const wxString& mode)
56 {
57 wxASSERT_MSG( !m_fp, wxT("should close or detach the old file first") );
58
59 FILE* const fp = wxFopen(filename, mode);
60
61 if ( !fp )
62 {
63 wxLogSysError(_("can't open file '%s'"), filename);
64
65 return false;
66 }
67
68 Attach(fp, filename);
69
70 return true;
71 }
72
73 bool wxFFile::Close()
74 {
75 if ( IsOpened() )
76 {
77 if ( fclose(m_fp) != 0 )
78 {
79 wxLogSysError(_("can't close file '%s'"), m_name.c_str());
80
81 return false;
82 }
83
84 m_fp = NULL;
85 }
86
87 return true;
88 }
89
90 // ----------------------------------------------------------------------------
91 // read/write
92 // ----------------------------------------------------------------------------
93
94 bool wxFFile::ReadAll(wxString *str, const wxMBConv& conv)
95 {
96 wxCHECK_MSG( str, false, wxT("invalid parameter") );
97 wxCHECK_MSG( IsOpened(), false, wxT("can't read from closed file") );
98 wxCHECK_MSG( Length() >= 0, false, wxT("invalid length") );
99 size_t length = wx_truncate_cast(size_t, Length());
100 wxCHECK_MSG( (wxFileOffset)length == Length(), false, wxT("huge file not supported") );
101
102 clearerr(m_fp);
103
104 wxCharBuffer buf(length);
105
106 // note that real length may be less than file length for text files with DOS EOLs
107 // ('\r's get dropped by CRT when reading which means that we have
108 // realLen = fileLen - numOfLinesInTheFile)
109 length = fread(buf.data(), 1, length, m_fp);
110
111 if ( Error() )
112 {
113 wxLogSysError(_("Read error on file '%s'"), m_name.c_str());
114
115 return false;
116 }
117
118 buf.data()[length] = 0;
119
120 wxString strTmp(buf, conv);
121 str->swap(strTmp);
122
123 return true;
124 }
125
126 size_t wxFFile::Read(void *pBuf, size_t nCount)
127 {
128 wxCHECK_MSG( pBuf, 0, wxT("invalid parameter") );
129 wxCHECK_MSG( IsOpened(), 0, wxT("can't read from closed file") );
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
140 size_t wxFFile::Write(const void *pBuf, size_t nCount)
141 {
142 wxCHECK_MSG( pBuf, 0, wxT("invalid parameter") );
143 wxCHECK_MSG( IsOpened(), 0, wxT("can't write to closed file") );
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
154 bool 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
164 bool wxFFile::Flush()
165 {
166 if ( IsOpened() )
167 {
168 if ( fflush(m_fp) != 0 )
169 {
170 wxLogSysError(_("failed to flush the file '%s'"), m_name.c_str());
171
172 return false;
173 }
174 }
175
176 return true;
177 }
178
179 // ----------------------------------------------------------------------------
180 // seeking
181 // ----------------------------------------------------------------------------
182
183 bool wxFFile::Seek(wxFileOffset ofs, wxSeekMode mode)
184 {
185 wxCHECK_MSG( IsOpened(), false, wxT("can't seek on closed file") );
186
187 int origin;
188 switch ( mode )
189 {
190 default:
191 wxFAIL_MSG(wxT("unknown seek mode"));
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
207 #ifndef wxHAS_LARGE_FFILES
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 }
214
215 if ( wxFseek(m_fp, (long)ofs, origin) != 0 )
216 #else
217 if ( wxFseek(m_fp, ofs, origin) != 0 )
218 #endif
219 {
220 wxLogSysError(_("Seek error on file '%s'"), m_name.c_str());
221
222 return false;
223 }
224
225 return true;
226 }
227
228 wxFileOffset wxFFile::Tell() const
229 {
230 wxCHECK_MSG( IsOpened(), wxInvalidOffset,
231 wxT("wxFFile::Tell(): file is closed!") );
232
233 wxFileOffset rc = wxFtell(m_fp);
234 if ( rc == wxInvalidOffset )
235 {
236 wxLogSysError(_("Can't find current position in file '%s'"),
237 m_name.c_str());
238 }
239
240 return rc;
241 }
242
243 wxFileOffset wxFFile::Length() const
244 {
245 wxCHECK_MSG( IsOpened(), wxInvalidOffset,
246 wxT("wxFFile::Length(): file is closed!") );
247
248 wxFFile& self = *const_cast<wxFFile *>(this);
249
250 wxFileOffset posOld = Tell();
251 if ( posOld != wxInvalidOffset )
252 {
253 if ( self.SeekEnd() )
254 {
255 wxFileOffset len = Tell();
256
257 (void)self.Seek(posOld);
258
259 return len;
260 }
261 }
262
263 return wxInvalidOffset;
264 }
265
266 #endif // wxUSE_FFILE