123
This commit is contained in:
202
CrySystem/ZipDirFind.cpp
Normal file
202
CrySystem/ZipDirFind.cpp
Normal file
@@ -0,0 +1,202 @@
|
||||
#include "stdafx.h"
|
||||
#include "MTSafeAllocator.h"
|
||||
#include "smartptr.h"
|
||||
#include "ZipFileFormat.h"
|
||||
#include "ZipDirStructures.h"
|
||||
#include "ZipDirCache.h"
|
||||
#include "ZipDirFind.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
bool ZipDir::FindFile::FindFirst (const char* szWildcard)
|
||||
{
|
||||
if (!PreFind (szWildcard))
|
||||
return false;
|
||||
|
||||
// finally, this is the name of the file
|
||||
m_nFileEntry = 0;
|
||||
return SkipNonMatchingFiles();
|
||||
}
|
||||
|
||||
bool ZipDir::FindDir::FindFirst (const char* szWildcard)
|
||||
{
|
||||
if (!PreFind (szWildcard))
|
||||
return false;
|
||||
|
||||
// finally, this is the name of the file
|
||||
m_nDirEntry = 0;
|
||||
return SkipNonMatchingDirs();
|
||||
}
|
||||
|
||||
// matches the file wilcard in the m_szWildcard to the given file/dir name
|
||||
// this takes into account the fact that xxx. is the alias name for xxx
|
||||
bool ZipDir::FindData::MatchWildcard(const char* szName)
|
||||
{
|
||||
if (CryStringUtils::MatchWildcard(szName, m_szWildcard))
|
||||
return true;
|
||||
|
||||
// check if the file object name contains extension sign (.)
|
||||
const char* p;
|
||||
for (p = szName; *p && *p!='.'; ++p)
|
||||
continue;
|
||||
|
||||
if (*p)
|
||||
{
|
||||
// there's an extension sign in the object, but it wasn't matched..
|
||||
assert (*p == '.');
|
||||
return false;
|
||||
}
|
||||
|
||||
// no extension sign - add it
|
||||
char szAlias[_MAX_PATH+2];
|
||||
unsigned nLength = p - szName;
|
||||
if (nLength > _MAX_PATH)
|
||||
nLength = _MAX_PATH;
|
||||
memcpy (szAlias, szName, nLength);
|
||||
szAlias[nLength] = '.'; // add the alias
|
||||
szAlias[nLength+1] = '\0'; // terminate the string
|
||||
return CryStringUtils::MatchWildcard(szAlias, m_szWildcard);
|
||||
}
|
||||
|
||||
|
||||
ZipDir::FileEntry* ZipDir::FindFile::FindExact (const char* szPath)
|
||||
{
|
||||
if (!PreFind (szPath))
|
||||
return NULL;
|
||||
|
||||
FileEntry* pFileEntry = m_pDirHeader->FindFileEntry(m_szWildcard);
|
||||
if (pFileEntry)
|
||||
m_nFileEntry = pFileEntry - m_pDirHeader->GetFileEntry(0);
|
||||
else
|
||||
m_pDirHeader = NULL; // we didn't find it, fail the search
|
||||
|
||||
return pFileEntry;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// after this call returns successfully (with true returned), the m_szWildcard
|
||||
// contains the file name/wildcard and m_pDirHeader contains the directory where
|
||||
// the file (s) are to be found
|
||||
bool ZipDir::FindData::PreFind (const char* szWildcard)
|
||||
{
|
||||
if (!m_pRoot)
|
||||
return false;
|
||||
|
||||
// start the search from the root
|
||||
m_pDirHeader = m_pRoot;
|
||||
|
||||
// for each path dir name, copy it into the buffer and try to find the subdirectory
|
||||
const char* pPath = szWildcard;
|
||||
for (;;)
|
||||
{
|
||||
char* pName = m_szWildcard;
|
||||
|
||||
// at first we'll use the wildcard memory to save the directory names
|
||||
for (; *pPath && *pPath != '/' && *pPath != '\\' && pName < m_szWildcard+sizeof(m_szWildcard)-1; ++pPath, ++pName)
|
||||
*pName = ::tolower(*pPath);
|
||||
*pName = '\0';
|
||||
|
||||
if (*pPath)
|
||||
{
|
||||
if (*pPath != '/' && *pPath != '\\')
|
||||
return false;//ZD_ERROR_NAME_TOO_LONG;
|
||||
|
||||
// this is the name of the directory
|
||||
DirEntry* pDirEntry = m_pDirHeader->FindSubdirEntry(m_szWildcard);
|
||||
if (!pDirEntry)
|
||||
{
|
||||
m_pDirHeader = NULL; // finish the search
|
||||
return false;
|
||||
}
|
||||
m_pDirHeader = pDirEntry->GetDirectory();
|
||||
++pPath;
|
||||
assert(m_pDirHeader);
|
||||
}
|
||||
else
|
||||
{
|
||||
// finally, this is the name of the file (or directory)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// goes on to the next entry
|
||||
bool ZipDir::FindFile::FindNext ()
|
||||
{
|
||||
if (m_pDirHeader && m_nFileEntry < m_pDirHeader->numFiles)
|
||||
{
|
||||
++m_nFileEntry;
|
||||
return SkipNonMatchingFiles();
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
// goes on to the next entry
|
||||
bool ZipDir::FindDir::FindNext ()
|
||||
{
|
||||
if (m_pDirHeader && m_nDirEntry < m_pDirHeader->numDirs)
|
||||
{
|
||||
++m_nDirEntry;
|
||||
return SkipNonMatchingDirs();
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ZipDir::FindFile::SkipNonMatchingFiles()
|
||||
{
|
||||
assert(m_pDirHeader && m_nFileEntry <= m_pDirHeader->numFiles);
|
||||
|
||||
for(;m_nFileEntry < m_pDirHeader->numFiles;++m_nFileEntry)
|
||||
{
|
||||
if (MatchWildcard(GetFileName()))
|
||||
return true;
|
||||
}
|
||||
// we didn't find anything other file else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ZipDir::FindDir::SkipNonMatchingDirs()
|
||||
{
|
||||
assert(m_pDirHeader && m_nDirEntry <= m_pDirHeader->numDirs);
|
||||
|
||||
for(;m_nDirEntry < m_pDirHeader->numDirs;++m_nDirEntry)
|
||||
{
|
||||
if (MatchWildcard(GetDirName()))
|
||||
return true;
|
||||
}
|
||||
// we didn't find anything other file else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
ZipDir::FileEntry* ZipDir::FindFile::GetFileEntry()
|
||||
{
|
||||
return m_pDirHeader && m_nFileEntry < m_pDirHeader->numFiles? m_pDirHeader->GetFileEntry(m_nFileEntry) : NULL;
|
||||
}
|
||||
ZipDir::DirEntry* ZipDir::FindDir::GetDirEntry()
|
||||
{
|
||||
return m_pDirHeader && m_nDirEntry < m_pDirHeader->numDirs? m_pDirHeader->GetSubdirEntry(m_nDirEntry) : NULL;
|
||||
}
|
||||
|
||||
const char* ZipDir::FindFile::GetFileName ()
|
||||
{
|
||||
if (m_pDirHeader && m_nFileEntry < m_pDirHeader->numFiles)
|
||||
{
|
||||
const char* pNamePool = m_pDirHeader->GetNamePool();
|
||||
return m_pDirHeader->GetFileEntry(m_nFileEntry)->GetName(pNamePool);
|
||||
}
|
||||
else
|
||||
return ""; // default name
|
||||
}
|
||||
|
||||
const char* ZipDir::FindDir::GetDirName ()
|
||||
{
|
||||
if (m_pDirHeader && m_nDirEntry < m_pDirHeader->numDirs)
|
||||
{
|
||||
const char* pNamePool = m_pDirHeader->GetNamePool();
|
||||
return m_pDirHeader->GetSubdirEntry(m_nDirEntry)->GetName(pNamePool);
|
||||
}
|
||||
else
|
||||
return ""; // default name
|
||||
}
|
||||
Reference in New Issue
Block a user