/* gcc -g -Wall test_fast_read_dir.c -o test_fast_read_dir -lgdal -L. -Igcore -Iport */

#include "cpl_string.h"
#include "gdal.h"

typedef struct
{
    char* pszDir;
    char** papszDirFileList;
} sCacheDirEntry;

char** myReadDirFun(const char* pszDir)
{
    static int             nCachedDirEntries = 0;
    static sCacheDirEntry* psCacheDirEntries = NULL;

    int i;
    for(i=0;i<nCachedDirEntries;i++)
    {
        if (strcmp(pszDir, psCacheDirEntries[i].pszDir) == 0)
            return CSLDuplicate(psCacheDirEntries[i].papszDirFileList);
    }

    psCacheDirEntries = (sCacheDirEntry*)CPLRealloc(psCacheDirEntries, (nCachedDirEntries + 1) * sizeof(sCacheDirEntry));
    psCacheDirEntries[nCachedDirEntries].pszDir = CPLStrdup(pszDir);
    psCacheDirEntries[nCachedDirEntries].papszDirFileList = VSIReadDirWithoutCache(pszDir);
    nCachedDirEntries++;

    return CSLDuplicate(psCacheDirEntries[nCachedDirEntries-1].papszDirFileList);
}

int main(int argc, char* argv[])
{
    GDALAllRegister();

    VSIInstallCustomReadDirCallback(myReadDirFun);

    CPLSetErrorHandler(CPLQuietErrorHandler);

    const char* pszPath = (argc == 1) ? "." : argv[1];
    char** papszDirFileList = VSIReadDir(pszPath);
    char** papszIter = papszDirFileList;
    while(*papszIter)
    {
        char* pszFileName = CPLStrdup(CPLFormFilename(pszPath, *papszIter, NULL));
        GDALDatasetH hDS = GDALOpen(pszFileName, GA_ReadOnly);
        if (hDS)
        {
            printf("%s : %d x %d\n", *papszIter, GDALGetRasterXSize(hDS), GDALGetRasterYSize(hDS));
            GDALClose(hDS);
        }
        CPLFree(pszFileName);

        papszIter ++;
    }
    CSLDestroy(papszDirFileList);

    return 0;
}

