You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
254 lines
6.3 KiB
C++
254 lines
6.3 KiB
C++
/*
|
|
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
|
* its licensors.
|
|
*
|
|
* For complete copyright and license terms please see the LICENSE at the root of this
|
|
* distribution (the "License"). All use of this software is governed by the License,
|
|
* or, if provided, by the license below or the license accompanying this file. Do not
|
|
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
*
|
|
*/
|
|
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
|
|
|
|
|
#include "smartptr.h"
|
|
#include "ZipFileFormat.h"
|
|
#include "zipdirstructures.h"
|
|
#include "ZipDirTree.h"
|
|
#include "ZipDirCacheRW.h"
|
|
#include "ZipDirFindRW.h"
|
|
#include "StringHelpers.h"
|
|
|
|
bool ZipDir::FindFileRW::FindFirst (const char* szWildcard)
|
|
{
|
|
if (!PreFind (szWildcard))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// finally, this is the name of the file
|
|
m_itFile = m_pDirHeader->GetFileBegin();
|
|
return SkipNonMatchingFiles();
|
|
}
|
|
|
|
bool ZipDir::FindDirRW::FindFirst (const char* szWildcard)
|
|
{
|
|
if (!PreFind (szWildcard))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// finally, this is the name of the file
|
|
m_itDir = m_pDirHeader->GetDirBegin();
|
|
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::FindDataRW::MatchWildcard(const char* szName)
|
|
{
|
|
if (StringHelpers::MatchesWildcards(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];
|
|
size_t 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 StringHelpers::MatchesWildcards(szAlias, m_szWildcard);
|
|
}
|
|
|
|
|
|
ZipDir::FileEntry* ZipDir::FindFileRW::FindExact (const char* szPath)
|
|
{
|
|
if (!PreFind (szPath))
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
FileEntryTree::FileMap::iterator itFile = m_pDirHeader->FindFile(m_szWildcard);
|
|
if (itFile != m_pDirHeader->GetFileEnd())
|
|
{
|
|
m_itFile = itFile;
|
|
}
|
|
else
|
|
{
|
|
m_pDirHeader = NULL; // we didn't find it, fail the search
|
|
}
|
|
return m_pDirHeader ? m_pDirHeader->GetFileEntry(itFile) : NULL;
|
|
}
|
|
|
|
ZipDir::FileEntryTree* ZipDir::FindDirRW::FindExact (const char* szPath)
|
|
{
|
|
if (!PreFind(szPath))
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
// the wildcard will contain the target directory name
|
|
return m_pDirHeader->FindDir(m_szWildcard);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// initializes everything until the point where the file must be searched for
|
|
// 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::FindDataRW::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)
|
|
{
|
|
// this is the name of the directory
|
|
FileEntryTree* pDirEntry = m_pDirHeader->FindDir(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::FindFileRW::FindNext ()
|
|
{
|
|
if (m_pDirHeader && m_itFile != m_pDirHeader->GetFileEnd())
|
|
{
|
|
++m_itFile;
|
|
return SkipNonMatchingFiles();
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// goes on to the next entry
|
|
bool ZipDir::FindDirRW::FindNext ()
|
|
{
|
|
if (m_pDirHeader && m_itDir != m_pDirHeader->GetDirEnd())
|
|
{
|
|
++m_itDir;
|
|
return SkipNonMatchingDirs();
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool ZipDir::FindFileRW::SkipNonMatchingFiles()
|
|
{
|
|
assert(m_pDirHeader);
|
|
|
|
for (; m_itFile != m_pDirHeader->GetFileEnd(); ++m_itFile)
|
|
{
|
|
if (MatchWildcard(GetFileName()))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
// we didn't find anything other file else
|
|
return false;
|
|
}
|
|
|
|
bool ZipDir::FindDirRW::SkipNonMatchingDirs()
|
|
{
|
|
assert(m_pDirHeader);
|
|
|
|
for (; m_itDir != m_pDirHeader->GetDirEnd(); ++m_itDir)
|
|
{
|
|
if (MatchWildcard(GetDirName()))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
// we didn't find anything other file else
|
|
return false;
|
|
}
|
|
|
|
|
|
ZipDir::FileEntry* ZipDir::FindFileRW::GetFileEntry()
|
|
{
|
|
return m_pDirHeader && m_itFile != m_pDirHeader->GetFileEnd() ? m_pDirHeader->GetFileEntry(m_itFile) : NULL;
|
|
}
|
|
ZipDir::FileEntryTree* ZipDir::FindDirRW::GetDirEntry()
|
|
{
|
|
return m_pDirHeader && m_itDir != m_pDirHeader->GetDirEnd() ? m_pDirHeader->GetDirEntry(m_itDir) : NULL;
|
|
}
|
|
|
|
const char* ZipDir::FindFileRW::GetFileName ()
|
|
{
|
|
if (m_pDirHeader && m_itFile != m_pDirHeader->GetFileEnd())
|
|
{
|
|
return m_pDirHeader->GetFileName(m_itFile);
|
|
}
|
|
else
|
|
{
|
|
return ""; // default name
|
|
}
|
|
}
|
|
|
|
const char* ZipDir::FindDirRW::GetDirName ()
|
|
{
|
|
if (m_pDirHeader && m_itDir != m_pDirHeader->GetDirEnd())
|
|
{
|
|
return m_pDirHeader->GetDirName(m_itDir);
|
|
}
|
|
else
|
|
{
|
|
return ""; // default name
|
|
}
|
|
}
|