@@ -8,10 +8,12 @@ import 'dart:convert';
8
8
import 'package:file/file.dart' ;
9
9
import 'package:file/src/io.dart' as io;
10
10
11
+ import 'mutable_recording.dart' ;
11
12
import 'recording_file_system.dart' ;
12
13
import 'recording_file_system_entity.dart' ;
13
14
import 'recording_io_sink.dart' ;
14
15
import 'recording_random_access_file.dart' ;
16
+ import 'result_reference.dart' ;
15
17
16
18
/// [File] implementation that records all invocation activity to its file
17
19
/// system's recording.
@@ -31,14 +33,14 @@ class RecordingFile extends RecordingFileSystemEntity<File, io.File>
31
33
#lastModifiedSync: delegate.lastModifiedSync,
32
34
#open: _open,
33
35
#openSync: _openSync,
34
- #openRead: delegate.openRead ,
36
+ #openRead: _openRead ,
35
37
#openWrite: _openWrite,
36
- #readAsBytes: delegate.readAsBytes ,
37
- #readAsBytesSync: delegate.readAsBytesSync ,
38
- #readAsString: delegate.readAsString ,
39
- #readAsStringSync: delegate.readAsStringSync ,
40
- #readAsLines: delegate.readAsLines ,
41
- #readAsLinesSync: delegate.readAsLinesSync ,
38
+ #readAsBytes: _readAsBytes ,
39
+ #readAsBytesSync: _readAsBytesSync ,
40
+ #readAsString: _readAsString ,
41
+ #readAsStringSync: _readAsStringSync ,
42
+ #readAsLines: _readAsLines ,
43
+ #readAsLinesSync: _readAsLinesSync ,
42
44
#writeAsBytes: _writeAsBytes,
43
45
#writeAsBytesSync: delegate.writeAsBytesSync,
44
46
#writeAsString: _writeAsString,
@@ -65,13 +67,60 @@ class RecordingFile extends RecordingFileSystemEntity<File, io.File>
65
67
RandomAccessFile _openSync ({FileMode mode: FileMode .READ }) =>
66
68
_wrapRandomAccessFile (delegate.openSync (mode: mode));
67
69
70
+ StreamReference <List <int >> _openRead ([int start, int end]) =>
71
+ new _ByteArrayStreamReference (
72
+ recording,
73
+ 'openRead' ,
74
+ delegate.openRead (start, end),
75
+ );
76
+
68
77
IOSink _openWrite ({FileMode mode: FileMode .WRITE , Encoding encoding: UTF8 }) {
69
78
return new RecordingIOSink (
70
79
fileSystem,
71
80
delegate.openWrite (mode: mode, encoding: encoding),
72
81
);
73
82
}
74
83
84
+ FutureReference <List <int >> _readAsBytes () => new _ByteArrayFutureReference (
85
+ recording,
86
+ 'readAsBytes' ,
87
+ delegate.readAsBytes (),
88
+ );
89
+
90
+ ResultReference <List <int >> _readAsBytesSync () => new _ByteArrayReference (
91
+ recording,
92
+ 'readAsBytesSync' ,
93
+ delegate.readAsBytesSync (),
94
+ );
95
+
96
+ FutureReference <String > _readAsString ({Encoding encoding: UTF8 }) =>
97
+ new _FileContentFutureReference (
98
+ recording,
99
+ 'readAsString' ,
100
+ delegate.readAsString (encoding: encoding),
101
+ );
102
+
103
+ ResultReference <String > _readAsStringSync ({Encoding encoding: UTF8 }) =>
104
+ new _FileContentReference (
105
+ recording,
106
+ 'readAsStringSync' ,
107
+ delegate.readAsStringSync (encoding: encoding),
108
+ );
109
+
110
+ FutureReference <List <String >> _readAsLines ({Encoding encoding: UTF8 }) =>
111
+ new _LinesFutureReference (
112
+ recording,
113
+ 'readAsLines' ,
114
+ delegate.readAsLines (encoding: encoding),
115
+ );
116
+
117
+ ResultReference <List <String >> _readAsLinesSync ({Encoding encoding: UTF8 }) =>
118
+ new _LinesReference (
119
+ recording,
120
+ 'readAsLinesSync' ,
121
+ delegate.readAsLinesSync (encoding: encoding),
122
+ );
123
+
75
124
Future <File > _writeAsBytes (
76
125
List <int > bytes, {
77
126
FileMode mode: FileMode .WRITE ,
@@ -89,3 +138,156 @@ class RecordingFile extends RecordingFileSystemEntity<File, io.File>
89
138
.writeAsString (contents, mode: mode, encoding: encoding, flush: flush)
90
139
.then (wrap);
91
140
}
141
+
142
+ class _ByteArrayStreamReference extends StreamReference <List <int >> {
143
+ final File file;
144
+ IOSink _sink;
145
+
146
+ _ByteArrayStreamReference (
147
+ MutableRecording recording, String name, Stream <List <int >> stream)
148
+ : file = recording.newFile (name)..createSync (),
149
+ super (stream);
150
+
151
+ @override
152
+ void onData (List <int > event) {
153
+ if (_sink == null ) {
154
+ _sink = file.openWrite ();
155
+ }
156
+ _sink.add (event);
157
+ }
158
+
159
+ @override
160
+ void onDone () {
161
+ if (_sink != null ) {
162
+ _sink.close ();
163
+ }
164
+ }
165
+
166
+ @override
167
+ dynamic get serializedValue => '!${file .basename }' ;
168
+
169
+ // TODO(tvolkert): remove `.then()` once Dart 1.22 is in stable
170
+ @override
171
+ Future <Null > get complete =>
172
+ Future .wait (< Future <dynamic >> [super .complete, _sink.done]).then ((_) {});
173
+ }
174
+
175
+ class _ByteArrayFutureReference extends FutureReference <List <int >> {
176
+ final File file;
177
+
178
+ _ByteArrayFutureReference (
179
+ MutableRecording recording, String name, Future <List <int >> future)
180
+ : file = recording.newFile (name),
181
+ super (future);
182
+
183
+ @override
184
+ Future <List <int >> get value {
185
+ return super .value.then ((List <int > bytes) async {
186
+ await file.writeAsBytes (bytes, flush: true );
187
+ return bytes;
188
+ });
189
+ }
190
+
191
+ @override
192
+ dynamic get serializedValue => '!${file .basename }' ;
193
+ }
194
+
195
+ class _ByteArrayReference extends ResultReference <List <int >> {
196
+ final File file;
197
+ final List <int > bytes;
198
+
199
+ _ByteArrayReference (MutableRecording recording, String name, this .bytes)
200
+ : file = recording.newFile (name);
201
+
202
+ @override
203
+ List <int > get value {
204
+ file.writeAsBytesSync (bytes, flush: true );
205
+ return bytes;
206
+ }
207
+
208
+ @override
209
+ List <int > get recordedValue => bytes;
210
+
211
+ @override
212
+ dynamic get serializedValue => '!${file .basename }' ;
213
+ }
214
+
215
+ class _FileContentFutureReference extends FutureReference <String > {
216
+ final File file;
217
+
218
+ _FileContentFutureReference (
219
+ MutableRecording recording, String name, Future <String > future)
220
+ : file = recording.newFile (name),
221
+ super (future);
222
+
223
+ @override
224
+ Future <String > get value {
225
+ return super .value.then ((String content) async {
226
+ await file.writeAsString (content, flush: true );
227
+ return content;
228
+ });
229
+ }
230
+
231
+ @override
232
+ dynamic get serializedValue => '!${file .basename }' ;
233
+ }
234
+
235
+ class _FileContentReference extends ResultReference <String > {
236
+ final File file;
237
+ final String content;
238
+
239
+ _FileContentReference (MutableRecording recording, String name, this .content)
240
+ : file = recording.newFile (name);
241
+
242
+ @override
243
+ String get value {
244
+ file.writeAsStringSync (content, flush: true );
245
+ return content;
246
+ }
247
+
248
+ @override
249
+ String get recordedValue => content;
250
+
251
+ @override
252
+ dynamic get serializedValue => '!${file .basename }' ;
253
+ }
254
+
255
+ class _LinesFutureReference extends FutureReference <List <String >> {
256
+ final File file;
257
+
258
+ _LinesFutureReference (
259
+ MutableRecording recording, String name, Future <List <String >> future)
260
+ : file = recording.newFile (name),
261
+ super (future);
262
+
263
+ @override
264
+ Future <List <String >> get value {
265
+ return super .value.then ((List <String > lines) async {
266
+ await file.writeAsString (lines.join ('\n ' ), flush: true );
267
+ return lines;
268
+ });
269
+ }
270
+
271
+ @override
272
+ dynamic get serializedValue => '!${file .basename }' ;
273
+ }
274
+
275
+ class _LinesReference extends ResultReference <List <String >> {
276
+ final File file;
277
+ final List <String > lines;
278
+
279
+ _LinesReference (MutableRecording recording, String name, this .lines)
280
+ : file = recording.newFile (name);
281
+
282
+ @override
283
+ List <String > get value {
284
+ file.writeAsStringSync (lines.join ('\n ' ), flush: true );
285
+ return lines;
286
+ }
287
+
288
+ @override
289
+ List <String > get recordedValue => lines;
290
+
291
+ @override
292
+ dynamic get serializedValue => '!${file .basename }' ;
293
+ }
0 commit comments