CLAM-Development  1.4.0
TraverseDirectory.cxx
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2004 MUSIC TECHNOLOGY GROUP (MTG)
3  * UNIVERSITAT POMPEU FABRA
4  *
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  */
21 
22 #include "TraverseDirectory.hxx"
23 #include <sys/types.h>
24 #include <cstring>
25 
27 {
28 
29 }
30 // Helper method for TraverseHelper
31 bool TraverseDirectory::IsCurrentOrParentDir(DirectoryEntry dirEntry) const
32 {
33 #ifndef WIN32
34  return !strcmp(dirEntry->d_name,".") || !strcmp(dirEntry->d_name,"..");
35 #else
36  return false;
37 #endif
38 }
39 
40 std::string TraverseDirectory::CompleteName(const std::string& currentDirName, DirectoryEntry dirEntry) const
41 {
42 #ifndef WIN32
43  bool noDirName = currentDirName == "";
44  return noDirName? dirEntry->d_name : currentDirName+"/"+dirEntry->d_name;
45 #else
46  return "";
47 #endif
48 
49 }
50 
51 void TraverseDirectory::TraverseHelper( Directory dir, const std::string& currentDirname,
52  int curdepth, int maxdepth )
53 {
54 #ifndef WIN32
55  dirent* dirEntry;
56  while ((dirEntry = readdir(dir)))
57  {
58  if (IsCurrentOrParentDir(dirEntry))
59  continue;
60 
61  std::string currentItemName = CompleteName(currentDirname, dirEntry);
62  DIR* subdir = opendir(currentItemName.c_str());
63  if (subdir)
64  {
65  OnDirectory(currentItemName); // 'template method'
66  if (curdepth<maxdepth || maxdepth==-1)
67  {
68  TraverseHelper(subdir, currentItemName, curdepth+1, maxdepth);
69  }
70  closedir(subdir);
71  }else
72  {
73  OnFile(currentItemName); // 'template method'
74  }
75  }
76 #else
77  WIN32_FIND_DATA fd;
78  HANDLE hFind;
79  std::string tmp;;
80  if(currentDirname!="")
81  {
82  tmp+=currentDirname;
83  tmp+="/";
84  }
85  tmp+="*.*";
86  hFind = FindFirstFile(tmp.c_str(), &fd);
87  if (hFind == INVALID_HANDLE_VALUE) return;
88 
89  do
90  {
91  std::string tmp2=currentDirname;
92  tmp2+="/";
93  tmp2+=fd.cFileName;
94 
95  if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
96  {
97  if (strcmp(fd.cFileName,".") && strcmp(fd.cFileName,".."))
98  {
99 
100  OnDirectory(tmp2);
101  if (curdepth<maxdepth || maxdepth==-1)
102  {
103  TraverseHelper(fd, tmp2, curdepth+1, maxdepth);
104  }
105  }
106  }
107  else
108  {
109  OnFile(tmp2);
110  }
111  } while (FindNextFile(hFind, &fd)); // enumerates contents
112  FindClose(hFind);
113 #endif
114 }
115 
116 void TraverseDirectory::Traverse(const std::string& rootname,int maxdepth)
117 {
118 #ifndef WIN32
119  DIR* dir;
120 
121  dir = opendir(rootname == "" ? "." : rootname.c_str());
122 
123  if (dir)
124  {
125  OnDirectory(rootname);
126  TraverseHelper(dir,rootname,0,maxdepth);
127  closedir(dir);
128  }
129 #else
130  WIN32_FIND_DATA fd;
131  HANDLE hFind;
132  std::string tmp = rootname;
133  if ((tmp.rfind("/")!=tmp.length()-1)
134  &&
135  (tmp.rfind("\\")!=tmp.length()-1))
136  {
137  tmp += "\\";
138  }
139  tmp += "*.*";
140  hFind = FindFirstFile(tmp.c_str(), &fd);
141  if (hFind == INVALID_HANDLE_VALUE) return;
142  if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
143  {
144  OnDirectory(rootname);
145  TraverseHelper(fd,rootname,0,maxdepth);
146  }
147  FindClose(hFind);;
148 
149 #endif
150 }
151 
152 
153 //Auxiliary function to return the extension of a given filename
154 std::string TraverseDirectory::GetExtension(const std::string& filename)
155 {
156  return filename.substr(filename.rfind('.')+1);
157 }
158