Skip to content

Commit

Permalink
Moved MultipartSentence logic to decode method and bump version t…
Browse files Browse the repository at this point in the history
…o 3.2.0
  • Loading branch information
ricardoboss committed Jan 16, 2023
1 parent fc3dc6c commit 5d7a765
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 43 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
Changelog
=========

Version 3.2.0
-------------

* Moved `MultipartSentence` logic to `decode` method

Version 3.1.0
-------------

Expand Down
88 changes: 46 additions & 42 deletions lib/src/nmea_decoder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -131,43 +131,9 @@ class NmeaDecoder extends StreamTransformerBase<String, NmeaSentence> {
Stream<NmeaSentence> bind(Stream<String> stream) async* {
await for (var line in stream) {
var sentence = decode(line);
sentence ??= onUnknownSentence?.call(line);

if (sentence == null || (onlyAllowValid && !sentence.valid)) {
continue;
if (sentence != null) {
yield sentence;
}

if (sentence is MultipartSentence) {
final existingIndex =
_incompleteSentences.indexWhere(sentence.belongsTo);
if (existingIndex < 0) {
if (sentence.isLast) {
// shortcut if the multipart sentence only consists of one part
yield sentence;
} else if (sentence.isFirst) {
// new multipart sentence
_incompleteSentences.add(sentence);
} else {
// 'mid-sequence' multipart sentence (we didn't get the first one)
final fallback = onIncompleteMultipartSentence?.call(sentence);
if (fallback != null) {
fallback.appendFrom(sentence);
_incompleteSentences.add(fallback);
}
}
} else {
final existing = _incompleteSentences[existingIndex];
existing.appendFrom(sentence);
if (sentence.isLast) {
yield existing;
_incompleteSentences.removeAt(existingIndex);
}
}

continue;
}

yield sentence;
}

for (var incomplete in _incompleteSentences) {
Expand All @@ -182,17 +148,55 @@ class NmeaDecoder extends StreamTransformerBase<String, NmeaSentence> {
/// You can handle unknown sentences by checking if the result of this method
/// is `null` and then invoking the appropriate handler.
NmeaSentence? decode(String line) {
NmeaSentence? sentence;

if (line.length > 1 && line[1] == nmeaProprietaryDenominator) {
return decodeProprietary(line);
sentence = decodeProprietary(line);
} else if (line.length > 5 && line[5] == nmeaQueryDenominator) {
sentence = decodeQuery(line);
} else {
sentence = decodeTalker(line) ??
decodeCustomChecksum(line) ??
decodeCustom(line);
}

if (line.length > 5 && line[5] == nmeaQueryDenominator) {
return decodeQuery(line);
sentence ??= onUnknownSentence?.call(line);

if (sentence == null || (onlyAllowValid && !sentence.valid)) {
return null;
}

if (sentence is MultipartSentence) {
final existingIndex =
_incompleteSentences.indexWhere(sentence.belongsTo);
if (existingIndex < 0) {
if (sentence.isLast) {
// shortcut if the multipart sentence only consists of one part
return sentence;
} else if (sentence.isFirst) {
// new multipart sentence
_incompleteSentences.add(sentence);
} else {
// 'mid-sequence' multipart sentence (we didn't get the first one)
final fallback = onIncompleteMultipartSentence?.call(sentence);
if (fallback != null) {
fallback.appendFrom(sentence);
_incompleteSentences.add(fallback);
}
}
} else {
final existing = _incompleteSentences[existingIndex];
existing.appendFrom(sentence);
if (sentence.isLast) {
_incompleteSentences.removeAt(existingIndex);
return existing;
}
}

return null;
}

return decodeTalker(line) ??
decodeCustomChecksum(line) ??
decodeCustom(line);
return sentence;
}

/// Tries to decode the given line as a custom sentence.
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ homepage: https://github.com/ricardoboss/dart_nmea
repository: https://github.com/ricardoboss/dart_nmea
issue_tracker: https://github.com/ricardoboss/dart_nmea/issues

version: 3.1.0
version: 3.2.0

environment:
sdk: ">=2.17.1 <3.0.0"
Expand Down
23 changes: 23 additions & 0 deletions test/multipart_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,29 @@ void main() {
expect(multipart.complete, isTrue);
});

test("decodes multipart messages in decode method", () async {
final decoder = NmeaDecoder()
..registerTalkerSentence(MultipartTestTalkerSentence.id,
(line) => MultipartTestTalkerSentence(raw: line));

final decoded = [
"\$--TE1,1,3,123,456*78",
"\$--TE1,2,3,789,012*34",
"\$--TE1,3,3,345,678*56",
]
.map((line) => decoder.decode(line))
.where((element) => element != null)
.toList();

expect(decoded.length, equals(1));
expect(decoded[0], isA<MultipartTestTalkerSentence>());
final multipart = decoded[0] as MultipartTestTalkerSentence;
expect(multipart.total, equals(3));
expect(multipart.sequence, equals(1));
expect(multipart.values, equals([123, 456, 789, 012, 345, 678]));
expect(multipart.complete, isTrue);
});

test("returns incomplete sentences at end-of-stream", () async {
final decoder = NmeaDecoder()
..registerTalkerSentence(MultipartTestTalkerSentence.id,
Expand Down

0 comments on commit 5d7a765

Please sign in to comment.