| 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 "include/dart_api.h" | 11 #include "include/dart_api.h" |
| 11 #include "platform/assert.h" | 12 #include "platform/assert.h" |
| 12 | 13 |
| 13 namespace dart { | 14 namespace dart { |
| 14 namespace bin { | 15 namespace bin { |
| 15 | 16 |
| 16 void FUNCTION_NAME(Directory_Current)(Dart_NativeArguments args) { | 17 void FUNCTION_NAME(Directory_Current)(Dart_NativeArguments args) { |
| 17 const char* current = Directory::Current(); | 18 const char* current = Directory::Current(); |
| 18 if (current != NULL) { | 19 if (current != NULL) { |
| 19 Dart_SetReturnValue(args, DartUtils::NewString(current)); | 20 Dart_SetReturnValue(args, DartUtils::NewString(current)); |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 132 } | 133 } |
| 133 SyncDirectoryListing sync_listing(results, | 134 SyncDirectoryListing sync_listing(results, |
| 134 DartUtils::GetStringValue(path), | 135 DartUtils::GetStringValue(path), |
| 135 DartUtils::GetBooleanValue(recursive), | 136 DartUtils::GetBooleanValue(recursive), |
| 136 DartUtils::GetBooleanValue(follow_links)); | 137 DartUtils::GetBooleanValue(follow_links)); |
| 137 Directory::List(&sync_listing); | 138 Directory::List(&sync_listing); |
| 138 Dart_SetReturnValue(args, results); | 139 Dart_SetReturnValue(args, results); |
| 139 } | 140 } |
| 140 | 141 |
| 141 | 142 |
| 143 static const int kAsyncDirectoryListerFieldIndex = 0; |
| 144 |
| 145 |
| 146 void FUNCTION_NAME(Directory_GetAsyncDirectoryListerPointer)( |
| 147 Dart_NativeArguments args) { |
| 148 AsyncDirectoryListing* listing; |
| 149 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); |
| 150 ASSERT(Dart_IsInstance(dart_this)); |
| 151 ThrowIfError(Dart_GetNativeInstanceField( |
| 152 dart_this, |
| 153 kAsyncDirectoryListerFieldIndex, |
| 154 reinterpret_cast<intptr_t*>(&listing))); |
| 155 if (listing != NULL) { |
| 156 intptr_t listing_pointer = reinterpret_cast<intptr_t>(listing); |
| 157 // Increment the listing's reference count. This native should only be |
| 158 // be called when we are about to send the AsyncDirectoryListing* to the |
| 159 // IO service. |
| 160 listing->Retain(); |
| 161 Dart_SetReturnValue(args, Dart_NewInteger(listing_pointer)); |
| 162 } |
| 163 } |
| 164 |
| 165 |
| 166 static void ReleaseListing(void* isolate_callback_data, |
| 167 Dart_WeakPersistentHandle handle, |
| 168 void* peer) { |
| 169 AsyncDirectoryListing* listing = |
| 170 reinterpret_cast<AsyncDirectoryListing*>(peer); |
| 171 listing->Release(); |
| 172 } |
| 173 |
| 174 |
| 175 void FUNCTION_NAME(Directory_SetAsyncDirectoryListerPointer)( |
| 176 Dart_NativeArguments args) { |
| 177 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); |
| 178 intptr_t listing_pointer = |
| 179 DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 1)); |
| 180 AsyncDirectoryListing* listing = |
| 181 reinterpret_cast<AsyncDirectoryListing*>(listing_pointer); |
| 182 Dart_NewWeakPersistentHandle( |
| 183 dart_this, |
| 184 reinterpret_cast<void*>(listing), |
| 185 sizeof(*listing), |
| 186 ReleaseListing); |
| 187 Dart_Handle result = Dart_SetNativeInstanceField( |
| 188 dart_this, |
| 189 kAsyncDirectoryListerFieldIndex, |
| 190 listing_pointer); |
| 191 if (Dart_IsError(result)) { |
| 192 Log::PrintErr("SetAsyncDirectoryListerPointer failed\n"); |
| 193 Dart_PropagateError(result); |
| 194 } |
| 195 } |
| 196 |
| 197 |
| 142 CObject* Directory::CreateRequest(const CObjectArray& request) { | 198 CObject* Directory::CreateRequest(const CObjectArray& request) { |
| 143 if ((request.Length() == 1) && request[0]->IsString()) { | 199 if ((request.Length() == 1) && request[0]->IsString()) { |
| 144 CObjectString path(request[0]); | 200 CObjectString path(request[0]); |
| 145 if (Directory::Create(path.CString())) { | 201 if (Directory::Create(path.CString())) { |
| 146 return CObject::True(); | 202 return CObject::True(); |
| 147 } else { | 203 } else { |
| 148 return CObject::NewOSError(); | 204 return CObject::NewOSError(); |
| 149 } | 205 } |
| 150 } | 206 } |
| 151 return CObject::IllegalArgumentError(); | 207 return CObject::IllegalArgumentError(); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 219 CObjectString path(request[0]); | 275 CObjectString path(request[0]); |
| 220 CObjectBool recursive(request[1]); | 276 CObjectBool recursive(request[1]); |
| 221 CObjectBool follow_links(request[2]); | 277 CObjectBool follow_links(request[2]); |
| 222 AsyncDirectoryListing* dir_listing = | 278 AsyncDirectoryListing* dir_listing = |
| 223 new AsyncDirectoryListing(path.CString(), | 279 new AsyncDirectoryListing(path.CString(), |
| 224 recursive.Value(), | 280 recursive.Value(), |
| 225 follow_links.Value()); | 281 follow_links.Value()); |
| 226 if (dir_listing->error()) { | 282 if (dir_listing->error()) { |
| 227 // Report error now, so we capture the correct OSError. | 283 // Report error now, so we capture the correct OSError. |
| 228 CObject* err = CObject::NewOSError(); | 284 CObject* err = CObject::NewOSError(); |
| 229 delete dir_listing; | 285 dir_listing->Release(); |
| 230 CObjectArray* error = new CObjectArray(CObject::NewArray(3)); | 286 CObjectArray* error = new CObjectArray(CObject::NewArray(3)); |
| 231 error->SetAt(0, new CObjectInt32( | 287 error->SetAt(0, new CObjectInt32( |
| 232 CObject::NewInt32(AsyncDirectoryListing::kListError))); | 288 CObject::NewInt32(AsyncDirectoryListing::kListError))); |
| 233 error->SetAt(1, request[0]); | 289 error->SetAt(1, request[0]); |
| 234 error->SetAt(2, err); | 290 error->SetAt(2, err); |
| 235 return error; | 291 return error; |
| 236 } | 292 } |
| 237 // TODO(ajohnsen): Consider returning the first few results. | 293 // TODO(ajohnsen): Consider returning the first few results. |
| 238 return new CObjectIntptr(CObject::NewIntptr( | 294 return new CObjectIntptr(CObject::NewIntptr( |
| 239 reinterpret_cast<intptr_t>(dir_listing))); | 295 reinterpret_cast<intptr_t>(dir_listing))); |
| 240 } | 296 } |
| 241 return CreateIllegalArgumentError(); | 297 return CreateIllegalArgumentError(); |
| 242 } | 298 } |
| 243 | 299 |
| 244 | 300 |
| 245 CObject* Directory::ListNextRequest(const CObjectArray& request) { | 301 CObject* Directory::ListNextRequest(const CObjectArray& request) { |
| 246 if ((request.Length() == 1) && request[0]->IsIntptr()) { | 302 if ((request.Length() == 1) && request[0]->IsIntptr()) { |
| 247 CObjectIntptr ptr(request[0]); | 303 CObjectIntptr ptr(request[0]); |
| 248 AsyncDirectoryListing* dir_listing = | 304 AsyncDirectoryListing* dir_listing = |
| 249 reinterpret_cast<AsyncDirectoryListing*>(ptr.Value()); | 305 reinterpret_cast<AsyncDirectoryListing*>(ptr.Value()); |
| 306 RefCntReleaseScope<AsyncDirectoryListing> rs(dir_listing); |
| 250 if (dir_listing->IsEmpty()) { | 307 if (dir_listing->IsEmpty()) { |
| 251 return new CObjectArray(CObject::NewArray(0)); | 308 return new CObjectArray(CObject::NewArray(0)); |
| 252 } | 309 } |
| 253 const int kArraySize = 128; | 310 const int kArraySize = 128; |
| 254 CObjectArray* response = new CObjectArray(CObject::NewArray(kArraySize)); | 311 CObjectArray* response = new CObjectArray(CObject::NewArray(kArraySize)); |
| 255 dir_listing->SetArray(response, kArraySize); | 312 dir_listing->SetArray(response, kArraySize); |
| 256 Directory::List(dir_listing); | 313 Directory::List(dir_listing); |
| 257 // In case the listing ended before it hit the buffer length, we need to | 314 // In case the listing ended before it hit the buffer length, we need to |
| 258 // override the array length. | 315 // override the array length. |
| 259 response->AsApiCObject()->value.as_array.length = dir_listing->index(); | 316 response->AsApiCObject()->value.as_array.length = dir_listing->index(); |
| 260 return response; | 317 return response; |
| 261 } | 318 } |
| 262 return CreateIllegalArgumentError(); | 319 return CreateIllegalArgumentError(); |
| 263 } | 320 } |
| 264 | 321 |
| 265 | 322 |
| 266 CObject* Directory::ListStopRequest(const CObjectArray& request) { | 323 CObject* Directory::ListStopRequest(const CObjectArray& request) { |
| 267 if ((request.Length() == 1) && request[0]->IsIntptr()) { | 324 if ((request.Length() == 1) && request[0]->IsIntptr()) { |
| 268 CObjectIntptr ptr(request[0]); | 325 CObjectIntptr ptr(request[0]); |
| 269 AsyncDirectoryListing* dir_listing = | 326 AsyncDirectoryListing* dir_listing = |
| 270 reinterpret_cast<AsyncDirectoryListing*>(ptr.Value()); | 327 reinterpret_cast<AsyncDirectoryListing*>(ptr.Value()); |
| 271 delete dir_listing; | 328 RefCntReleaseScope<AsyncDirectoryListing> rs(dir_listing); |
| 329 |
| 330 // We have retained a reference to the listing here. Therefore the listing's |
| 331 // destructor can't be running. Since no further requests are dispatched by |
| 332 // the Dart code after an async stop call, this PopAll() can't be racing |
| 333 // with any other call on the listing. We don't do an extra Release(), and |
| 334 // we don't delete the weak persistent handle. The file is closed here, but |
| 335 // the memory for the listing will be cleaned up when the finalizer runs. |
| 336 dir_listing->PopAll(); |
| 272 return new CObjectBool(CObject::Bool(true)); | 337 return new CObjectBool(CObject::Bool(true)); |
| 273 } | 338 } |
| 274 return CreateIllegalArgumentError(); | 339 return CreateIllegalArgumentError(); |
| 275 } | 340 } |
| 276 | 341 |
| 277 | 342 |
| 278 CObject* Directory::RenameRequest(const CObjectArray& request) { | 343 CObject* Directory::RenameRequest(const CObjectArray& request) { |
| 279 if ((request.Length() == 2) && | 344 if ((request.Length() == 2) && |
| 280 request[0]->IsString() && | 345 request[0]->IsString() && |
| 281 request[1]->IsString()) { | 346 request[1]->IsString()) { |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 419 listing->HandleDone(); | 484 listing->HandleDone(); |
| 420 } else { | 485 } else { |
| 421 while (ListNext(listing)) {} | 486 while (ListNext(listing)) {} |
| 422 } | 487 } |
| 423 } | 488 } |
| 424 | 489 |
| 425 } // namespace bin | 490 } // namespace bin |
| 426 } // namespace dart | 491 } // namespace dart |
| 427 | 492 |
| 428 #endif // !defined(DART_IO_DISABLED) | 493 #endif // !defined(DART_IO_DISABLED) |
| OLD | NEW |