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 class _FileInputStream extends _BaseDataInputStream implements InputStream { | 5 class _FileInputStream extends _BaseDataInputStream implements InputStream { |
6 _FileInputStream(String name) | 6 _FileInputStream(String name) |
7 : _data = [], | 7 : _data = [], |
8 _position = 0, | 8 _position = 0, |
9 _filePosition = 0 { | 9 _filePosition = 0 { |
10 var file = new File(name); | 10 var file = new File(name); |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 static final int _bufferLength = 64 * 1024; | 122 static final int _bufferLength = 64 * 1024; |
123 | 123 |
124 RandomAccessFile _openedFile; | 124 RandomAccessFile _openedFile; |
125 List<int> _data; | 125 List<int> _data; |
126 int _position; | 126 int _position; |
127 int _filePosition; | 127 int _filePosition; |
128 int _fileLength; | 128 int _fileLength; |
129 } | 129 } |
130 | 130 |
131 | 131 |
| 132 class _PendingOperation { |
| 133 const _PendingOperation(this._id); |
| 134 static final _PendingOperation CLOSE = const _PendingOperation(0); |
| 135 static final _PendingOperation FLUSH = const _PendingOperation(1); |
| 136 final int _id; |
| 137 } |
| 138 |
| 139 |
132 class _FileOutputStream extends _BaseOutputStream implements OutputStream { | 140 class _FileOutputStream extends _BaseOutputStream implements OutputStream { |
133 _FileOutputStream(String name, FileMode mode) { | 141 _FileOutputStream(String name, FileMode mode) { |
134 _pendingOperations = new List<List<int>>(); | 142 _pendingOperations = new List(); |
135 var f = new File(name); | 143 var f = new File(name); |
136 var openFuture = f.open(mode); | 144 var openFuture = f.open(mode); |
137 openFuture.then((openedFile) { | 145 openFuture.then((openedFile) { |
138 _file = openedFile; | 146 _file = openedFile; |
139 _processPendingOperations(); | 147 _processPendingOperations(); |
140 }); | 148 }); |
141 openFuture.handleException((e) { | 149 openFuture.handleException((e) { |
142 _reportError(e); | 150 _reportError(e); |
143 return true; | 151 return true; |
144 }); | 152 }); |
(...skipping 24 matching lines...) Expand all Loading... |
169 var length = buffer.length - offset; | 177 var length = buffer.length - offset; |
170 if (len != null) { | 178 if (len != null) { |
171 if (len > length) throw new IndexOutOfRangeException(len); | 179 if (len > length) throw new IndexOutOfRangeException(len); |
172 length = len; | 180 length = len; |
173 } | 181 } |
174 var copy = new Uint8List(length); | 182 var copy = new Uint8List(length); |
175 copy.setRange(0, length, buffer, offset); | 183 copy.setRange(0, length, buffer, offset); |
176 return write(copy); | 184 return write(copy); |
177 } | 185 } |
178 | 186 |
| 187 |
| 188 void flush() { |
| 189 if (_file == null) { |
| 190 _pendingOperations.add(_PendingOperation.FLUSH); |
| 191 } else { |
| 192 _file.flush().then((ignored) => null); |
| 193 } |
| 194 } |
| 195 |
| 196 |
179 void close() { | 197 void close() { |
180 if (_file == null) { | 198 if (_file == null) { |
181 _pendingOperations.add(null); | 199 _pendingOperations.add(_PendingOperation.CLOSE); |
182 } else if (!_streamMarkedClosed) { | 200 } else if (!_streamMarkedClosed) { |
183 _file.close().then((ignore) { | 201 _file.close().then((ignore) { |
184 if (_onClosed != null) _onClosed(); | 202 if (_onClosed != null) _onClosed(); |
185 }); | 203 }); |
186 _streamMarkedClosed = true; | 204 _streamMarkedClosed = true; |
187 } | 205 } |
188 } | 206 } |
189 | 207 |
190 void set onNoPendingWrites(void callback()) { | 208 void set onNoPendingWrites(void callback()) { |
191 _onNoPendingWrites = callback; | 209 _onNoPendingWrites = callback; |
192 if (((_pendingOperations == null) || (_pendingOperations.length == 0)) && | 210 if (((_pendingOperations == null) || (_pendingOperations.length == 0)) && |
193 (outstandingWrites == 0) && | 211 (outstandingWrites == 0) && |
194 !_streamMarkedClosed && | 212 !_streamMarkedClosed && |
195 (_onNoPendingWrites != null)) { | 213 (_onNoPendingWrites != null)) { |
196 new Timer(0, (t) { | 214 new Timer(0, (t) { |
197 if (_onNoPendingWrites != null) { | 215 if (_onNoPendingWrites != null) { |
198 _onNoPendingWrites(); | 216 _onNoPendingWrites(); |
199 } | 217 } |
200 }); | 218 }); |
201 } | 219 } |
202 } | 220 } |
203 | 221 |
204 void set onClosed(void callback()) { | 222 void set onClosed(void callback()) { |
205 _onClosed = callback; | 223 _onClosed = callback; |
206 } | 224 } |
207 | 225 |
208 void _processPendingOperations() { | 226 void _processPendingOperations() { |
209 _pendingOperations.forEach((buffer) { | 227 _pendingOperations.forEach((buffer) { |
210 (buffer != null) ? write(buffer) : close(); | 228 if (buffer is _PendingOperation) { |
| 229 if (buffer === _PendingOperation.CLOSE) { |
| 230 close(); |
| 231 } else { |
| 232 assert(buffer === _PendingOperation.FLUSH); |
| 233 flush(); |
| 234 } |
| 235 } else { |
| 236 write(buffer); |
| 237 } |
211 }); | 238 }); |
212 _pendingOperations = null; | 239 _pendingOperations = null; |
213 } | 240 } |
214 | 241 |
215 void _write(List<int> buffer, int offset, int len) { | 242 void _write(List<int> buffer, int offset, int len) { |
216 outstandingWrites++; | 243 outstandingWrites++; |
217 var writeListFuture = _file.writeList(buffer, offset, len); | 244 var writeListFuture = _file.writeList(buffer, offset, len); |
218 writeListFuture.then((ignore) { | 245 writeListFuture.then((ignore) { |
219 outstandingWrites--; | 246 outstandingWrites--; |
220 if ((outstandingWrites == 0) && | 247 if ((outstandingWrites == 0) && |
(...skipping 17 matching lines...) Expand all Loading... |
238 | 265 |
239 // When this is set to true the close callback has been called and | 266 // When this is set to true the close callback has been called and |
240 // the stream is fully closed. | 267 // the stream is fully closed. |
241 bool _closeCallbackCalled = false; | 268 bool _closeCallbackCalled = false; |
242 | 269 |
243 // Number of writes that have not yet completed. | 270 // Number of writes that have not yet completed. |
244 int outstandingWrites = 0; | 271 int outstandingWrites = 0; |
245 | 272 |
246 // List of pending writes that were issued before the underlying | 273 // List of pending writes that were issued before the underlying |
247 // file was successfully opened. | 274 // file was successfully opened. |
248 List<List<int>> _pendingOperations; | 275 List _pendingOperations; |
249 | 276 |
250 Function _onNoPendingWrites; | 277 Function _onNoPendingWrites; |
251 Function _onClosed; | 278 Function _onClosed; |
252 } | 279 } |
253 | 280 |
254 | 281 |
255 // Helper class containing static file helper methods. | 282 // Helper class containing static file helper methods. |
256 class _FileUtils { | 283 class _FileUtils { |
257 static final EXISTS_REQUEST = 0; | 284 static final EXISTS_REQUEST = 0; |
258 static final CREATE_REQUEST = 1; | 285 static final CREATE_REQUEST = 1; |
(...skipping 845 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1104 new FileIOException("File closed '$_name'")); | 1131 new FileIOException("File closed '$_name'")); |
1105 }); | 1132 }); |
1106 return completer.future; | 1133 return completer.future; |
1107 } | 1134 } |
1108 | 1135 |
1109 final String _name; | 1136 final String _name; |
1110 int _id; | 1137 int _id; |
1111 | 1138 |
1112 SendPort _fileService; | 1139 SendPort _fileService; |
1113 } | 1140 } |
OLD | NEW |