4 // Copyright (C) 2005 Novell, Inc.
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and associated documentation files (the "Software"), to deal
10 // in the Software without restriction, including without limitation the rights
11 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 // copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions:
15 // The above copyright notice and this permission notice shall be included in all
16 // copies or substantial portions of the Software.
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 using System
.Collections
;
30 using System
.Runtime
.InteropServices
;
33 namespace Beagle
.Util
{
35 public class DirectoryWalker
{
37 public delegate bool FileFilter (string path
, string name
);
38 private delegate object FileObjectifier (string path
, string name
);
40 [DllImport ("libc", SetLastError
= true)]
41 private static extern IntPtr
opendir (string name
);
43 [DllImport ("libc", SetLastError
= true)]
44 private static extern int closedir (IntPtr dir
);
46 [DllImport ("libbeagleglue", EntryPoint
= "beagled_utils_readdir", SetLastError
= true)]
47 private static extern int sys_readdir (IntPtr dir
, [Out
] StringBuilder name
, int max_len
);
49 private static string readdir (IntPtr dir
, StringBuilder buffer
)
53 while (r
== 0 && buffer
.Length
== 0) {
54 r
= sys_readdir (dir
, buffer
, buffer
.Capacity
);
60 return buffer
.ToString ();
63 private class FileEnumerator
: IEnumerator
{
66 FileFilter file_filter
;
67 FileObjectifier file_objectifier
;
68 IntPtr dir_handle
= IntPtr
.Zero
;
70 StringBuilder name_buffer
= new StringBuilder (256);
72 public bool NamesOnly
= false;
74 public FileEnumerator (string path
,
75 FileFilter file_filter
,
76 FileObjectifier file_objectifier
)
79 this.file_filter
= file_filter
;
80 this.file_objectifier
= file_objectifier
;
86 if (dir_handle
!= IntPtr
.Zero
)
87 closedir (dir_handle
);
90 public object Current
{
92 object current_obj
= null;
93 if (current
!= null) {
94 if (file_objectifier
!= null)
95 current_obj
= file_objectifier (path
, current
);
97 current_obj
= current
;
99 current_obj
= Path
.Combine (path
, current
);
106 public bool MoveNext ()
108 bool skip_file
= false;
111 current
= readdir (dir_handle
, name_buffer
);
117 if (current
== "." || current
== "..") {
120 } else if (file_filter
!= null) {
122 if (! file_filter (path
, current
))
125 } catch (Exception ex
) {
126 Logger
.Log
.Debug ("Caught exception in file_filter");
127 Logger
.Log
.Debug (ex
.Message
);
129 // If we have a filter that fails on a file,
130 // it is probably safest to skip that file.
137 if (current
== null) {
138 closedir (dir_handle
);
139 dir_handle
= IntPtr
.Zero
;
142 return current
!= null;
148 if (dir_handle
!= IntPtr
.Zero
)
149 closedir (dir_handle
);
150 dir_handle
= opendir (path
);
151 if (dir_handle
== IntPtr
.Zero
)
152 throw new DirectoryNotFoundException (path
);
156 private class FileEnumerable
: IEnumerable
{
159 FileFilter file_filter
;
160 FileObjectifier file_objectifier
;
162 public bool NamesOnly
= false;
164 public FileEnumerable (string path
,
165 FileFilter file_filter
,
166 FileObjectifier file_objectifier
)
169 this.file_filter
= file_filter
;
170 this.file_objectifier
= file_objectifier
;
173 public IEnumerator
GetEnumerator ()
176 e
= new FileEnumerator (path
, file_filter
, file_objectifier
);
177 e
.NamesOnly
= this.NamesOnly
;
182 static private bool IsFile (string path
, string name
)
184 return File
.Exists (Path
.Combine (path
, name
));
187 static private object FileInfoObjectifier (string path
, string name
)
189 return new FileInfo (Path
.Combine (path
, name
));
192 /////////////////////////////////////////////////////////////////////////////////
194 static public bool IsWalkable (string path
)
197 dir_handle
= opendir (path
);
198 if (dir_handle
== IntPtr
.Zero
)
200 closedir (dir_handle
);
204 /////////////////////////////////////////////////////////////////////////////////
206 static public IEnumerable
GetFiles (string path
)
208 return new FileEnumerable (path
, new FileFilter (IsFile
), null);
211 static public IEnumerable
GetFiles (DirectoryInfo dirinfo
)
213 return GetFiles (dirinfo
.FullName
);
216 static public IEnumerable
GetFileInfos (string path
)
218 return new FileEnumerable (path
,
219 new FileFilter (IsFile
),
220 new FileObjectifier (FileInfoObjectifier
));
223 static public IEnumerable
GetFileInfos (DirectoryInfo dirinfo
)
225 return GetFileInfos (dirinfo
.FullName
);
228 static private bool IsDirectory (string path
, string name
)
230 return Directory
.Exists (Path
.Combine (path
, name
));
233 static private object DirectoryInfoObjectifier (string path
, string name
)
235 return new DirectoryInfo (Path
.Combine (path
, name
));
238 static public IEnumerable
GetDirectories (string path
)
240 return new FileEnumerable (path
, new FileFilter (IsDirectory
), null);
243 static public IEnumerable
GetDirectories (DirectoryInfo dirinfo
)
245 return GetDirectories (dirinfo
.FullName
);
248 static public IEnumerable
GetDirectoryNames (string path
)
251 fe
= new FileEnumerable (path
, new FileFilter (IsDirectory
), null);
256 static public IEnumerable
GetDirectoryInfos (string path
)
258 return new FileEnumerable (path
,
259 new FileFilter (IsDirectory
),
260 new FileObjectifier (DirectoryInfoObjectifier
));
263 static public IEnumerable
GetDirectoryInfos (DirectoryInfo dirinfo
)
265 return GetDirectoryInfos (dirinfo
.FullName
);
268 static public IEnumerable
GetItems (string path
, FileFilter filter
)
270 return new FileEnumerable (path
, filter
, null);