Merge branch 'fixes' into main/rendor-staging
[ryzomcore.git] / ryzom / common / src / game_share / file_description_container.cpp
blobe974bd7d223890800e6c09c0876e73be016f9add
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 //-------------------------------------------------------------------------------------------------
18 // includes
19 //-------------------------------------------------------------------------------------------------
21 #include "stdpch.h"
23 #include "nel/misc/path.h"
24 #include "nel/misc/algo.h"
26 #include "utils.h"
27 #include "file_description_container.h"
30 //-------------------------------------------------------------------------------------------------
31 // namespaces
32 //-------------------------------------------------------------------------------------------------
34 using namespace std;
35 using namespace NLMISC;
38 //-------------------------------------------------------------------------------------------------
39 // methods CFileDescription
40 //-------------------------------------------------------------------------------------------------
42 CFileDescription::CFileDescription(const string& name,uint32 time,uint32 size)
44 FileName=name;
45 FileTimeStamp=time;
46 FileSize=size;
49 bool CFileDescription::set(const string& name)
51 FileName=name;
53 // if the file doesn't exist then zero out time stamp and size and return false
54 if (!NLMISC::CFile::fileExists(name))
56 FileTimeStamp=0;
57 FileSize=0;
58 return false;
61 // setup timestamp and size for the file
62 FileTimeStamp=NLMISC::CFile::getFileModificationDate(name);
63 FileSize=NLMISC::CFile::getFileSize(name);
65 return true;
68 void CFileDescription::serial(NLMISC::IStream& stream)
70 stream.serial(FileName);
71 stream.serial(FileTimeStamp);
72 stream.serial(FileSize);
75 CSString CFileDescription::toString(uint32 maxFileNameLen) const
77 return NLMISC::toString("%*s (size: %u, time stamp: %s)",maxFileNameLen,FileName.c_str(),FileSize,IDisplayer::dateToHumanString(FileTimeStamp));
80 bool CFileDescription::operator<(const CFileDescription& other) const
82 return FileName<other.FileName;
86 //-------------------------------------------------------------------------------------------------
87 // methods CFileDescriptionContainer
88 //-------------------------------------------------------------------------------------------------
90 // add a specific file to the container
91 void CFileDescriptionContainer::addFile(const CFileDescription& fileDescription)
93 _FileDescriptions.push_back(fileDescription);
96 void CFileDescriptionContainer::addFile(const string& fileName, uint32 timeStamp, uint32 size)
98 CFileDescription& theFileDescription= vectAppend(_FileDescriptions);
99 theFileDescription.FileName= fileName;
100 theFileDescription.FileTimeStamp= timeStamp;
101 theFileDescription.FileSize= size;
104 void CFileDescriptionContainer::addFile(const string& fileName)
106 if (CFile::fileExists(fileName))
108 addFile(fileName,CFile::getFileModificationDate(fileName),CFile::getFileSize(fileName));
112 void CFileDescriptionContainer::addFileSpec(const string& fileSpec,bool recurse)
114 // extract path and wildcard from fileSpec
115 string theWildcard=NLMISC::CFile::getFilename(fileSpec);
116 string path=NLMISC::CFile::getPath(fileSpec);
117 std::vector<std::string> wildcards;
118 wildcards.push_back(theWildcard.empty()? "*": theWildcard);
119 addFiles(path,wildcards,recurse);
122 void CFileDescriptionContainer::addFiles(const std::string& directory, const std::vector<std::string>& wildcards, bool recurse)
124 H_AUTO(fdcAddFiles)
125 std::string path= directory.empty()? ".": directory;
127 // build a list of all files in the matching directory
128 vector<string> rawFileNames;
130 H_AUTO(fdcAddFilesGetPathContents)
131 NLMISC::CPath::getPathContent(path.c_str(),recurse,false,true,rawFileNames);
134 // extract the files that match the given wildcard and build a result vector
136 H_AUTO(fdcAddFilesTestWildcards)
137 for (uint32 i=(uint32)rawFileNames.size();i--;)
139 uint32 j;
140 for (j=0;j<wildcards.size();++j)
142 if (testWildCard(NLMISC::CFile::getFilename(rawFileNames[i]),wildcards[j]))
143 break;
145 if (j!=wildcards.size())
147 H_AUTO(fdcAddFilesGetFileProperties)
148 addFile(rawFileNames[i]);
154 void CFileDescriptionContainer::addFiles(const std::string& directory, const NLMISC::CVectorSString& wildcards, bool recurse)
156 // note that a CVectorSString is guaranteed to be bitwise identical to a vector of std::string
157 addFiles(directory,reinterpret_cast<const std::vector<std::string>&>(wildcards),recurse);
160 void CFileDescriptionContainer::addFiles(const CFileDescriptionContainer& other)
162 // note: the following can doubtless be done with a single tsl operation (eg +=)
163 // but I don't have an stl refference to hand so doing it longhand...
165 // make room in the file description container for the data from the other object
166 uint32 otherSize= (uint32)other._FileDescriptions.size();
167 uint32 oldSize= (uint32)_FileDescriptions.size();
168 uint32 newSize= oldSize + otherSize;
169 _FileDescriptions.resize(newSize);
171 // prepare to copy from one vector to the other
172 TFileDescriptions::iterator destIt = _FileDescriptions.begin()+oldSize;
173 TFileDescriptions::const_iterator srcIt = other._FileDescriptions.begin();
174 TFileDescriptions::const_iterator itEnd = other._FileDescriptions.end();
176 // do the copy
177 while (srcIt!=itEnd)
179 *destIt= *srcIt;
180 ++srcIt;
181 ++destIt;
185 void CFileDescriptionContainer::display(NLMISC::CLog* log) const
187 nlassert(log!=NULL);
189 // determine the length of the longest file name
190 uint32 longest=10;
191 for (uint32 i=0;i<_FileDescriptions.size();++i)
192 longest=max(longest,(uint32)_FileDescriptions[i].FileName.size());
194 // build a vector of strings to display
195 vector<string> lines;
196 for (uint32 i=0;i<_FileDescriptions.size();++i)
197 lines.push_back(NLMISC::toString("%-*s %12d %s",longest,
198 _FileDescriptions[i].FileName.c_str(),
199 _FileDescriptions[i].FileSize,
200 IDisplayer::dateToHumanString(_FileDescriptions[i].FileTimeStamp)));
202 // sort the lines to make a nice alphabetical list
203 sort(lines.begin(),lines.end());
205 // display a nice banner
206 log->displayNL("%-*s %12s %12s",longest,"File_Name","File_Size","File_Time");
208 // display the file list
209 for (uint32 i=0;i<_FileDescriptions.size();++i)
210 log->displayNL(lines[i].c_str());
213 void CFileDescriptionContainer::serial(NLMISC::IStream& stream)
215 stream.serialCont(_FileDescriptions);
218 uint32 CFileDescriptionContainer::size() const
220 return (uint32)_FileDescriptions.size();
223 bool CFileDescriptionContainer::empty() const
225 return _FileDescriptions.empty();
228 void CFileDescriptionContainer::clear()
230 _FileDescriptions.clear();
233 const CFileDescription& CFileDescriptionContainer::operator[](uint32 idx) const
235 return (_FileDescriptions[idx]);
238 CFileDescription& CFileDescriptionContainer::operator[](uint32 idx)
240 return (_FileDescriptions[idx]);
243 // remove the 'n'th element from a file description container
244 void CFileDescriptionContainer::removeFile(uint32 idx)
246 BOMB_IF(idx>=_FileDescriptions.size(),"trying to remove files beyond the end of the file description vector",return);
247 _FileDescriptions[idx]=_FileDescriptions.back();
248 _FileDescriptions.pop_back();
252 // remove the provided string if found at the beginning of FileName
253 void CFileDescriptionContainer::stripFilename(const std::string& header)
255 for (std::vector<CFileDescription>::iterator it=_FileDescriptions.begin(); it!=_FileDescriptions.end(); ++it)
257 it->stripFilename(header);
262 //-------------------------------------------------------------------------------------------------