123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- /* Copyright (c) 2002-2012 Croteam Ltd.
- This program is free software; you can redistribute it and/or modify
- it under the terms of version 2 of the GNU General Public License as published by
- the Free Software Foundation
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
- #include "stdh.h"
- #include <Engine/Base/Stream.h>
- #include <Engine/Base/FileName.h>
- #include <Engine/Base/Unzip.h>
- #include <Engine/Templates/DynamicStackArray.cpp>
- #include <io.h>
- extern CDynamicStackArray<CTFileName> _afnmBaseBrowseInc;
- extern CDynamicStackArray<CTFileName> _afnmBaseBrowseExc;
- class CDirToRead {
- public:
- CListNode dr_lnNode;
- CTString dr_strDir;
- };
- int qsort_CompareCTFileName(const void *elem1, const void *elem2 )
- {
- const CTFileName &fnm1 = **(CTFileName **)elem1;
- const CTFileName &fnm2 = **(CTFileName **)elem2;
- return strcmp(fnm1, fnm2);
- }
- extern BOOL FileMatchesList(CDynamicStackArray<CTFileName> &afnm, const CTFileName &fnm);
- void FillDirList_internal(const CTFileName &fnmBasePath,
- CDynamicStackArray<CTFileName> &afnm, const CTFileName &fnmDir, const CTString &strPattern, BOOL bRecursive,
- CDynamicStackArray<CTFileName> *pafnmInclude, CDynamicStackArray<CTFileName> *pafnmExclude)
- {
- // add the directory to list of directories to search
- CListHead lhDirs;
- CDirToRead *pdrFirst = new CDirToRead;
- pdrFirst->dr_strDir = fnmDir;
- lhDirs.AddTail(pdrFirst->dr_lnNode);
- // while the list of directories is not empty
- while (!lhDirs.IsEmpty()) {
- // take the first one
- CDirToRead *pdr = LIST_HEAD(lhDirs, CDirToRead, dr_lnNode);
- CTFileName fnmDir = pdr->dr_strDir;
- delete pdr;
- // if the dir is not allowed
- if (pafnmInclude!=NULL &&
- (!FileMatchesList(*pafnmInclude, fnmDir) || FileMatchesList(*pafnmExclude, fnmDir)) ) {
- // skip it
- continue;
- }
-
- // start listing the directory
- struct _finddata_t c_file; long hFile;
- hFile = _findfirst( (const char *)(fnmBasePath+fnmDir+"*"), &c_file );
-
- // for each file in the directory
- for (
- BOOL bFileExists = hFile!=-1;
- bFileExists;
- bFileExists = _findnext( hFile, &c_file )==0) {
- // if dummy dir (this dir, parent dir, or any dir starting with '.')
- if (c_file.name[0]=='.') {
- // skip it
- continue;
- }
- // get the file's filepath
- CTFileName fnm = fnmDir+c_file.name;
- // if it is a directory
- if (c_file.attrib&_A_SUBDIR) {
- // if recursive reading
- if (bRecursive) {
- // add it to the list of directories to search
- CDirToRead *pdrNew = new CDirToRead;
- pdrNew->dr_strDir = fnm+"\\";
- lhDirs.AddTail(pdrNew->dr_lnNode);
- }
- // if it matches the pattern
- } else if (strPattern=="" || fnm.Matches(strPattern)) {
- // add that file
- afnm.Push() = fnm;
- }
- }
- }
- }
- // make a list of all files in a directory
- ENGINE_API void MakeDirList(
- CDynamicStackArray<CTFileName> &afnmDir, const CTFileName &fnmDir, const CTString &strPattern, ULONG ulFlags)
- {
- afnmDir.PopAll();
- BOOL bRecursive = ulFlags&DLI_RECURSIVE;
- BOOL bSearchCD = ulFlags&DLI_SEARCHCD;
- // make one temporary array
- CDynamicStackArray<CTFileName> afnm;
- if (_fnmMod!="") {
- FillDirList_internal(_fnmApplicationPath, afnm, fnmDir, strPattern, bRecursive,
- &_afnmBaseBrowseInc, &_afnmBaseBrowseExc);
- if (bSearchCD) {
- FillDirList_internal(_fnmCDPath, afnm, fnmDir, strPattern, bRecursive,
- &_afnmBaseBrowseInc, &_afnmBaseBrowseExc);
- }
- FillDirList_internal(_fnmApplicationPath+_fnmMod, afnm, fnmDir, strPattern, bRecursive, NULL, NULL);
- } else {
- FillDirList_internal(_fnmApplicationPath, afnm, fnmDir, strPattern, bRecursive, NULL, NULL);
- if (bSearchCD) {
- FillDirList_internal(_fnmCDPath, afnm, fnmDir, strPattern, bRecursive, NULL, NULL);
- }
- }
- // for each file in zip archives
- CTString strDirPattern = fnmDir;
- INDEX ctFilesInZips = UNZIPGetFileCount();
- for(INDEX iFileInZip=0; iFileInZip<ctFilesInZips; iFileInZip++) {
- const CTFileName &fnm = UNZIPGetFileAtIndex(iFileInZip);
- // if not in this dir, skip it
- if (bRecursive) {
- if (!fnm.HasPrefix(strDirPattern)) {
- continue;
- }
- } else {
- if (fnm.FileDir()!=fnmDir) {
- continue;
- }
- }
- // if doesn't match pattern
- if (strPattern!="" && !fnm.Matches(strPattern)) {
- // skip it
- continue;
- }
- // if mod is active, and the file is not in mod
- if (_fnmMod!="" && !UNZIPIsFileAtIndexMod(iFileInZip)) {
- // if it doesn't match base browse path
- if ( !FileMatchesList(_afnmBaseBrowseInc, fnm) || FileMatchesList(_afnmBaseBrowseExc, fnm) ) {
- // skip it
- continue;
- }
- }
- // add that file
- afnm.Push() = fnm;
- }
- // if no files
- if (afnm.Count()==0) {
- // don't check for duplicates
- return;
- }
- // resort the array
- qsort(afnm.da_Pointers, afnm.Count(), sizeof(void*), qsort_CompareCTFileName);
- // for each file
- INDEX ctFiles = afnm.Count();
- for (INDEX iFile=0; iFile<ctFiles; iFile++) {
- // if not same as last one
- if (iFile==0 || afnm[iFile]!=afnm[iFile-1]) {
- // copy over to final array
- afnmDir.Push() = afnm[iFile];
- }
- }
- }
|