132
|
1 /*******************************************************************************
|
|
2
|
|
3 copyright: Copyright (c) 2004 Kris Bell. All rights reserved
|
|
4
|
|
5 license: BSD style: $(LICENSE)
|
|
6
|
|
7 version: Mar 2004: Initial release
|
|
8 version: Feb 2007: Now using mutating paths
|
|
9
|
|
10 author: Kris, Chris Sauls (Win95 file support)
|
|
11
|
|
12 *******************************************************************************/
|
|
13
|
|
14 module tango.io.FileSystem;
|
|
15
|
|
16 private import tango.sys.Common;
|
|
17
|
|
18 private import tango.io.FilePath;
|
|
19
|
|
20 private import tango.core.Exception;
|
|
21
|
|
22 version (Posix)
|
|
23 {
|
|
24 private import tango.stdc.string;
|
|
25 private import tango.stdc.posix.unistd;
|
|
26 }
|
|
27
|
|
28 /*******************************************************************************
|
|
29
|
|
30 Models an OS-specific file-system. Included here are methods to
|
|
31 manipulate the current working directory, and to convert a path
|
|
32 to its absolute form.
|
|
33
|
|
34 *******************************************************************************/
|
|
35
|
|
36 class FileSystem
|
|
37 {
|
|
38 /***********************************************************************
|
|
39
|
|
40 Convert the provided path to an absolute path, using the
|
|
41 current working directory where prefix is not provided.
|
|
42 If the given path is already an absolute path, return it
|
|
43 intact.
|
|
44
|
|
45 Returns the provided path, adjusted as necessary
|
|
46
|
|
47 ***********************************************************************/
|
|
48
|
|
49 static FilePath toAbsolute (FilePath target, char[] prefix=null)
|
|
50 {
|
|
51 if (! target.isAbsolute)
|
|
52 {
|
|
53 if (prefix is null)
|
|
54 prefix = getDirectory;
|
|
55
|
|
56 target.prepend (target.padded(prefix));
|
|
57 }
|
|
58 return target;
|
|
59 }
|
|
60
|
|
61 /***********************************************************************
|
|
62
|
|
63 ***********************************************************************/
|
|
64
|
|
65 private static void exception (char[] msg)
|
|
66 {
|
|
67 throw new IOException (msg);
|
|
68 }
|
|
69
|
|
70 /***********************************************************************
|
|
71
|
|
72 ***********************************************************************/
|
|
73
|
|
74 version (Win32)
|
|
75 {
|
|
76 /***************************************************************
|
|
77
|
|
78 Set the current working directory
|
|
79
|
|
80 ***************************************************************/
|
|
81
|
|
82 static void setDirectory (char[] path)
|
|
83 {
|
|
84 version (Win32SansUnicode)
|
|
85 {
|
|
86 char[MAX_PATH+1] tmp = void;
|
|
87 tmp[0..path.length] = path;
|
|
88 tmp[path.length] = 0;
|
|
89
|
|
90 if (! SetCurrentDirectoryA (tmp.ptr))
|
|
91 exception ("Failed to set current directory");
|
|
92 }
|
|
93 else
|
|
94 {
|
|
95 // convert into output buffer
|
|
96 wchar[MAX_PATH+1] tmp = void;
|
|
97 assert (path.length < tmp.length);
|
|
98 auto i = MultiByteToWideChar (CP_UTF8, 0,
|
|
99 path.ptr, path.length,
|
|
100 tmp.ptr, tmp.length);
|
|
101 tmp[i] = 0;
|
|
102
|
|
103 if (! SetCurrentDirectoryW (tmp.ptr))
|
|
104 exception ("Failed to set current directory");
|
|
105 }
|
|
106 }
|
|
107
|
|
108 /***************************************************************
|
|
109
|
|
110 Return the current working directory
|
|
111
|
|
112 ***************************************************************/
|
|
113
|
|
114 static char[] getDirectory ()
|
|
115 {
|
|
116 char[] path;
|
|
117
|
|
118 version (Win32SansUnicode)
|
|
119 {
|
|
120 int len = GetCurrentDirectoryA (0, null);
|
|
121 auto dir = new char [len];
|
|
122 GetCurrentDirectoryA (len, dir.ptr);
|
|
123 if (len)
|
|
124 {
|
|
125 dir[len-1] = '\\';
|
|
126 path = dir;
|
|
127 }
|
|
128 else
|
|
129 exception ("Failed to get current directory");
|
|
130 }
|
|
131 else
|
|
132 {
|
|
133 wchar[MAX_PATH+2] tmp = void;
|
|
134
|
|
135 auto len = GetCurrentDirectoryW (0, null);
|
|
136 assert (len < tmp.length);
|
|
137 auto dir = new char [len * 3];
|
|
138 GetCurrentDirectoryW (len, tmp.ptr);
|
|
139 auto i = WideCharToMultiByte (CP_UTF8, 0, tmp.ptr, len,
|
|
140 dir.ptr, dir.length, null, null);
|
|
141 if (len && i)
|
|
142 {
|
|
143 path = dir[0..i];
|
|
144 path[$-1] = '\\';
|
|
145 }
|
|
146 else
|
|
147 exception ("Failed to get current directory");
|
|
148 }
|
|
149
|
|
150 return path;
|
|
151 }
|
|
152 }
|
|
153
|
|
154 /***********************************************************************
|
|
155
|
|
156 ***********************************************************************/
|
|
157
|
|
158 version (Posix)
|
|
159 {
|
|
160 /***************************************************************
|
|
161
|
|
162 Set the current working directory
|
|
163
|
|
164 ***************************************************************/
|
|
165
|
|
166 static void setDirectory (char[] path)
|
|
167 {
|
|
168 char[512] tmp = void;
|
|
169 tmp [path.length] = 0;
|
|
170 tmp[0..path.length] = path;
|
|
171
|
|
172 if (tango.stdc.posix.unistd.chdir (tmp.ptr))
|
|
173 exception ("Failed to set current directory");
|
|
174 }
|
|
175
|
|
176 /***************************************************************
|
|
177
|
|
178 Return the current working directory
|
|
179
|
|
180 ***************************************************************/
|
|
181
|
|
182 static char[] getDirectory ()
|
|
183 {
|
|
184 char[512] tmp = void;
|
|
185
|
|
186 char *s = tango.stdc.posix.unistd.getcwd (tmp.ptr, tmp.length);
|
|
187 if (s is null)
|
|
188 exception ("Failed to get current directory");
|
|
189
|
|
190 auto path = s[0 .. strlen(s)+1].dup;
|
|
191 path[$-1] = '/';
|
|
192 return path;
|
|
193 }
|
|
194 }
|
|
195 }
|
|
196
|
|
197
|
|
198 /******************************************************************************
|
|
199
|
|
200 ******************************************************************************/
|
|
201
|
|
202 debug (FileSystem)
|
|
203 {
|
|
204 import tango.io.Stdout;
|
|
205
|
|
206 static void foo (FilePath path)
|
|
207 {
|
|
208 Stdout("all: ") (path).newline;
|
|
209 Stdout("path: ") (path.path).newline;
|
|
210 Stdout("file: ") (path.file).newline;
|
|
211 Stdout("folder: ") (path.folder).newline;
|
|
212 Stdout("name: ") (path.name).newline;
|
|
213 Stdout("ext: ") (path.ext).newline;
|
|
214 Stdout("suffix: ") (path.suffix).newline.newline;
|
|
215 }
|
|
216
|
|
217 void main()
|
|
218 {
|
|
219 auto path = new FilePath (".");
|
|
220 foo (path);
|
|
221
|
|
222 path.set ("..");
|
|
223 foo (path);
|
|
224
|
|
225 path.set ("...");
|
|
226 foo (path);
|
|
227
|
|
228 path.set (r"\x\y\.file");
|
|
229 foo (path);
|
|
230
|
|
231 path.suffix = ".foo";
|
|
232 foo (path);
|
|
233
|
|
234 path.set ("file.bar");
|
|
235 FileSystem.toAbsolute(path);
|
|
236 foo(path);
|
|
237
|
|
238 path.set (r"arf\test");
|
|
239 foo(path);
|
|
240 FileSystem.toAbsolute(path);
|
|
241 foo(path);
|
|
242
|
|
243 path.name = "foo";
|
|
244 foo(path);
|
|
245
|
|
246 path.suffix = ".d";
|
|
247 path.name = path.suffix;
|
|
248 foo(path);
|
|
249
|
|
250 }
|
|
251 }
|