79 lines
2.3 KiB
Dart
79 lines
2.3 KiB
Dart
import 'dart:async';
|
|
import 'dart:io';
|
|
|
|
import 'package:path_provider/path_provider.dart';
|
|
|
|
import '../layout/layout_controller.dart';
|
|
import '../session/log_buffer.dart';
|
|
import '../session/packet_buffer.dart';
|
|
import 'csv_exporter_base.dart';
|
|
|
|
export 'csv_exporter_base.dart';
|
|
|
|
/// Native CSV exporter: writes to a file in the documents directory.
|
|
class CsvExporterImpl implements CsvExporter {
|
|
static const int _chunkRows = 1000;
|
|
|
|
@override
|
|
Future<ExportResult> exportData({
|
|
required PacketBuffer buffer,
|
|
required LayoutController layout,
|
|
ProgressCallback? onProgress,
|
|
}) async {
|
|
final builder = CsvDataRowBuilder(layout);
|
|
final dir = await getApplicationDocumentsDirectory();
|
|
final ts = DateTime.now().toIso8601String().replaceAll(':', '-');
|
|
final file = File('${dir.path}/telemetry_data_$ts.csv');
|
|
final sink = file.openWrite();
|
|
sink.writeln(builder.header());
|
|
final total = buffer.length;
|
|
var written = 0;
|
|
for (var i = 0; i < total; i++) {
|
|
sink.writeln(builder.row(buffer[i]));
|
|
written++;
|
|
if (written % _chunkRows == 0) {
|
|
onProgress?.call(written / total);
|
|
// Yield to the event loop so the UI stays responsive.
|
|
await Future<void>.delayed(Duration.zero);
|
|
}
|
|
}
|
|
await sink.flush();
|
|
await sink.close();
|
|
onProgress?.call(1.0);
|
|
return ExportResult(
|
|
path: file.path,
|
|
bytesWritten: await file.length(),
|
|
);
|
|
}
|
|
|
|
@override
|
|
Future<ExportResult> exportLog({
|
|
required LogBuffer buffer,
|
|
ProgressCallback? onProgress,
|
|
}) async {
|
|
final dir = await getApplicationDocumentsDirectory();
|
|
final ts = DateTime.now().toIso8601String().replaceAll(':', '-');
|
|
final file = File('${dir.path}/telemetry_log_$ts.csv');
|
|
final sink = file.openWrite();
|
|
const builder = CsvLogRowBuilder();
|
|
sink.writeln(builder.header());
|
|
final total = buffer.length;
|
|
var written = 0;
|
|
for (final entry in buffer.iterate()) {
|
|
sink.writeln(builder.row(entry));
|
|
written++;
|
|
if (written % _chunkRows == 0) {
|
|
onProgress?.call(written / total);
|
|
await Future<void>.delayed(Duration.zero);
|
|
}
|
|
}
|
|
await sink.flush();
|
|
await sink.close();
|
|
onProgress?.call(1.0);
|
|
return ExportResult(
|
|
path: file.path,
|
|
bytesWritten: await file.length(),
|
|
);
|
|
}
|
|
}
|