Example #1
0
void CGitStatusCache::Create()
{
    ATLASSERT(m_pInstance == NULL);
    m_pInstance = new CGitStatusCache;

    m_pInstance->watcher.SetFolderCrawler(&m_pInstance->m_folderCrawler);
#define LOADVALUEFROMFILE(x) if (fread(&x, sizeof(x), 1, pFile)!=1) goto exit;
#define LOADVALUEFROMFILE2(x) if (fread(&x, sizeof(x), 1, pFile)!=1) goto error;
    unsigned int value = (unsigned int)-1;
    FILE * pFile = NULL;
    // find the location of the cache
    TCHAR path[MAX_PATH];		//MAX_PATH ok here.
    TCHAR path2[MAX_PATH];
    if (SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, SHGFP_TYPE_CURRENT, path)==S_OK)
    {
        _tcscat_s(path, MAX_PATH, _T("\\TGitCache"));
        if (!PathIsDirectory(path))
        {
            if (CreateDirectory(path, NULL)==0)
                goto error;
        }
        _tcscat_s(path, MAX_PATH, _T("\\cache"));
        // in case the cache file is corrupt, we could crash while
        // reading it! To prevent crashing every time once that happens,
        // we make a copy of the cache file and use that copy to read from.
        // if that copy is corrupt, the original file won't exist anymore
        // and the second time we start up and try to read the file,
        // it's not there anymore and we start from scratch without a crash.
        _tcscpy_s(path2, MAX_PATH, path);
        _tcscat_s(path2, MAX_PATH, _T("2"));
        DeleteFile(path2);
        CopyFile(path, path2, FALSE);
        DeleteFile(path);
        pFile = _tfsopen(path2, _T("rb"), _SH_DENYNO);
        if (pFile)
        {
            try
            {
                LOADVALUEFROMFILE(value);
                if (value != 2)
                {
                    goto error;
                }
                int mapsize = 0;
                LOADVALUEFROMFILE(mapsize);
                for (int i=0; i<mapsize; ++i)
                {
                    LOADVALUEFROMFILE2(value);
                    if (value > MAX_PATH)
                        goto error;
                    if (value)
                    {
                        CString sKey;
                        if (fread(sKey.GetBuffer(value+1), sizeof(TCHAR), value, pFile)!=value)
                        {
                            sKey.ReleaseBuffer(0);
                            goto error;
                        }
                        sKey.ReleaseBuffer(value);
                        CCachedDirectory * cacheddir = new CCachedDirectory();
                        if (cacheddir == NULL)
                            goto error;
                        if (!cacheddir->LoadFromDisk(pFile))
                            goto error;
                        CTGitPath KeyPath = CTGitPath(sKey);
                        if (m_pInstance->IsPathAllowed(KeyPath))
                        {
                            m_pInstance->m_directoryCache[KeyPath] = cacheddir;
                            // only add the path to the watch list if it is versioned
                            if ((cacheddir->GetCurrentFullStatus() != git_wc_status_unversioned)&&(cacheddir->GetCurrentFullStatus() != git_wc_status_none))
                                m_pInstance->watcher.AddPath(KeyPath, false);
                            // do *not* add the paths for crawling!
                            // because crawled paths will trigger a shell
                            // notification, which makes the desktop flash constantly
                            // until the whole first time crawling is over
                            // m_pInstance->AddFolderForCrawling(KeyPath);
                        }
                    }
                }
            }
            catch (CAtlException)
            {
                goto error;
            }
        }
    }
exit:
    if (pFile)
        fclose(pFile);
    DeleteFile(path2);
    m_pInstance->watcher.ClearInfoMap();
    ATLTRACE("cache loaded from disk successfully!\n");
    return;
error:
    if (pFile)
        fclose(pFile);
    DeleteFile(path2);
    m_pInstance->watcher.ClearInfoMap();
    Destroy();
    m_pInstance = new CGitStatusCache;
    ATLTRACE("cache not loaded from disk\n");
}
Example #2
0
void CSVNStatusCache::Create()
{
    ATLASSERT(m_pInstance == NULL);
    if (m_pInstance != NULL)
        return;

    m_pInstance = new CSVNStatusCache;

    m_pInstance->watcher.SetFolderCrawler(&m_pInstance->m_folderCrawler);
#define LOADVALUEFROMFILE(x) if (fread(&x, sizeof(x), 1, pFile)!=1) goto exit;
#define LOADVALUEFROMFILE2(x) if (fread(&x, sizeof(x), 1, pFile)!=1) goto error;
    unsigned int value = (unsigned int)-1;
    FILE * pFile = NULL;
    // find the location of the cache
    CString path = GetSpecialFolder(FOLDERID_LocalAppData);
    CString path2;
    if (!path.IsEmpty())
    {
        path += L"\\TSVNCache";
        if (!PathIsDirectory(path))
        {
            DeleteFile(path);
            if (CreateDirectory(path, NULL)==0)
                goto error;
        }
        path += STATUSCACHEFILENAME;
        // in case the cache file is corrupt, we could crash while
        // reading it! To prevent crashing every time once that happens,
        // we make a copy of the cache file and use that copy to read from.
        // if that copy is corrupt, the original file won't exist anymore
        // and the second time we start up and try to read the file,
        // it's not there anymore and we start from scratch without a crash.
        path2 = path;
        path2 += L"2";
        DeleteFile(path2);
        CopyFile(path, path2, FALSE);
        DeleteFile(path);
        pFile = _tfsopen(path2, L"rb", _SH_DENYNO);
        if (pFile)
        {
            try
            {
                LOADVALUEFROMFILE(value);
                if (value != CACHEDISKVERSION)
                {
                    goto error;
                }
                int mapsize = 0;
                LOADVALUEFROMFILE(mapsize);
                for (int i=0; i<mapsize; ++i)
                {
                    LOADVALUEFROMFILE2(value);
                    if (value > MAX_PATH)
                        goto error;
                    if (value)
                    {
                        CString sKey;
                        if (fread(sKey.GetBuffer(value+1), sizeof(TCHAR), value, pFile)!=value)
                        {
                            sKey.ReleaseBuffer(0);
                            goto error;
                        }
                        sKey.ReleaseBuffer(value);
                        std::unique_ptr<CCachedDirectory> cacheddir (new CCachedDirectory());
                        if (!cacheddir.get() || !cacheddir->LoadFromDisk(pFile))
                        {
                            cacheddir.reset();
                            goto error;
                        }
                        CTSVNPath KeyPath = CTSVNPath(sKey);
                        if (m_pInstance->IsPathAllowed(KeyPath))
                        {
                            // only add the path to the watch list if it is versioned
                            if ((cacheddir->GetCurrentFullStatus() != svn_wc_status_unversioned)&&(cacheddir->GetCurrentFullStatus() != svn_wc_status_none))
                                m_pInstance->watcher.AddPath(KeyPath, false);

                            m_pInstance->m_directoryCache[KeyPath] = cacheddir.release();

                            // do *not* add the paths for crawling!
                            // because crawled paths will trigger a shell
                            // notification, which makes the desktop flash constantly
                            // until the whole first time crawling is over
                            // m_pInstance->AddFolderForCrawling(KeyPath);
                        }
                    }
                }
            }
            catch (CAtlException)
            {
                goto error;
            }
        }
    }
exit:
    if (pFile)
        fclose(pFile);
    if (!path2.IsEmpty())
        DeleteFile(path2);
    m_pInstance->watcher.ClearInfoMap();
    CTraceToOutputDebugString::Instance()(__FUNCTION__ ": cache loaded from disk successfully!\n");
    return;
error:
    if (pFile)
        fclose(pFile);
    if (!path2.IsEmpty())
        DeleteFile(path2);
    m_pInstance->watcher.ClearInfoMap();
    Destroy();
    m_pInstance = new CSVNStatusCache;
    CTraceToOutputDebugString::Instance()(__FUNCTION__ ": cache not loaded from disk\n");
}