OLD | NEW |
---|---|
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 | 5 |
6 class _Directory implements Directory { | 6 class _Directory implements Directory { |
7 static final kCreateRequest = 0; | 7 static final kCreateRequest = 0; |
8 static final kDeleteRequest = 1; | 8 static final kDeleteRequest = 1; |
9 static final kExistsRequest = 2; | 9 static final kExistsRequest = 2; |
10 static final kCreateTempRequest = 3; | 10 static final kCreateTempRequest = 3; |
11 static final kListRequest = 4; | 11 static final kListRequest = 4; |
12 | 12 |
13 static final kSuccessResponse = 0; | |
14 static final kIllegalArgumentResponse = 1; | |
15 static final kOSErrorResponse = 2; | |
16 | |
13 _Directory(String this._path); | 17 _Directory(String this._path); |
14 _Directory.current() : _path = _current(); | 18 _Directory.current() : _path = _current(); |
15 | 19 |
16 static String _current() native "Directory_Current"; | 20 static String _current() native "Directory_Current"; |
17 static _createTemp(String template) native "Directory_CreateTemp"; | 21 static _createTemp(String template) native "Directory_CreateTemp"; |
18 static int _exists(String path) native "Directory_Exists"; | 22 static int _exists(String path) native "Directory_Exists"; |
19 static bool _create(String path) native "Directory_Create"; | 23 static _create(String path) native "Directory_Create"; |
20 static bool _delete(String path, bool recursive) native "Directory_Delete"; | 24 static _delete(String path, bool recursive) native "Directory_Delete"; |
21 static SendPort _newServicePort() native "Directory_NewServicePort"; | 25 static SendPort _newServicePort() native "Directory_NewServicePort"; |
22 | 26 |
23 void exists(void callback(bool exists)) { | 27 void exists(void callback(bool exists)) { |
24 _ensureDirectoryService(); | 28 _ensureDirectoryService(); |
25 List request = new List(2); | 29 List request = new List(2); |
26 request[0] = kExistsRequest; | 30 request[0] = kExistsRequest; |
27 request[1] = _path; | 31 request[1] = _path; |
28 _directoryService.call(request).then((result) { | 32 _directoryService.call(request).then((response) { |
29 if (result < 0) { | 33 if (_isErrorResponse(response)) { |
30 if (_onError != null) { | 34 _reportError(response, "Exists failed"); |
31 _onError("Diretory exists test failed: $_path"); | |
32 } | |
33 } else { | 35 } else { |
34 callback(result == 1); | 36 callback(response == 1); |
35 } | 37 } |
36 }); | 38 }); |
37 } | 39 } |
38 | 40 |
39 bool existsSync() { | 41 bool existsSync() { |
40 int exists = _exists(_path); | 42 if (_path is !String) { |
41 if (exists < 0) { | 43 throw new IllegalArgumentException(); |
42 throw new DirectoryIOException("Diretory exists test failed: $_path"); | |
43 } | 44 } |
44 return (exists == 1); | 45 var result = _exists(_path); |
46 if (result is OSError) { | |
47 throw new DirectoryIOException("Exists failed", _path, result); | |
48 } | |
49 return (result == 1); | |
45 } | 50 } |
46 | 51 |
47 void create(void callback()) { | 52 void create(void callback()) { |
48 _ensureDirectoryService(); | 53 _ensureDirectoryService(); |
49 List request = new List(2); | 54 List request = new List(2); |
50 request[0] = kCreateRequest; | 55 request[0] = kCreateRequest; |
51 request[1] = _path; | 56 request[1] = _path; |
52 _directoryService.call(request).then((result) { | 57 _directoryService.call(request).then((response) { |
53 if (result) { | 58 if (_isErrorResponse(response)) { |
59 _reportError(response, "Creation failed"); | |
60 } else { | |
54 callback(); | 61 callback(); |
55 } else if (_onError != null) { | |
56 _onError("Directory creation failed: $_path"); | |
57 } | 62 } |
58 }); | 63 }); |
59 } | 64 } |
60 | 65 |
61 void createSync() { | 66 void createSync() { |
62 if (!_create(_path)) { | 67 if (_path is !String) { |
63 throw new DirectoryIOException("Directory creation failed: $_path"); | 68 throw new IllegalArgumentException(); |
69 } | |
70 var result = _create(_path); | |
71 if (result is OSError) { | |
72 throw new DirectoryIOException("Creation failed", _path, result); | |
64 } | 73 } |
65 } | 74 } |
66 | 75 |
67 void createTemp(void callback()) { | 76 void createTemp(void callback()) { |
68 _ensureDirectoryService(); | 77 _ensureDirectoryService(); |
69 List request = new List(2); | 78 List request = new List(2); |
70 request[0] = kCreateTempRequest; | 79 request[0] = kCreateTempRequest; |
71 request[1] = _path; | 80 request[1] = _path; |
72 _directoryService.call(request).then((result) { | 81 _directoryService.call(request).then((response) { |
73 if (result is !List) { | 82 if (_isErrorResponse(response)) { |
74 _path = result; | 83 _reportError(response, "Creation of temporary directory failed"); |
84 } else { | |
85 _path = response; | |
75 callback(); | 86 callback(); |
76 } else if (_onError != null) { | |
77 _onError("Could not create temporary directory [$_path]: ${result[1]}"); | |
78 } | 87 } |
79 }); | 88 }); |
80 } | 89 } |
81 | 90 |
82 void createTempSync() { | 91 void createTempSync() { |
83 if (_path is !String) { | 92 if (_path is !String) { |
84 throw new IllegalArgumentException(); | 93 throw new IllegalArgumentException(); |
85 } | 94 } |
86 var result = _createTemp(path); | 95 var result = _createTemp(path); |
87 if (result is OSError) { | 96 if (result is OSError) { |
88 throw new DirectoryIOException("Could not create temporary directory", | 97 throw new DirectoryIOException("Creation of temporary directory failed", |
98 _path, | |
89 result); | 99 result); |
90 } | 100 } |
91 _path = result; | 101 _path = result; |
92 } | 102 } |
93 | 103 |
94 void _deleteHelper(bool recursive, String errorMsg, void callback()) { | 104 void _deleteHelper(bool recursive, String errorMsg, void callback()) { |
95 _ensureDirectoryService(); | 105 _ensureDirectoryService(); |
96 List request = new List(3); | 106 List request = new List(3); |
97 request[0] = kDeleteRequest; | 107 request[0] = kDeleteRequest; |
98 request[1] = _path; | 108 request[1] = _path; |
99 request[2] = recursive; | 109 request[2] = recursive; |
100 _directoryService.call(request).then((result) { | 110 _directoryService.call(request).then((response) { |
101 if (result) { | 111 if (_isErrorResponse(response)) { |
112 _reportError(response, errorMsg); | |
113 } else { | |
102 callback(); | 114 callback(); |
103 } else if (_onError != null) { | |
104 _onError("${errorMsg}: $_path"); | |
105 } | 115 } |
106 }); | 116 }); |
107 } | 117 } |
108 | 118 |
109 void delete(void callback()) { | 119 void delete(void callback()) { |
110 _deleteHelper(false, "Directory deletion failed", callback); | 120 _deleteHelper(false, "Deletion failed", callback); |
111 } | 121 } |
112 | 122 |
113 void deleteRecursively(void callback()) { | 123 void deleteRecursively(void callback()) { |
114 _deleteHelper(true, "Recursive directory deletion failed", callback); | 124 _deleteHelper(true, "Deletion failed", callback); |
115 } | 125 } |
116 | 126 |
117 void deleteSync() { | 127 void deleteSync() { |
118 bool recursive = false; | 128 if (_path is !String) { |
119 if (!_delete(_path, recursive)) { | 129 throw new IllegalArgumentException(); |
120 throw new DirectoryIOException("Directory deletion failed: $_path"); | 130 } |
131 var result = _delete(_path, false); | |
132 if (result is OSError) { | |
133 throw new DirectoryIOException("Deletion failed", _path, result); | |
121 } | 134 } |
122 } | 135 } |
123 | 136 |
124 void deleteRecursivelySync() { | 137 void deleteRecursivelySync() { |
125 bool recursive = true; | 138 if (_path is !String) { |
126 if (!_delete(_path, recursive)) { | 139 throw new IllegalArgumentException(); |
127 throw new DirectoryIOException( | 140 } |
128 "Recursive directory deletion failed: $_path"); | 141 var result = _delete(_path, true); |
142 if (result is OSError) { | |
143 throw new DirectoryIOException("Deletion failed", _path, result); | |
129 } | 144 } |
130 } | 145 } |
131 | 146 |
132 void list([bool recursive = false]) { | 147 void list([bool recursive = false]) { |
133 final int kListDirectory = 0; | 148 final int kListDirectory = 0; |
134 final int kListFile = 1; | 149 final int kListFile = 1; |
135 final int kListError = 2; | 150 final int kListError = 2; |
136 final int kListDone = 3; | 151 final int kListDone = 3; |
137 | 152 |
138 List request = new List(3); | 153 List request = new List(3); |
139 request[0] = kListRequest; | 154 request[0] = kListRequest; |
140 request[1] = _path; | 155 request[1] = _path; |
141 request[2] = recursive; | 156 request[2] = recursive; |
142 ReceivePort responsePort = new ReceivePort(); | 157 ReceivePort responsePort = new ReceivePort(); |
143 // Use a separate directory service port for each listing as | 158 // Use a separate directory service port for each listing as |
144 // listing operations on the same directory can run in parallel. | 159 // listing operations on the same directory can run in parallel. |
145 _newServicePort().send(request, responsePort.toSendPort()); | 160 _newServicePort().send(request, responsePort.toSendPort()); |
146 responsePort.receive((message, replyTo) { | 161 responsePort.receive((message, replyTo) { |
147 if (message is !List || message[0] is !int) { | 162 if (message is !List || message[0] is !int) { |
148 responsePort.close(); | 163 responsePort.close(); |
149 if (_onError != null) _onError("Internal error"); | 164 if (_onError != null) { |
165 _onError(new DirectoryIOException("Internal error")); | |
166 } | |
150 return; | 167 return; |
151 } | 168 } |
152 switch (message[0]) { | 169 switch (message[0]) { |
153 case kListDirectory: | 170 case kListDirectory: |
154 if (_onDir != null) _onDir(message[1]); | 171 if (_onDir != null) _onDir(message[1]); |
155 break; | 172 break; |
156 case kListFile: | 173 case kListFile: |
157 if (_onFile != null) _onFile(message[1]); | 174 if (_onFile != null) _onFile(message[1]); |
158 break; | 175 break; |
159 case kListError: | 176 case kListError: |
160 if (_onError != null) _onError(message[1]); | 177 if (_onError != null) { |
178 if (message[2][0] == _FileUtils.kIllegalArgumentResponse) { | |
179 _onError(new IllegalArgumentException()); | |
180 } else if (message[2][0] == _FileUtils.kOSErrorResponse) { | |
181 _onError(new DirectoryIOException("Directory listing failed", | |
182 message[1], | |
183 new OSError(message[2][2], | |
Mads Ager (google)
2012/03/26 16:03:05
Maybe introduce named constants for the indices in
Søren Gjesse
2012/04/02 07:33:02
Done.
| |
184 message[2][1]))); | |
185 } else { | |
186 _onError(new DirectoryIOException("Internal error")); | |
187 } | |
188 } | |
161 break; | 189 break; |
162 case kListDone: | 190 case kListDone: |
163 responsePort.close(); | 191 responsePort.close(); |
164 if (_onDone != null) _onDone(message[1]); | 192 if (_onDone != null) _onDone(message[1]); |
165 break; | 193 break; |
166 } | 194 } |
167 }); | 195 }); |
168 } | 196 } |
169 | 197 |
170 void set onDir(void onDir(String dir)) { | 198 void set onDir(void onDir(String dir)) { |
171 _onDir = onDir; | 199 _onDir = onDir; |
172 } | 200 } |
173 | 201 |
174 void set onFile(void onFile(String file)) { | 202 void set onFile(void onFile(String file)) { |
175 _onFile = onFile; | 203 _onFile = onFile; |
176 } | 204 } |
177 | 205 |
178 void set onDone(void onDone(bool completed)) { | 206 void set onDone(void onDone(bool completed)) { |
179 _onDone = onDone; | 207 _onDone = onDone; |
180 } | 208 } |
181 | 209 |
182 void set onError(void onError(String error)) { | 210 void set onError(void onError(Exception e)) { |
183 _onError = onError; | 211 _onError = onError; |
184 } | 212 } |
185 | 213 |
186 String get path() { return _path; } | 214 String get path() { return _path; } |
187 | 215 |
188 void _ensureDirectoryService() { | 216 void _ensureDirectoryService() { |
189 if (_directoryService == null) { | 217 if (_directoryService == null) { |
190 _directoryService = _newServicePort(); | 218 _directoryService = _newServicePort(); |
191 } | 219 } |
192 } | 220 } |
193 | 221 |
194 var _onDir; | 222 bool _isErrorResponse(response) { |
195 var _onFile; | 223 return response is List && response[0] != _FileUtils.kSuccessResponse; |
196 var _onDone; | 224 } |
197 var _onError; | 225 |
226 bool _reportError(response, String message) { | |
227 assert(_isErrorResponse(response)); | |
228 if (_onError != null) { | |
229 switch (response[0]) { | |
230 case _FileUtils.kIllegalArgumentResponse: | |
231 _onError(new IllegalArgumentException()); | |
232 break; | |
233 case _FileUtils.kOSErrorResponse: | |
234 _onError(new DirectoryIOException( | |
235 message, _path, new OSError(response[2], response[1]))); | |
Mads Ager (google)
2012/03/26 16:03:05
Ditto. Naming response[2] and response[1] would im
Søren Gjesse
2012/04/02 07:33:02
Done.
I have put it on my TODO list that we need
| |
236 break; | |
237 default: | |
238 _onError(new Exception("Unknown error")); | |
239 break; | |
240 } | |
241 } | |
242 } | |
243 | |
244 Function _onDir; | |
245 Function _onFile; | |
246 Function _onDone; | |
247 Function _onError; | |
198 | 248 |
199 String _path; | 249 String _path; |
200 SendPort _directoryService; | 250 SendPort _directoryService; |
201 } | 251 } |
OLD | NEW |