Skip to content

Commit 725df3c

Browse files
authored
Fix the 1024 bytes package spliting in Dart (#1667)
2 parents 7bff9b9 + 51298b6 commit 725df3c

File tree

2 files changed

+50
-11
lines changed

2 files changed

+50
-11
lines changed

app/lib/backend/http/api/messages.dart

+36-6
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'package:friend_private/backend/http/shared.dart';
66
import 'package:friend_private/backend/schema/message.dart';
77
import 'package:friend_private/env/env.dart';
88
import 'package:friend_private/utils/logger.dart';
9+
import 'package:friend_private/utils/other/string_utils.dart';
910
import 'package:http/http.dart' as http;
1011
import 'package:instabug_flutter/instabug_flutter.dart';
1112
import 'package:path/path.dart';
@@ -99,10 +100,25 @@ Stream<ServerMessageChunk> sendMessageStreamServer(String text, {String? appId})
99100
return;
100101
}
101102

102-
var messageId = "1000"; // default new message
103+
var buffers = <String>[];
104+
var messageId = "1000"; // Default new message
103105
await for (var data in response.transform(utf8.decoder)) {
104106
var lines = data.split('\n\n');
105107
for (var line in lines.where((line) => line.isNotEmpty)) {
108+
// Dealing w/ the package spliting by 1024 bytes in dart
109+
// Waiting for the next package
110+
if (line.length >= 1024) {
111+
buffers.add(line);
112+
continue;
113+
}
114+
115+
// Merge package if needed
116+
if (buffers.isNotEmpty) {
117+
buffers.add(line);
118+
line = buffers.join();
119+
buffers.clear();
120+
}
121+
106122
if (line.startsWith('think: ')) {
107123
yield ServerMessageChunk(messageId, line.substring(7).replaceAll("__CRLF__", "\n"), MessageChunkType.think);
108124
continue;
@@ -114,8 +130,7 @@ Stream<ServerMessageChunk> sendMessageStreamServer(String text, {String? appId})
114130
}
115131

116132
if (line.startsWith('done: ')) {
117-
var text = utf8.decode(base64.decode(line.substring(6)));
118-
debugPrint(text);
133+
var text = decodeBase64(line.substring(6));
119134
yield ServerMessageChunk(messageId, text, MessageChunkType.done,
120135
message: ServerMessage.fromJson(json.decode(text)));
121136
continue;
@@ -162,10 +177,25 @@ Stream<ServerMessageChunk> sendVoiceMessageStreamServer(List<File> files) async*
162177
return;
163178
}
164179

165-
var messageId = "1000"; // default new message
180+
var buffers = <String>[];
181+
var messageId = "1000"; // Default new message
166182
await for (var data in response.stream.transform(utf8.decoder)) {
167183
var lines = data.split('\n\n');
168184
for (var line in lines.where((line) => line.isNotEmpty)) {
185+
// Dealing w/ the package spliting by 1024 bytes in dart
186+
// Waiting for the next package
187+
if (line.length >= 1024) {
188+
buffers.add(line);
189+
continue;
190+
}
191+
192+
// Merge package if needed
193+
if (buffers.isNotEmpty) {
194+
buffers.add(line);
195+
line = buffers.join();
196+
buffers.clear();
197+
}
198+
169199
if (line.startsWith('think: ')) {
170200
yield ServerMessageChunk(messageId, line.substring(7).replaceAll("__CRLF__", "\n"), MessageChunkType.think);
171201
continue;
@@ -177,14 +207,14 @@ Stream<ServerMessageChunk> sendVoiceMessageStreamServer(List<File> files) async*
177207
}
178208

179209
if (line.startsWith('done: ')) {
180-
var text = utf8.decode(base64.decode(line.substring(6)));
210+
var text = decodeBase64(line.substring(6));
181211
yield ServerMessageChunk(messageId, text, MessageChunkType.done,
182212
message: ServerMessage.fromJson(json.decode(text)));
183213
continue;
184214
}
185215

186216
if (line.startsWith('message: ')) {
187-
var text = utf8.decode(base64.decode(line.substring(9)));
217+
var text = decodeBase64(line.substring(9));
188218
yield ServerMessageChunk(messageId, text, MessageChunkType.message,
189219
message: ServerMessage.fromJson(json.decode(text)));
190220
continue;

app/lib/utils/other/string_utils.dart

+14-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// string_utils.dart
22

3+
import 'dart:convert';
4+
35
String extractJson(String input) {
46
int braceCount = 0;
57
int startIndex = -1;
@@ -34,12 +36,19 @@ String extractJson(String input) {
3436
}
3537

3638
String convertToHHMMSS(int seconds) {
37-
int hours = seconds ~/ 3600;
38-
int minutes = (seconds % 3600) ~/ 60;
39-
int remainingSeconds = seconds % 60;
39+
int hours = seconds ~/ 3600;
40+
int minutes = (seconds % 3600) ~/ 60;
41+
int remainingSeconds = seconds % 60;
42+
43+
String twoDigits(int n) => n.toString().padLeft(2, '0');
4044

41-
String twoDigits(int n) => n.toString().padLeft(2, '0');
45+
return '${twoDigits(hours)}:${twoDigits(minutes)}:${twoDigits(remainingSeconds)}';
46+
}
4247

43-
return '${twoDigits(hours)}:${twoDigits(minutes)}:${twoDigits(remainingSeconds)}';
48+
String padBase64(String rawBase64) {
49+
return (rawBase64.length % 4 > 0) ? rawBase64 += List.filled(4 - (rawBase64.length % 4), "_").join("") : rawBase64;
4450
}
4551

52+
String decodeBase64(String data) {
53+
return utf8.decode(base64.decode(padBase64(data)));
54+
}

0 commit comments

Comments
 (0)