Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Null safety #14

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions example/actions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import "package:upnp/upnp.dart";
main(List<String> args) async {
var client = new DiscoveredClient.fake(args[0]);
var device = await client.getDevice();
print(device.services);
print(device!.services);
var service = await device.getService(args[1]);
var result = await service.invokeAction(args[2], {});
var result = await service!.invokeAction(args[2], {});
print(result);
}
6 changes: 3 additions & 3 deletions example/coffee_maker.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ void main() {
return devices.where((it) => it.modelName == "CoffeeMaker");
}).then((devices) {
for (var device in devices) {
Service service;
Service? service;
device.getService("urn:Belkin:service:deviceevent:1").then((_) {
service = _;
return service.invokeAction("GetAttributes", {});
return service!.invokeAction("GetAttributes", {});
}).then((result) {
var attributes = WemoHelper.parseAttributes(result["attributeList"]);
var attributes = WemoHelper.parseAttributes(result["attributeList"]!);
var brewing = attributes["Brewing"];
var brewed = attributes["Brewed"];
var mode = attributes["Mode"];
Expand Down
2 changes: 1 addition & 1 deletion example/discover_list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ main() async {
disc.quickDiscoverClients().listen((client) async {
try {
var dev = await client.getDevice();
print("${dev.friendlyName}: ${dev.url}");
print("${dev!.friendlyName}: ${dev.url}");
} catch (e, stack) {
print("ERROR: ${e} - ${client.location}");
print(stack);
Expand Down
39 changes: 12 additions & 27 deletions example/list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,14 @@ import "package:upnp/src/utils.dart";

Future printDevice(Device device) async {
void prelude() {
print("- ${device.modelName} by ${device.manufacturer} (uuid: ${device.uuid})");
print(
"- ${device.modelName} by ${device.manufacturer} (uuid: ${device.uuid})");
print("- URL: ${device.url}");
}

if (device.services == null) {
prelude();
print("-----");
return;
}

var svcs = <Service>[];
var svcs = <Service?>[];

for (var svc in device.services) {
if (svc == null) {
continue;
}

var service = await svc.getService();
svcs.add(service);
}
Expand All @@ -40,14 +31,10 @@ Future printDevice(Device device) async {

for (var action in service.actions) {
print(" - Name: ${action.name}");
print(" - Arguments: ${action.arguments
.where((it) => it.direction == "in")
.map((it) => it.name)
.toList()}");
print(" - Results: ${action.arguments
.where((it) => it.direction == "out")
.map((it) => it.name)
.toList()}");
print(
" - Arguments: ${action.arguments.where((it) => it.direction == "in").map((it) => it.name).toList()}");
print(
" - Results: ${action.arguments.where((it) => it.direction == "out").map((it) => it.name).toList()}");

print("");
}
Expand Down Expand Up @@ -81,9 +68,9 @@ main(List<String> args) async {
var discoverer = new DeviceDiscoverer();
await discoverer.start(ipv6: false);
await discoverer
.quickDiscoverClients()
.listen((DiscoveredClient client) async {
Device device;
.quickDiscoverClients()
.listen((DiscoveredClient client) async {
Device? device;

try {
device = await client.getDevice();
Expand All @@ -98,10 +85,8 @@ main(List<String> args) async {
return;
}

if (device != null) {
await printDevice(device);
}
await printDevice(device);
}).asFuture();

await UpnpCommon.httpClient.close();
UpnpCommon.httpClient.close();
}
2 changes: 1 addition & 1 deletion example/router.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import "dart:io";
main() async {
await for (var router in Router.findAll()) {
var address = await router.getExternalIpAddress();
print("Router ${Uri.parse(router.device.url).host}:");
print("Router ${Uri.parse(router.device!.url!).host}:");
print(" External IP Address: ${address}");
var totalBytesSent = await router.getTotalBytesSent();
print(" Total Bytes Sent: ${totalBytesSent} bytes");
Expand Down
6 changes: 3 additions & 3 deletions example/sub.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ main() async {

for (Device device in devices) {
for (ServiceDescription desc in device.services) {
Service service;
Service? service;

try {
service = await desc.getService(device).timeout(const Duration(seconds: 5));
Expand All @@ -25,9 +25,9 @@ main() async {
if (service != null) {
try {
sub.subscribeToService(service).listen((value) {
print("${device.friendlyName} - ${service.id}: ${value}");
print("${device.friendlyName} - ${service!.id}: ${value}");
}, onError: (e, stack) {
print("Error while subscribing to ${service.type} for ${device.friendlyName}: ${e}");
print("Error while subscribing to ${service!.type} for ${device.friendlyName}: ${e}");
});
} catch (e) {
print(e);
Expand Down
2 changes: 1 addition & 1 deletion lib/server.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import "dart:convert";
import "dart:io";
import "dart:math" show Random;

import "package:xml/xml.dart" as XML;
import "package:xml/xml.dart";

part "src/server/server.dart";
part "src/server/device.dart";
Expand Down
109 changes: 48 additions & 61 deletions lib/src/action.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
part of upnp;

class Action {
Service service;
String name;
late Service service;
String? name;
List<ActionArgument> arguments = [];

Action();
Expand All @@ -18,14 +18,12 @@ class Action {
}

var direction = XmlUtils.getTextSafe(argdef, "direction");
var relatedStateVariable = XmlUtils.getTextSafe(
argdef,
"relatedStateVariable"
);
var relatedStateVariable =
XmlUtils.getTextSafe(argdef, "relatedStateVariable");
var isRetVal = direction == "out";

if (this.name.startsWith("Get")) {
var of = this.name.substring(3);
if (this.name!.startsWith("Get")) {
var of = this.name!.substring(3);
if (of == name) {
isRetVal = true;
}
Expand All @@ -35,55 +33,52 @@ class Action {
name = name.substring(3);
}

arguments.add(
new ActionArgument(
this,
name,
direction,
relatedStateVariable,
isRetVal
)
);
arguments.add(new ActionArgument(
this, name, direction, relatedStateVariable, isRetVal));
}

var argumentLists = e.findElements("argumentList");
if (argumentLists.isNotEmpty) {
var argList = argumentLists.first;
if (argList.children.any((x) => x is XmlElement && x.name.local == "name")) {
if (argList.children
.any((x) => x is XmlElement && x.name.local == "name")) {
// Bad UPnP Implementation fix for WeMo
addArgDef(argList, true);
} else {
for (var argdef in argList.children.where((it) => it is XmlElement)) {
addArgDef(argdef);
addArgDef(argdef as XmlElement);
}
}
}
}

Future<Map<String, String>> invoke(Map<String, dynamic> args) async {
var param = ' <u:${name} xmlns:u="${service.type}">' + args.keys.map((it) {
String argsIt = args[it].toString();
argsIt = argsIt.replaceAll("&", "&amp;");
return "<${it}>${argsIt}</${it}>";
}).join("\n") + '</u:${name}>\n';
var param = ' <u:${name} xmlns:u="${service.type}">' +
args.keys.map((it) {
String argsIt = args[it].toString();
argsIt = argsIt.replaceAll("&", "&amp;");
return "<${it}>${argsIt}</${it}>";
}).join("\n") +
'</u:${name}>\n';

var result = await service.sendToControlUrl(name, param);
var doc = xml.parse(result);
XmlElement response = doc
.rootElement;
var doc = XmlDocument.parse(result);
XmlElement response = doc.rootElement;

if (response.name.local != "Body") {
response = response.children.firstWhere((x) => x is XmlElement);
response =
response.children.firstWhere((x) => x is XmlElement) as XmlElement;
}

if (const bool.fromEnvironment("upnp.action.show_response", defaultValue: false)) {
if (const bool.fromEnvironment("upnp.action.show_response",
defaultValue: false)) {
print("Got Action Response: ${response.toXmlString()}");
}

if (response is XmlElement
&& !response.name.local.contains("Response") &&
response.children.length > 1) {
response = response.children[1];
if (response is XmlElement &&
!response.name.local.contains("Response") &&
response.children.length > 1) {
response = response.children[1] as XmlElement;
}

if (response.children.length == 1) {
Expand All @@ -96,13 +91,13 @@ class Action {
}
}

if (const bool.fromEnvironment("upnp.action.show_response", defaultValue: false)) {
if (const bool.fromEnvironment("upnp.action.show_response",
defaultValue: false)) {
print("Got Action Response (Real): ${response.toXmlString()}");
}

List<XmlElement> results = response.children
.whereType<XmlElement>()
.toList();
List<XmlElement> results =
response.children.whereType<XmlElement>().toList();
var map = <String, String>{};
for (XmlElement r in results) {
map[r.name.local] = r.text;
Expand All @@ -112,9 +107,9 @@ class Action {
}

class StateVariable {
Service service;
String name;
String dataType;
late Service service;
String? name;
String? dataType;
dynamic defaultValue;
bool doesSendEvents = false;

Expand All @@ -123,43 +118,35 @@ class StateVariable {
StateVariable.fromXml(XmlElement e) {
name = XmlUtils.getTextSafe(e, "name");
dataType = XmlUtils.getTextSafe(e, "dataType");
defaultValue = XmlUtils.asValueType(
XmlUtils.getTextSafe(e, "defaultValue"),
dataType
);
defaultValue =
XmlUtils.asValueType(XmlUtils.getTextSafe(e, "defaultValue"), dataType);
doesSendEvents = e.getAttribute("sendEvents") == "yes";
}

String getGenericId() {
return sha1.convert(utf8.encode(
"${service.device.uuid}::${service.id}::${name}"
)).toString();
return sha1
.convert(utf8.encode("${service.device!.uuid}::${service.id}::${name}"))
.toString();
}
}

class ActionArgument {
final Action action;
final String name;
final String direction;
final String relatedStateVariable;
final String? name;
final String? direction;
final String? relatedStateVariable;
final bool isRetVal;

ActionArgument(
this.action,
this.name,
this.direction,
this.relatedStateVariable,
this.isRetVal);
ActionArgument(this.action, this.name, this.direction,
this.relatedStateVariable, this.isRetVal);

StateVariable getStateVariable() {
StateVariable? getStateVariable() {
if (relatedStateVariable != null) {
return null;
}

Iterable<StateVariable> vars = action
.service
.stateVariables
.where((x) => x.name == relatedStateVariable);
Iterable<StateVariable> vars = action.service.stateVariables
.where((x) => x.name == relatedStateVariable);

if (vars.isNotEmpty) {
return vars.first;
Expand Down
Loading