From: Vadim Zeitlin Date: Sat, 7 Apr 2007 18:23:57 +0000 (+0000) Subject: add support for resources forks in wxCopyFile() (modified patch 1620336) X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/0597e7f977c87d107e24bf3e95ebfa3d60efc249 add support for resources forks in wxCopyFile() (modified patch 1620336) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@45308 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/docs/changes.txt b/docs/changes.txt index 564cb53174..d9141a11c5 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -117,6 +117,7 @@ wxMac: - Fix duplicate (empty) help menu in non-English programs (Andreas Jacobs) - Allow accelerators to be used with buttons too (Ryan Wilcox) +- Support resource forks in wxCopyFile() (Hank Schultz) wxMSW: diff --git a/docs/latex/wx/function.tex b/docs/latex/wx/function.tex index 30bb2dd121..c6db80094d 100644 --- a/docs/latex/wx/function.tex +++ b/docs/latex/wx/function.tex @@ -1178,10 +1178,12 @@ true if successful. \func{bool}{wxCopyFile}{\param{const wxString\& }{file1}, \param{const wxString\& }{file2}, \param{bool }{overwrite = true}} Copies {\it file1} to {\it file2}, returning true if successful. If -{\it overwrite} parameter is true (default), the destination file is overwritten -if it exists, but if {\it overwrite} is false, the functions fails in this +{\it overwrite} parameter is \true (default), the destination file is overwritten +if it exists, but if {\it overwrite} is \false, the functions fails in this case. +This function supports resources forks under Mac OS. + \membersection{::wxGetCwd}\label{wxgetcwd} diff --git a/src/common/filefn.cpp b/src/common/filefn.cpp index 3d2807acc1..636e3d9aac 100644 --- a/src/common/filefn.cpp +++ b/src/common/filefn.cpp @@ -158,7 +158,7 @@ WXDLLEXPORT int wxOpen( const wxChar *pathname, int flags, mode_t mode ) // BCC 5.5 and 5.5.1 have a bug in _wopen where files are created read only // regardless of the mode parameter. This hack works around the problem by // setting the mode with _wchmod. -// +// int wxOpen(const wchar_t *pathname, int flags, mode_t mode) { int moreflags = 0; @@ -1058,6 +1058,51 @@ wxConcatFiles (const wxString& file1, const wxString& file2, const wxString& fil #endif } +// helper of generic implementation of wxCopyFile() +#if !(defined(__WIN32__) || defined(__OS2__) || defined(__PALMOS__)) && \ + wxUSE_FILE + +static bool +wxDoCopyFile(wxFile& fileIn, + const wxStructStat& fbuf, + const wxString& filenameDst, + bool overwrite) +{ + // reset the umask as we want to create the file with exactly the same + // permissions as the original one + wxCHANGE_UMASK(0); + + // create file2 with the same permissions than file1 and open it for + // writing + + wxFile fileOut; + if ( !fileOut.Create(filenameDst, overwrite, fbuf.st_mode & 0777) ) + return false; + + // copy contents of file1 to file2 + char buf[4096]; + for ( ;; ) + { + ssize_t count = fileIn.Read(buf, WXSIZEOF(buf)); + if ( count == wxInvalidOffset ) + return false; + + // end of file? + if ( !count ) + break; + + if ( fileOut.Write(buf, count) < (size_t)count ) + return false; + } + + // we can expect fileIn to be closed successfully, but we should ensure + // that fileOut was closed as some write errors (disk full) might not be + // detected before doing this + return fileIn.Close() && fileOut.Close(); +} + +#endif // generic implementation of wxCopyFile + // Copy files bool wxCopyFile (const wxString& file1, const wxString& file2, bool overwrite) @@ -1107,38 +1152,49 @@ wxCopyFile (const wxString& file1, const wxString& file2, bool overwrite) return false; } - // reset the umask as we want to create the file with exactly the same - // permissions as the original one - wxCHANGE_UMASK(0); + wxDoCopyFile(fileIn, fbuf, file2, overwrite); - // create file2 with the same permissions than file1 and open it for - // writing - - wxFile fileOut; - if ( !fileOut.Create(file2, overwrite, fbuf.st_mode & 0777) ) - return false; +#if defined(__WXMAC__) || defined(__WXCOCOA__) + // copy the resource fork of the file too if it's present + wxString pathRsrcOut; + wxFile fileRsrcIn; - // copy contents of file1 to file2 - char buf[4096]; - for ( ;; ) { - ssize_t count = fileIn.Read(buf, WXSIZEOF(buf)); - if ( count == wxInvalidOffset ) - return false; + // suppress error messages from this block as resource forks don't have + // to exist + wxLogNull noLog; + + // it's not enough to check for file existence: it always does on HFS + // but is empty for files without resources + if ( fileRsrcIn.Open(file1 + wxT("/..namedfork/rsrc")) && + fileRsrcIn.Length() > 0 ) + { + // we must be using HFS or another filesystem with resource fork + // support, suppose that destination file system also is HFS[-like] + pathRsrcOut = file2 + wxT("/..namedfork/rsrc"); + } + else // check if we have resource fork in separate file (non-HFS case) + { + wxFileName fnRsrc(file1); + fnRsrc.SetName(wxT("._") + fnRsrc.GetName()); - // end of file? - if ( !count ) - break; + fileRsrcIn.Close(); + if ( fileRsrcIn.Open( fnRsrc.GetFullPath() ) ) + { + fnRsrc = file2; + fnRsrc.SetName(wxT("._") + fnRsrc.GetName()); - if ( fileOut.Write(buf, count) < (size_t)count ) - return false; + pathRsrcOut = fnRsrc.GetFullPath(); + } + } } - // we can expect fileIn to be closed successfully, but we should ensure - // that fileOut was closed as some write errors (disk full) might not be - // detected before doing this - if ( !fileIn.Close() || !fileOut.Close() ) - return false; + if ( !pathRsrcOut.empty() ) + { + if ( !wxDoCopyFile(fileRsrcIn, fbuf, pathRsrcOut, overwrite) ) + return false; + } +#endif // wxMac || wxCocoa #if !defined(__VISAGECPP__) && !defined(__WXMAC__) || defined(__UNIX__) // no chmod in VA. Should be some permission API for HPFS386 partitions