| 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 | 5 |
| 6 /** | 6 /** |
| 7 * FileMode describes the modes in which a file can be opened. | 7 * FileMode describes the modes in which a file can be opened. |
| 8 */ | 8 */ |
| 9 class FileMode { | 9 class FileMode { |
| 10 static final READ = const FileMode._internal(0); | 10 static final READ = const FileMode._internal(0); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 * streams using [openInputStream] and [openOutputStream] or open the | 22 * streams using [openInputStream] and [openOutputStream] or open the |
| 23 * file for random access operations using [open]. | 23 * file for random access operations using [open]. |
| 24 */ | 24 */ |
| 25 interface File default _File { | 25 interface File default _File { |
| 26 /** | 26 /** |
| 27 * Create a File object. | 27 * Create a File object. |
| 28 */ | 28 */ |
| 29 File(String name); | 29 File(String name); |
| 30 | 30 |
| 31 /** | 31 /** |
| 32 * Check if the file exists. The callback is called with the result | 32 * Check if the file exists. Does not block and returns a |
| 33 * when the operation completes. The [onError] function registered | 33 * [:Future<bool>:]. |
| 34 * on the file object is called if an error occurs. | |
| 35 */ | 34 */ |
| 36 void exists(void callback(bool exists)); | 35 Future<bool> exists(); |
| 37 | 36 |
| 38 /** | 37 /** |
| 39 * Synchronously check if the file exists. | 38 * Synchronously check if the file exists. |
| 40 */ | 39 */ |
| 41 bool existsSync(); | 40 bool existsSync(); |
| 42 | 41 |
| 43 /** | 42 /** |
| 44 * Create the file. The callback is called when the file has been | 43 * Create the file. Returns a [:Future<File>:] that completes with |
| 45 * created. The [onError] function registered on the file object is | 44 * the file when it has been created. |
| 46 * called if the file cannot be created. Existing files are left | 45 * |
| 47 * untouched by create. Calling create on an existing file might | 46 * Existing files are left untouched by create. Calling create on an |
| 48 * fail if there are restrictive permissions on the file. | 47 * existing file might fail if there are restrictive permissions on |
| 48 * the file. |
| 49 */ | 49 */ |
| 50 void create(void callback()); | 50 Future<File> create(); |
| 51 | 51 |
| 52 /** | 52 /** |
| 53 * Synchronously create the file. Existing files are left untouched | 53 * Synchronously create the file. Existing files are left untouched |
| 54 * by create. Calling create on an existing file might fail if there | 54 * by create. Calling create on an existing file might fail if there |
| 55 * are restrictive permissions on the file. | 55 * are restrictive permissions on the file. |
| 56 */ | 56 */ |
| 57 void createSync(); | 57 void createSync(); |
| 58 | 58 |
| 59 /** | 59 /** |
| 60 * Delete the file. The callback is called when the file has been | 60 * Delete the file. Returns a [:Future<File>:] that completes with |
| 61 * successfully deleted. The [onError] function registered on the | 61 * the file when it has been deleted. |
| 62 * file object is called if the file cannot be deleted. | |
| 63 */ | 62 */ |
| 64 void delete(void callback()); | 63 Future<File> delete(); |
| 65 | 64 |
| 66 /** | 65 /** |
| 67 * Synchronously delete the file. | 66 * Synchronously delete the file. |
| 68 */ | 67 */ |
| 69 void deleteSync(); | 68 void deleteSync(); |
| 70 | 69 |
| 71 /** | 70 /** |
| 72 * Get a Directory object for the directory containing this | 71 * Get a Directory object for the directory containing this |
| 73 * file. When the operation completes the callback is called with | 72 * file. Returns a [:Future<Directory>:] that completes with the |
| 74 * the result. If the file does not exist the [onError] function | 73 * directory. |
| 75 * registered on the file object is called. | |
| 76 */ | 74 */ |
| 77 void directory(void callback(Directory dir)); | 75 Future<Directory> directory(); |
| 78 | 76 |
| 79 /** | 77 /** |
| 80 * Synchronously get a Directory object for the directory containing | 78 * Synchronously get a Directory object for the directory containing |
| 81 * this file. | 79 * this file. |
| 82 */ | 80 */ |
| 83 Directory directorySync(); | 81 Directory directorySync(); |
| 84 | 82 |
| 85 /** | 83 /** |
| 86 * Get the length of the file. When the operation completes the | 84 * Get the length of the file. Returns a [:Future<int>:] that |
| 87 * callback is called with the length. | 85 * completes with the length in bytes. |
| 88 */ | 86 */ |
| 89 void length(void callback(int length)); | 87 Future<int> length(); |
| 90 | 88 |
| 91 /** | 89 /** |
| 92 * Synchronously get the length of the file. | 90 * Synchronously get the length of the file. |
| 93 */ | 91 */ |
| 94 int lengthSync(); | 92 int lengthSync(); |
| 95 | 93 |
| 96 /** | 94 /** |
| 97 * Open the file for random access operations. When the file is | 95 * Open the file for random access operations. Returns a |
| 98 * opened the callback is called with the resulting | 96 * [:Future<RandomAccessFile>:] that completes with the opened |
| 99 * RandomAccessFile. RandomAccessFiles must be closed using the | 97 * random access file. RandomAccessFiles must be closed using the |
| 100 * [close] method. If the file cannot be opened [onError] is called. | 98 * [close] method. |
| 101 * | 99 * |
| 102 * Files can be opened in three modes: | 100 * Files can be opened in three modes: |
| 103 * | 101 * |
| 104 * FileMode.READ: open the file for reading. If the file does not | 102 * FileMode.READ: open the file for reading. If the file does not |
| 105 * exist [onError] is called. | 103 * exist [onError] is called. |
| 106 * | 104 * |
| 107 * FileMode.WRITE: open the file for both reading and writing and | 105 * FileMode.WRITE: open the file for both reading and writing and |
| 108 * truncate the file to length zero. If the file does not exist the | 106 * truncate the file to length zero. If the file does not exist the |
| 109 * file is created. | 107 * file is created. |
| 110 * | 108 * |
| 111 * FileMode.APPEND: same as FileMode.WRITE except that the file is | 109 * FileMode.APPEND: same as FileMode.WRITE except that the file is |
| 112 * not truncated. | 110 * not truncated. |
| 111 * |
| 112 * The default value for [mode] is [:FileMode.READ:]. |
| 113 */ | 113 */ |
| 114 void open(FileMode mode, void callback(RandomAccessFile opened)); | 114 Future<RandomAccessFile> open([FileMode mode]); |
| 115 | 115 |
| 116 /** | 116 /** |
| 117 * Synchronously open the file for random access operations. The | 117 * Synchronously open the file for random access operations. The |
| 118 * result is a RandomAccessFile on which random access operations | 118 * result is a RandomAccessFile on which random access operations |
| 119 * can be performed. Opened RandomAccessFiles must be closed using | 119 * can be performed. Opened RandomAccessFiles must be closed using |
| 120 * the [close] method. | 120 * the [close] method. |
| 121 * | 121 * |
| 122 * The default value for [mode] is [:FileMode.READ:]. | 122 * The default value for [mode] is [:FileMode.READ:]. |
| 123 * | 123 * |
| 124 * See [open] for information on the [mode] argument. | 124 * See [open] for information on the [mode] argument. |
| 125 */ | 125 */ |
| 126 RandomAccessFile openSync([FileMode mode]); | 126 RandomAccessFile openSync([FileMode mode]); |
| 127 | 127 |
| 128 /** | 128 /** |
| 129 * Get the canonical full path corresponding to the file name. The | 129 * Get the canonical full path corresponding to the file name. |
| 130 * callback is called with the result when the | 130 * Returns a [:Future<String>:] that completes with the path. |
| 131 * fullPath operation completes. If the operation fails the | |
| 132 * [onError] function registered on the file object is called. | |
| 133 */ | 131 */ |
| 134 void fullPath(void callback(String path)); | 132 Future<String> fullPath(); |
| 135 | 133 |
| 136 /** | 134 /** |
| 137 * Synchronously get the canonical full path corresponding to the file name. | 135 * Synchronously get the canonical full path corresponding to the file name. |
| 138 */ | 136 */ |
| 139 String fullPathSync(); | 137 String fullPathSync(); |
| 140 | 138 |
| 141 /** | 139 /** |
| 142 * Create a new independent input stream for the file. The file | 140 * Create a new independent input stream for the file. The file |
| 143 * input stream must be closed when no longer used to free up system | 141 * input stream must be closed when no longer used to free up system |
| 144 * resources. | 142 * resources. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 156 * file to length zero. | 154 * file to length zero. |
| 157 * | 155 * |
| 158 * FileMode.APPEND: create the stream and set the position to the end of | 156 * FileMode.APPEND: create the stream and set the position to the end of |
| 159 * the underlying file. | 157 * the underlying file. |
| 160 * | 158 * |
| 161 * By default the mode is FileMode.WRITE. | 159 * By default the mode is FileMode.WRITE. |
| 162 */ | 160 */ |
| 163 OutputStream openOutputStream([FileMode mode]); | 161 OutputStream openOutputStream([FileMode mode]); |
| 164 | 162 |
| 165 /** | 163 /** |
| 166 * Read the entire file contents as a list of bytes. When the | 164 * Read the entire file contents as a list of bytes. Returns a |
| 167 * operation completes the callback is called. The [onError] | 165 * [:Future<List<int>>:] that completes with the list of bytes that |
| 168 * function registered on the file object is called if the operation | 166 * is the contents of the file. |
| 169 * fails. | |
| 170 */ | 167 */ |
| 171 void readAsBytes(void callback(List<int> bytes)); | 168 Future<List<int>> readAsBytes(); |
| 172 | 169 |
| 173 /** | 170 /** |
| 174 * Synchronously read the entire file contents as a list of bytes. | 171 * Synchronously read the entire file contents as a list of bytes. |
| 175 */ | 172 */ |
| 176 List<int> readAsBytesSync(); | 173 List<int> readAsBytesSync(); |
| 177 | 174 |
| 178 /** | 175 /** |
| 179 * Read the entire file contents as text using the given | 176 * Read the entire file contents as text using the given |
| 180 * [encoding]. The default encoding is UTF-8 - [:Encoding.UTF_8:]. | 177 * [encoding]. The default encoding is [:Encoding.UTF_8:]. |
| 181 * | 178 * |
| 182 * When the operation completes the callback is called. The | 179 * Returns a [:Future<String>:] that completes with the string once |
| 183 * [onError] function registered on the file object is called if the | 180 * the file contents has been read. |
| 184 * operation fails. | |
| 185 */ | 181 */ |
| 186 void readAsText(Encoding encoding, void callback(String text)); | 182 Future<String> readAsText([Encoding encoding]); |
| 187 | 183 |
| 188 /** | 184 /** |
| 189 * Synchronously read the entire file contents as text using the | 185 * Synchronously read the entire file contents as text using the |
| 190 * given [encoding]. The default encoding is UTF-8 - [:Encoding.UTF_8:]. | 186 * given [encoding]. The default encoding is [:Encoding.UTF_8:]. |
| 191 */ | 187 */ |
| 192 String readAsTextSync([Encoding encoding]); | 188 String readAsTextSync([Encoding encoding]); |
| 193 | 189 |
| 194 /** | 190 /** |
| 195 * Read the entire file contents as lines of text using the give | 191 * Read the entire file contents as lines of text using the give |
| 196 * [encoding]. The default encoding is UTF-8 - [:Encoding.UTF_8:]. | 192 * [encoding]. The default encoding is [:Encoding.UTF_8:]. |
| 197 * | 193 * |
| 198 * When the operation completes the callback is called. The | 194 * Returns a [:Future<List<String>>:] that completes with the lines |
| 199 * [onError] function registered on the file object is called if the | 195 * once the file contents has been read. |
| 200 * operation fails. | |
| 201 */ | 196 */ |
| 202 void readAsLines(Encoding encoding, void callback(List<String> lines)); | 197 Future<List<String>> readAsLines([Encoding encoding]); |
| 203 | 198 |
| 204 /** | 199 /** |
| 205 * Synchronously read the entire file contents as lines of text | 200 * Synchronously read the entire file contents as lines of text |
| 206 * using the given [encoding] The default encoding is UTF-8 - | 201 * using the given [encoding] The default encoding is |
| 207 * [:Encoding.UTF_8:]. | 202 * [:Encoding.UTF_8:]. |
| 208 */ | 203 */ |
| 209 List<String> readAsLinesSync([Encoding encoding]); | 204 List<String> readAsLinesSync([Encoding encoding]); |
| 210 | 205 |
| 211 /** | 206 /** |
| 212 * Get the name of the file. | 207 * Get the name of the file. |
| 213 */ | 208 */ |
| 214 String get name(); | 209 String get name(); |
| 215 | |
| 216 /** | |
| 217 * Sets the handler that gets called when errors occur during | |
| 218 * operations on this file. | |
| 219 */ | |
| 220 void set onError(void handler(e)); | |
| 221 } | 210 } |
| 222 | 211 |
| 223 | 212 |
| 224 /** | 213 /** |
| 225 * [RandomAccessFile] provides random access to the data in a | 214 * [RandomAccessFile] provides random access to the data in a |
| 226 * file. [RandomAccessFile] objects are obtained by calling the | 215 * file. [RandomAccessFile] objects are obtained by calling the |
| 227 * [:open:] method on a [File] object. | 216 * [:open:] method on a [File] object. |
| 228 */ | 217 */ |
| 229 interface RandomAccessFile { | 218 interface RandomAccessFile { |
| 230 /** | 219 /** |
| 231 * Close the file. When the file is closed the callback is called. | 220 * Close the file. Returns a [:Future<RandomAccessFile>:] that |
| 221 * completes with this RandomAccessFile when it has been closed. |
| 232 */ | 222 */ |
| 233 void close(void callback()); | 223 Future<RandomAccessFile> close(); |
| 234 | 224 |
| 235 /** | 225 /** |
| 236 * Synchronously close the file. | 226 * Synchronously close the file. |
| 237 */ | 227 */ |
| 238 void closeSync(); | 228 void closeSync(); |
| 239 | 229 |
| 240 /** | 230 /** |
| 241 * Read a byte from the file. When the byte has been read the | 231 * Read a byte from the file. Returns a [:Future<int>:] that |
| 242 * callback is called with the value. If end of file has been | 232 * completes with the byte or -1 if end of file has been reached. |
| 243 * reached the value will be -1. | |
| 244 */ | 233 */ |
| 245 void readByte(void callback(int byte)); | 234 Future<int> readByte(); |
| 246 | 235 |
| 247 /** | 236 /** |
| 248 * Synchronously read a single byte from the file. If end of file | 237 * Synchronously read a single byte from the file. If end of file |
| 249 * has been reached -1 is returned. | 238 * has been reached -1 is returned. |
| 250 */ | 239 */ |
| 251 int readByteSync(); | 240 int readByteSync(); |
| 252 | 241 |
| 253 /** | 242 /** |
| 254 * Read a List<int> from the file. When the list has been read the | 243 * Read a List<int> from the file. Returns a [:Future<int>:] that |
| 255 * callback is called with an integer indicating how much was read. | 244 * completes with an indication of how much was read. |
| 256 */ | 245 */ |
| 257 void readList(List<int> buffer, int offset, int bytes, | 246 Future<int> readList(List<int> buffer, int offset, int bytes); |
| 258 void callback(int read)); | |
| 259 | 247 |
| 260 /** | 248 /** |
| 261 * Synchronously read a List<int> from the file. Returns the number | 249 * Synchronously read a List<int> from the file. Returns the number |
| 262 * of bytes read. | 250 * of bytes read. |
| 263 */ | 251 */ |
| 264 int readListSync(List<int> buffer, int offset, int bytes); | 252 int readListSync(List<int> buffer, int offset, int bytes); |
| 265 | 253 |
| 266 /** | 254 /** |
| 267 * Write a single byte to the file. If the byte cannot be written | 255 * Write a single byte to the file. Returns a |
| 268 * [onError] is called. When all pending write operations have | 256 * [:Future<RandomAccessFile>:] that completes with this |
| 269 * finished [onNoPendingWrites] is called. | 257 * RandomAccessFile when the write completes. |
| 270 */ | 258 */ |
| 271 void writeByte(int value); | 259 Future<RandomAccessFile> writeByte(int value); |
| 272 | 260 |
| 273 /** | 261 /** |
| 274 * Synchronously write a single byte to the file. Returns the | 262 * Synchronously write a single byte to the file. Returns the |
| 275 * number of bytes successfully written. | 263 * number of bytes successfully written. |
| 276 */ | 264 */ |
| 277 int writeByteSync(int value); | 265 int writeByteSync(int value); |
| 278 | 266 |
| 279 /** | 267 /** |
| 280 * Write a List<int> to the file. If the list cannot be written the | 268 * Write a List<int> to the file. Returns a |
| 281 * [onError] is called. When all pending write operations have | 269 * [:Future<RandomAccessFile>:] that completes with this |
| 282 * finished [onNoPendingWrites] is called. | 270 * RandomAccessFile when the write completes. |
| 283 */ | 271 */ |
| 284 void writeList(List<int> buffer, int offset, int bytes); | 272 Future<RandomAccessFile> writeList(List<int> buffer, int offset, int bytes); |
| 285 | 273 |
| 286 /** | 274 /** |
| 287 * Synchronously write a List<int> to the file. Returns the number | 275 * Synchronously write a List<int> to the file. Returns the number |
| 288 * of bytes successfully written. | 276 * of bytes successfully written. |
| 289 */ | 277 */ |
| 290 int writeListSync(List<int> buffer, int offset, int bytes); | 278 int writeListSync(List<int> buffer, int offset, int bytes); |
| 291 | 279 |
| 292 /** | 280 /** |
| 293 * Write a string to the file using the given [encoding]. If the | 281 * Write a string to the file using the given [encoding]. The |
| 294 * string cannot be written [onError] is called. The default | 282 * default encoding is UTF-8 - [:Encoding.UTF_8:]. Returns a |
| 295 * encoding is UTF-8 - [:Encoding.UTF_8:]. | 283 * [:Future<RandomAccessFile>:] that completes with this |
| 296 * | 284 * RandomAccessFile when the write completes. |
| 297 * When all pending write operations have finished | |
| 298 * [onNoPendingWrites] is called. | |
| 299 */ | 285 */ |
| 300 void writeString(String string, [Encoding encoding]); | 286 Future<RandomAccessFile> writeString(String string, [Encoding encoding]); |
| 301 | 287 |
| 302 /** | 288 /** |
| 303 * Synchronously write a single string to the file using the given | 289 * Synchronously write a single string to the file using the given |
| 304 * [encoding]. Returns the number of characters successfully | 290 * [encoding]. Returns the number of characters successfully |
| 305 * written. The default encoding is UTF-8 - [:Encoding.UTF_8:]. | 291 * written. The default encoding is UTF-8 - [:Encoding.UTF_8:]. |
| 306 */ | 292 */ |
| 307 int writeStringSync(String string, [Encoding encoding]); | 293 int writeStringSync(String string, [Encoding encoding]); |
| 308 | 294 |
| 309 /** | 295 /** |
| 310 * Get the current byte position in the file. When the operation | 296 * Get the current byte position in the file. Returns a |
| 311 * completes the callback is called with the position. | 297 * [:Future<int>:] that completes with the position. |
| 312 */ | 298 */ |
| 313 void position(void callback(int position)); | 299 Future<int> position(); |
| 314 | 300 |
| 315 /** | 301 /** |
| 316 * Synchronously get the current byte position in the file. | 302 * Synchronously get the current byte position in the file. |
| 317 */ | 303 */ |
| 318 int positionSync(); | 304 int positionSync(); |
| 319 | 305 |
| 320 /** | 306 /** |
| 321 * Set the byte position in the file. When the operation completes | 307 * Set the byte position in the file. Returns a |
| 322 * the callback is called. | 308 * [:Future<RandomAccessFile>:] that completes with this |
| 309 * RandomAccessFile when the position has been set. |
| 323 */ | 310 */ |
| 324 void setPosition(int position, void callback()); | 311 Future<RandomAccessFile> setPosition(int position); |
| 325 | 312 |
| 326 /** | 313 /** |
| 327 * Synchronously set the byte position in the file. | 314 * Synchronously set the byte position in the file. |
| 328 */ | 315 */ |
| 329 void setPositionSync(int position); | 316 void setPositionSync(int position); |
| 330 | 317 |
| 331 /** | 318 /** |
| 332 * Truncate (or extend) the file to [length] bytes. When the | 319 * Truncate (or extend) the file to [length] bytes. Returns a |
| 333 * operation completes successfully the callback is called. | 320 * [:Future<RandomAccessFile>:] that completes with this |
| 321 * RandomAccessFile when the truncation has been performed. |
| 334 */ | 322 */ |
| 335 void truncate(int length, void callback()); | 323 Future<RandomAccessFile> truncate(int length); |
| 336 | 324 |
| 337 /** | 325 /** |
| 338 * Synchronously truncate (or extend) the file to [length] bytes. | 326 * Synchronously truncate (or extend) the file to [length] bytes. |
| 339 */ | 327 */ |
| 340 void truncateSync(int length); | 328 void truncateSync(int length); |
| 341 | 329 |
| 342 /** | 330 /** |
| 343 * Get the length of the file. When the operation completes the | 331 * Get the length of the file. Returns a [:Future<int>:] that |
| 344 * callback is called with the length. | 332 * completes with the length in bytes. |
| 345 */ | 333 */ |
| 346 void length(void callback(int length)); | 334 Future<int> length(); |
| 347 | 335 |
| 348 /** | 336 /** |
| 349 * Synchronously get the length of the file. | 337 * Synchronously get the length of the file. |
| 350 */ | 338 */ |
| 351 int lengthSync(); | 339 int lengthSync(); |
| 352 | 340 |
| 353 /** | 341 /** |
| 354 * Flush the contents of the file to disk. The callback is | 342 * Flush the contents of the file to disk. Returns a |
| 355 * called when the flush operation completes. | 343 * [:Future<RandomAccessFile>:] that completes with this |
| 344 * RandomAccessFile when the flush operation completes. |
| 356 */ | 345 */ |
| 357 void flush(void callback()); | 346 Future<RandomAccessFile> flush(); |
| 358 | 347 |
| 359 /** | 348 /** |
| 360 * Synchronously flush the contents of the file to disk. | 349 * Synchronously flush the contents of the file to disk. |
| 361 */ | 350 */ |
| 362 void flushSync(); | 351 void flushSync(); |
| 363 | 352 |
| 364 /** | 353 /** |
| 365 * Get the name of the file. | 354 * Get the name of the file. |
| 366 */ | 355 */ |
| 367 String get name(); | 356 String get name(); |
| 368 | |
| 369 /** | |
| 370 * Sets the handler that gets called when there are no more write | |
| 371 * operations pending for this file. | |
| 372 */ | |
| 373 void set onNoPendingWrites(void handler()); | |
| 374 | |
| 375 /** | |
| 376 * Sets the handler that gets called when errors occur when | |
| 377 * operating on this file. | |
| 378 */ | |
| 379 void set onError(void handler(e)); | |
| 380 } | 357 } |
| 381 | 358 |
| 382 | 359 |
| 383 class FileIOException implements Exception { | 360 class FileIOException implements Exception { |
| 384 const FileIOException([String this.message = "", | 361 const FileIOException([String this.message = "", |
| 385 OSError this.osError = null]); | 362 OSError this.osError = null]); |
| 386 String toString() { | 363 String toString() { |
| 387 StringBuffer sb = new StringBuffer(); | 364 StringBuffer sb = new StringBuffer(); |
| 388 sb.add("FileIOException"); | 365 sb.add("FileIOException"); |
| 389 if (!message.isEmpty()) { | 366 if (!message.isEmpty()) { |
| 390 sb.add(": $message"); | 367 sb.add(": $message"); |
| 391 if (osError != null) { | 368 if (osError != null) { |
| 392 sb.add(" ($osError)"); | 369 sb.add(" ($osError)"); |
| 393 } | 370 } |
| 394 } else if (osError != null) { | 371 } else if (osError != null) { |
| 395 sb.add(": osError"); | 372 sb.add(": osError"); |
| 396 } | 373 } |
| 397 return sb.toString(); | 374 return sb.toString(); |
| 398 } | 375 } |
| 399 final String message; | 376 final String message; |
| 400 final OSError osError; | 377 final OSError osError; |
| 401 } | 378 } |
| OLD | NEW |