Added GSocket for Unix (only GTK for the moment)
[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, _T("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 m_fp = fopen(tmp_fname, mode);
68
69 delete tmp_fname;
70 #else
71 m_fp = fopen(filename, mode);
72 #endif
73
74
75 if ( !m_fp )
76 {
77 wxLogSysError(_("can't open file '%s'"), filename);
78
79 return FALSE;
80 }
81
82 m_name = filename;
83
84 return TRUE;
85 }
86
87 bool wxFFile::Close()
88 {
89 if ( IsOpened() )
90 {
91 if ( fclose(m_fp) != 0 )
92 {
93 wxLogSysError(_("can't close file '%s'"), m_name.c_str());
94
95 return FALSE;
96 }
97
98 Detach();
99 }
100
101 return TRUE;
102 }
103
104 // ----------------------------------------------------------------------------
105 // read/write
106 // ----------------------------------------------------------------------------
107
108 bool wxFFile::ReadAll(wxString *str)
109 {
110 wxCHECK_MSG( str, FALSE, _T("invalid parameter") );
111 wxCHECK_MSG( IsOpened(), FALSE, _T("can't read from closed file") );
112
113 clearerr(m_fp);
114
115 str->Empty();
116 str->Alloc(Length());
117
118 wxChar buf[1024];
119 static const size_t nSize = WXSIZEOF(buf) - 1; // -1 for trailing '\0'
120 while ( !Eof() )
121 {
122 size_t nRead = fread(buf, sizeof(wxChar), nSize, m_fp);
123 if ( (nRead < nSize) && Error() )
124 {
125 wxLogSysError(_("Read error on file '%s'"), m_name.c_str());
126
127 return FALSE;
128 }
129 //else: just EOF
130
131 buf[nRead] = 0;
132 *str += buf;
133 }
134
135 return TRUE;
136 }
137
138 size_t wxFFile::Read(void *pBuf, size_t nCount)
139 {
140 wxCHECK_MSG( pBuf, FALSE, _T("invalid parameter") );
141 wxCHECK_MSG( IsOpened(), FALSE, _T("can't read from closed file") );
142
143 size_t nRead = fread(pBuf, 1, nCount, m_fp);
144 if ( (nRead < nCount) && Error() )
145 {
146 wxLogSysError(_("Read error on file '%s'"), m_name.c_str());
147 }
148
149 return nRead;
150 }
151
152 size_t wxFFile::Write(const void *pBuf, size_t nCount)
153 {
154 wxCHECK_MSG( pBuf, FALSE, _T("invalid parameter") );
155 wxCHECK_MSG( IsOpened(), FALSE, _T("can't write to closed file") );
156
157 size_t nWritten = fwrite(pBuf, 1, nCount, m_fp);
158 if ( nWritten < nCount )
159 {
160 wxLogSysError(_("Write error on file '%s'"), m_name.c_str());
161 }
162
163 return nWritten;
164 }
165
166 bool wxFFile::Flush()
167 {
168 if ( IsOpened() )
169 {
170 if ( !fflush(m_fp) )
171 {
172 wxLogSysError(_("failed to flush the file '%s'"), m_name.c_str());
173
174 return FALSE;
175 }
176 }
177
178 return TRUE;
179 }
180
181 // ----------------------------------------------------------------------------
182 // seeking
183 // ----------------------------------------------------------------------------
184
185 bool wxFFile::Seek(long ofs, wxSeekMode mode)
186 {
187 wxCHECK_MSG( IsOpened(), FALSE, _T("can't seek on closed file") );
188
189 int origin;
190 switch ( mode )
191 {
192 default:
193 wxFAIL_MSG(_T("unknown seek mode"));
194 // still fall through
195
196 case wxFromStart:
197 origin = SEEK_SET;
198 break;
199
200 case wxFromCurrent:
201 origin = SEEK_CUR;
202 break;
203
204 case wxFromEnd:
205 origin = SEEK_END;
206 break;
207 }
208
209 if ( fseek(m_fp, ofs, origin) != 0 )
210 {
211 wxLogSysError(_("Seek error on file '%s'"), m_name.c_str());
212
213 return FALSE;
214 }
215
216 return TRUE;
217 }
218
219 size_t wxFFile::Tell() const
220 {
221 long rc = ftell(m_fp);
222 if ( rc == -1 )
223 {
224 wxLogSysError(_("Can't find current position in file '%s'"),
225 m_name.c_str());
226 }
227
228 return (size_t)rc;
229 }
230
231 size_t wxFFile::Length() const
232 {
233 wxFFile& self = *(wxFFile *)this; // const_cast
234
235 size_t posOld = Tell();
236 if ( posOld != (size_t)-1 )
237 {
238 if ( self.SeekEnd() )
239 {
240 size_t len = Tell();
241
242 (void)self.Seek(posOld);
243
244 return len;
245 }
246 }
247
248 return (size_t)-1;
249 }
250
251 #endif // wxUSE_FILE