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 #if !defined(DART_IO_DISABLED) | 5 #if !defined(DART_IO_DISABLED) |
6 | 6 |
7 #include "bin/directory.h" | 7 #include "bin/directory.h" |
8 | 8 |
9 #include "bin/dartutils.h" | 9 #include "bin/dartutils.h" |
10 #include "bin/log.h" | 10 #include "bin/log.h" |
11 #include "include/dart_api.h" | 11 #include "include/dart_api.h" |
12 #include "platform/assert.h" | 12 #include "platform/assert.h" |
13 | 13 |
14 namespace dart { | 14 namespace dart { |
15 namespace bin { | 15 namespace bin { |
16 | 16 |
17 char* Directory::system_temp_path_override_ = NULL; | 17 char* Directory::system_temp_path_override_ = NULL; |
18 | 18 |
19 void FUNCTION_NAME(Directory_Current)(Dart_NativeArguments args) { | 19 void FUNCTION_NAME(Directory_Current)(Dart_NativeArguments args) { |
20 const char* current = Directory::Current(); | 20 const char* current = Directory::Current(); |
21 if (current != NULL) { | 21 if (current != NULL) { |
22 Dart_SetReturnValue(args, DartUtils::NewString(current)); | 22 Dart_SetReturnValue(args, DartUtils::NewString(current)); |
23 } else { | 23 } else { |
24 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); | 24 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); |
25 } | 25 } |
26 } | 26 } |
27 | 27 |
28 | |
29 void FUNCTION_NAME(Directory_SetCurrent)(Dart_NativeArguments args) { | 28 void FUNCTION_NAME(Directory_SetCurrent)(Dart_NativeArguments args) { |
30 int argc = Dart_GetNativeArgumentCount(args); | 29 int argc = Dart_GetNativeArgumentCount(args); |
31 Dart_Handle path; | 30 Dart_Handle path; |
32 if (argc == 1) { | 31 if (argc == 1) { |
33 path = Dart_GetNativeArgument(args, 0); | 32 path = Dart_GetNativeArgument(args, 0); |
34 } | 33 } |
35 if ((argc != 1) || !Dart_IsString(path)) { | 34 if ((argc != 1) || !Dart_IsString(path)) { |
36 Dart_SetReturnValue(args, DartUtils::NewDartArgumentError(NULL)); | 35 Dart_SetReturnValue(args, DartUtils::NewDartArgumentError(NULL)); |
37 } else { | 36 } else { |
38 if (Directory::SetCurrent(DartUtils::GetStringValue(path))) { | 37 if (Directory::SetCurrent(DartUtils::GetStringValue(path))) { |
39 Dart_SetReturnValue(args, Dart_True()); | 38 Dart_SetReturnValue(args, Dart_True()); |
40 } else { | 39 } else { |
41 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); | 40 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); |
42 } | 41 } |
43 } | 42 } |
44 } | 43 } |
45 | 44 |
46 | |
47 void FUNCTION_NAME(Directory_Exists)(Dart_NativeArguments args) { | 45 void FUNCTION_NAME(Directory_Exists)(Dart_NativeArguments args) { |
48 static const int kExists = 1; | 46 static const int kExists = 1; |
49 static const int kDoesNotExist = 0; | 47 static const int kDoesNotExist = 0; |
50 Dart_Handle path = Dart_GetNativeArgument(args, 0); | 48 Dart_Handle path = Dart_GetNativeArgument(args, 0); |
51 Directory::ExistsResult result = | 49 Directory::ExistsResult result = |
52 Directory::Exists(DartUtils::GetStringValue(path)); | 50 Directory::Exists(DartUtils::GetStringValue(path)); |
53 if (result == Directory::EXISTS) { | 51 if (result == Directory::EXISTS) { |
54 Dart_SetReturnValue(args, Dart_NewInteger(kExists)); | 52 Dart_SetReturnValue(args, Dart_NewInteger(kExists)); |
55 } else if (result == Directory::DOES_NOT_EXIST) { | 53 } else if (result == Directory::DOES_NOT_EXIST) { |
56 Dart_SetReturnValue(args, Dart_NewInteger(kDoesNotExist)); | 54 Dart_SetReturnValue(args, Dart_NewInteger(kDoesNotExist)); |
57 } else { | 55 } else { |
58 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); | 56 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); |
59 } | 57 } |
60 } | 58 } |
61 | 59 |
62 | |
63 void FUNCTION_NAME(Directory_Create)(Dart_NativeArguments args) { | 60 void FUNCTION_NAME(Directory_Create)(Dart_NativeArguments args) { |
64 Dart_Handle path = Dart_GetNativeArgument(args, 0); | 61 Dart_Handle path = Dart_GetNativeArgument(args, 0); |
65 if (Directory::Create(DartUtils::GetStringValue(path))) { | 62 if (Directory::Create(DartUtils::GetStringValue(path))) { |
66 Dart_SetReturnValue(args, Dart_True()); | 63 Dart_SetReturnValue(args, Dart_True()); |
67 } else { | 64 } else { |
68 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); | 65 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); |
69 } | 66 } |
70 } | 67 } |
71 | 68 |
72 | |
73 void FUNCTION_NAME(Directory_SystemTemp)(Dart_NativeArguments args) { | 69 void FUNCTION_NAME(Directory_SystemTemp)(Dart_NativeArguments args) { |
74 const char* result = Directory::SystemTemp(); | 70 const char* result = Directory::SystemTemp(); |
75 Dart_SetReturnValue(args, DartUtils::NewString(result)); | 71 Dart_SetReturnValue(args, DartUtils::NewString(result)); |
76 } | 72 } |
77 | 73 |
78 | |
79 void FUNCTION_NAME(Directory_CreateTemp)(Dart_NativeArguments args) { | 74 void FUNCTION_NAME(Directory_CreateTemp)(Dart_NativeArguments args) { |
80 Dart_Handle path = Dart_GetNativeArgument(args, 0); | 75 Dart_Handle path = Dart_GetNativeArgument(args, 0); |
81 if (!Dart_IsString(path)) { | 76 if (!Dart_IsString(path)) { |
82 Dart_SetReturnValue( | 77 Dart_SetReturnValue( |
83 args, DartUtils::NewDartArgumentError( | 78 args, DartUtils::NewDartArgumentError( |
84 "Prefix argument of CreateSystemTempSync is not a String")); | 79 "Prefix argument of CreateSystemTempSync is not a String")); |
85 return; | 80 return; |
86 } | 81 } |
87 const char* result = Directory::CreateTemp(DartUtils::GetStringValue(path)); | 82 const char* result = Directory::CreateTemp(DartUtils::GetStringValue(path)); |
88 if (result != NULL) { | 83 if (result != NULL) { |
89 Dart_SetReturnValue(args, DartUtils::NewString(result)); | 84 Dart_SetReturnValue(args, DartUtils::NewString(result)); |
90 } else { | 85 } else { |
91 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); | 86 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); |
92 } | 87 } |
93 } | 88 } |
94 | 89 |
95 | |
96 void FUNCTION_NAME(Directory_Delete)(Dart_NativeArguments args) { | 90 void FUNCTION_NAME(Directory_Delete)(Dart_NativeArguments args) { |
97 Dart_Handle path = Dart_GetNativeArgument(args, 0); | 91 Dart_Handle path = Dart_GetNativeArgument(args, 0); |
98 Dart_Handle recursive = Dart_GetNativeArgument(args, 1); | 92 Dart_Handle recursive = Dart_GetNativeArgument(args, 1); |
99 if (Directory::Delete(DartUtils::GetStringValue(path), | 93 if (Directory::Delete(DartUtils::GetStringValue(path), |
100 DartUtils::GetBooleanValue(recursive))) { | 94 DartUtils::GetBooleanValue(recursive))) { |
101 Dart_SetReturnValue(args, Dart_True()); | 95 Dart_SetReturnValue(args, Dart_True()); |
102 } else { | 96 } else { |
103 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); | 97 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); |
104 } | 98 } |
105 } | 99 } |
106 | 100 |
107 | |
108 void FUNCTION_NAME(Directory_Rename)(Dart_NativeArguments args) { | 101 void FUNCTION_NAME(Directory_Rename)(Dart_NativeArguments args) { |
109 Dart_Handle path = Dart_GetNativeArgument(args, 0); | 102 Dart_Handle path = Dart_GetNativeArgument(args, 0); |
110 Dart_Handle newPath = Dart_GetNativeArgument(args, 1); | 103 Dart_Handle newPath = Dart_GetNativeArgument(args, 1); |
111 if (Directory::Rename(DartUtils::GetStringValue(path), | 104 if (Directory::Rename(DartUtils::GetStringValue(path), |
112 DartUtils::GetStringValue(newPath))) { | 105 DartUtils::GetStringValue(newPath))) { |
113 Dart_SetReturnValue(args, Dart_True()); | 106 Dart_SetReturnValue(args, Dart_True()); |
114 } else { | 107 } else { |
115 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); | 108 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); |
116 } | 109 } |
117 } | 110 } |
118 | 111 |
119 | |
120 void FUNCTION_NAME(Directory_FillWithDirectoryListing)( | 112 void FUNCTION_NAME(Directory_FillWithDirectoryListing)( |
121 Dart_NativeArguments args) { | 113 Dart_NativeArguments args) { |
122 // The list that we should fill. | 114 // The list that we should fill. |
123 Dart_Handle results = Dart_GetNativeArgument(args, 0); | 115 Dart_Handle results = Dart_GetNativeArgument(args, 0); |
124 Dart_Handle path = Dart_GetNativeArgument(args, 1); | 116 Dart_Handle path = Dart_GetNativeArgument(args, 1); |
125 Dart_Handle recursive = Dart_GetNativeArgument(args, 2); | 117 Dart_Handle recursive = Dart_GetNativeArgument(args, 2); |
126 Dart_Handle follow_links = Dart_GetNativeArgument(args, 3); | 118 Dart_Handle follow_links = Dart_GetNativeArgument(args, 3); |
127 | 119 |
128 Dart_Handle dart_error; | 120 Dart_Handle dart_error; |
129 { | 121 { |
130 // Pass the list that should hold the directory listing to the | 122 // Pass the list that should hold the directory listing to the |
131 // SyncDirectoryListing object, which adds elements to it. | 123 // SyncDirectoryListing object, which adds elements to it. |
132 SyncDirectoryListing sync_listing(results, DartUtils::GetStringValue(path), | 124 SyncDirectoryListing sync_listing(results, DartUtils::GetStringValue(path), |
133 DartUtils::GetBooleanValue(recursive), | 125 DartUtils::GetBooleanValue(recursive), |
134 DartUtils::GetBooleanValue(follow_links)); | 126 DartUtils::GetBooleanValue(follow_links)); |
135 Directory::List(&sync_listing); | 127 Directory::List(&sync_listing); |
136 dart_error = sync_listing.dart_error(); | 128 dart_error = sync_listing.dart_error(); |
137 } | 129 } |
138 if (Dart_IsError(dart_error)) { | 130 if (Dart_IsError(dart_error)) { |
139 Dart_PropagateError(dart_error); | 131 Dart_PropagateError(dart_error); |
140 } else if (!Dart_IsNull(dart_error)) { | 132 } else if (!Dart_IsNull(dart_error)) { |
141 Dart_ThrowException(dart_error); | 133 Dart_ThrowException(dart_error); |
142 } | 134 } |
143 } | 135 } |
144 | 136 |
145 | |
146 static const int kAsyncDirectoryListerFieldIndex = 0; | 137 static const int kAsyncDirectoryListerFieldIndex = 0; |
147 | 138 |
148 | |
149 void FUNCTION_NAME(Directory_GetAsyncDirectoryListerPointer)( | 139 void FUNCTION_NAME(Directory_GetAsyncDirectoryListerPointer)( |
150 Dart_NativeArguments args) { | 140 Dart_NativeArguments args) { |
151 AsyncDirectoryListing* listing; | 141 AsyncDirectoryListing* listing; |
152 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); | 142 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); |
153 ASSERT(Dart_IsInstance(dart_this)); | 143 ASSERT(Dart_IsInstance(dart_this)); |
154 ThrowIfError( | 144 ThrowIfError( |
155 Dart_GetNativeInstanceField(dart_this, kAsyncDirectoryListerFieldIndex, | 145 Dart_GetNativeInstanceField(dart_this, kAsyncDirectoryListerFieldIndex, |
156 reinterpret_cast<intptr_t*>(&listing))); | 146 reinterpret_cast<intptr_t*>(&listing))); |
157 if (listing != NULL) { | 147 if (listing != NULL) { |
158 intptr_t listing_pointer = reinterpret_cast<intptr_t>(listing); | 148 intptr_t listing_pointer = reinterpret_cast<intptr_t>(listing); |
159 // Increment the listing's reference count. This native should only be | 149 // Increment the listing's reference count. This native should only be |
160 // be called when we are about to send the AsyncDirectoryListing* to the | 150 // be called when we are about to send the AsyncDirectoryListing* to the |
161 // IO service. | 151 // IO service. |
162 listing->Retain(); | 152 listing->Retain(); |
163 Dart_SetReturnValue(args, Dart_NewInteger(listing_pointer)); | 153 Dart_SetReturnValue(args, Dart_NewInteger(listing_pointer)); |
164 } | 154 } |
165 } | 155 } |
166 | 156 |
167 | |
168 static void ReleaseListing(void* isolate_callback_data, | 157 static void ReleaseListing(void* isolate_callback_data, |
169 Dart_WeakPersistentHandle handle, | 158 Dart_WeakPersistentHandle handle, |
170 void* peer) { | 159 void* peer) { |
171 AsyncDirectoryListing* listing = | 160 AsyncDirectoryListing* listing = |
172 reinterpret_cast<AsyncDirectoryListing*>(peer); | 161 reinterpret_cast<AsyncDirectoryListing*>(peer); |
173 listing->Release(); | 162 listing->Release(); |
174 } | 163 } |
175 | 164 |
176 | |
177 void FUNCTION_NAME(Directory_SetAsyncDirectoryListerPointer)( | 165 void FUNCTION_NAME(Directory_SetAsyncDirectoryListerPointer)( |
178 Dart_NativeArguments args) { | 166 Dart_NativeArguments args) { |
179 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); | 167 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); |
180 intptr_t listing_pointer = | 168 intptr_t listing_pointer = |
181 DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 1)); | 169 DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 1)); |
182 AsyncDirectoryListing* listing = | 170 AsyncDirectoryListing* listing = |
183 reinterpret_cast<AsyncDirectoryListing*>(listing_pointer); | 171 reinterpret_cast<AsyncDirectoryListing*>(listing_pointer); |
184 Dart_NewWeakPersistentHandle(dart_this, reinterpret_cast<void*>(listing), | 172 Dart_NewWeakPersistentHandle(dart_this, reinterpret_cast<void*>(listing), |
185 sizeof(*listing), ReleaseListing); | 173 sizeof(*listing), ReleaseListing); |
186 Dart_Handle result = Dart_SetNativeInstanceField( | 174 Dart_Handle result = Dart_SetNativeInstanceField( |
187 dart_this, kAsyncDirectoryListerFieldIndex, listing_pointer); | 175 dart_this, kAsyncDirectoryListerFieldIndex, listing_pointer); |
188 if (Dart_IsError(result)) { | 176 if (Dart_IsError(result)) { |
189 Log::PrintErr("SetAsyncDirectoryListerPointer failed\n"); | 177 Log::PrintErr("SetAsyncDirectoryListerPointer failed\n"); |
190 Dart_PropagateError(result); | 178 Dart_PropagateError(result); |
191 } | 179 } |
192 } | 180 } |
193 | 181 |
194 | |
195 void Directory::SetSystemTemp(const char* path) { | 182 void Directory::SetSystemTemp(const char* path) { |
196 if (system_temp_path_override_ != NULL) { | 183 if (system_temp_path_override_ != NULL) { |
197 free(system_temp_path_override_); | 184 free(system_temp_path_override_); |
198 system_temp_path_override_ = NULL; | 185 system_temp_path_override_ = NULL; |
199 } | 186 } |
200 if (path != NULL) { | 187 if (path != NULL) { |
201 system_temp_path_override_ = strdup(path); | 188 system_temp_path_override_ = strdup(path); |
202 } | 189 } |
203 } | 190 } |
204 | 191 |
205 | |
206 CObject* Directory::CreateRequest(const CObjectArray& request) { | 192 CObject* Directory::CreateRequest(const CObjectArray& request) { |
207 if ((request.Length() == 1) && request[0]->IsString()) { | 193 if ((request.Length() == 1) && request[0]->IsString()) { |
208 CObjectString path(request[0]); | 194 CObjectString path(request[0]); |
209 if (Directory::Create(path.CString())) { | 195 if (Directory::Create(path.CString())) { |
210 return CObject::True(); | 196 return CObject::True(); |
211 } else { | 197 } else { |
212 return CObject::NewOSError(); | 198 return CObject::NewOSError(); |
213 } | 199 } |
214 } | 200 } |
215 return CObject::IllegalArgumentError(); | 201 return CObject::IllegalArgumentError(); |
216 } | 202 } |
217 | 203 |
218 | |
219 CObject* Directory::DeleteRequest(const CObjectArray& request) { | 204 CObject* Directory::DeleteRequest(const CObjectArray& request) { |
220 if ((request.Length() == 2) && request[0]->IsString() && | 205 if ((request.Length() == 2) && request[0]->IsString() && |
221 request[1]->IsBool()) { | 206 request[1]->IsBool()) { |
222 CObjectString path(request[0]); | 207 CObjectString path(request[0]); |
223 CObjectBool recursive(request[1]); | 208 CObjectBool recursive(request[1]); |
224 if (Directory::Delete(path.CString(), recursive.Value())) { | 209 if (Directory::Delete(path.CString(), recursive.Value())) { |
225 return CObject::True(); | 210 return CObject::True(); |
226 } else { | 211 } else { |
227 return CObject::NewOSError(); | 212 return CObject::NewOSError(); |
228 } | 213 } |
229 } | 214 } |
230 return CObject::IllegalArgumentError(); | 215 return CObject::IllegalArgumentError(); |
231 } | 216 } |
232 | 217 |
233 | |
234 CObject* Directory::ExistsRequest(const CObjectArray& request) { | 218 CObject* Directory::ExistsRequest(const CObjectArray& request) { |
235 static const int kExists = 1; | 219 static const int kExists = 1; |
236 static const int kDoesNotExist = 0; | 220 static const int kDoesNotExist = 0; |
237 if ((request.Length() == 1) && request[0]->IsString()) { | 221 if ((request.Length() == 1) && request[0]->IsString()) { |
238 CObjectString path(request[0]); | 222 CObjectString path(request[0]); |
239 Directory::ExistsResult result = Directory::Exists(path.CString()); | 223 Directory::ExistsResult result = Directory::Exists(path.CString()); |
240 if (result == Directory::EXISTS) { | 224 if (result == Directory::EXISTS) { |
241 return new CObjectInt32(CObject::NewInt32(kExists)); | 225 return new CObjectInt32(CObject::NewInt32(kExists)); |
242 } else if (result == Directory::DOES_NOT_EXIST) { | 226 } else if (result == Directory::DOES_NOT_EXIST) { |
243 return new CObjectInt32(CObject::NewInt32(kDoesNotExist)); | 227 return new CObjectInt32(CObject::NewInt32(kDoesNotExist)); |
244 } else { | 228 } else { |
245 return CObject::NewOSError(); | 229 return CObject::NewOSError(); |
246 } | 230 } |
247 } | 231 } |
248 return CObject::IllegalArgumentError(); | 232 return CObject::IllegalArgumentError(); |
249 } | 233 } |
250 | 234 |
251 | |
252 CObject* Directory::CreateTempRequest(const CObjectArray& request) { | 235 CObject* Directory::CreateTempRequest(const CObjectArray& request) { |
253 if ((request.Length() == 1) && request[0]->IsString()) { | 236 if ((request.Length() == 1) && request[0]->IsString()) { |
254 CObjectString path(request[0]); | 237 CObjectString path(request[0]); |
255 const char* result = Directory::CreateTemp(path.CString()); | 238 const char* result = Directory::CreateTemp(path.CString()); |
256 if (result != NULL) { | 239 if (result != NULL) { |
257 CObject* temp_dir = new CObjectString(CObject::NewString(result)); | 240 CObject* temp_dir = new CObjectString(CObject::NewString(result)); |
258 return temp_dir; | 241 return temp_dir; |
259 } else { | 242 } else { |
260 return CObject::NewOSError(); | 243 return CObject::NewOSError(); |
261 } | 244 } |
262 } | 245 } |
263 return CObject::IllegalArgumentError(); | 246 return CObject::IllegalArgumentError(); |
264 } | 247 } |
265 | 248 |
266 | |
267 static CObject* CreateIllegalArgumentError() { | 249 static CObject* CreateIllegalArgumentError() { |
268 // Respond with an illegal argument list error message. | 250 // Respond with an illegal argument list error message. |
269 CObjectArray* error = new CObjectArray(CObject::NewArray(3)); | 251 CObjectArray* error = new CObjectArray(CObject::NewArray(3)); |
270 error->SetAt(0, new CObjectInt32( | 252 error->SetAt(0, new CObjectInt32( |
271 CObject::NewInt32(AsyncDirectoryListing::kListError))); | 253 CObject::NewInt32(AsyncDirectoryListing::kListError))); |
272 error->SetAt(1, CObject::Null()); | 254 error->SetAt(1, CObject::Null()); |
273 error->SetAt(2, CObject::IllegalArgumentError()); | 255 error->SetAt(2, CObject::IllegalArgumentError()); |
274 return error; | 256 return error; |
275 } | 257 } |
276 | 258 |
277 | |
278 CObject* Directory::ListStartRequest(const CObjectArray& request) { | 259 CObject* Directory::ListStartRequest(const CObjectArray& request) { |
279 if ((request.Length() == 3) && request[0]->IsString() && | 260 if ((request.Length() == 3) && request[0]->IsString() && |
280 request[1]->IsBool() && request[2]->IsBool()) { | 261 request[1]->IsBool() && request[2]->IsBool()) { |
281 CObjectString path(request[0]); | 262 CObjectString path(request[0]); |
282 CObjectBool recursive(request[1]); | 263 CObjectBool recursive(request[1]); |
283 CObjectBool follow_links(request[2]); | 264 CObjectBool follow_links(request[2]); |
284 AsyncDirectoryListing* dir_listing = new AsyncDirectoryListing( | 265 AsyncDirectoryListing* dir_listing = new AsyncDirectoryListing( |
285 path.CString(), recursive.Value(), follow_links.Value()); | 266 path.CString(), recursive.Value(), follow_links.Value()); |
286 if (dir_listing->error()) { | 267 if (dir_listing->error()) { |
287 // Report error now, so we capture the correct OSError. | 268 // Report error now, so we capture the correct OSError. |
288 CObject* err = CObject::NewOSError(); | 269 CObject* err = CObject::NewOSError(); |
289 dir_listing->Release(); | 270 dir_listing->Release(); |
290 CObjectArray* error = new CObjectArray(CObject::NewArray(3)); | 271 CObjectArray* error = new CObjectArray(CObject::NewArray(3)); |
291 error->SetAt(0, new CObjectInt32(CObject::NewInt32( | 272 error->SetAt(0, new CObjectInt32(CObject::NewInt32( |
292 AsyncDirectoryListing::kListError))); | 273 AsyncDirectoryListing::kListError))); |
293 error->SetAt(1, request[0]); | 274 error->SetAt(1, request[0]); |
294 error->SetAt(2, err); | 275 error->SetAt(2, err); |
295 return error; | 276 return error; |
296 } | 277 } |
297 // TODO(ajohnsen): Consider returning the first few results. | 278 // TODO(ajohnsen): Consider returning the first few results. |
298 return new CObjectIntptr( | 279 return new CObjectIntptr( |
299 CObject::NewIntptr(reinterpret_cast<intptr_t>(dir_listing))); | 280 CObject::NewIntptr(reinterpret_cast<intptr_t>(dir_listing))); |
300 } | 281 } |
301 return CreateIllegalArgumentError(); | 282 return CreateIllegalArgumentError(); |
302 } | 283 } |
303 | 284 |
304 | |
305 CObject* Directory::ListNextRequest(const CObjectArray& request) { | 285 CObject* Directory::ListNextRequest(const CObjectArray& request) { |
306 if ((request.Length() == 1) && request[0]->IsIntptr()) { | 286 if ((request.Length() == 1) && request[0]->IsIntptr()) { |
307 CObjectIntptr ptr(request[0]); | 287 CObjectIntptr ptr(request[0]); |
308 AsyncDirectoryListing* dir_listing = | 288 AsyncDirectoryListing* dir_listing = |
309 reinterpret_cast<AsyncDirectoryListing*>(ptr.Value()); | 289 reinterpret_cast<AsyncDirectoryListing*>(ptr.Value()); |
310 RefCntReleaseScope<AsyncDirectoryListing> rs(dir_listing); | 290 RefCntReleaseScope<AsyncDirectoryListing> rs(dir_listing); |
311 if (dir_listing->IsEmpty()) { | 291 if (dir_listing->IsEmpty()) { |
312 return new CObjectArray(CObject::NewArray(0)); | 292 return new CObjectArray(CObject::NewArray(0)); |
313 } | 293 } |
314 const int kArraySize = 128; | 294 const int kArraySize = 128; |
315 CObjectArray* response = new CObjectArray(CObject::NewArray(kArraySize)); | 295 CObjectArray* response = new CObjectArray(CObject::NewArray(kArraySize)); |
316 dir_listing->SetArray(response, kArraySize); | 296 dir_listing->SetArray(response, kArraySize); |
317 Directory::List(dir_listing); | 297 Directory::List(dir_listing); |
318 // In case the listing ended before it hit the buffer length, we need to | 298 // In case the listing ended before it hit the buffer length, we need to |
319 // override the array length. | 299 // override the array length. |
320 response->AsApiCObject()->value.as_array.length = dir_listing->index(); | 300 response->AsApiCObject()->value.as_array.length = dir_listing->index(); |
321 return response; | 301 return response; |
322 } | 302 } |
323 return CreateIllegalArgumentError(); | 303 return CreateIllegalArgumentError(); |
324 } | 304 } |
325 | 305 |
326 | |
327 CObject* Directory::ListStopRequest(const CObjectArray& request) { | 306 CObject* Directory::ListStopRequest(const CObjectArray& request) { |
328 if ((request.Length() == 1) && request[0]->IsIntptr()) { | 307 if ((request.Length() == 1) && request[0]->IsIntptr()) { |
329 CObjectIntptr ptr(request[0]); | 308 CObjectIntptr ptr(request[0]); |
330 AsyncDirectoryListing* dir_listing = | 309 AsyncDirectoryListing* dir_listing = |
331 reinterpret_cast<AsyncDirectoryListing*>(ptr.Value()); | 310 reinterpret_cast<AsyncDirectoryListing*>(ptr.Value()); |
332 RefCntReleaseScope<AsyncDirectoryListing> rs(dir_listing); | 311 RefCntReleaseScope<AsyncDirectoryListing> rs(dir_listing); |
333 | 312 |
334 // We have retained a reference to the listing here. Therefore the listing's | 313 // We have retained a reference to the listing here. Therefore the listing's |
335 // destructor can't be running. Since no further requests are dispatched by | 314 // destructor can't be running. Since no further requests are dispatched by |
336 // the Dart code after an async stop call, this PopAll() can't be racing | 315 // the Dart code after an async stop call, this PopAll() can't be racing |
337 // with any other call on the listing. We don't do an extra Release(), and | 316 // with any other call on the listing. We don't do an extra Release(), and |
338 // we don't delete the weak persistent handle. The file is closed here, but | 317 // we don't delete the weak persistent handle. The file is closed here, but |
339 // the memory for the listing will be cleaned up when the finalizer runs. | 318 // the memory for the listing will be cleaned up when the finalizer runs. |
340 dir_listing->PopAll(); | 319 dir_listing->PopAll(); |
341 return new CObjectBool(CObject::Bool(true)); | 320 return new CObjectBool(CObject::Bool(true)); |
342 } | 321 } |
343 return CreateIllegalArgumentError(); | 322 return CreateIllegalArgumentError(); |
344 } | 323 } |
345 | 324 |
346 | |
347 CObject* Directory::RenameRequest(const CObjectArray& request) { | 325 CObject* Directory::RenameRequest(const CObjectArray& request) { |
348 if ((request.Length() == 2) && request[0]->IsString() && | 326 if ((request.Length() == 2) && request[0]->IsString() && |
349 request[1]->IsString()) { | 327 request[1]->IsString()) { |
350 CObjectString path(request[0]); | 328 CObjectString path(request[0]); |
351 CObjectString new_path(request[1]); | 329 CObjectString new_path(request[1]); |
352 bool completed = Directory::Rename(path.CString(), new_path.CString()); | 330 bool completed = Directory::Rename(path.CString(), new_path.CString()); |
353 if (completed) { | 331 if (completed) { |
354 return CObject::True(); | 332 return CObject::True(); |
355 } | 333 } |
356 return CObject::NewOSError(); | 334 return CObject::NewOSError(); |
357 } | 335 } |
358 return CObject::IllegalArgumentError(); | 336 return CObject::IllegalArgumentError(); |
359 } | 337 } |
360 | 338 |
361 | |
362 bool AsyncDirectoryListing::AddFileSystemEntityToResponse(Response type, | 339 bool AsyncDirectoryListing::AddFileSystemEntityToResponse(Response type, |
363 const char* arg) { | 340 const char* arg) { |
364 array_->SetAt(index_++, new CObjectInt32(CObject::NewInt32(type))); | 341 array_->SetAt(index_++, new CObjectInt32(CObject::NewInt32(type))); |
365 if (arg != NULL) { | 342 if (arg != NULL) { |
366 array_->SetAt(index_++, new CObjectString(CObject::NewString(arg))); | 343 array_->SetAt(index_++, new CObjectString(CObject::NewString(arg))); |
367 } else { | 344 } else { |
368 array_->SetAt(index_++, CObject::Null()); | 345 array_->SetAt(index_++, CObject::Null()); |
369 } | 346 } |
370 return index_ < length_; | 347 return index_ < length_; |
371 } | 348 } |
372 | 349 |
373 | |
374 bool AsyncDirectoryListing::HandleDirectory(const char* dir_name) { | 350 bool AsyncDirectoryListing::HandleDirectory(const char* dir_name) { |
375 return AddFileSystemEntityToResponse(kListDirectory, dir_name); | 351 return AddFileSystemEntityToResponse(kListDirectory, dir_name); |
376 } | 352 } |
377 | 353 |
378 | |
379 bool AsyncDirectoryListing::HandleFile(const char* file_name) { | 354 bool AsyncDirectoryListing::HandleFile(const char* file_name) { |
380 return AddFileSystemEntityToResponse(kListFile, file_name); | 355 return AddFileSystemEntityToResponse(kListFile, file_name); |
381 } | 356 } |
382 | 357 |
383 | |
384 bool AsyncDirectoryListing::HandleLink(const char* link_name) { | 358 bool AsyncDirectoryListing::HandleLink(const char* link_name) { |
385 return AddFileSystemEntityToResponse(kListLink, link_name); | 359 return AddFileSystemEntityToResponse(kListLink, link_name); |
386 } | 360 } |
387 | 361 |
388 | |
389 void AsyncDirectoryListing::HandleDone() { | 362 void AsyncDirectoryListing::HandleDone() { |
390 AddFileSystemEntityToResponse(kListDone, NULL); | 363 AddFileSystemEntityToResponse(kListDone, NULL); |
391 } | 364 } |
392 | 365 |
393 | |
394 bool AsyncDirectoryListing::HandleError() { | 366 bool AsyncDirectoryListing::HandleError() { |
395 CObject* err = CObject::NewOSError(); | 367 CObject* err = CObject::NewOSError(); |
396 array_->SetAt(index_++, new CObjectInt32(CObject::NewInt32(kListError))); | 368 array_->SetAt(index_++, new CObjectInt32(CObject::NewInt32(kListError))); |
397 CObjectArray* response = new CObjectArray(CObject::NewArray(3)); | 369 CObjectArray* response = new CObjectArray(CObject::NewArray(3)); |
398 response->SetAt(0, new CObjectInt32(CObject::NewInt32(kListError))); | 370 response->SetAt(0, new CObjectInt32(CObject::NewInt32(kListError))); |
399 // Delay calling CurrentPath() until after CObject::NewOSError() in case | 371 // Delay calling CurrentPath() until after CObject::NewOSError() in case |
400 // CurrentPath() pollutes the OS error code. | 372 // CurrentPath() pollutes the OS error code. |
401 response->SetAt(1, new CObjectString(CObject::NewString( | 373 response->SetAt(1, new CObjectString(CObject::NewString( |
402 error() ? "Invalid path" : CurrentPath()))); | 374 error() ? "Invalid path" : CurrentPath()))); |
403 response->SetAt(2, err); | 375 response->SetAt(2, err); |
404 array_->SetAt(index_++, response); | 376 array_->SetAt(index_++, response); |
405 return index_ < length_; | 377 return index_ < length_; |
406 } | 378 } |
407 | 379 |
408 | |
409 bool SyncDirectoryListing::HandleDirectory(const char* dir_name) { | 380 bool SyncDirectoryListing::HandleDirectory(const char* dir_name) { |
410 Dart_Handle dir_name_dart = DartUtils::NewString(dir_name); | 381 Dart_Handle dir_name_dart = DartUtils::NewString(dir_name); |
411 Dart_Handle dir = Dart_New(directory_type_, Dart_Null(), 1, &dir_name_dart); | 382 Dart_Handle dir = Dart_New(directory_type_, Dart_Null(), 1, &dir_name_dart); |
412 Dart_Handle result = Dart_Invoke(results_, add_string_, 1, &dir); | 383 Dart_Handle result = Dart_Invoke(results_, add_string_, 1, &dir); |
413 if (Dart_IsError(result)) { | 384 if (Dart_IsError(result)) { |
414 dart_error_ = result; | 385 dart_error_ = result; |
415 return false; | 386 return false; |
416 } | 387 } |
417 return true; | 388 return true; |
418 } | 389 } |
419 | 390 |
420 | |
421 bool SyncDirectoryListing::HandleLink(const char* link_name) { | 391 bool SyncDirectoryListing::HandleLink(const char* link_name) { |
422 Dart_Handle link_name_dart = DartUtils::NewString(link_name); | 392 Dart_Handle link_name_dart = DartUtils::NewString(link_name); |
423 Dart_Handle link = Dart_New(link_type_, Dart_Null(), 1, &link_name_dart); | 393 Dart_Handle link = Dart_New(link_type_, Dart_Null(), 1, &link_name_dart); |
424 Dart_Handle result = Dart_Invoke(results_, add_string_, 1, &link); | 394 Dart_Handle result = Dart_Invoke(results_, add_string_, 1, &link); |
425 if (Dart_IsError(result)) { | 395 if (Dart_IsError(result)) { |
426 dart_error_ = result; | 396 dart_error_ = result; |
427 return false; | 397 return false; |
428 } | 398 } |
429 return true; | 399 return true; |
430 } | 400 } |
431 | 401 |
432 | |
433 bool SyncDirectoryListing::HandleFile(const char* file_name) { | 402 bool SyncDirectoryListing::HandleFile(const char* file_name) { |
434 Dart_Handle file_name_dart = DartUtils::NewString(file_name); | 403 Dart_Handle file_name_dart = DartUtils::NewString(file_name); |
435 Dart_Handle file = Dart_New(file_type_, Dart_Null(), 1, &file_name_dart); | 404 Dart_Handle file = Dart_New(file_type_, Dart_Null(), 1, &file_name_dart); |
436 Dart_Handle result = Dart_Invoke(results_, add_string_, 1, &file); | 405 Dart_Handle result = Dart_Invoke(results_, add_string_, 1, &file); |
437 if (Dart_IsError(result)) { | 406 if (Dart_IsError(result)) { |
438 dart_error_ = result; | 407 dart_error_ = result; |
439 return false; | 408 return false; |
440 } | 409 } |
441 return true; | 410 return true; |
442 } | 411 } |
443 | 412 |
444 | |
445 bool SyncDirectoryListing::HandleError() { | 413 bool SyncDirectoryListing::HandleError() { |
446 Dart_Handle dart_os_error = DartUtils::NewDartOSError(); | 414 Dart_Handle dart_os_error = DartUtils::NewDartOSError(); |
447 Dart_Handle args[3]; | 415 Dart_Handle args[3]; |
448 args[0] = DartUtils::NewString("Directory listing failed"); | 416 args[0] = DartUtils::NewString("Directory listing failed"); |
449 args[1] = DartUtils::NewString(error() ? "Invalid path" : CurrentPath()); | 417 args[1] = DartUtils::NewString(error() ? "Invalid path" : CurrentPath()); |
450 args[2] = dart_os_error; | 418 args[2] = dart_os_error; |
451 | 419 |
452 dart_error_ = Dart_New( | 420 dart_error_ = Dart_New( |
453 DartUtils::GetDartType(DartUtils::kIOLibURL, "FileSystemException"), | 421 DartUtils::GetDartType(DartUtils::kIOLibURL, "FileSystemException"), |
454 Dart_Null(), 3, args); | 422 Dart_Null(), 3, args); |
455 return false; | 423 return false; |
456 } | 424 } |
457 | 425 |
458 | |
459 static bool ListNext(DirectoryListing* listing) { | 426 static bool ListNext(DirectoryListing* listing) { |
460 switch (listing->top()->Next(listing)) { | 427 switch (listing->top()->Next(listing)) { |
461 case kListFile: | 428 case kListFile: |
462 return listing->HandleFile(listing->CurrentPath()); | 429 return listing->HandleFile(listing->CurrentPath()); |
463 | 430 |
464 case kListLink: | 431 case kListLink: |
465 return listing->HandleLink(listing->CurrentPath()); | 432 return listing->HandleLink(listing->CurrentPath()); |
466 | 433 |
467 case kListDirectory: | 434 case kListDirectory: |
468 if (listing->recursive()) { | 435 if (listing->recursive()) { |
(...skipping 12 matching lines...) Expand all Loading... |
481 } else { | 448 } else { |
482 return true; | 449 return true; |
483 } | 450 } |
484 | 451 |
485 default: | 452 default: |
486 UNREACHABLE(); | 453 UNREACHABLE(); |
487 } | 454 } |
488 return false; | 455 return false; |
489 } | 456 } |
490 | 457 |
491 | |
492 void Directory::List(DirectoryListing* listing) { | 458 void Directory::List(DirectoryListing* listing) { |
493 if (listing->error()) { | 459 if (listing->error()) { |
494 listing->HandleError(); | 460 listing->HandleError(); |
495 listing->HandleDone(); | 461 listing->HandleDone(); |
496 } else { | 462 } else { |
497 while (ListNext(listing)) { | 463 while (ListNext(listing)) { |
498 } | 464 } |
499 } | 465 } |
500 } | 466 } |
501 | 467 |
502 } // namespace bin | 468 } // namespace bin |
503 } // namespace dart | 469 } // namespace dart |
504 | 470 |
505 #endif // !defined(DART_IO_DISABLED) | 471 #endif // !defined(DART_IO_DISABLED) |
OLD | NEW |