From e5b04f44d2e457419e3dc3d3e0e7f91bce9aef35 Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Sun, 19 Nov 2023 12:09:35 +0100 Subject: [PATCH] perf(dynamite_runtime,nextcloud): BytesStreamExtension add stream based xml decoding Signed-off-by: Nikolas Rimikis --- .../lib/src/http_extensions.dart | 20 +++++++++++++++++-- .../dynamite/dynamite_runtime/pubspec.yaml | 2 ++ packages/nextcloud/lib/src/webdav/client.dart | 3 +-- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/packages/dynamite/dynamite_runtime/lib/src/http_extensions.dart b/packages/dynamite/dynamite_runtime/lib/src/http_extensions.dart index 7351e2de..6da979cc 100644 --- a/packages/dynamite/dynamite_runtime/lib/src/http_extensions.dart +++ b/packages/dynamite/dynamite_runtime/lib/src/http_extensions.dart @@ -3,13 +3,18 @@ import 'dart:convert'; import 'dart:typed_data'; import 'package:universal_io/io.dart'; +import 'package:xml/xml.dart'; +import 'package:xml/xml_events.dart'; /// A stream of bytes. /// /// Usually a `Stream`. typedef BytesStream = Stream>; -final _utf8JsonDecoder = utf8.decoder.fuse(json.decoder); +final _jsonBytesConverter = utf8.decoder.fuse(json.decoder); + +final _xmlBytesConverter = + utf8.decoder.fuse(XmlEventDecoder()).fuse(const XmlNormalizeEvents()).fuse(const XmlNodeDecoder()); /// Extension on byte streams that enable efficient transformations. extension BytesStreamExtension on BytesStream { @@ -26,7 +31,18 @@ extension BytesStreamExtension on BytesStream { Future get string => transform(utf8.decoder).join(); /// Converts the stream into a JSON using the [utf8] encoding. - Future get json => transform(_utf8JsonDecoder).first; + Future get json => transform(_jsonBytesConverter).first; + + /// Converts the stream into XML using the [utf8] encoding. + /// + /// Returns the root element of this stream. + Future get xml async { + final element = await transform(_xmlBytesConverter) + .expand((final events) => events) + .firstWhere((final element) => element is XmlElement); + + return element as XmlElement; + } } /// Extension on a http responses. diff --git a/packages/dynamite/dynamite_runtime/pubspec.yaml b/packages/dynamite/dynamite_runtime/pubspec.yaml index 9faf1275..eeef5839 100644 --- a/packages/dynamite/dynamite_runtime/pubspec.yaml +++ b/packages/dynamite/dynamite_runtime/pubspec.yaml @@ -8,9 +8,11 @@ environment: dependencies: built_collection: ^5.0.0 built_value: ^8.0.1 + collection: ^1.0.0 cookie_jar: ^4.0.7 meta: ^1.0.0 universal_io: ^2.0.0 + xml: ^6.0.0 dev_dependencies: build_runner: ^2.4.6 diff --git a/packages/nextcloud/lib/src/webdav/client.dart b/packages/nextcloud/lib/src/webdav/client.dart index a41d7fc2..f4f7a3dd 100644 --- a/packages/nextcloud/lib/src/webdav/client.dart +++ b/packages/nextcloud/lib/src/webdav/client.dart @@ -8,7 +8,6 @@ import 'package:nextcloud/src/webdav/path_uri.dart'; import 'package:nextcloud/src/webdav/props.dart'; import 'package:nextcloud/src/webdav/webdav.dart'; import 'package:universal_io/io.dart'; -import 'package:xml/xml.dart' as xml; /// Base path used on the server final webdavBase = PathUri.parse('/remote.php/webdav'); @@ -73,7 +72,7 @@ class WebDavClient { } Future _parseResponse(final HttpClientResponse response) async => - WebDavMultistatus.fromXmlElement(xml.XmlDocument.parse(await response.string).rootElement); + WebDavMultistatus.fromXmlElement(await response.xml); Map _getUploadHeaders({ required final DateTime? lastModified,