1
2
3
4
5
6 using System;
7 using System.Collections;
8 using System.Os;
9
10 namespace System.IO
11 {
12 public const int pathMax = 4096;
13 public const int statBufSize = 70;
14
15 public string GetCurrentWorkingDirectory()
16 {
17 Buffer buffer(pathMax);
18 char* buf = cast<char*>(cast<void*>(buffer.Mem()));
19 long count = buffer.Size();
20 GetCWD(buf, count);
21 return string(buf);
22 }
23
24 public static class Directory
25 {
26 public static bool Exists(const string& directoryPath)
27 {
28 return DirectoryExists(directoryPath);
29 }
30 public static bool IsEmpty(const string& directoryPath)
31 {
32 return IsDirectoryEmpty(directoryPath);
33 }
34 public static void Create(const string& directoryPath)
35 {
36 Create(directoryPath, 0);
37 }
38 public static void Create(const string& directoryPath, int mode)
39 {
40 CreateDirectory(directoryPath, mode);
41 }
42 public static DateTime AccessTime(const string& directoryPath)
43 {
44 return GetDirectoryAccessTime(directoryPath);
45 }
46 public static DateTime ModificationTime(const string& directoryPath)
47 {
48 return GetDirectoryModificationTime(directoryPath);
49 }
50 public static void GetTimes(const string& directoryPath, DateTime& accessTime, DateTime& modificationTime)
51 {
52 GetDirectoryTimes(directoryPath, accessTime, modificationTime);
53 }
54 public static void SetTimes(const string& directoryPath, const DateTime& accessTime, const DateTime& modificationTime)
55 {
56 SetDirectoryTimes(directoryPath, accessTime, modificationTime);
57 }
58 public static void Remove(const string& directoryPath)
59 {
60 RemoveDirectory(directoryPath);
61 }
62 }
63
64 public void CreateDirectory(const string& directoryPath)
65 {
66 CreateDirectory(directoryPath, 0);
67 }
68
69 public void CreateDirectory(const string& directoryPath, int mode)
70 {
71 MkDir(directoryPath.Chars(), mode);
72 }
73
74 public void CreateDirectories(const string& directoryPath)
75 {
76 CreateDirectories(directoryPath, 0);
77 }
78
79 public void CreateDirectories(const string& directoryPath, int mode)
80 {
81 if (directoryPath.IsEmpty())
82 {
83 throw InvalidPathException("directory path is empty");
84 }
85 List<string> components = directoryPath.Split('/');
86 int n = cast<int>(components.Count());
87 string dir;
88 int next = 0;
89 if (components[0].IsEmpty())
90 {
91 dir = "/" + components[1];
92 next = 2;
93 }
94 else
95 {
96 dir = components[0];
97 next = 1;
98 }
99 if (!Directory.Exists(dir))
100 {
101 MkDir(dir.Chars(), mode);
102 }
103 for (int i = next; i < n; ++i;)
104 {
105 dir = Path.Combine(dir, components[i]);
106 if (!Directory.Exists(dir))
107 {
108 MkDir(dir.Chars(), mode);
109 }
110 }
111 }
112
113 public bool DirectoryExists(const string& dirPath)
114 {
115 byte[statBufSize] statBuf;
116 int result = stat(dirPath.Chars(), &statBuf[0], statBufSize);
117 if (result == -1)
118 {
119 SystemError systemError = GetSystemError();
120 if (systemError.errorCode == ENOTFOUND)
121 {
122 return false;
123 }
124 else
125 {
126 ThrowSystemError();
127 }
128 }
129 else
130 {
131 FileStatus status;
132 GetFileStatus(&statBuf[0], status);
133 if (status.fileType == FileType.directory)
134 {
135 return true;
136 }
137 else
138 {
139 throw FileSystemException("path '" + dirPath + "' is not a directory path");
140 }
141 }
142 }
143
144 public bool IsDirectoryEmpty(const string& dirPath)
145 {
146 if (!DirectoryExists(dirPath))
147 {
148 throw FileSystemException("directory path '" + dirPath + "' does not exist");
149 }
150 DirectoryEntry entry;
151 DirectoryReader reader(dirPath);
152 while (reader.Read(entry))
153 {
154 if (entry.IsDot() || entry.IsDotDot())
155 {
156 continue;
157 }
158 return false;
159 }
160 return true;
161 }
162
163 public DateTime GetDirectoryAccessTime(const string& dirPath)
164 {
165 FileStatus status;
166 Stat(dirPath.Chars(), status);
167 if (status.fileType != FileType.directory)
168 {
169 throw FileSystemException("path '" + dirPath + "' is not a directory path");
170 }
171 return status.atime;
172 }
173
174 public DateTime GetDirectoryModificationTime(const string& dirPath)
175 {
176 FileStatus status;
177 Stat(dirPath.Chars(), status);
178 if (status.fileType != FileType.directory)
179 {
180 throw FileSystemException("path '" + dirPath + "' is not a directory path");
181 }
182 return status.mtime;
183 }
184
185 public void GetDirectoryTimes(const string& dirPath, DateTime& accessTime, DateTime& modificationTime)
186 {
187 FileStatus status;
188 Stat(dirPath.Chars(), status);
189 if (status.fileType != FileType.directory)
190 {
191 throw FileSystemException("path '" + dirPath + "' is not a directory path");
192 }
193 accessTime = status.atime;
194 modificationTime = status.mtime;
195 }
196
197 public void SetDirectoryTimes(const string& dirPath, const DateTime& accessTime, const DateTime& modificationTime)
198 {
199 UTime(dirPath.Chars(), accessTime, modificationTime);
200 }
201
202 public class DirectoryEntry
203 {
204 public nothrow DirectoryEntry() : inodeNumber(-1), name()
205 {
206 }
207 public nothrow DirectoryEntry(int inodeNumber_, const string& name_) : inodeNumber(inodeNumber_), name(name_)
208 {
209 }
210 public nothrow bool IsDot() const
211 {
212 return name == ".";
213 }
214 public nothrow bool IsDotDot() const
215 {
216 return name == "..";
217 }
218 public int inodeNumber;
219 public string name;
220 }
221
222 public const int directoryEntrySize = 256;
223
224 public class DirectoryReader
225 {
226 public nothrow DirectoryReader(const string& dirPath) : dfd(OpenDir(dirPath.Chars()))
227 {
228 }
229 public bool Read(DirectoryEntry& dirEntry)
230 {
231 byte[directoryEntrySize] dirEntryBuf;
232 int result = ReadDir(dfd, &dirEntryBuf[0], directoryEntrySize);
233 if (result == 1)
234 {
235 MemoryReader reader(&dirEntryBuf[0], directoryEntrySize);
236 dirEntry.inodeNumber = reader.ReadInt();
237 dirEntry.name = reader.ReadString();
238 return true;
239 }
240 return false;
241 }
242 public ~DirectoryReader()
243 {
244 try
245 {
246 CloseDir(dfd);
247 }
248 catch (const Exception&)
249 {
250 }
251 }
252 private int dfd;
253 }
254
255 public void RemoveDirectory(const string& dirPath)
256 {
257 Unlink(dirPath.Chars());
258 }
259 }