Skip to content

Commit bef2416

Browse files
authored
Merge pull request #57 from namib-project/improve-content
Improve `Content` APIs
2 parents 6d025ce + e9885f3 commit bef2416

File tree

9 files changed

+35
-60
lines changed

9 files changed

+35
-60
lines changed

lib/src/binding_coap/coap_client.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ final class CoapClient implements ProtocolClient {
9797
coap.BlockSize? block1Size,
9898
coap.BlockSize? block2Size,
9999
}) async {
100-
final payload = (await content?.byteBuffer)?.asUint8List();
100+
final payload = await content?.toByteList();
101101

102102
final request = coap.CoapRequest(
103103
uri,

lib/src/binding_http/http_client.dart

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -188,18 +188,15 @@ final class HttpClient implements ProtocolClient {
188188
Future<StreamedResponse> _createRequest(
189189
Form form,
190190
OperationType operationType,
191-
String? payload,
191+
Content? content,
192192
) async {
193193
final requestMethod =
194194
HttpRequestMethod.getRequestMethod(form, operationType);
195195
final Uri uri = form.resolvedHref;
196196

197197
final request = Request(requestMethod.methodName, uri)
198-
..headers.addAll(_getHeadersFromForm(form));
199-
200-
if (payload != null) {
201-
request.body = payload;
202-
}
198+
..headers.addAll(_getHeadersFromForm(form))
199+
..bodyBytes = await content?.toByteList() ?? [];
203200

204201
await _applyCredentialsFromForm(request, form);
205202

@@ -244,12 +241,6 @@ final class HttpClient implements ProtocolClient {
244241
return headers;
245242
}
246243

247-
Future<String> _getInputFromContent(Content content) async {
248-
final inputBuffer = await content.byteBuffer;
249-
return utf8.decoder
250-
.convert(inputBuffer.asUint8List().toList(growable: false));
251-
}
252-
253244
Content _contentFromResponse(Form form, StreamedResponse response) {
254245
final type = response.headers['Content-Type'] ?? form.contentType;
255246
final responseStream = response.stream.asBroadcastStream()
@@ -259,9 +250,8 @@ final class HttpClient implements ProtocolClient {
259250

260251
@override
261252
Future<Content> invokeResource(Form form, Content content) async {
262-
final input = await _getInputFromContent(content);
263253
final response =
264-
await _createRequest(form, OperationType.invokeaction, input);
254+
await _createRequest(form, OperationType.invokeaction, content);
265255
return _contentFromResponse(form, response);
266256
}
267257

@@ -284,8 +274,7 @@ final class HttpClient implements ProtocolClient {
284274

285275
@override
286276
Future<void> writeResource(Form form, Content content) async {
287-
final input = await _getInputFromContent(content);
288-
await _createRequest(form, OperationType.writeproperty, input);
277+
await _createRequest(form, OperationType.writeproperty, content);
289278
}
290279

291280
@override

lib/src/binding_mqtt/mqtt_client.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ final class MqttClient implements ProtocolClient {
107107
..publishMessage(
108108
topic,
109109
qualityOfService,
110-
Uint8Buffer()..addAll((await content.byteBuffer).asUint8List()),
110+
Uint8Buffer()..addAll(await content.toByteList()),
111111
retain: form.retain ?? false,
112112
)
113113
..disconnect();
@@ -162,7 +162,7 @@ final class MqttClient implements ProtocolClient {
162162
..publishMessage(
163163
topic,
164164
qualityOfService,
165-
Uint8Buffer()..addAll((await content.byteBuffer).asUint8List()),
165+
Uint8Buffer()..addAll(await content.toByteList()),
166166
retain: form.retain ?? false,
167167
)
168168
..disconnect();

lib/src/core/codecs/cbor_codec.dart

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
//
55
// SPDX-License-Identifier: BSD-3-Clause
66

7-
import 'dart:typed_data';
8-
97
import 'package:cbor/cbor.dart' as cbor;
108

119
import '../../definitions/data_schema.dart';
@@ -14,23 +12,21 @@ import 'content_codec.dart';
1412
/// A [ContentCodec] that encodes and decodes CBOR data.
1513
class CborCodec extends ContentCodec {
1614
@override
17-
ByteBuffer valueToBytes(
15+
List<int> valueToBytes(
1816
Object? value,
1917
DataSchema? dataSchema,
2018
Map<String, String>? parameters,
2119
) {
22-
final result = cbor.cborEncode(cbor.CborValue(value));
23-
return Uint8List.fromList(result).buffer;
20+
return cbor.cborEncode(cbor.CborValue(value));
2421
}
2522

2623
@override
2724
Object? bytesToValue(
28-
ByteBuffer bytes,
25+
List<int> bytes,
2926
DataSchema? dataSchema,
3027
Map<String, String>? parameters,
3128
) {
3229
// TODO(JKRhb): Use dataSchema for validation
33-
final result = cbor.cborDecode(bytes.asUint8List().toList(growable: false));
34-
return result.toObject();
30+
return cbor.cborDecode(bytes).toObject();
3531
}
3632
}

lib/src/core/codecs/content_codec.dart

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,20 @@
44
//
55
// SPDX-License-Identifier: BSD-3-Clause
66

7-
import 'dart:typed_data';
8-
97
import '../../definitions/data_schema.dart';
108

119
/// Interface for providing a codec for a specific media type.
1210
abstract class ContentCodec {
1311
/// Converts an [Object] to its byte representation in the given media type.
14-
ByteBuffer valueToBytes(
12+
List<int> valueToBytes(
1513
Object? value,
1614
DataSchema? dataSchema,
1715
Map<String, String>? parameters,
1816
);
1917

2018
/// Converts a payload of the given media type to an [Object].
2119
Object? bytesToValue(
22-
ByteBuffer bytes,
20+
List<int> bytes,
2321
DataSchema? dataSchema,
2422
Map<String, String>? parameters,
2523
);

lib/src/core/codecs/json_codec.dart

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
// SPDX-License-Identifier: BSD-3-Clause
66

77
import 'dart:convert';
8-
import 'dart:typed_data';
98

109
import '../../definitions/data_schema.dart';
1110

@@ -14,28 +13,22 @@ import 'content_codec.dart';
1413
/// A [ContentCodec] that encodes and decodes JSON data.
1514
class JsonCodec extends ContentCodec {
1615
@override
17-
ByteBuffer valueToBytes(
16+
List<int> valueToBytes(
1817
Object? value,
1918
DataSchema? dataSchema,
2019
Map<String, String>? parameters,
2120
) {
22-
if (value == null) {
23-
return Uint8List(0).buffer;
24-
} else {
25-
// TODO(JKRhb): This probably has to be revisited
26-
final utf8List = utf8.encode(jsonEncode(value));
27-
return Uint8List.fromList(utf8List).buffer;
28-
}
21+
return utf8.encode(jsonEncode(value));
2922
}
3023

3124
@override
3225
Object? bytesToValue(
33-
ByteBuffer bytes,
26+
List<int> bytes,
3427
DataSchema? dataSchema,
3528
Map<String, String>? parameters,
3629
) {
3730
// TODO(JKRhb): Use dataSchema for validation
3831

39-
return jsonDecode(utf8.decoder.convert(bytes.asUint8List()));
32+
return jsonDecode(utf8.decoder.convert(bytes));
4033
}
4134
}

lib/src/core/codecs/link_format_codec.dart

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
// SPDX-License-Identifier: BSD-3-Clause
66

77
import 'dart:convert';
8-
import 'dart:typed_data';
98

109
import 'package:coap/coap.dart';
1110

@@ -17,28 +16,27 @@ import 'content_codec.dart';
1716
/// [RFC 6690]: https://datatracker.ietf.org/doc/html/rfc6690
1817
class LinkFormatCodec extends ContentCodec {
1918
@override
20-
ByteBuffer valueToBytes(
19+
List<int> valueToBytes(
2120
Object? value,
2221
DataSchema? dataSchema,
2322
Map<String, String>? parameters,
2423
) {
2524
// TODO(JKRhb): The question which value types are allowed needs to be
2625
// revisited.
2726
if (value is CoapResource) {
28-
return Uint8List.fromList(CoapLinkFormat.serialize(value).codeUnits)
29-
.buffer;
27+
return CoapLinkFormat.serialize(value).codeUnits;
3028
}
3129

3230
throw FormatException('Error deserializing CoRE Link Format', value);
3331
}
3432

3533
@override
3634
Object? bytesToValue(
37-
ByteBuffer bytes,
35+
List<int> bytes,
3836
DataSchema? dataSchema,
3937
Map<String, String>? parameters,
4038
) {
41-
final string = utf8.decode(bytes.asUint8List().toList(growable: false));
39+
final string = utf8.decode(bytes);
4240
return CoapLinkFormat.parse(string);
4341
}
4442
}

lib/src/core/content.dart

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,14 @@ class Content {
2424

2525
/// Converts the [body] of the content to a [ByteBuffer] asynchronously.
2626
Future<ByteBuffer> get byteBuffer async {
27-
final buffer = Uint8Buffer();
28-
await for (final bytes in body) {
29-
buffer.addAll(bytes);
30-
}
27+
final buffer = Uint8Buffer()..addAll(await toByteList());
28+
3129
return buffer.buffer;
3230
}
31+
32+
/// Converts the [body] of this [Content] to a [List] of bytes asynchronously.
33+
Future<List<int>> toByteList() async =>
34+
body.expand<int>((element) => element).toList();
3335
}
3436

3537
/// [Content] specific for discovery.

lib/src/core/content_serdes.dart

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
import 'dart:convert';
88
import 'dart:io';
9-
import 'dart:typed_data';
109

1110
import 'package:http_parser/http_parser.dart';
1211
import 'package:json_schema/json_schema.dart';
@@ -169,19 +168,19 @@ class ContentSerdes {
169168
final mimeType = parsedMediaType.mimeType;
170169
final parameters = parsedMediaType.parameters;
171170

172-
ByteBuffer bytes;
171+
List<int> bytes;
173172
final codec = _getCodecFromMediaType(mimeType);
173+
174174
if (codec != null) {
175175
bytes = codec.valueToBytes(value, dataSchema, parameters);
176176
} else {
177177
// Media Type is unsupported. Convert the String representation to bytes
178178
// instead.
179179
// TODO(JKRhb): Could be moved to a dedicated Value class method.
180-
bytes = utf8.encoder.convert(value.toString()).buffer;
180+
bytes = utf8.encoder.convert(value.toString());
181181
}
182182

183-
final byteList = bytes.asUint8List().toList(growable: false);
184-
return Content(resolvedMediaType, Stream.value(byteList));
183+
return Content(resolvedMediaType, Stream.value(bytes));
185184
}
186185

187186
/// Converts a [Content] object to a typed [Object].
@@ -197,10 +196,10 @@ class ContentSerdes {
197196
final mimeType = parsedMediaType.mimeType;
198197
final parameters = parsedMediaType.parameters;
199198

200-
final bytes = await content.byteBuffer;
199+
final bytes = await content.toByteList();
201200

202201
// TODO: Should null be returned in this case?
203-
if (bytes.lengthInBytes == 0) {
202+
if (bytes.isEmpty) {
204203
return null;
205204
}
206205

@@ -211,7 +210,7 @@ class ContentSerdes {
211210
return value;
212211
} else {
213212
// TODO(JKRhb): Should unsupported data be returned as a String?
214-
return utf8.decode(bytes.asUint8List());
213+
return utf8.decode(bytes.toList());
215214
}
216215
}
217216
}

0 commit comments

Comments
 (0)