| 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 #include "bin/directory.h" | 5 #include "bin/directory.h" |
| 6 | 6 |
| 7 #include "bin/dartutils.h" | 7 #include "bin/dartutils.h" |
| 8 #include "bin/thread.h" | 8 #include "bin/thread.h" |
| 9 #include "include/dart_api.h" | 9 #include "include/dart_api.h" |
| 10 #include "platform/assert.h" | 10 #include "platform/assert.h" |
| 11 | 11 |
| 12 | 12 |
| 13 namespace dart { | 13 namespace dart { |
| 14 namespace bin { | 14 namespace bin { |
| 15 | 15 |
| 16 // Forward declaration. | |
| 17 static void DirectoryService(Dart_Port, Dart_Port, Dart_CObject*); | |
| 18 | |
| 19 NativeService Directory::directory_service_("DirectoryService", | |
| 20 DirectoryService, | |
| 21 16); | |
| 22 | |
| 23 | |
| 24 void FUNCTION_NAME(Directory_Current)(Dart_NativeArguments args) { | 16 void FUNCTION_NAME(Directory_Current)(Dart_NativeArguments args) { |
| 25 char* current = Directory::Current(); | 17 char* current = Directory::Current(); |
| 26 if (current != NULL) { | 18 if (current != NULL) { |
| 27 Dart_SetReturnValue(args, DartUtils::NewString(current)); | 19 Dart_SetReturnValue(args, DartUtils::NewString(current)); |
| 28 free(current); | 20 free(current); |
| 29 } else { | 21 } else { |
| 30 Dart_Handle err = DartUtils::NewDartOSError(); | 22 Dart_Handle err = DartUtils::NewDartOSError(); |
| 31 if (Dart_IsError(err)) Dart_PropagateError(err); | 23 if (Dart_IsError(err)) Dart_PropagateError(err); |
| 32 Dart_SetReturnValue(args, err); | 24 Dart_SetReturnValue(args, err); |
| 33 } | 25 } |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 141 NULL); | 133 NULL); |
| 142 SyncDirectoryListing sync_listing(results, | 134 SyncDirectoryListing sync_listing(results, |
| 143 DartUtils::GetStringValue(path), | 135 DartUtils::GetStringValue(path), |
| 144 DartUtils::GetBooleanValue(recursive), | 136 DartUtils::GetBooleanValue(recursive), |
| 145 DartUtils::GetBooleanValue(follow_links)); | 137 DartUtils::GetBooleanValue(follow_links)); |
| 146 Directory::List(&sync_listing); | 138 Directory::List(&sync_listing); |
| 147 Dart_SetReturnValue(args, results); | 139 Dart_SetReturnValue(args, results); |
| 148 } | 140 } |
| 149 | 141 |
| 150 | 142 |
| 151 static CObject* DirectoryCreateRequest(const CObjectArray& request) { | 143 CObject* Directory::CreateRequest(const CObjectArray& request) { |
| 152 if (request.Length() == 2 && request[1]->IsString()) { | 144 if (request.Length() == 1 && request[0]->IsString()) { |
| 153 CObjectString path(request[1]); | 145 CObjectString path(request[0]); |
| 154 if (Directory::Create(path.CString())) { | 146 if (Directory::Create(path.CString())) { |
| 155 return CObject::True(); | 147 return CObject::True(); |
| 156 } else { | 148 } else { |
| 157 return CObject::NewOSError(); | 149 return CObject::NewOSError(); |
| 158 } | 150 } |
| 159 } | 151 } |
| 160 return CObject::IllegalArgumentError(); | 152 return CObject::IllegalArgumentError(); |
| 161 } | 153 } |
| 162 | 154 |
| 163 | 155 |
| 164 static CObject* DirectoryDeleteRequest(const CObjectArray& request) { | 156 CObject* Directory::DeleteRequest(const CObjectArray& request) { |
| 165 if (request.Length() == 3 && request[1]->IsString() && request[2]->IsBool()) { | 157 if (request.Length() == 2 && request[0]->IsString() && request[1]->IsBool()) { |
| 166 CObjectString path(request[1]); | 158 CObjectString path(request[0]); |
| 167 CObjectBool recursive(request[2]); | 159 CObjectBool recursive(request[1]); |
| 168 if (Directory::Delete(path.CString(), recursive.Value())) { | 160 if (Directory::Delete(path.CString(), recursive.Value())) { |
| 169 return CObject::True(); | 161 return CObject::True(); |
| 170 } else { | 162 } else { |
| 171 return CObject::NewOSError(); | 163 return CObject::NewOSError(); |
| 172 } | 164 } |
| 173 } | 165 } |
| 174 return CObject::IllegalArgumentError(); | 166 return CObject::IllegalArgumentError(); |
| 175 } | 167 } |
| 176 | 168 |
| 177 | 169 |
| 178 static CObject* DirectoryExistsRequest(const CObjectArray& request) { | 170 CObject* Directory::ExistsRequest(const CObjectArray& request) { |
| 179 static const int kExists = 1; | 171 static const int kExists = 1; |
| 180 static const int kDoesNotExist = 0; | 172 static const int kDoesNotExist = 0; |
| 181 if (request.Length() == 2 && request[1]->IsString()) { | 173 if (request.Length() == 1 && request[0]->IsString()) { |
| 182 CObjectString path(request[1]); | 174 CObjectString path(request[0]); |
| 183 Directory::ExistsResult result = Directory::Exists(path.CString()); | 175 Directory::ExistsResult result = Directory::Exists(path.CString()); |
| 184 if (result == Directory::EXISTS) { | 176 if (result == Directory::EXISTS) { |
| 185 return new CObjectInt32(CObject::NewInt32(kExists)); | 177 return new CObjectInt32(CObject::NewInt32(kExists)); |
| 186 } else if (result == Directory::DOES_NOT_EXIST) { | 178 } else if (result == Directory::DOES_NOT_EXIST) { |
| 187 return new CObjectInt32(CObject::NewInt32(kDoesNotExist)); | 179 return new CObjectInt32(CObject::NewInt32(kDoesNotExist)); |
| 188 } else { | 180 } else { |
| 189 return CObject::NewOSError(); | 181 return CObject::NewOSError(); |
| 190 } | 182 } |
| 191 } | 183 } |
| 192 return CObject::IllegalArgumentError(); | 184 return CObject::IllegalArgumentError(); |
| 193 } | 185 } |
| 194 | 186 |
| 195 | 187 |
| 196 static CObject* DirectoryCreateTempRequest(const CObjectArray& request) { | 188 CObject* Directory::CreateTempRequest(const CObjectArray& request) { |
| 197 if (request.Length() == 2 && request[1]->IsString()) { | 189 if (request.Length() == 1 && request[0]->IsString()) { |
| 198 CObjectString path(request[1]); | 190 CObjectString path(request[0]); |
| 199 char* result = Directory::CreateTemp(path.CString()); | 191 char* result = Directory::CreateTemp(path.CString()); |
| 200 if (result != NULL) { | 192 if (result != NULL) { |
| 201 CObject* temp_dir = new CObjectString(CObject::NewString(result)); | 193 CObject* temp_dir = new CObjectString(CObject::NewString(result)); |
| 202 free(result); | 194 free(result); |
| 203 return temp_dir; | 195 return temp_dir; |
| 204 } else { | 196 } else { |
| 205 return CObject::NewOSError(); | 197 return CObject::NewOSError(); |
| 206 } | 198 } |
| 207 } | 199 } |
| 208 return CObject::IllegalArgumentError(); | 200 return CObject::IllegalArgumentError(); |
| 209 } | 201 } |
| 210 | 202 |
| 211 static CObject* CreateIllegalArgumentError() { | 203 static CObject* CreateIllegalArgumentError() { |
| 212 // Respond with an illegal argument list error message. | 204 // Respond with an illegal argument list error message. |
| 213 CObjectArray* error = new CObjectArray(CObject::NewArray(3)); | 205 CObjectArray* error = new CObjectArray(CObject::NewArray(3)); |
| 214 error->SetAt(0, new CObjectInt32( | 206 error->SetAt(0, new CObjectInt32( |
| 215 CObject::NewInt32(AsyncDirectoryListing::kListError))); | 207 CObject::NewInt32(AsyncDirectoryListing::kListError))); |
| 216 error->SetAt(1, CObject::Null()); | 208 error->SetAt(1, CObject::Null()); |
| 217 error->SetAt(2, CObject::IllegalArgumentError()); | 209 error->SetAt(2, CObject::IllegalArgumentError()); |
| 218 return error; | 210 return error; |
| 219 } | 211 } |
| 220 | 212 |
| 221 static CObject* DirectoryListStartRequest(const CObjectArray& request) { | 213 CObject* Directory::ListStartRequest(const CObjectArray& request) { |
| 222 if (request.Length() == 4 && | 214 if (request.Length() == 3 && |
| 223 request[1]->IsString() && | 215 request[0]->IsString() && |
| 224 request[2]->IsBool() && | 216 request[1]->IsBool() && |
| 225 request[3]->IsBool()) { | 217 request[2]->IsBool()) { |
| 226 CObjectString path(request[1]); | 218 CObjectString path(request[0]); |
| 227 CObjectBool recursive(request[2]); | 219 CObjectBool recursive(request[1]); |
| 228 CObjectBool follow_links(request[3]); | 220 CObjectBool follow_links(request[2]); |
| 229 AsyncDirectoryListing* dir_listing = | 221 AsyncDirectoryListing* dir_listing = |
| 230 new AsyncDirectoryListing(path.CString(), | 222 new AsyncDirectoryListing(path.CString(), |
| 231 recursive.Value(), | 223 recursive.Value(), |
| 232 follow_links.Value()); | 224 follow_links.Value()); |
| 233 if (dir_listing->error()) { | 225 if (dir_listing->error()) { |
| 234 // Report error now, so we capture the correct OSError. | 226 // Report error now, so we capture the correct OSError. |
| 235 CObject* err = CObject::NewOSError(); | 227 CObject* err = CObject::NewOSError(); |
| 236 delete dir_listing; | 228 delete dir_listing; |
| 237 CObjectArray* error = new CObjectArray(CObject::NewArray(3)); | 229 CObjectArray* error = new CObjectArray(CObject::NewArray(3)); |
| 238 error->SetAt(0, new CObjectInt32( | 230 error->SetAt(0, new CObjectInt32( |
| 239 CObject::NewInt32(AsyncDirectoryListing::kListError))); | 231 CObject::NewInt32(AsyncDirectoryListing::kListError))); |
| 240 error->SetAt(1, request[1]); | 232 error->SetAt(1, request[0]); |
| 241 error->SetAt(2, err); | 233 error->SetAt(2, err); |
| 242 return error; | 234 return error; |
| 243 } | 235 } |
| 244 // TODO(ajohnsen): Consider returning the first few results. | 236 // TODO(ajohnsen): Consider returning the first few results. |
| 245 return new CObjectIntptr(CObject::NewIntptr( | 237 return new CObjectIntptr(CObject::NewIntptr( |
| 246 reinterpret_cast<intptr_t>(dir_listing))); | 238 reinterpret_cast<intptr_t>(dir_listing))); |
| 247 } | 239 } |
| 248 return CreateIllegalArgumentError(); | 240 return CreateIllegalArgumentError(); |
| 249 } | 241 } |
| 250 | 242 |
| 251 | 243 |
| 252 static CObject* DirectoryListNextRequest(const CObjectArray& request) { | 244 CObject* Directory::ListNextRequest(const CObjectArray& request) { |
| 253 if (request.Length() == 2 && | 245 if (request.Length() == 1 && |
| 254 request[1]->IsIntptr()) { | 246 request[0]->IsIntptr()) { |
| 255 CObjectIntptr ptr(request[1]); | 247 CObjectIntptr ptr(request[0]); |
| 256 AsyncDirectoryListing* dir_listing = | 248 AsyncDirectoryListing* dir_listing = |
| 257 reinterpret_cast<AsyncDirectoryListing*>(ptr.Value()); | 249 reinterpret_cast<AsyncDirectoryListing*>(ptr.Value()); |
| 258 const int kArraySize = 128; | 250 const int kArraySize = 128; |
| 259 CObjectArray* response = new CObjectArray(CObject::NewArray(kArraySize)); | 251 CObjectArray* response = new CObjectArray(CObject::NewArray(kArraySize)); |
| 260 dir_listing->SetArray(response, kArraySize); | 252 dir_listing->SetArray(response, kArraySize); |
| 261 Directory::List(dir_listing); | 253 Directory::List(dir_listing); |
| 262 // In case the listing ended before it hit the buffer length, we need to | 254 // In case the listing ended before it hit the buffer length, we need to |
| 263 // override the array length. | 255 // override the array length. |
| 264 response->AsApiCObject()->value.as_array.length = dir_listing->index(); | 256 response->AsApiCObject()->value.as_array.length = dir_listing->index(); |
| 265 return response; | 257 return response; |
| 266 } | 258 } |
| 267 return CreateIllegalArgumentError(); | 259 return CreateIllegalArgumentError(); |
| 268 } | 260 } |
| 269 | 261 |
| 270 | 262 |
| 271 static CObject* DirectoryListStopRequest(const CObjectArray& request) { | 263 CObject* Directory::ListStopRequest(const CObjectArray& request) { |
| 272 if (request.Length() == 2 && request[1]->IsIntptr()) { | 264 if (request.Length() == 1 && request[0]->IsIntptr()) { |
| 273 CObjectIntptr ptr(request[1]); | 265 CObjectIntptr ptr(request[0]); |
| 274 AsyncDirectoryListing* dir_listing = | 266 AsyncDirectoryListing* dir_listing = |
| 275 reinterpret_cast<AsyncDirectoryListing*>(ptr.Value()); | 267 reinterpret_cast<AsyncDirectoryListing*>(ptr.Value()); |
| 276 delete dir_listing; | 268 delete dir_listing; |
| 277 return new CObjectBool(CObject::Bool(true)); | 269 return new CObjectBool(CObject::Bool(true)); |
| 278 } | 270 } |
| 279 return CreateIllegalArgumentError(); | 271 return CreateIllegalArgumentError(); |
| 280 } | 272 } |
| 281 | 273 |
| 282 | 274 |
| 283 static CObject* DirectoryRenameRequest(const CObjectArray& request, | 275 CObject* Directory::RenameRequest(const CObjectArray& request) { |
| 284 Dart_Port response_port) { | 276 if (request.Length() == 2 && |
| 285 if (request.Length() == 3 && | 277 request[0]->IsString() && |
| 286 request[1]->IsString() && | 278 request[1]->IsString()) { |
| 287 request[2]->IsString()) { | 279 CObjectString path(request[0]); |
| 288 CObjectString path(request[1]); | 280 CObjectString new_path(request[1]); |
| 289 CObjectString new_path(request[2]); | |
| 290 bool completed = Directory::Rename(path.CString(), new_path.CString()); | 281 bool completed = Directory::Rename(path.CString(), new_path.CString()); |
| 291 if (completed) return CObject::True(); | 282 if (completed) return CObject::True(); |
| 292 return CObject::NewOSError(); | 283 return CObject::NewOSError(); |
| 293 } | 284 } |
| 294 return CObject::IllegalArgumentError(); | 285 return CObject::IllegalArgumentError(); |
| 295 } | 286 } |
| 296 | 287 |
| 297 | 288 |
| 298 static void DirectoryService(Dart_Port dest_port_id, | |
| 299 Dart_Port reply_port_id, | |
| 300 Dart_CObject* message) { | |
| 301 CObject* response = CObject::IllegalArgumentError(); | |
| 302 CObjectArray request(message); | |
| 303 if (message->type == Dart_CObject_kArray) { | |
| 304 if (request.Length() > 1 && request[0]->IsInt32()) { | |
| 305 CObjectInt32 requestType(request[0]); | |
| 306 switch (requestType.Value()) { | |
| 307 case Directory::kCreateRequest: | |
| 308 response = DirectoryCreateRequest(request); | |
| 309 break; | |
| 310 case Directory::kDeleteRequest: | |
| 311 response = DirectoryDeleteRequest(request); | |
| 312 break; | |
| 313 case Directory::kExistsRequest: | |
| 314 response = DirectoryExistsRequest(request); | |
| 315 break; | |
| 316 case Directory::kCreateTempRequest: | |
| 317 response = DirectoryCreateTempRequest(request); | |
| 318 break; | |
| 319 case Directory::kListStartRequest: | |
| 320 response = DirectoryListStartRequest(request); | |
| 321 break; | |
| 322 case Directory::kListNextRequest: | |
| 323 response = DirectoryListNextRequest(request); | |
| 324 break; | |
| 325 case Directory::kListStopRequest: | |
| 326 response = DirectoryListStopRequest(request); | |
| 327 break; | |
| 328 case Directory::kRenameRequest: | |
| 329 response = DirectoryRenameRequest(request, reply_port_id); | |
| 330 break; | |
| 331 default: | |
| 332 UNREACHABLE(); | |
| 333 } | |
| 334 } | |
| 335 } | |
| 336 | |
| 337 Dart_PostCObject(reply_port_id, response->AsApiCObject()); | |
| 338 } | |
| 339 | |
| 340 | |
| 341 Dart_Port Directory::GetServicePort() { | |
| 342 return directory_service_.GetServicePort(); | |
| 343 } | |
| 344 | |
| 345 | |
| 346 void FUNCTION_NAME(Directory_NewServicePort)(Dart_NativeArguments args) { | |
| 347 Dart_SetReturnValue(args, Dart_Null()); | |
| 348 Dart_Port service_port = Directory::GetServicePort(); | |
| 349 if (service_port != ILLEGAL_PORT) { | |
| 350 // Return a send port for the service port. | |
| 351 Dart_Handle send_port = Dart_NewSendPort(service_port); | |
| 352 Dart_SetReturnValue(args, send_port); | |
| 353 } | |
| 354 } | |
| 355 | |
| 356 | |
| 357 bool AsyncDirectoryListing::AddFileSystemEntityToResponse(Response type, | 289 bool AsyncDirectoryListing::AddFileSystemEntityToResponse(Response type, |
| 358 char* arg) { | 290 char* arg) { |
| 359 array_->SetAt(index_++, new CObjectInt32(CObject::NewInt32(type))); | 291 array_->SetAt(index_++, new CObjectInt32(CObject::NewInt32(type))); |
| 360 if (arg != NULL) { | 292 if (arg != NULL) { |
| 361 array_->SetAt(index_++, new CObjectString(CObject::NewString(arg))); | 293 array_->SetAt(index_++, new CObjectString(CObject::NewString(arg))); |
| 362 } else { | 294 } else { |
| 363 array_->SetAt(index_++, CObject::Null()); | 295 array_->SetAt(index_++, CObject::Null()); |
| 364 } | 296 } |
| 365 return index_ < length_; | 297 return index_ < length_; |
| 366 } | 298 } |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 471 if (listing->error()) { | 403 if (listing->error()) { |
| 472 listing->HandleError("Invalid path"); | 404 listing->HandleError("Invalid path"); |
| 473 listing->HandleDone(); | 405 listing->HandleDone(); |
| 474 } else { | 406 } else { |
| 475 while (ListNext(listing)) {} | 407 while (ListNext(listing)) {} |
| 476 } | 408 } |
| 477 } | 409 } |
| 478 | 410 |
| 479 } // namespace bin | 411 } // namespace bin |
| 480 } // namespace dart | 412 } // namespace dart |
| OLD | NEW |