Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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/file.h" | 7 #include "bin/file.h" |
| 8 | 8 |
| 9 #include "bin/builtin.h" | 9 #include "bin/builtin.h" |
| 10 #include "bin/dartutils.h" | 10 #include "bin/dartutils.h" |
| 11 #include "bin/embedded_dart_io.h" | 11 #include "bin/embedded_dart_io.h" |
| 12 #include "bin/io_buffer.h" | 12 #include "bin/io_buffer.h" |
| 13 #include "bin/utils.h" | 13 #include "bin/utils.h" |
| 14 | 14 |
| 15 #include "include/dart_api.h" | 15 #include "include/dart_api.h" |
| 16 #include "include/dart_tools_api.h" | 16 #include "include/dart_tools_api.h" |
| 17 | 17 |
| 18 namespace dart { | 18 namespace dart { |
| 19 namespace bin { | 19 namespace bin { |
| 20 | 20 |
| 21 static const int kFileNativeFieldIndex = 0; | |
| 21 static const int kMSPerSecond = 1000; | 22 static const int kMSPerSecond = 1000; |
| 22 | 23 |
| 23 // The file pointer has been passed into Dart as an intptr_t and it is safe | 24 // The file pointer has been passed into Dart as an intptr_t and it is safe |
| 24 // to pull it out of Dart as a 64-bit integer, cast it to an intptr_t and | 25 // to pull it out of Dart as a 64-bit integer, cast it to an intptr_t and |
| 25 // from there to a File pointer. | 26 // from there to a File pointer. |
| 26 static File* GetFilePointer(Dart_Handle handle) { | 27 static File* GetFile(Dart_NativeArguments args) { |
| 27 intptr_t value = DartUtils::GetIntptrValue(handle); | 28 File* file; |
| 28 return reinterpret_cast<File*>(value); | 29 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); |
| 30 ASSERT(Dart_IsInstance(dart_this)); | |
| 31 ThrowIfError(Dart_GetNativeInstanceField( | |
| 32 dart_this, | |
| 33 kFileNativeFieldIndex, | |
| 34 reinterpret_cast<intptr_t*>(&file))); | |
| 35 return file; | |
| 29 } | 36 } |
| 30 | 37 |
| 31 | 38 |
| 39 static void SetFile(Dart_Handle dart_this, intptr_t file_pointer) { | |
| 40 Dart_Handle result = Dart_SetNativeInstanceField( | |
| 41 dart_this, | |
| 42 kFileNativeFieldIndex, | |
| 43 file_pointer); | |
| 44 if (Dart_IsError(result)) { | |
| 45 Log::PrintErr("SetNativeInstanceField in SetFile() failed\n"); | |
| 46 Dart_PropagateError(result); | |
| 47 } | |
| 48 } | |
| 49 | |
| 50 | |
| 51 void FUNCTION_NAME(File_GetPointer)(Dart_NativeArguments args) { | |
| 52 File* file = GetFile(args); | |
| 53 // If the file is already closed, GetFile() will return NULL. | |
| 54 if (file != NULL) { | |
| 55 // Increment file's reference count. File_GetPointer() should only be called | |
| 56 // when we are about to send the File* to the IO Service. | |
| 57 file->Retain(); | |
| 58 } | |
| 59 intptr_t file_pointer = reinterpret_cast<intptr_t>(file); | |
| 60 Dart_SetReturnValue(args, Dart_NewInteger(file_pointer)); | |
| 61 } | |
| 62 | |
| 63 | |
| 64 static void ReleaseFile(void* isolate_callback_data, | |
| 65 Dart_WeakPersistentHandle handle, | |
| 66 void* peer) { | |
| 67 File* file = reinterpret_cast<File*>(peer); | |
| 68 file->Release(); | |
| 69 } | |
| 70 | |
| 71 | |
| 72 void FUNCTION_NAME(File_SetPointer)(Dart_NativeArguments args) { | |
| 73 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); | |
| 74 intptr_t file_pointer = | |
| 75 DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 1)); | |
| 76 File* file = reinterpret_cast<File*>(file_pointer); | |
| 77 Dart_WeakPersistentHandle handle = Dart_NewWeakPersistentHandle( | |
| 78 dart_this, reinterpret_cast<void*>(file), sizeof(*file), ReleaseFile); | |
| 79 file->SetWeakHandle(handle); | |
| 80 SetFile(dart_this, file_pointer); | |
| 81 } | |
| 82 | |
| 83 | |
| 32 void FUNCTION_NAME(File_Open)(Dart_NativeArguments args) { | 84 void FUNCTION_NAME(File_Open)(Dart_NativeArguments args) { |
| 33 const char* filename = | 85 const char* filename = |
| 34 DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0)); | 86 DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0)); |
| 35 int64_t mode = DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 1)); | 87 int64_t mode = DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 1)); |
| 36 File::DartFileOpenMode dart_file_mode = | 88 File::DartFileOpenMode dart_file_mode = |
| 37 static_cast<File::DartFileOpenMode>(mode); | 89 static_cast<File::DartFileOpenMode>(mode); |
| 38 File::FileOpenMode file_mode = File::DartModeToFileMode(dart_file_mode); | 90 File::FileOpenMode file_mode = File::DartModeToFileMode(dart_file_mode); |
| 39 // Check that the file exists before opening it only for | 91 // Check that the file exists before opening it only for |
| 40 // reading. This is to prevent the opening of directories as | 92 // reading. This is to prevent the opening of directories as |
| 41 // files. Directories can be opened for reading using the posix | 93 // files. Directories can be opened for reading using the posix |
| 42 // 'open' call. | 94 // 'open' call. |
| 43 File* file = NULL; | 95 File* file = File::ScopedOpen(filename, file_mode); |
| 44 file = File::ScopedOpen(filename, file_mode); | |
| 45 if (file != NULL) { | 96 if (file != NULL) { |
| 46 Dart_SetReturnValue(args, | 97 Dart_SetReturnValue(args, |
| 47 Dart_NewInteger(reinterpret_cast<intptr_t>(file))); | 98 Dart_NewInteger(reinterpret_cast<intptr_t>(file))); |
| 48 } else { | 99 } else { |
| 49 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); | 100 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); |
| 50 } | 101 } |
| 51 } | 102 } |
| 52 | 103 |
| 53 | 104 |
| 54 void FUNCTION_NAME(File_Exists)(Dart_NativeArguments args) { | 105 void FUNCTION_NAME(File_Exists)(Dart_NativeArguments args) { |
| 55 const char* filename = | 106 const char* filename = |
| 56 DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0)); | 107 DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0)); |
| 57 bool exists = File::Exists(filename); | 108 bool exists = File::Exists(filename); |
| 58 Dart_SetReturnValue(args, Dart_NewBoolean(exists)); | 109 Dart_SetReturnValue(args, Dart_NewBoolean(exists)); |
| 59 } | 110 } |
| 60 | 111 |
| 61 | 112 |
| 62 void FUNCTION_NAME(File_Close)(Dart_NativeArguments args) { | 113 void FUNCTION_NAME(File_Close)(Dart_NativeArguments args) { |
| 63 File* file = GetFilePointer(Dart_GetNativeArgument(args, 0)); | 114 File* file = GetFile(args); |
| 64 ASSERT(file != NULL); | 115 ASSERT(file != NULL); |
| 65 delete file; | 116 file->DeleteWeakHandle(Dart_CurrentIsolate()); |
| 117 file->Release(); | |
| 118 | |
| 119 // NULL-out the now potentially dangling pointer. | |
| 120 Dart_Handle dart_this = Dart_GetNativeArgument(args, 0); | |
|
Ivan Posva
2016/04/20 05:31:06
Can you rely on the Dart code to do the disassocia
zra
2016/04/20 17:07:52
The native object is associated by extending Nativ
| |
| 121 SetFile(dart_this, 0); | |
| 66 Dart_SetReturnValue(args, Dart_NewInteger(0)); | 122 Dart_SetReturnValue(args, Dart_NewInteger(0)); |
| 67 } | 123 } |
| 68 | 124 |
| 69 | 125 |
| 70 void FUNCTION_NAME(File_GetFD)(Dart_NativeArguments args) { | |
| 71 File* file = GetFilePointer(Dart_GetNativeArgument(args, 0)); | |
| 72 ASSERT(file != NULL); | |
| 73 Dart_SetReturnValue(args, Dart_NewInteger(file->GetFD())); | |
| 74 } | |
| 75 | |
| 76 | |
| 77 void FUNCTION_NAME(File_ReadByte)(Dart_NativeArguments args) { | 126 void FUNCTION_NAME(File_ReadByte)(Dart_NativeArguments args) { |
| 78 File* file = GetFilePointer(Dart_GetNativeArgument(args, 0)); | 127 File* file = GetFile(args); |
| 79 ASSERT(file != NULL); | 128 ASSERT(file != NULL); |
| 80 uint8_t buffer; | 129 uint8_t buffer; |
| 81 int64_t bytes_read = file->Read(reinterpret_cast<void*>(&buffer), 1); | 130 int64_t bytes_read = file->Read(reinterpret_cast<void*>(&buffer), 1); |
| 82 if (bytes_read == 1) { | 131 if (bytes_read == 1) { |
| 83 Dart_SetReturnValue(args, Dart_NewInteger(buffer)); | 132 Dart_SetReturnValue(args, Dart_NewInteger(buffer)); |
| 84 } else if (bytes_read == 0) { | 133 } else if (bytes_read == 0) { |
| 85 Dart_SetReturnValue(args, Dart_NewInteger(-1)); | 134 Dart_SetReturnValue(args, Dart_NewInteger(-1)); |
| 86 } else { | 135 } else { |
| 87 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); | 136 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); |
| 88 } | 137 } |
| 89 } | 138 } |
| 90 | 139 |
| 91 | 140 |
| 92 void FUNCTION_NAME(File_WriteByte)(Dart_NativeArguments args) { | 141 void FUNCTION_NAME(File_WriteByte)(Dart_NativeArguments args) { |
| 93 File* file = GetFilePointer(Dart_GetNativeArgument(args, 0)); | 142 File* file = GetFile(args); |
| 94 ASSERT(file != NULL); | 143 ASSERT(file != NULL); |
| 95 int64_t byte = 0; | 144 int64_t byte = 0; |
| 96 if (DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 1), &byte)) { | 145 if (DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 1), &byte)) { |
| 97 uint8_t buffer = static_cast<uint8_t>(byte & 0xff); | 146 uint8_t buffer = static_cast<uint8_t>(byte & 0xff); |
| 98 bool success = file->WriteFully(reinterpret_cast<void*>(&buffer), 1); | 147 bool success = file->WriteFully(reinterpret_cast<void*>(&buffer), 1); |
| 99 if (success) { | 148 if (success) { |
| 100 Dart_SetReturnValue(args, Dart_NewInteger(1)); | 149 Dart_SetReturnValue(args, Dart_NewInteger(1)); |
| 101 } else { | 150 } else { |
| 102 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); | 151 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); |
| 103 } | 152 } |
| 104 } else { | 153 } else { |
| 105 OSError os_error(-1, "Invalid argument", OSError::kUnknown); | 154 OSError os_error(-1, "Invalid argument", OSError::kUnknown); |
| 106 Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error)); | 155 Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error)); |
| 107 } | 156 } |
| 108 } | 157 } |
| 109 | 158 |
| 110 | 159 |
| 111 void FUNCTION_NAME(File_Read)(Dart_NativeArguments args) { | 160 void FUNCTION_NAME(File_Read)(Dart_NativeArguments args) { |
| 112 File* file = GetFilePointer(Dart_GetNativeArgument(args, 0)); | 161 File* file = GetFile(args); |
| 113 ASSERT(file != NULL); | 162 ASSERT(file != NULL); |
| 114 Dart_Handle length_object = Dart_GetNativeArgument(args, 1); | 163 Dart_Handle length_object = Dart_GetNativeArgument(args, 1); |
| 115 int64_t length = 0; | 164 int64_t length = 0; |
| 116 if (DartUtils::GetInt64Value(length_object, &length)) { | 165 if (DartUtils::GetInt64Value(length_object, &length)) { |
| 117 uint8_t* buffer = NULL; | 166 uint8_t* buffer = NULL; |
| 118 Dart_Handle external_array = IOBuffer::Allocate(length, &buffer); | 167 Dart_Handle external_array = IOBuffer::Allocate(length, &buffer); |
| 119 int64_t bytes_read = file->Read(reinterpret_cast<void*>(buffer), length); | 168 int64_t bytes_read = file->Read(reinterpret_cast<void*>(buffer), length); |
| 120 if (bytes_read < 0) { | 169 if (bytes_read < 0) { |
| 121 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); | 170 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); |
| 122 } else { | 171 } else { |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 143 } | 192 } |
| 144 } | 193 } |
| 145 } else { | 194 } else { |
| 146 OSError os_error(-1, "Invalid argument", OSError::kUnknown); | 195 OSError os_error(-1, "Invalid argument", OSError::kUnknown); |
| 147 Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error)); | 196 Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error)); |
| 148 } | 197 } |
| 149 } | 198 } |
| 150 | 199 |
| 151 | 200 |
| 152 void FUNCTION_NAME(File_ReadInto)(Dart_NativeArguments args) { | 201 void FUNCTION_NAME(File_ReadInto)(Dart_NativeArguments args) { |
| 153 File* file = GetFilePointer(Dart_GetNativeArgument(args, 0)); | 202 File* file = GetFile(args); |
| 154 ASSERT(file != NULL); | 203 ASSERT(file != NULL); |
| 155 Dart_Handle buffer_obj = Dart_GetNativeArgument(args, 1); | 204 Dart_Handle buffer_obj = Dart_GetNativeArgument(args, 1); |
| 156 ASSERT(Dart_IsList(buffer_obj)); | 205 ASSERT(Dart_IsList(buffer_obj)); |
| 157 // start and end arguments are checked in Dart code to be | 206 // start and end arguments are checked in Dart code to be |
| 158 // integers and have the property that end <= | 207 // integers and have the property that end <= |
| 159 // list.length. Therefore, it is safe to extract their value as | 208 // list.length. Therefore, it is safe to extract their value as |
| 160 // intptr_t. | 209 // intptr_t. |
| 161 intptr_t start = | 210 intptr_t start = |
| 162 DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 2)); | 211 DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 2)); |
| 163 intptr_t end = | 212 intptr_t end = |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 178 } else { | 227 } else { |
| 179 Dart_SetReturnValue(args, Dart_NewInteger(bytes_read)); | 228 Dart_SetReturnValue(args, Dart_NewInteger(bytes_read)); |
| 180 } | 229 } |
| 181 } else { | 230 } else { |
| 182 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); | 231 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); |
| 183 } | 232 } |
| 184 } | 233 } |
| 185 | 234 |
| 186 | 235 |
| 187 void FUNCTION_NAME(File_WriteFrom)(Dart_NativeArguments args) { | 236 void FUNCTION_NAME(File_WriteFrom)(Dart_NativeArguments args) { |
| 188 File* file = GetFilePointer(Dart_GetNativeArgument(args, 0)); | 237 File* file = GetFile(args); |
| 189 ASSERT(file != NULL); | 238 ASSERT(file != NULL); |
| 190 | 239 |
| 191 Dart_Handle buffer_obj = Dart_GetNativeArgument(args, 1); | 240 Dart_Handle buffer_obj = Dart_GetNativeArgument(args, 1); |
| 192 | 241 |
| 193 // Offset and length arguments are checked in Dart code to be | 242 // Offset and length arguments are checked in Dart code to be |
| 194 // integers and have the property that (offset + length) <= | 243 // integers and have the property that (offset + length) <= |
| 195 // list.length. Therefore, it is safe to extract their value as | 244 // list.length. Therefore, it is safe to extract their value as |
| 196 // intptr_t. | 245 // intptr_t. |
| 197 intptr_t start = | 246 intptr_t start = |
| 198 DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 2)); | 247 DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 2)); |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 226 | 275 |
| 227 if (!success) { | 276 if (!success) { |
| 228 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); | 277 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); |
| 229 } else { | 278 } else { |
| 230 Dart_SetReturnValue(args, Dart_Null()); | 279 Dart_SetReturnValue(args, Dart_Null()); |
| 231 } | 280 } |
| 232 } | 281 } |
| 233 | 282 |
| 234 | 283 |
| 235 void FUNCTION_NAME(File_Position)(Dart_NativeArguments args) { | 284 void FUNCTION_NAME(File_Position)(Dart_NativeArguments args) { |
| 236 File* file = GetFilePointer(Dart_GetNativeArgument(args, 0)); | 285 File* file = GetFile(args); |
| 237 ASSERT(file != NULL); | 286 ASSERT(file != NULL); |
| 238 intptr_t return_value = file->Position(); | 287 intptr_t return_value = file->Position(); |
| 239 if (return_value >= 0) { | 288 if (return_value >= 0) { |
| 240 Dart_SetReturnValue(args, Dart_NewInteger(return_value)); | 289 Dart_SetReturnValue(args, Dart_NewInteger(return_value)); |
| 241 } else { | 290 } else { |
| 242 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); | 291 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); |
| 243 } | 292 } |
| 244 } | 293 } |
| 245 | 294 |
| 246 | 295 |
| 247 void FUNCTION_NAME(File_SetPosition)(Dart_NativeArguments args) { | 296 void FUNCTION_NAME(File_SetPosition)(Dart_NativeArguments args) { |
| 248 File* file = GetFilePointer(Dart_GetNativeArgument(args, 0)); | 297 File* file = GetFile(args); |
| 249 ASSERT(file != NULL); | 298 ASSERT(file != NULL); |
| 250 int64_t position = 0; | 299 int64_t position = 0; |
| 251 if (DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 1), &position)) { | 300 if (DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 1), &position)) { |
| 252 if (file->SetPosition(position)) { | 301 if (file->SetPosition(position)) { |
| 253 Dart_SetReturnValue(args, Dart_True()); | 302 Dart_SetReturnValue(args, Dart_True()); |
| 254 } else { | 303 } else { |
| 255 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); | 304 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); |
| 256 } | 305 } |
| 257 } else { | 306 } else { |
| 258 OSError os_error(-1, "Invalid argument", OSError::kUnknown); | 307 OSError os_error(-1, "Invalid argument", OSError::kUnknown); |
| 259 Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error)); | 308 Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error)); |
| 260 } | 309 } |
| 261 } | 310 } |
| 262 | 311 |
| 263 | 312 |
| 264 void FUNCTION_NAME(File_Truncate)(Dart_NativeArguments args) { | 313 void FUNCTION_NAME(File_Truncate)(Dart_NativeArguments args) { |
| 265 File* file = GetFilePointer(Dart_GetNativeArgument(args, 0)); | 314 File* file = GetFile(args); |
| 266 ASSERT(file != NULL); | 315 ASSERT(file != NULL); |
| 267 int64_t length = 0; | 316 int64_t length = 0; |
| 268 if (DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 1), &length)) { | 317 if (DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 1), &length)) { |
| 269 if (file->Truncate(length)) { | 318 if (file->Truncate(length)) { |
| 270 Dart_SetReturnValue(args, Dart_True()); | 319 Dart_SetReturnValue(args, Dart_True()); |
| 271 } else { | 320 } else { |
| 272 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); | 321 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); |
| 273 } | 322 } |
| 274 } else { | 323 } else { |
| 275 OSError os_error(-1, "Invalid argument", OSError::kUnknown); | 324 OSError os_error(-1, "Invalid argument", OSError::kUnknown); |
| 276 Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error)); | 325 Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error)); |
| 277 } | 326 } |
| 278 } | 327 } |
| 279 | 328 |
| 280 | 329 |
| 281 void FUNCTION_NAME(File_Length)(Dart_NativeArguments args) { | 330 void FUNCTION_NAME(File_Length)(Dart_NativeArguments args) { |
| 282 File* file = GetFilePointer(Dart_GetNativeArgument(args, 0)); | 331 File* file = GetFile(args); |
| 283 ASSERT(file != NULL); | 332 ASSERT(file != NULL); |
| 284 int64_t return_value = file->Length(); | 333 int64_t return_value = file->Length(); |
| 285 if (return_value >= 0) { | 334 if (return_value >= 0) { |
| 286 Dart_SetReturnValue(args, Dart_NewInteger(return_value)); | 335 Dart_SetReturnValue(args, Dart_NewInteger(return_value)); |
| 287 } else { | 336 } else { |
| 288 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); | 337 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); |
| 289 } | 338 } |
| 290 } | 339 } |
| 291 | 340 |
| 292 | 341 |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 308 int64_t return_value = File::LastModified(name); | 357 int64_t return_value = File::LastModified(name); |
| 309 if (return_value >= 0) { | 358 if (return_value >= 0) { |
| 310 Dart_SetReturnValue(args, Dart_NewInteger(return_value * kMSPerSecond)); | 359 Dart_SetReturnValue(args, Dart_NewInteger(return_value * kMSPerSecond)); |
| 311 } else { | 360 } else { |
| 312 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); | 361 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); |
| 313 } | 362 } |
| 314 } | 363 } |
| 315 | 364 |
| 316 | 365 |
| 317 void FUNCTION_NAME(File_Flush)(Dart_NativeArguments args) { | 366 void FUNCTION_NAME(File_Flush)(Dart_NativeArguments args) { |
| 318 File* file = GetFilePointer(Dart_GetNativeArgument(args, 0)); | 367 File* file = GetFile(args); |
| 319 ASSERT(file != NULL); | 368 ASSERT(file != NULL); |
| 320 if (file->Flush()) { | 369 if (file->Flush()) { |
| 321 Dart_SetReturnValue(args, Dart_True()); | 370 Dart_SetReturnValue(args, Dart_True()); |
| 322 } else { | 371 } else { |
| 323 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); | 372 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); |
| 324 } | 373 } |
| 325 } | 374 } |
| 326 | 375 |
| 327 | 376 |
| 328 void FUNCTION_NAME(File_Lock)(Dart_NativeArguments args) { | 377 void FUNCTION_NAME(File_Lock)(Dart_NativeArguments args) { |
| 329 File* file = GetFilePointer(Dart_GetNativeArgument(args, 0)); | 378 File* file = GetFile(args); |
| 330 ASSERT(file != NULL); | 379 ASSERT(file != NULL); |
| 331 int64_t lock; | 380 int64_t lock; |
| 332 int64_t start; | 381 int64_t start; |
| 333 int64_t end; | 382 int64_t end; |
| 334 if (DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 1), &lock) && | 383 if (DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 1), &lock) && |
| 335 DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 2), &start) && | 384 DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 2), &start) && |
| 336 DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 3), &end)) { | 385 DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 3), &end)) { |
| 337 if ((lock >= File::kLockMin) && (lock <= File::kLockMax) && | 386 if ((lock >= File::kLockMin) && (lock <= File::kLockMax) && |
| 338 (start >= 0) && (end == -1 || end > start)) { | 387 (start >= 0) && (end == -1 || end > start)) { |
| 339 if (file->Lock(static_cast<File::LockType>(lock), start, end)) { | 388 if (file->Lock(static_cast<File::LockType>(lock), start, end)) { |
| (...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 697 } | 746 } |
| 698 } | 747 } |
| 699 return CObject::IllegalArgumentError(); | 748 return CObject::IllegalArgumentError(); |
| 700 } | 749 } |
| 701 | 750 |
| 702 | 751 |
| 703 CObject* File::CloseRequest(const CObjectArray& request) { | 752 CObject* File::CloseRequest(const CObjectArray& request) { |
| 704 intptr_t return_value = -1; | 753 intptr_t return_value = -1; |
| 705 if ((request.Length() == 1) && request[0]->IsIntptr()) { | 754 if ((request.Length() == 1) && request[0]->IsIntptr()) { |
| 706 File* file = CObjectToFilePointer(request[0]); | 755 File* file = CObjectToFilePointer(request[0]); |
| 707 ASSERT(file != NULL); | 756 RefCntReleaseScope<File> rs(file); |
| 708 delete file; | |
| 709 return_value = 0; | 757 return_value = 0; |
| 758 // We have retained a reference to the file here. Therefore the file's | |
| 759 // destructor can't be running. Since no further requests are dispatched by | |
| 760 // the Dart code after an async close call, this Close() can't be racing | |
| 761 // with any other call on the file. We don't do an extra Release(), and we | |
| 762 // don't delete the weak persistent handle. The file is closed here, but the | |
| 763 // memory will be cleaned up when the finalizer runs. | |
| 764 ASSERT(!file->IsClosed()); | |
| 765 file->Close(); | |
| 710 } | 766 } |
| 711 return new CObjectIntptr(CObject::NewIntptr(return_value)); | 767 return new CObjectIntptr(CObject::NewIntptr(return_value)); |
| 712 } | 768 } |
| 713 | 769 |
| 714 | 770 |
| 715 CObject* File::PositionRequest(const CObjectArray& request) { | 771 CObject* File::PositionRequest(const CObjectArray& request) { |
| 716 if ((request.Length() == 1) && request[0]->IsIntptr()) { | 772 if ((request.Length() == 1) && request[0]->IsIntptr()) { |
| 717 File* file = CObjectToFilePointer(request[0]); | 773 File* file = CObjectToFilePointer(request[0]); |
| 718 ASSERT(file != NULL); | 774 RefCntReleaseScope<File> rs(file); |
| 719 if (!file->IsClosed()) { | 775 if (!file->IsClosed()) { |
| 720 intptr_t return_value = file->Position(); | 776 intptr_t return_value = file->Position(); |
| 721 if (return_value >= 0) { | 777 if (return_value >= 0) { |
| 722 return new CObjectIntptr(CObject::NewIntptr(return_value)); | 778 return new CObjectIntptr(CObject::NewIntptr(return_value)); |
| 723 } else { | 779 } else { |
| 724 return CObject::NewOSError(); | 780 return CObject::NewOSError(); |
| 725 } | 781 } |
| 726 } else { | 782 } else { |
| 727 return CObject::FileClosedError(); | 783 return CObject::FileClosedError(); |
| 728 } | 784 } |
| 729 } | 785 } |
| 730 return CObject::IllegalArgumentError(); | 786 return CObject::IllegalArgumentError(); |
| 731 } | 787 } |
| 732 | 788 |
| 733 | 789 |
| 734 CObject* File::SetPositionRequest(const CObjectArray& request) { | 790 CObject* File::SetPositionRequest(const CObjectArray& request) { |
| 735 if ((request.Length() == 2) && | 791 if ((request.Length() == 2) && |
| 736 request[0]->IsIntptr() && | 792 request[0]->IsIntptr() && |
| 737 request[1]->IsInt32OrInt64()) { | 793 request[1]->IsInt32OrInt64()) { |
| 738 File* file = CObjectToFilePointer(request[0]); | 794 File* file = CObjectToFilePointer(request[0]); |
| 739 ASSERT(file != NULL); | 795 RefCntReleaseScope<File> rs(file); |
| 740 if (!file->IsClosed()) { | 796 if (!file->IsClosed()) { |
| 741 int64_t position = CObjectInt32OrInt64ToInt64(request[1]); | 797 int64_t position = CObjectInt32OrInt64ToInt64(request[1]); |
| 742 if (file->SetPosition(position)) { | 798 if (file->SetPosition(position)) { |
| 743 return CObject::True(); | 799 return CObject::True(); |
| 744 } else { | 800 } else { |
| 745 return CObject::NewOSError(); | 801 return CObject::NewOSError(); |
| 746 } | 802 } |
| 747 } else { | 803 } else { |
| 748 return CObject::FileClosedError(); | 804 return CObject::FileClosedError(); |
| 749 } | 805 } |
| 750 } | 806 } |
| 751 return CObject::IllegalArgumentError(); | 807 return CObject::IllegalArgumentError(); |
| 752 } | 808 } |
| 753 | 809 |
| 754 | 810 |
| 755 CObject* File::TruncateRequest(const CObjectArray& request) { | 811 CObject* File::TruncateRequest(const CObjectArray& request) { |
| 756 if ((request.Length() == 2) && | 812 if ((request.Length() == 2) && |
| 757 request[0]->IsIntptr() && | 813 request[0]->IsIntptr() && |
| 758 request[1]->IsInt32OrInt64()) { | 814 request[1]->IsInt32OrInt64()) { |
| 759 File* file = CObjectToFilePointer(request[0]); | 815 File* file = CObjectToFilePointer(request[0]); |
| 760 ASSERT(file != NULL); | 816 RefCntReleaseScope<File> rs(file); |
| 761 if (!file->IsClosed()) { | 817 if (!file->IsClosed()) { |
| 762 int64_t length = CObjectInt32OrInt64ToInt64(request[1]); | 818 int64_t length = CObjectInt32OrInt64ToInt64(request[1]); |
| 763 if (file->Truncate(length)) { | 819 if (file->Truncate(length)) { |
| 764 return CObject::True(); | 820 return CObject::True(); |
| 765 } else { | 821 } else { |
| 766 return CObject::NewOSError(); | 822 return CObject::NewOSError(); |
| 767 } | 823 } |
| 768 } else { | 824 } else { |
| 769 return CObject::FileClosedError(); | 825 return CObject::FileClosedError(); |
| 770 } | 826 } |
| 771 } | 827 } |
| 772 return CObject::IllegalArgumentError(); | 828 return CObject::IllegalArgumentError(); |
| 773 } | 829 } |
| 774 | 830 |
| 775 | 831 |
| 776 CObject* File::LengthRequest(const CObjectArray& request) { | 832 CObject* File::LengthRequest(const CObjectArray& request) { |
| 777 if ((request.Length() == 1) && request[0]->IsIntptr()) { | 833 if ((request.Length() == 1) && request[0]->IsIntptr()) { |
| 778 File* file = CObjectToFilePointer(request[0]); | 834 File* file = CObjectToFilePointer(request[0]); |
| 779 ASSERT(file != NULL); | 835 RefCntReleaseScope<File> rs(file); |
| 780 if (!file->IsClosed()) { | 836 if (!file->IsClosed()) { |
| 781 int64_t return_value = file->Length(); | 837 int64_t return_value = file->Length(); |
| 782 if (return_value >= 0) { | 838 if (return_value >= 0) { |
| 783 return new CObjectInt64(CObject::NewInt64(return_value)); | 839 return new CObjectInt64(CObject::NewInt64(return_value)); |
| 784 } else { | 840 } else { |
| 785 return CObject::NewOSError(); | 841 return CObject::NewOSError(); |
| 786 } | 842 } |
| 787 } else { | 843 } else { |
| 788 return CObject::FileClosedError(); | 844 return CObject::FileClosedError(); |
| 789 } | 845 } |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 816 return CObject::NewOSError(); | 872 return CObject::NewOSError(); |
| 817 } | 873 } |
| 818 } | 874 } |
| 819 return CObject::IllegalArgumentError(); | 875 return CObject::IllegalArgumentError(); |
| 820 } | 876 } |
| 821 | 877 |
| 822 | 878 |
| 823 CObject* File::FlushRequest(const CObjectArray& request) { | 879 CObject* File::FlushRequest(const CObjectArray& request) { |
| 824 if ((request.Length() == 1) && request[0]->IsIntptr()) { | 880 if ((request.Length() == 1) && request[0]->IsIntptr()) { |
| 825 File* file = CObjectToFilePointer(request[0]); | 881 File* file = CObjectToFilePointer(request[0]); |
| 826 ASSERT(file != NULL); | 882 RefCntReleaseScope<File> rs(file); |
| 827 if (!file->IsClosed()) { | 883 if (!file->IsClosed()) { |
| 828 if (file->Flush()) { | 884 if (file->Flush()) { |
| 829 return CObject::True(); | 885 return CObject::True(); |
| 830 } else { | 886 } else { |
| 831 return CObject::NewOSError(); | 887 return CObject::NewOSError(); |
| 832 } | 888 } |
| 833 } else { | 889 } else { |
| 834 return CObject::FileClosedError(); | 890 return CObject::FileClosedError(); |
| 835 } | 891 } |
| 836 } | 892 } |
| 837 return CObject::IllegalArgumentError(); | 893 return CObject::IllegalArgumentError(); |
| 838 } | 894 } |
| 839 | 895 |
| 840 | 896 |
| 841 CObject* File::ReadByteRequest(const CObjectArray& request) { | 897 CObject* File::ReadByteRequest(const CObjectArray& request) { |
| 842 if ((request.Length() == 1) && request[0]->IsIntptr()) { | 898 if ((request.Length() == 1) && request[0]->IsIntptr()) { |
| 843 File* file = CObjectToFilePointer(request[0]); | 899 File* file = CObjectToFilePointer(request[0]); |
| 844 ASSERT(file != NULL); | 900 RefCntReleaseScope<File> rs(file); |
| 845 if (!file->IsClosed()) { | 901 if (!file->IsClosed()) { |
| 846 uint8_t buffer; | 902 uint8_t buffer; |
| 847 int64_t bytes_read = file->Read(reinterpret_cast<void*>(&buffer), 1); | 903 int64_t bytes_read = file->Read(reinterpret_cast<void*>(&buffer), 1); |
| 848 if (bytes_read > 0) { | 904 if (bytes_read > 0) { |
| 849 return new CObjectIntptr(CObject::NewIntptr(buffer)); | 905 return new CObjectIntptr(CObject::NewIntptr(buffer)); |
| 850 } else if (bytes_read == 0) { | 906 } else if (bytes_read == 0) { |
| 851 return new CObjectIntptr(CObject::NewIntptr(-1)); | 907 return new CObjectIntptr(CObject::NewIntptr(-1)); |
| 852 } else { | 908 } else { |
| 853 return CObject::NewOSError(); | 909 return CObject::NewOSError(); |
| 854 } | 910 } |
| 855 } else { | 911 } else { |
| 856 return CObject::FileClosedError(); | 912 return CObject::FileClosedError(); |
| 857 } | 913 } |
| 858 } | 914 } |
| 859 return CObject::IllegalArgumentError(); | 915 return CObject::IllegalArgumentError(); |
| 860 } | 916 } |
| 861 | 917 |
| 862 | 918 |
| 863 CObject* File::WriteByteRequest(const CObjectArray& request) { | 919 CObject* File::WriteByteRequest(const CObjectArray& request) { |
| 864 if ((request.Length() == 2) && | 920 if ((request.Length() == 2) && |
| 865 request[0]->IsIntptr() && | 921 request[0]->IsIntptr() && |
| 866 request[1]->IsInt32OrInt64()) { | 922 request[1]->IsInt32OrInt64()) { |
| 867 File* file = CObjectToFilePointer(request[0]); | 923 File* file = CObjectToFilePointer(request[0]); |
| 868 ASSERT(file != NULL); | 924 RefCntReleaseScope<File> rs(file); |
| 869 if (!file->IsClosed()) { | 925 if (!file->IsClosed()) { |
| 870 int64_t byte = CObjectInt32OrInt64ToInt64(request[1]); | 926 int64_t byte = CObjectInt32OrInt64ToInt64(request[1]); |
| 871 uint8_t buffer = static_cast<uint8_t>(byte & 0xff); | 927 uint8_t buffer = static_cast<uint8_t>(byte & 0xff); |
| 872 bool success = file->WriteFully(reinterpret_cast<void*>(&buffer), 1); | 928 bool success = file->WriteFully(reinterpret_cast<void*>(&buffer), 1); |
| 873 if (success) { | 929 if (success) { |
| 874 return new CObjectInt64(CObject::NewInt64(1)); | 930 return new CObjectInt64(CObject::NewInt64(1)); |
| 875 } else { | 931 } else { |
| 876 return CObject::NewOSError(); | 932 return CObject::NewOSError(); |
| 877 } | 933 } |
| 878 } else { | 934 } else { |
| 879 return CObject::FileClosedError(); | 935 return CObject::FileClosedError(); |
| 880 } | 936 } |
| 881 } | 937 } |
| 882 return CObject::IllegalArgumentError(); | 938 return CObject::IllegalArgumentError(); |
| 883 } | 939 } |
| 884 | 940 |
| 885 | 941 |
| 886 CObject* File::ReadRequest(const CObjectArray& request) { | 942 CObject* File::ReadRequest(const CObjectArray& request) { |
| 887 if ((request.Length() == 2) && | 943 if ((request.Length() == 2) && |
| 888 request[0]->IsIntptr() && | 944 request[0]->IsIntptr() && |
| 889 request[1]->IsInt32OrInt64()) { | 945 request[1]->IsInt32OrInt64()) { |
| 890 File* file = CObjectToFilePointer(request[0]); | 946 File* file = CObjectToFilePointer(request[0]); |
| 891 ASSERT(file != NULL); | 947 RefCntReleaseScope<File> rs(file); |
| 892 if (!file->IsClosed()) { | 948 if (!file->IsClosed()) { |
| 893 int64_t length = CObjectInt32OrInt64ToInt64(request[1]); | 949 int64_t length = CObjectInt32OrInt64ToInt64(request[1]); |
| 894 Dart_CObject* io_buffer = CObject::NewIOBuffer(length); | 950 Dart_CObject* io_buffer = CObject::NewIOBuffer(length); |
| 895 ASSERT(io_buffer != NULL); | 951 ASSERT(io_buffer != NULL); |
| 896 uint8_t* data = io_buffer->value.as_external_typed_data.data; | 952 uint8_t* data = io_buffer->value.as_external_typed_data.data; |
| 897 int64_t bytes_read = file->Read(data, length); | 953 int64_t bytes_read = file->Read(data, length); |
| 898 if (bytes_read >= 0) { | 954 if (bytes_read >= 0) { |
| 899 CObjectExternalUint8Array* external_array = | 955 CObjectExternalUint8Array* external_array = |
| 900 new CObjectExternalUint8Array(io_buffer); | 956 new CObjectExternalUint8Array(io_buffer); |
| 901 external_array->SetLength(bytes_read); | 957 external_array->SetLength(bytes_read); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 913 } | 969 } |
| 914 return CObject::IllegalArgumentError(); | 970 return CObject::IllegalArgumentError(); |
| 915 } | 971 } |
| 916 | 972 |
| 917 | 973 |
| 918 CObject* File::ReadIntoRequest(const CObjectArray& request) { | 974 CObject* File::ReadIntoRequest(const CObjectArray& request) { |
| 919 if ((request.Length() == 2) && | 975 if ((request.Length() == 2) && |
| 920 request[0]->IsIntptr() && | 976 request[0]->IsIntptr() && |
| 921 request[1]->IsInt32OrInt64()) { | 977 request[1]->IsInt32OrInt64()) { |
| 922 File* file = CObjectToFilePointer(request[0]); | 978 File* file = CObjectToFilePointer(request[0]); |
| 923 ASSERT(file != NULL); | 979 RefCntReleaseScope<File> rs(file); |
| 924 if (!file->IsClosed()) { | 980 if (!file->IsClosed()) { |
| 925 int64_t length = CObjectInt32OrInt64ToInt64(request[1]); | 981 int64_t length = CObjectInt32OrInt64ToInt64(request[1]); |
| 926 Dart_CObject* io_buffer = CObject::NewIOBuffer(length); | 982 Dart_CObject* io_buffer = CObject::NewIOBuffer(length); |
| 927 ASSERT(io_buffer != NULL); | 983 ASSERT(io_buffer != NULL); |
| 928 uint8_t* data = io_buffer->value.as_external_typed_data.data; | 984 uint8_t* data = io_buffer->value.as_external_typed_data.data; |
| 929 int64_t bytes_read = file->Read(data, length); | 985 int64_t bytes_read = file->Read(data, length); |
| 930 if (bytes_read >= 0) { | 986 if (bytes_read >= 0) { |
| 931 CObjectExternalUint8Array* external_array = | 987 CObjectExternalUint8Array* external_array = |
| 932 new CObjectExternalUint8Array(io_buffer); | 988 new CObjectExternalUint8Array(io_buffer); |
| 933 external_array->SetLength(bytes_read); | 989 external_array->SetLength(bytes_read); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 973 } | 1029 } |
| 974 | 1030 |
| 975 | 1031 |
| 976 CObject* File::WriteFromRequest(const CObjectArray& request) { | 1032 CObject* File::WriteFromRequest(const CObjectArray& request) { |
| 977 if ((request.Length() == 4) && | 1033 if ((request.Length() == 4) && |
| 978 request[0]->IsIntptr() && | 1034 request[0]->IsIntptr() && |
| 979 (request[1]->IsTypedData() || request[1]->IsArray()) && | 1035 (request[1]->IsTypedData() || request[1]->IsArray()) && |
| 980 request[2]->IsInt32OrInt64() && | 1036 request[2]->IsInt32OrInt64() && |
| 981 request[3]->IsInt32OrInt64()) { | 1037 request[3]->IsInt32OrInt64()) { |
| 982 File* file = CObjectToFilePointer(request[0]); | 1038 File* file = CObjectToFilePointer(request[0]); |
| 983 ASSERT(file != NULL); | 1039 RefCntReleaseScope<File> rs(file); |
| 984 if (!file->IsClosed()) { | 1040 if (!file->IsClosed()) { |
| 985 int64_t start = CObjectInt32OrInt64ToInt64(request[2]); | 1041 int64_t start = CObjectInt32OrInt64ToInt64(request[2]); |
| 986 int64_t end = CObjectInt32OrInt64ToInt64(request[3]); | 1042 int64_t end = CObjectInt32OrInt64ToInt64(request[3]); |
| 987 int64_t length = end - start; | 1043 int64_t length = end - start; |
| 988 uint8_t* buffer_start; | 1044 uint8_t* buffer_start; |
| 989 if (request[1]->IsTypedData()) { | 1045 if (request[1]->IsTypedData()) { |
| 990 CObjectTypedData typed_data(request[1]); | 1046 CObjectTypedData typed_data(request[1]); |
| 991 start = start * SizeInBytes(typed_data.Type()); | 1047 start = start * SizeInBytes(typed_data.Type()); |
| 992 length = length * SizeInBytes(typed_data.Type()); | 1048 length = length * SizeInBytes(typed_data.Type()); |
| 993 buffer_start = typed_data.Buffer() + start; | 1049 buffer_start = typed_data.Buffer() + start; |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1136 } | 1192 } |
| 1137 | 1193 |
| 1138 | 1194 |
| 1139 CObject* File::LockRequest(const CObjectArray& request) { | 1195 CObject* File::LockRequest(const CObjectArray& request) { |
| 1140 if ((request.Length() == 4) && | 1196 if ((request.Length() == 4) && |
| 1141 request[0]->IsIntptr() && | 1197 request[0]->IsIntptr() && |
| 1142 request[1]->IsInt32OrInt64() && | 1198 request[1]->IsInt32OrInt64() && |
| 1143 request[2]->IsInt32OrInt64() && | 1199 request[2]->IsInt32OrInt64() && |
| 1144 request[3]->IsInt32OrInt64()) { | 1200 request[3]->IsInt32OrInt64()) { |
| 1145 File* file = CObjectToFilePointer(request[0]); | 1201 File* file = CObjectToFilePointer(request[0]); |
| 1146 ASSERT(file != NULL); | 1202 RefCntReleaseScope<File> rs(file); |
| 1147 if (!file->IsClosed()) { | 1203 if (!file->IsClosed()) { |
| 1148 int64_t lock = CObjectInt32OrInt64ToInt64(request[1]); | 1204 int64_t lock = CObjectInt32OrInt64ToInt64(request[1]); |
| 1149 int64_t start = CObjectInt32OrInt64ToInt64(request[2]); | 1205 int64_t start = CObjectInt32OrInt64ToInt64(request[2]); |
| 1150 int64_t end = CObjectInt32OrInt64ToInt64(request[3]); | 1206 int64_t end = CObjectInt32OrInt64ToInt64(request[3]); |
| 1151 if (file->Lock(static_cast<File::LockType>(lock), start, end)) { | 1207 if (file->Lock(static_cast<File::LockType>(lock), start, end)) { |
| 1152 return CObject::True(); | 1208 return CObject::True(); |
| 1153 } else { | 1209 } else { |
| 1154 return CObject::NewOSError(); | 1210 return CObject::NewOSError(); |
| 1155 } | 1211 } |
| 1156 } else { | 1212 } else { |
| 1157 return CObject::FileClosedError(); | 1213 return CObject::FileClosedError(); |
| 1158 } | 1214 } |
| 1159 } | 1215 } |
| 1160 return CObject::IllegalArgumentError(); | 1216 return CObject::IllegalArgumentError(); |
| 1161 } | 1217 } |
| 1162 | 1218 |
| 1163 } // namespace bin | 1219 } // namespace bin |
| 1164 } // namespace dart | 1220 } // namespace dart |
| 1165 | 1221 |
| 1166 #endif // !defined(DART_IO_DISABLED) | 1222 #endif // !defined(DART_IO_DISABLED) |
| OLD | NEW |