| 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 |