New e-d-s backend which indexes all local addressbooks and calendars.
[beagle.git] / Util / DirectoryWalker.cs
blob89053eeaedb05e7bd62ae820b8a99af2e6223470
1 //
2 // DirectoryWalker.cs
3 //
4 // Copyright (C) 2005 Novell, Inc.
5 //
7 //
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
24 // SOFTWARE.
27 using System;
28 using System.Collections;
29 using System.IO;
30 using System.Runtime.InteropServices;
31 using System.Text;
33 namespace Beagle.Util {
35 public class DirectoryWalker {
36 #if false
37 public static void Main (string[] args)
39 IEnumerable en = DirectoryWalker.GetFileInfos (args [0]);
41 foreach (FileInfo file in en) {
42 Console.WriteLine (file.FullName);
45 #endif
46 private delegate bool FileFilter (string path, string name);
47 private delegate object FileObjectifier (string path, string name);
49 [DllImport ("libc", SetLastError = true)]
50 private static extern IntPtr opendir (string name);
52 [DllImport ("libc", SetLastError = true)]
53 private static extern int closedir (IntPtr dir);
55 [DllImport ("libbeagledglue", EntryPoint = "beagled_utils_readdir", SetLastError = true)]
56 private static extern int sys_readdir (IntPtr dir, StringBuilder name);
58 private static string readdir (IntPtr dir)
60 int r = 0;
61 StringBuilder name = new StringBuilder (256);
63 while (r == 0 && name.Length == 0) {
64 r = sys_readdir (dir, name);
67 if (r == -1)
68 return null;
70 return name.ToString ();
73 private class FileEnumerator : IEnumerator {
75 string path;
76 FileFilter file_filter;
77 FileObjectifier file_objectifier;
78 IntPtr dir_handle = IntPtr.Zero;
79 string current;
81 public FileEnumerator (string path,
82 FileFilter file_filter,
83 FileObjectifier file_objectifier)
85 this.path = path;
86 this.file_filter = file_filter;
87 this.file_objectifier = file_objectifier;
88 Reset ();
91 ~FileEnumerator ()
93 if (dir_handle != IntPtr.Zero)
94 closedir (dir_handle);
97 public object Current {
98 get {
99 object current_obj = null;
100 if (current != null) {
101 if (file_objectifier != null)
102 current_obj = file_objectifier (path, current);
103 else
104 current_obj = Path.Combine (path, current);
107 return current_obj;
111 public bool MoveNext ()
113 bool skip_file = false;
115 do {
116 current = readdir (dir_handle);
117 if (current == null)
118 break;
120 skip_file = false;
122 if (current == "." || current == "..") {
123 skip_file = true;
125 } else if (file_filter != null) {
126 try {
127 if (! file_filter (path, current))
128 skip_file = true;
130 } catch (Exception ex) {
131 Logger.Log.Debug ("Caught exception in file_filter");
132 Logger.Log.Debug (ex.Message);
134 // If we have a filter that fails on a file,
135 // it is probably safest to skip that file.
136 skip_file = true;
140 } while (skip_file);
142 if (current == null) {
143 closedir (dir_handle);
144 dir_handle = IntPtr.Zero;
147 return current != null;
150 public void Reset ()
152 current = null;
153 if (dir_handle != IntPtr.Zero)
154 closedir (dir_handle);
155 dir_handle = opendir (path);
156 if (dir_handle == IntPtr.Zero)
157 throw new DirectoryNotFoundException (path);
161 private class FileEnumerable : IEnumerable {
163 string path;
164 FileFilter file_filter;
165 FileObjectifier file_objectifier;
167 public FileEnumerable (string path,
168 FileFilter file_filter,
169 FileObjectifier file_objectifier)
171 this.path = path;
172 this.file_filter = file_filter;
173 this.file_objectifier = file_objectifier;
176 public IEnumerator GetEnumerator ()
178 return new FileEnumerator (path, file_filter, file_objectifier);
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 static public IEnumerable GetFiles (string path)
194 return new FileEnumerable (path, new FileFilter (IsFile), null);
197 static public IEnumerable GetFiles (DirectoryInfo dirinfo)
199 return GetFiles (dirinfo.FullName);
202 static public IEnumerable GetFileInfos (string path)
204 return new FileEnumerable (path,
205 new FileFilter (IsFile),
206 new FileObjectifier (FileInfoObjectifier));
209 static public IEnumerable GetFileInfos (DirectoryInfo dirinfo)
211 return GetFileInfos (dirinfo.FullName);
214 static private bool IsDirectory (string path, string name)
216 return Directory.Exists (Path.Combine (path, name));
219 static private object DirectoryInfoObjectifier (string path, string name)
221 return new DirectoryInfo (Path.Combine (path, name));
224 static public IEnumerable GetDirectories (string path)
226 return new FileEnumerable (path, new FileFilter (IsDirectory), null);
229 static public IEnumerable GetDirectories (DirectoryInfo dirinfo)
231 return GetDirectories (dirinfo.FullName);
234 static public IEnumerable GetDirectoryInfos (string path)
236 return new FileEnumerable (path,
237 new FileFilter (IsDirectory),
238 new FileObjectifier (DirectoryInfoObjectifier));
241 static public IEnumerable GetDirectoryInfos (DirectoryInfo dirinfo)
243 return GetDirectoryInfos (dirinfo.FullName);