1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
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.
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 //-------------------------------------------------------------------------------------------------
19 //-------------------------------------------------------------------------------------------------
23 #include "nel/misc/path.h"
24 #include "nel/misc/algo.h"
27 #include "file_description_container.h"
30 //-------------------------------------------------------------------------------------------------
32 //-------------------------------------------------------------------------------------------------
35 using namespace NLMISC
;
38 //-------------------------------------------------------------------------------------------------
39 // methods CFileDescription
40 //-------------------------------------------------------------------------------------------------
42 CFileDescription::CFileDescription(const string
& name
,uint32 time
,uint32 size
)
49 bool CFileDescription::set(const string
& name
)
53 // if the file doesn't exist then zero out time stamp and size and return false
54 if (!NLMISC::CFile::fileExists(name
))
61 // setup timestamp and size for the file
62 FileTimeStamp
=NLMISC::CFile::getFileModificationDate(name
);
63 FileSize
=NLMISC::CFile::getFileSize(name
);
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
)
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
--;)
140 for (j
=0;j
<wildcards
.size();++j
)
142 if (testWildCard(NLMISC::CFile::getFilename(rawFileNames
[i
]),wildcards
[j
]))
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();
185 void CFileDescriptionContainer::display(NLMISC::CLog
* log
) const
189 // determine the length of the longest file name
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 //-------------------------------------------------------------------------------------------------