Index: port/cpl_vsi.h
===================================================================
--- port/cpl_vsi.h	(révision 13728)
+++ port/cpl_vsi.h	(copie de travail)
@@ -176,8 +176,12 @@
 /*      Other...                                                        */
 /* ==================================================================== */
 
+typedef char** (*VSICustomReadDirCallback)(const char* pszPath);
+void CPL_DLL VSIInstallCustomReadDirCallback(VSICustomReadDirCallback _pfnCustomReadDir);
+
 #define CPLReadDir VSIReadDir
 char CPL_DLL **VSIReadDir( const char * );
+char CPL_DLL **VSIReadDirDefault( const char *pszPath );
 int CPL_DLL VSIMkdir( const char * pathname, long mode );
 int CPL_DLL VSIRmdir( const char * pathname );
 int CPL_DLL VSIUnlink( const char * pathname );
Index: port/cpl_vsil.cpp
===================================================================
--- port/cpl_vsil.cpp	(révision 13728)
+++ port/cpl_vsil.cpp	(copie de travail)
@@ -33,7 +33,51 @@
 
 CPL_CVSID("$Id$");
 
+static VSICustomReadDirCallback pfnCustomReadDir = NULL;
+
 /************************************************************************/
+/*                VSIInstallCustomReadDirCallback()                     */
+/************************************************************************/
+
+/**
+ * \brief Install a callback to speed up VSIReadDir
+ *
+ * This function install a callback that can be used by VSIReadDir to speed
+ * up directory file listing. This can be usefull when the calling application
+ * knows that the directory content has not changed for example.
+ * The signature of the callback is : char** cachedReadDir(char* pszPath).
+ * The return value of the callback will be freed by CSLDestroy.
+ *
+ * @note The callback implementation must be thread-safe if GDAL is used
+ *       in a multi-threaded application.
+ */
+
+void VSIInstallCustomReadDirCallback(VSICustomReadDirCallback _pfnCustomReadDir)
+{
+    pfnCustomReadDir = _pfnCustomReadDir;
+}
+
+/************************************************************************/
+/*                          VSIReadDirDefault()                         */
+/************************************************************************/
+
+/**
+ * \brief Read names in a directory.
+ *
+ * This function acts similarly to VSIReadDir, except it does not use
+ * the callback installed by VSIInstallCustomReadDirCallback
+ *
+ */
+
+char **VSIReadDirDefault(const char *pszPath)
+{
+    VSIFilesystemHandler *poFSHandler = 
+        VSIFileManager::GetHandler( pszPath );
+
+    return poFSHandler->ReadDir( pszPath );
+}
+
+/************************************************************************/
 /*                             VSIReadDir()                             */
 /************************************************************************/
 
@@ -47,6 +91,9 @@
  *
  * Note that no error is issued via CPLError() if the directory path is
  * invalid, though NULL is returned.
+ *
+ * This function will used the callback installed by VSIInstallCustomReadDirCallback
+ * if available.
  * 
  * This function used to be known as CPLReadDir(), but the old name is now 
  * deprecated. 
@@ -58,10 +105,14 @@
 
 char **VSIReadDir(const char *pszPath)
 {
-    VSIFilesystemHandler *poFSHandler = 
-        VSIFileManager::GetHandler( pszPath );
+    if (pfnCustomReadDir)
+    {
+        char** papszDir = pfnCustomReadDir(pszPath);
+        if (papszDir)
+            return papszDir;
+    }
 
-    return poFSHandler->ReadDir( pszPath );
+    return VSIReadDirDefault(pszPath);
 }
 
 /************************************************************************/

