/[pcsx2_0.9.7]/trunk/3rdparty/wxWidgets/src/common/file.cpp
ViewVC logotype

Annotation of /trunk/3rdparty/wxWidgets/src/common/file.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (hide annotations) (download)
Tue Sep 7 03:24:11 2010 UTC (10 years, 4 months ago) by william
File size: 14296 byte(s)
committing r3113 initial commit again...
1 william 31 /////////////////////////////////////////////////////////////////////////////
2     // Name: file.cpp
3     // Purpose: wxFile - encapsulates low-level "file descriptor"
4     // wxTempFile
5     // Author: Vadim Zeitlin
6     // Modified by:
7     // Created: 29/01/98
8     // RCS-ID: $Id: file.cpp 42876 2006-10-31 23:29:02Z SN $
9     // Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
10     // Licence: wxWindows licence
11     /////////////////////////////////////////////////////////////////////////////
12    
13     // ----------------------------------------------------------------------------
14     // headers
15     // ----------------------------------------------------------------------------
16    
17     // For compilers that support precompilation, includes "wx.h".
18     #include "wx/wxprec.h"
19    
20     #ifdef __BORLANDC__
21     #pragma hdrstop
22     #endif
23    
24     #if wxUSE_FILE
25    
26     // standard
27     #if defined(__WXMSW__) && !defined(__GNUWIN32__) && !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
28    
29     #ifndef __SALFORDC__
30     #define WIN32_LEAN_AND_MEAN
31     #define NOSERVICE
32     #define NOIME
33     #define NOATOM
34     #define NOGDI
35     #define NOGDICAPMASKS
36     #define NOMETAFILE
37     #define NOMINMAX
38     #define NOMSG
39     #define NOOPENFILE
40     #define NORASTEROPS
41     #define NOSCROLL
42     #define NOSOUND
43     #define NOSYSMETRICS
44     #define NOTEXTMETRIC
45     #define NOWH
46     #define NOCOMM
47     #define NOKANJI
48     #define NOCRYPT
49     #define NOMCX
50     #endif
51    
52     #elif defined(__WXMSW__) && defined(__WXWINCE__)
53     #include "wx/msw/missing.h"
54     #elif (defined(__OS2__))
55     #include <io.h>
56     #elif (defined(__UNIX__) || defined(__GNUWIN32__))
57     #include <unistd.h>
58     #include <time.h>
59     #include <sys/stat.h>
60     #ifdef __GNUWIN32__
61     #include "wx/msw/wrapwin.h"
62     #endif
63     #elif defined(__DOS__)
64     #if defined(__WATCOMC__)
65     #include <io.h>
66     #elif defined(__DJGPP__)
67     #include <io.h>
68     #include <unistd.h>
69     #include <stdio.h>
70     #else
71     #error "Please specify the header with file functions declarations."
72     #endif
73     #elif (defined(__WXSTUBS__))
74     // Have to ifdef this for different environments
75     #include <io.h>
76     #elif (defined(__WXMAC__))
77     #if __MSL__ < 0x6000
78     int access( const char *path, int mode ) { return 0 ; }
79     #else
80     int _access( const char *path, int mode ) { return 0 ; }
81     #endif
82     char* mktemp( char * path ) { return path ;}
83     #include <stat.h>
84     #include <unistd.h>
85     #else
86     #error "Please specify the header with file functions declarations."
87     #endif //Win/UNIX
88    
89     #include <stdio.h> // SEEK_xxx constants
90    
91     // Windows compilers don't have these constants
92     #ifndef W_OK
93     enum
94     {
95     F_OK = 0, // test for existence
96     X_OK = 1, // execute permission
97     W_OK = 2, // write
98     R_OK = 4 // read
99     };
100     #endif // W_OK
101    
102     #ifdef __SALFORDC__
103     #include <unix.h>
104     #endif
105    
106     // some broken compilers don't have 3rd argument in open() and creat()
107     #ifdef __SALFORDC__
108     #define ACCESS(access)
109     #define stat _stat
110     #else // normal compiler
111     #define ACCESS(access) , (access)
112     #endif // Salford C
113    
114     // wxWidgets
115     #ifndef WX_PRECOMP
116     #include "wx/string.h"
117     #include "wx/intl.h"
118     #include "wx/log.h"
119     #endif // !WX_PRECOMP
120    
121     #include "wx/filename.h"
122     #include "wx/file.h"
123     #include "wx/filefn.h"
124    
125     // there is no distinction between text and binary files under Unix, so define
126     // O_BINARY as 0 if the system headers don't do it already
127     #if defined(__UNIX__) && !defined(O_BINARY)
128     #define O_BINARY (0)
129     #endif //__UNIX__
130    
131     #ifdef __WXMSW__
132     #include "wx/msw/mslu.h"
133     #endif
134    
135     #ifdef __WXWINCE__
136     #include "wx/msw/private.h"
137     #endif
138    
139     #ifndef MAX_PATH
140     #define MAX_PATH 512
141     #endif
142    
143     // ============================================================================
144     // implementation of wxFile
145     // ============================================================================
146    
147     // ----------------------------------------------------------------------------
148     // static functions
149     // ----------------------------------------------------------------------------
150    
151     bool wxFile::Exists(const wxChar *name)
152     {
153     return wxFileExists(name);
154     }
155    
156     bool wxFile::Access(const wxChar *name, OpenMode mode)
157     {
158     int how;
159    
160     switch ( mode )
161     {
162     default:
163     wxFAIL_MSG(wxT("bad wxFile::Access mode parameter."));
164     // fall through
165    
166     case read:
167     how = R_OK;
168     break;
169    
170     case write:
171     how = W_OK;
172     break;
173    
174     case read_write:
175     how = R_OK | W_OK;
176     break;
177     }
178    
179     return wxAccess(name, how) == 0;
180     }
181    
182     // ----------------------------------------------------------------------------
183     // opening/closing
184     // ----------------------------------------------------------------------------
185    
186     // ctors
187     wxFile::wxFile(const wxChar *szFileName, OpenMode mode)
188     {
189     m_fd = fd_invalid;
190     m_error = false;
191    
192     Open(szFileName, mode);
193     }
194    
195     // create the file, fail if it already exists and bOverwrite
196     bool wxFile::Create(const wxChar *szFileName, bool bOverwrite, int accessMode)
197     {
198     // if bOverwrite we create a new file or truncate the existing one,
199     // otherwise we only create the new file and fail if it already exists
200     #if defined(__WXMAC__) && !defined(__UNIX__) && !wxUSE_UNICODE
201     // Dominic Mazzoni [dmazzoni+@cs.cmu.edu] reports that open is still broken on the mac, so we replace
202     // int fd = open( szFileName , O_CREAT | (bOverwrite ? O_TRUNC : O_EXCL), access);
203     int fd = creat( szFileName , accessMode);
204     #else
205     int fd = wxOpen( szFileName,
206     O_BINARY | O_WRONLY | O_CREAT |
207     (bOverwrite ? O_TRUNC : O_EXCL)
208     ACCESS(accessMode) );
209     #endif
210     if ( fd == -1 )
211     {
212     wxLogSysError(_("can't create file '%s'"), szFileName);
213     return false;
214     }
215    
216     Attach(fd);
217     return true;
218     }
219    
220     // open the file
221     bool wxFile::Open(const wxChar *szFileName, OpenMode mode, int accessMode)
222     {
223     int flags = O_BINARY;
224    
225     switch ( mode )
226     {
227     case read:
228     flags |= O_RDONLY;
229     break;
230    
231     case write_append:
232     if ( wxFile::Exists(szFileName) )
233     {
234     flags |= O_WRONLY | O_APPEND;
235     break;
236     }
237     //else: fall through as write_append is the same as write if the
238     // file doesn't exist
239    
240     case write:
241     flags |= O_WRONLY | O_CREAT | O_TRUNC;
242     break;
243    
244     case write_excl:
245     flags |= O_WRONLY | O_CREAT | O_EXCL;
246     break;
247    
248     case read_write:
249     flags |= O_RDWR;
250     break;
251     }
252    
253     #ifdef __WINDOWS__
254     // only read/write bits for "all" are supported by this function under
255     // Windows, and VC++ 8 returns EINVAL if any other bits are used in
256     // accessMode, so clear them as they have at best no effect anyhow
257     accessMode &= wxS_IRUSR | wxS_IWUSR;
258     #endif // __WINDOWS__
259    
260     int fd = wxOpen( szFileName, flags ACCESS(accessMode));
261    
262     if ( fd == -1 )
263     {
264     wxLogSysError(_("can't open file '%s'"), szFileName);
265     return false;
266     }
267    
268     Attach(fd);
269     return true;
270     }
271    
272     // close
273     bool wxFile::Close()
274     {
275     if ( IsOpened() ) {
276     if (wxClose(m_fd) == -1)
277     {
278     wxLogSysError(_("can't close file descriptor %d"), m_fd);
279     m_fd = fd_invalid;
280     return false;
281     }
282     else
283     m_fd = fd_invalid;
284     }
285    
286     return true;
287     }
288    
289     // ----------------------------------------------------------------------------
290     // read/write
291     // ----------------------------------------------------------------------------
292    
293     // read
294     ssize_t wxFile::Read(void *pBuf, size_t nCount)
295     {
296     wxCHECK( (pBuf != NULL) && IsOpened(), 0 );
297    
298     ssize_t iRc = wxRead(m_fd, pBuf, nCount);
299    
300     if ( iRc == -1 )
301     {
302     wxLogSysError(_("can't read from file descriptor %d"), m_fd);
303     return wxInvalidOffset;
304     }
305    
306     return iRc;
307     }
308    
309     // write
310     size_t wxFile::Write(const void *pBuf, size_t nCount)
311     {
312     wxCHECK( (pBuf != NULL) && IsOpened(), 0 );
313    
314     ssize_t iRc = wxWrite(m_fd, pBuf, nCount);
315    
316     if ( iRc == -1 )
317     {
318     wxLogSysError(_("can't write to file descriptor %d"), m_fd);
319     m_error = true;
320     iRc = 0;
321     }
322    
323     return iRc;
324     }
325    
326     // flush
327     bool wxFile::Flush()
328     {
329     #ifdef HAVE_FSYNC
330     // fsync() only works on disk files and returns errors for pipes, don't
331     // call it then
332     if ( IsOpened() && GetKind() == wxFILE_KIND_DISK )
333     {
334     if ( wxFsync(m_fd) == -1 )
335     {
336     wxLogSysError(_("can't flush file descriptor %d"), m_fd);
337     return false;
338     }
339     }
340     #endif // HAVE_FSYNC
341    
342     return true;
343     }
344    
345     // ----------------------------------------------------------------------------
346     // seek
347     // ----------------------------------------------------------------------------
348    
349     // seek
350     wxFileOffset wxFile::Seek(wxFileOffset ofs, wxSeekMode mode)
351     {
352     wxASSERT_MSG( IsOpened(), _T("can't seek on closed file") );
353     wxCHECK_MSG( ofs != wxInvalidOffset || mode != wxFromStart,
354     wxInvalidOffset,
355     _T("invalid absolute file offset") );
356    
357     int origin;
358     switch ( mode ) {
359     default:
360     wxFAIL_MSG(_("unknown seek origin"));
361    
362     case wxFromStart:
363     origin = SEEK_SET;
364     break;
365    
366     case wxFromCurrent:
367     origin = SEEK_CUR;
368     break;
369    
370     case wxFromEnd:
371     origin = SEEK_END;
372     break;
373     }
374    
375     wxFileOffset iRc = wxSeek(m_fd, ofs, origin);
376     if ( iRc == wxInvalidOffset )
377     {
378     wxLogSysError(_("can't seek on file descriptor %d"), m_fd);
379     }
380    
381     return iRc;
382     }
383    
384     // get current file offset
385     wxFileOffset wxFile::Tell() const
386     {
387     wxASSERT( IsOpened() );
388    
389     wxFileOffset iRc = wxTell(m_fd);
390     if ( iRc == wxInvalidOffset )
391     {
392     wxLogSysError(_("can't get seek position on file descriptor %d"), m_fd);
393     }
394    
395     return iRc;
396     }
397    
398     // get current file length
399     wxFileOffset wxFile::Length() const
400     {
401     wxASSERT( IsOpened() );
402    
403     wxFileOffset iRc = Tell();
404     if ( iRc != wxInvalidOffset ) {
405     // have to use const_cast :-(
406     wxFileOffset iLen = ((wxFile *)this)->SeekEnd();
407     if ( iLen != wxInvalidOffset ) {
408     // restore old position
409     if ( ((wxFile *)this)->Seek(iRc) == wxInvalidOffset ) {
410     // error
411     iLen = wxInvalidOffset;
412     }
413     }
414    
415     iRc = iLen;
416     }
417    
418     if ( iRc == wxInvalidOffset )
419     {
420     wxLogSysError(_("can't find length of file on file descriptor %d"), m_fd);
421     }
422    
423     return iRc;
424     }
425    
426     // is end of file reached?
427     bool wxFile::Eof() const
428     {
429     wxASSERT( IsOpened() );
430    
431     wxFileOffset iRc;
432    
433     #if defined(__DOS__) || defined(__UNIX__) || defined(__GNUWIN32__) || defined( __MWERKS__ ) || defined(__SALFORDC__)
434     // @@ this doesn't work, of course, on unseekable file descriptors
435     wxFileOffset ofsCur = Tell(),
436     ofsMax = Length();
437     if ( ofsCur == wxInvalidOffset || ofsMax == wxInvalidOffset )
438     iRc = wxInvalidOffset;
439     else
440     iRc = ofsCur == ofsMax;
441     #else // Windows and "native" compiler
442     iRc = wxEof(m_fd);
443     #endif // Windows/Unix
444    
445     if ( iRc == 1)
446     {}
447     else if ( iRc == 0 )
448     return false;
449     else if ( iRc == wxInvalidOffset )
450     wxLogSysError(_("can't determine if the end of file is reached on descriptor %d"), m_fd);
451     else
452     wxFAIL_MSG(_("invalid eof() return value."));
453    
454     return true;
455     }
456    
457     // ============================================================================
458     // implementation of wxTempFile
459     // ============================================================================
460    
461     // ----------------------------------------------------------------------------
462     // construction
463     // ----------------------------------------------------------------------------
464    
465     wxTempFile::wxTempFile(const wxString& strName)
466     {
467     Open(strName);
468     }
469    
470     bool wxTempFile::Open(const wxString& strName)
471     {
472     // we must have an absolute filename because otherwise CreateTempFileName()
473     // would create the temp file in $TMP (i.e. the system standard location
474     // for the temp files) which might be on another volume/drive/mount and
475     // wxRename()ing it later to m_strName from Commit() would then fail
476     //
477     // with the absolute filename, the temp file is created in the same
478     // directory as this one which ensures that wxRename() may work later
479     wxFileName fn(strName);
480     if ( !fn.IsAbsolute() )
481     {
482     fn.Normalize(wxPATH_NORM_ABSOLUTE);
483     }
484    
485     m_strName = fn.GetFullPath();
486    
487     m_strTemp = wxFileName::CreateTempFileName(m_strName, &m_file);
488    
489     if ( m_strTemp.empty() )
490     {
491     // CreateTempFileName() failed
492     return false;
493     }
494    
495     #ifdef __UNIX__
496     // the temp file should have the same permissions as the original one
497     mode_t mode;
498    
499     wxStructStat st;
500     if ( stat( (const char*) m_strName.fn_str(), &st) == 0 )
501     {
502     mode = st.st_mode;
503     }
504     else
505     {
506     // file probably didn't exist, just give it the default mode _using_
507     // user's umask (new files creation should respect umask)
508     mode_t mask = umask(0777);
509     mode = 0666 & ~mask;
510     umask(mask);
511     }
512    
513     if ( chmod( (const char*) m_strTemp.fn_str(), mode) == -1 )
514     {
515     #ifndef __OS2__
516     wxLogSysError(_("Failed to set temporary file permissions"));
517     #endif
518     }
519     #endif // Unix
520    
521     return true;
522     }
523    
524     // ----------------------------------------------------------------------------
525     // destruction
526     // ----------------------------------------------------------------------------
527    
528     wxTempFile::~wxTempFile()
529     {
530     if ( IsOpened() )
531     Discard();
532     }
533    
534     bool wxTempFile::Commit()
535     {
536     m_file.Close();
537    
538     if ( wxFile::Exists(m_strName) && wxRemove(m_strName) != 0 ) {
539     wxLogSysError(_("can't remove file '%s'"), m_strName.c_str());
540     return false;
541     }
542    
543     if ( !wxRenameFile(m_strTemp, m_strName) ) {
544     wxLogSysError(_("can't commit changes to file '%s'"), m_strName.c_str());
545     return false;
546     }
547    
548     return true;
549     }
550    
551     void wxTempFile::Discard()
552     {
553     m_file.Close();
554     if ( wxRemove(m_strTemp) != 0 )
555     wxLogSysError(_("can't remove temporary file '%s'"), m_strTemp.c_str());
556     }
557    
558     #endif // wxUSE_FILE
559    

  ViewVC Help
Powered by ViewVC 1.1.22