1
1
import 'dart:async' ;
2
2
import 'dart:convert' ;
3
3
import 'dart:typed_data' ;
4
+
4
5
import 'package:http_parser/http_parser.dart' ;
5
6
6
7
import 'adapter.dart' ;
7
- import 'options.dart' ;
8
8
import 'dio_error.dart' ;
9
9
import 'headers.dart' ;
10
+ import 'options.dart' ;
10
11
import 'utils.dart' ;
11
12
12
13
/// [Transformer] allows changes to the request/response data before
@@ -83,21 +84,29 @@ class DefaultTransformer extends Transformer {
83
84
}
84
85
var completer = Completer ();
85
86
var stream =
86
- response.stream.transform <Uint8List >(StreamTransformer .fromHandlers (
87
+ response.stream.transform <Uint8List >(StreamTransformer .fromHandlers (
87
88
handleData: (data, sink) {
88
- sink.add (Uint8List . fromList ( data) );
89
+ sink.add (data);
89
90
if (showDownloadProgress) {
90
91
received += data.length;
91
92
options.onReceiveProgress (received, length);
92
93
}
93
94
},
94
95
));
95
- var buffer = < int > [];
96
- StreamSubscription subscription;
97
- subscription = stream.listen (
98
- (element) => buffer.addAll (element),
99
- onError: (e) => completer.completeError (e),
100
- onDone: () => completer.complete (),
96
+ // let's keep references to the data chunks and concatenate them later
97
+ final List <Uint8List > chunks = [];
98
+ int finalSize = 0 ;
99
+ StreamSubscription subscription = stream.listen (
100
+ (chunk) {
101
+ finalSize += chunk.length;
102
+ chunks.add (chunk);
103
+ },
104
+ onError: (e) {
105
+ completer.completeError (e);
106
+ },
107
+ onDone: () {
108
+ completer.complete ();
109
+ },
101
110
cancelOnError: true ,
102
111
);
103
112
// ignore: unawaited_futures
@@ -119,13 +128,22 @@ class DefaultTransformer extends Transformer {
119
128
} else {
120
129
await completer.future;
121
130
}
122
- if (options.responseType == ResponseType .bytes) return buffer;
131
+ // we create a final Uint8List and copy all chunks into it
132
+ final responseBytes = Uint8List (finalSize);
133
+ int chunkOffset = 0 ;
134
+ for (var chunk in chunks) {
135
+ responseBytes.setAll (chunkOffset, chunk);
136
+ chunkOffset += chunk.length;
137
+ }
138
+
139
+ if (options.responseType == ResponseType .bytes) return responseBytes;
140
+
123
141
String responseBody;
124
142
if (options.responseDecoder != null ) {
125
- responseBody =
126
- options. responseDecoder (buffer , options, response..stream = null );
143
+ responseBody = options. responseDecoder (
144
+ responseBytes , options, response..stream = null );
127
145
} else {
128
- responseBody = utf8.decode (buffer , allowMalformed: true );
146
+ responseBody = utf8.decode (responseBytes , allowMalformed: true );
129
147
}
130
148
if (responseBody != null &&
131
149
responseBody.isNotEmpty &&
0 commit comments