On Thu, Apr 30, 2009 at 12:42:27AM +0200, for...@lyx.org wrote:

> Author: forenr
> Date: Thu Apr 30 00:42:26 2009
> New Revision: 29444
> URL: http://www.lyx.org/trac/changeset/29444
> 
> Log:
> Speed up FileName operator==, such that working with child documents on
> Windows and Solaris is again possible.

Jürgen, OK for branch?

Without this patch it is a pain working with child documents.
In some cases, when I have finished quickly typing 5 or 6 characters,
only the first two have been shown on screen. With this patch I am not
able to type ahead, neither on Windows nor on Solaris.

> Modified:
>    lyx-devel/trunk/src/support/FileName.cpp
>    lyx-devel/trunk/src/support/os.h
>    lyx-devel/trunk/src/support/os_cygwin.cpp
>    lyx-devel/trunk/src/support/os_unix.cpp
>    lyx-devel/trunk/src/support/os_win32.cpp
> 
> Modified: lyx-devel/trunk/src/support/FileName.cpp
> ==============================================================================
> --- lyx-devel/trunk/src/support/FileName.cpp  Wed Apr 29 22:34:41 2009        
> (r29443)
> +++ lyx-devel/trunk/src/support/FileName.cpp  Thu Apr 30 00:42:26 2009        
> (r29444)
> @@ -921,49 +921,18 @@
>  }
>  
>  
> -// Note: According to Qt, QFileInfo::operator== is undefined when
> -// both files do not exist (Qt4.5 gives true for all non-existent
> -// files, while Qt4.4 compares the filenames).
> -// see:
> -// http://www.qtsoftware.com/developer/task-tracker/
> -//   index_html?id=248471&method=entry.
> -bool operator==(FileName const & l, FileName const & r)
> -{
> -     // FIXME: In future use Qt.
> -     // Qt 4.4: We need to solve this warning from Qt documentation:
> -     // * Long and short file names that refer to the same file on Windows 
> are
> -     //   treated as if they referred to different files.
> -     // This is supposed to be fixed for Qt5.
> -     FileName const lhs(os::internal_path(l.absFilename()));
> -     FileName const rhs(os::internal_path(r.absFilename()));
> -
> -     if (lhs.empty())
> -             // QFileInfo::operator==() returns false if the two QFileInfo 
> are empty.
> -             return rhs.empty();
> -
> -     if (rhs.empty())
> -             // Avoid unnecessary checks below.
> -             return false;
> -
> -     lhs.d->refresh();
> -     rhs.d->refresh();
> -     
> -     if (!lhs.d->fi.isSymLink() && !rhs.d->fi.isSymLink()) {
> -             // Qt already checks if the filesystem is case sensitive or not.
> -             // see note above why the extra check with fileName is needed.
> -             return lhs.d->fi == rhs.d->fi
> -                     && lhs.d->fi.fileName() == rhs.d->fi.fileName();
> +bool operator==(FileName const & lhs, FileName const & rhs)
> +{
> +     // Firstly, compare the filenames.
> +     if (QString::compare(toqstr(lhs.absFilename()),
> +                          toqstr(rhs.absFilename()),
> +                          os::isFilesystemCaseSensitive() ?
> +                          Qt::CaseSensitive : Qt::CaseInsensitive) == 0) {
> +             return true;
>       }
>  
> -     // FIXME: When/if QFileInfo support symlink comparison, remove this 
> code.
> -     QFileInfo fi1(lhs.d->fi);
> -     if (fi1.isSymLink())
> -             fi1 = QFileInfo(fi1.symLinkTarget());
> -     QFileInfo fi2(rhs.d->fi);
> -     if (fi2.isSymLink())
> -             fi2 = QFileInfo(fi2.symLinkTarget());
> -     // see note above why the extra check with fileName is needed.
> -     return fi1 == fi2 && fi1.fileName() == fi2.fileName();
> +     // They don't match, so check whether they point to the same file.
> +     return os::isSameFile(lhs.toFilesystemEncoding(), 
> rhs.toFilesystemEncoding());
>  }
>  
>  
> 
> Modified: lyx-devel/trunk/src/support/os.h
> ==============================================================================
> --- lyx-devel/trunk/src/support/os.h  Wed Apr 29 22:34:41 2009        (r29443)
> +++ lyx-devel/trunk/src/support/os.h  Thu Apr 30 00:42:26 2009        (r29444)
> @@ -112,6 +112,9 @@
>   */
>  bool autoOpenFile(std::string const & filename, auto_open_mode const mode = 
> VIEW);
>  
> +/// Check whether two filenames point to the same file.
> +bool isSameFile(std::string const & fileone, std::string const & filetwo);
> +
>  } // namespace os
>  } // namespace support
>  } // namespace lyx
> 
> Modified: lyx-devel/trunk/src/support/os_cygwin.cpp
> ==============================================================================
> --- lyx-devel/trunk/src/support/os_cygwin.cpp Wed Apr 29 22:34:41 2009        
> (r29443)
> +++ lyx-devel/trunk/src/support/os_cygwin.cpp Thu Apr 30 00:42:26 2009        
> (r29444)
> @@ -6,6 +6,7 @@
>   * \author Ruurd A. Reitsma
>   * \author Claus Hentschel
>   * \author Angus Leeming
> + * \author Enrico Forestieri
>   *
>   * Full author contact details are available in file CREDITS.
>   *
> @@ -26,8 +27,8 @@
>  #include <shellapi.h>
>  #include <shlwapi.h>
>  #include <limits.h>
> -
>  #include <sys/cygwin.h>
> +#include <sys/stat.h>
>  
>  using namespace std;
>  
> @@ -281,6 +282,21 @@
>               win_path.c_str(), NULL, NULL, 1)) > 32;
>  }
>  
> +
> +bool isSameFile(string const & fileone, string const & filetwo)
> +{
> +     struct stat st1;
> +     struct stat st2;
> +
> +     if (::stat(fileone.c_str(), &st1) == 0
> +         && ::stat(filetwo.c_str(), &st2) == 0) {
> +             return st1.st_ino == st2.st_ino && st1.st_dev == st2.st_dev;
> +     }
> +
> +     // One or both files cannot be accessed.
> +     return false;
> +}
> +
>  } // namespace os
>  } // namespace support
>  } // namespace lyx
> 
> Modified: lyx-devel/trunk/src/support/os_unix.cpp
> ==============================================================================
> --- lyx-devel/trunk/src/support/os_unix.cpp   Wed Apr 29 22:34:41 2009        
> (r29443)
> +++ lyx-devel/trunk/src/support/os_unix.cpp   Thu Apr 30 00:42:26 2009        
> (r29444)
> @@ -17,6 +17,8 @@
>  #include "support/FileName.h"
>  #include "support/lstrings.h"
>  
> +#include <sys/stat.h>
> +
>  #ifdef __APPLE__
>  #include <Carbon/Carbon.h>
>  #endif
> @@ -215,6 +217,21 @@
>  #endif
>  }
>  
> +
> +bool isSameFile(string const & fileone, string const & filetwo)
> +{
> +     struct stat st1;
> +     struct stat st2;
> +
> +     if (::stat(fileone.c_str(), &st1) == 0
> +         && ::stat(filetwo.c_str(), &st2) == 0) {
> +             return st1.st_ino == st2.st_ino && st1.st_dev == st2.st_dev;
> +     }
> +
> +     // One or both files cannot be accessed.
> +     return false;
> +}
> +
>  } // namespace os
>  } // namespace support
>  } // namespace lyx
> 
> Modified: lyx-devel/trunk/src/support/os_win32.cpp
> ==============================================================================
> --- lyx-devel/trunk/src/support/os_win32.cpp  Wed Apr 29 22:34:41 2009        
> (r29443)
> +++ lyx-devel/trunk/src/support/os_win32.cpp  Thu Apr 30 00:42:26 2009        
> (r29444)
> @@ -389,6 +389,43 @@
>               to_local8bit(from_utf8(filename)).c_str(), NULL, NULL, 1)) > 32;
>  }
>  
> +
> +bool isSameFile(string const & fileone, string const & filetwo)
> +{
> +     HANDLE h1 = CreateFile(fileone.c_str(), 0,
> +             FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
> +     HANDLE h2 = CreateFile(filetwo.c_str(), 0,
> +             FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
> +
> +     if (h1 == INVALID_HANDLE_VALUE || h2 == INVALID_HANDLE_VALUE) {
> +             // One or both files cannot be accessed.
> +             if (h1 != INVALID_HANDLE_VALUE)
> +                     CloseHandle(h1);
> +             if (h2 != INVALID_HANDLE_VALUE)
> +                     CloseHandle(h2);
> +             return false;
> +     }
> +
> +     BY_HANDLE_FILE_INFORMATION info1;
> +     BY_HANDLE_FILE_INFORMATION info2;
> +     bool samefile = false;
> +     if (GetFileInformationByHandle(h1, &info1) != 0
> +         && GetFileInformationByHandle(h2, &info2) != 0) {
> +             // Serial number of the volumes containing the files.
> +             ULONG st1_dev = info1.dwVolumeSerialNumber;
> +             ULONG st2_dev = info2.dwVolumeSerialNumber;
> +             // Unique identifiers associated to the files on the volumes.
> +             ULONGLONG highbits = info1.nFileIndexHigh & 0x0000FFFF;
> +             ULONGLONG st1_ino = (highbits << sizeof(ULONG)) | 
> info1.nFileIndexLow;
> +             highbits = info2.nFileIndexHigh & 0x0000FFFF;
> +             ULONGLONG st2_ino = (highbits << sizeof(ULONG)) | 
> info2.nFileIndexLow;
> +             samefile = st1_ino == st2_ino && st1_dev == st2_dev;
> +     }
> +     CloseHandle(h1);
> +     CloseHandle(h2);
> +     return samefile;
> +}
> +
>  } // namespace os
>  } // namespace support
>  } // namespace lyx

-- 
Enrico

Reply via email to