diff --git a/CHANGELOG.md b/CHANGELOG.md index fc59849..e3918db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ Changelog ========= +Version 3.2.0 +------------- + +* Moved `MultipartSentence` logic to `decode` method + Version 3.1.0 ------------- diff --git a/lib/src/nmea_decoder.dart b/lib/src/nmea_decoder.dart index a4ac4e5..88b5f54 100644 --- a/lib/src/nmea_decoder.dart +++ b/lib/src/nmea_decoder.dart @@ -131,43 +131,9 @@ class NmeaDecoder extends StreamTransformerBase { Stream bind(Stream 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) { @@ -182,17 +148,55 @@ class NmeaDecoder extends StreamTransformerBase { /// 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. diff --git a/pubspec.yaml b/pubspec.yaml index d8adc19..5721799 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -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" diff --git a/test/multipart_test.dart b/test/multipart_test.dart index a4e1b19..297ba8c 100644 --- a/test/multipart_test.dart +++ b/test/multipart_test.dart @@ -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()); + 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,