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

Migrate to null safety #35

Merged
merged 3 commits into from
Jan 25, 2022
Merged
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
1 change: 0 additions & 1 deletion analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ linter:
- always_put_required_named_parameters_first
- always_require_non_null_named_parameters
- annotate_overrides
- avoid_as
- avoid_annotating_with_dynamic
- avoid_classes_with_only_static_members
- avoid_bool_literals_in_conditional_expressions
Expand Down
10 changes: 5 additions & 5 deletions lib/src/convert/utf16.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'dart:convert';
import 'dart:core';

import 'package:utf/utf.dart' as utf;
import 'package:utf_convert/utf_convert.dart' as utf;

abstract class UTF16 extends Encoding {
List<int> get bom;
Expand Down Expand Up @@ -37,14 +37,14 @@ class _UTF16LEDecoder extends Converter<List<int>, String> {
@override
String convert(List<int> input) {
final decoder = utf.Utf16leBytesToCodeUnitsDecoder(input);
return String.fromCharCodes(decoder.decodeRest());
return String.fromCharCodes(decoder.decodeRest().cast<int>());
}
}

class _UTF16LEEncoder extends Converter<String, List<int>> {
@override
List<int> convert(String input) {
return utf.encodeUtf16le(input, true);
return utf.encodeUtf16le(input, true) as List<int>;
}
}

Expand All @@ -66,13 +66,13 @@ class _UTF16BEDecoder extends Converter<List<int>, String> {
@override
String convert(List<int> input) {
final decoder = utf.Utf16beBytesToCodeUnitsDecoder(input);
return String.fromCharCodes(decoder.decodeRest());
return String.fromCharCodes(decoder.decodeRest().cast<int>());
}
}

class _UTF16BEEncoder extends Converter<String, List<int>> {
@override
List<int> convert(String input) {
return utf.encodeUtf16be(input, true);
return utf.encodeUtf16be(input, true) as List<int>;
}
}
20 changes: 10 additions & 10 deletions lib/src/frames/frame.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,19 @@ import 'id3v2/default_frame.dart';
/// Abstract implementation of id3v2 frame
abstract class Frame<T> {
/// Encode [key] tag with [value] to bytearray
List<int> encode(T value, [String key]);
List<int> encode(T value, [String? key]);

/// Decode byte [data] to frame data map
MapEntry<String, T> decode(List<int> data);
MapEntry<String, T>? decode(List<int> data);
}

class FrameFactory<T extends Frame> {
class FrameFactory<T extends Frame?> {
String version;

// ignore: avoid_annotating_with_dynamic
Frame Function(dynamic entry) _frameGetter;
Frame? Function(dynamic entry) _frameGetter;

Frame defaultFrame;
Frame? defaultFrame;

FrameFactory._internal(this.version, this._frameGetter, [this.defaultFrame]);

Expand All @@ -40,7 +40,7 @@ class FrameFactory<T extends Frame> {
return FrameFactory._internal('0', (v) => null);
}

T getFrame(entry) => _frameGetter(entry);
Frame? getFrame(entry) => _frameGetter(entry);
}

class FramesID3V23 extends FramesID3V24 {
Expand All @@ -55,7 +55,7 @@ class FramesID3V23 extends FramesID3V24 {

@override
Frame<T> _getFrame<T>(String tag) {
return _frames[tag] ?? DefaultFrame(tag, version: 3);
return _frames[tag] as Frame<T>? ?? DefaultFrame(tag, version: 3) as Frame<T>;
}
}

Expand All @@ -69,16 +69,16 @@ class FramesID3V24 {
};

Frame<T> _getFrame<T>(String tag) {
return _frames[tag] ?? DefaultFrame(tag);
return _frames[tag] as Frame<T>? ?? DefaultFrame(tag) as Frame<T>;
}

String getTagByPseudonym(String tag) {
return consts.frameHeaderShortcutsID3V2_3_Rev.containsKey(tag)
? consts.frameHeaderShortcutsID3V2_3_Rev[tag]
? consts.frameHeaderShortcutsID3V2_3_Rev[tag]!
: consts.framesHeaders.containsKey(tag) ? tag : 'TXXX';
}

Frame<T> getFrame<T>(data) {
Frame<T>? getFrame<T>(data) {
assert(data is List<int> || data is String);

if (data is List<int>) {
Expand Down
4 changes: 2 additions & 2 deletions lib/src/frames/id3v2/apic_frame.dart
Original file line number Diff line number Diff line change
Expand Up @@ -83,14 +83,14 @@ class ApicFrame extends ID3V2Frame<AttachedPicture> {
final imageData = data.sublist(startOfImageData);

final extractedImageData = _imageExtractors.containsKey(mime)
? _imageExtractors[mime]().parse(imageData)
? _imageExtractors[mime]!().parse(imageData)
: imageData;

return AttachedPicture(mime, imageType, description, extractedImageData);
}

@override
List<int> encode(AttachedPicture value, [String key]) {
List<int> encode(AttachedPicture value, [String? key]) {
final mimeEncoded = latin1.encode(value.mime);
final descEncoded = utf8.encode(value.description);

Expand Down
2 changes: 1 addition & 1 deletion lib/src/frames/id3v2/comm_frame.dart
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class COMMFrame extends ID3V2Frame<Comment> {
}

@override
List<int> encode(Comment value, [String key]) {
List<int> encode(Comment value, [String? key]) {
final enc = header?.encoding ?? utf8;

return [
Expand Down
2 changes: 1 addition & 1 deletion lib/src/frames/id3v2/default_frame.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class DefaultFrame extends ID3V2Frame<String> {
}

@override
List<int> encode(String value, [String key]) {
List<int> encode(String value, [String? key]) {
final tag = getTagByPseudonym(frameTag);

final vBytes = utf8.encode(value);
Expand Down
26 changes: 13 additions & 13 deletions lib/src/frames/id3v2/id3v2_frame.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ abstract class ID3V2Frame<T> implements Frame<T> {

final int _version;

ID3V2FrameHeader _header;
ID3V2FrameHeader get header => _header;
ID3V2FrameHeader? _header;
ID3V2FrameHeader? get header => _header;

ID3V2Frame(this._version);

@override
MapEntry<String, T> decode(List<int> data) {
MapEntry<String, T>? decode(List<int> data) {
final tag = latin1.decode(data.sublist(0, 4));
if (!consts.framesHeaders.keys.contains(tag)) {
return null;
Expand All @@ -46,27 +46,27 @@ abstract class ID3V2Frame<T> implements Frame<T> {

_header = ID3V2FrameHeader(tag, size, encoding: encoding);

if (data.length < headerLength + _header?.length) {
if (data.length < headerLength + _header!.length) {
_header =
ID3V2FrameHeader(tag, data.length - headerLength, encoding: encoding);
}

final body = data.sublist(headerLength + 1, headerLength + _header?.length);
final body = data.sublist(headerLength + 1, headerLength + _header!.length);

return MapEntry<String, T>(
getTagPseudonym(_header.tag), decodeBody(body, encoding));
getTagPseudonym(_header!.tag), decodeBody(body, encoding));
}

T decodeBody(List<int> data, Encoding enc);

@override
List<int> encode(T value, [String key]);
List<int> encode(T value, [String? key]);

/// Returns size of frame in bytes
List<int> frameSizeInBytes(int value) {
assert(value <= 16777216);

final block = List<int>(4);
final block = List<int>.filled(4, 0);
final sevenBitMask = 0x7f;

block[0] = (value >> 21) & sevenBitMask;
Expand All @@ -79,13 +79,13 @@ abstract class ID3V2Frame<T> implements Frame<T> {

String getTagByPseudonym(String tag) {
return consts.frameHeaderShortcutsID3V2_3_Rev.containsKey(tag)
? consts.frameHeaderShortcutsID3V2_3_Rev[tag]
? consts.frameHeaderShortcutsID3V2_3_Rev[tag]!
: tag;
}

String getTagPseudonym(String tag) {
return consts.frameHeaderShortcutsID3V2_3.containsKey(tag)
? consts.frameHeaderShortcutsID3V2_3[tag]
? consts.frameHeaderShortcutsID3V2_3[tag]!
: tag;
}

Expand Down Expand Up @@ -133,7 +133,7 @@ abstract class ID3V2Frame<T> implements Frame<T> {

int indexOfSplitPattern(List<int> list, List<int> pattern,
[int initialOffset = 0]) {
for (var i = initialOffset ?? 0;
for (var i = initialOffset;
i < list.length - pattern.length;
i += pattern.length) {
final l = list.sublist(i, i + pattern.length);
Expand Down Expand Up @@ -182,10 +182,10 @@ class ID3V2FrameHeader {
String tag;
int length;

Encoding encoding;
Encoding? encoding;

// todo: implement futher
int flags;
int? flags;

ID3V2FrameHeader(this.tag, this.length, {this.flags, this.encoding}) {
assert(consts.framesHeaders.keys.contains(tag));
Expand Down
6 changes: 3 additions & 3 deletions lib/src/frames/id3v2/txxx_frame.dart
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ class TXXXFrame extends ID3V2Frame<String> {
@override
String get frameTag => 'TXXX';

String _customTagName;
String? _customTagName;

@override
MapEntry<String, String> decode(List<int> data) {
final entry = super.decode(data);
final entry = super.decode(data)!;
return MapEntry<String, String>(_customTagName ?? frameTag, entry.value);
}

Expand All @@ -64,7 +64,7 @@ class TXXXFrame extends ID3V2Frame<String> {
}

@override
List<int> encode(String value, [String key]) {
List<int> encode(String value, [String? key]) {
final body = utf8.encode('$key${utf8.decode([0x00])}$value');
return [
...utf8.encode(frameTag),
Expand Down
2 changes: 1 addition & 1 deletion lib/src/frames/id3v2/uslt_frame.dart
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class USLTFrame extends ID3V2Frame<UnSyncLyric> {
}

@override
List<int> encode(UnSyncLyric value, [String key]) {
List<int> encode(UnSyncLyric value, [String? key]) {
final enc = header?.encoding ?? utf8;

return [
Expand Down
2 changes: 1 addition & 1 deletion lib/src/frames/id3v2/wxxx_frame.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class WXXXFrame extends ID3V2Frame<WURL> {
String get frameTag => 'WXXX';

@override
List<int> encode(WURL value, [String key]) {
List<int> encode(WURL value, [String? key]) {
final vBytes = [
...utf8.encode('${value.description}${utf8.decode([0x00])}'),
...latin1.encode(value.url)
Expand Down
8 changes: 4 additions & 4 deletions lib/src/model/attached_picture.dart
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class AttachedPicture implements KeyEntity<String> {
/// Returns [String] representation of image type.
///
/// eg. 'Band/Orchestra' or 'Cover (front)' etc...
String get imageType => _picturesType[imageTypeCode ?? 0x00];
String get imageType => _picturesType[imageTypeCode];

AttachedPicture(
this.mime, this.imageTypeCode, this.description, this.imageData);
Expand All @@ -68,6 +68,9 @@ class AttachedPicture implements KeyEntity<String> {

@override
bool operator ==(other) {
if (!(other is AttachedPicture)) {
return false;
}
if (imageTypeCode != other.imageTypeCode) {
return false;
}
Expand All @@ -77,9 +80,6 @@ class AttachedPicture implements KeyEntity<String> {
if (description != other.description) {
return false;
}
if (imageData == null && other.imageData == null) {
return true;
}
if (imageData.length != other.imageData.length) {
return false;
}
Expand Down
3 changes: 3 additions & 0 deletions lib/src/model/comment.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ class Comment implements KeyEntity<String> {

@override
bool operator ==(other) {
if (!(other is Comment)) {
return false;
}
if (lang != other.lang) {
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion lib/src/model/consts.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/// Generes constants from id3v1.1 specification
final id3v1generes = const <String>[
final List<String> id3v1generes = const <String>[
'Blues',
'Classic Rock',
'Country',
Expand Down
3 changes: 3 additions & 0 deletions lib/src/model/lyrics.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ class UnSyncLyric implements KeyEntity<String> {

@override
bool operator ==(other) {
if (!(other is UnSyncLyric)) {
return false;
}
if (lang != other.lang) {
return false;
}
Expand Down
9 changes: 6 additions & 3 deletions lib/src/model/tag.dart
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
/// Class describes tag
class Tag {
/// Type of tag. At this time supports 'id3'
String type;
String? type;

/// Version of tag. eg. '2.4.0' or '1.1'
String version;
String? version;

/// The map of tags. Values are dynamic because it can be not only String.
Map<String, dynamic> tags;
late Map<String, dynamic> tags;

@override
bool operator ==(other) {
if (!(other is Tag)) {
return false;
}
if (type != other.type) {
return false;
}
Expand Down
3 changes: 3 additions & 0 deletions lib/src/model/wurl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ class WURL implements KeyEntity<String> {

@override
bool operator ==(other) {
if (!(other is WURL)) {
return false;
}
if (description != other.description) {
return false;
}
Expand Down
10 changes: 5 additions & 5 deletions lib/src/readers/id3v2.dart
Original file line number Diff line number Diff line change
Expand Up @@ -67,23 +67,23 @@ class ID3V2Reader extends Reader {
while (contin) {
final fr = bytes.sublist(offset);

final frame = ff.getFrame(fr);
final frame = ff.getFrame(fr)! as ID3V2Frame;
final m = frame.decode(fr);

if (m?.key != null && m?.value != null) {
if (m?.value is KeyEntity) {
if (tags[m.key] == null) {
if (tags[m!.key] == null) {
tags[m.key] = {m.value.key: m.value};
} else {
tags[m.key][m.value.key] = m.value;
}
} else {
tags[m.key] = m.value;
tags[m!.key] = m.value;
}
}

offset = offset + _headerLength + (frame?.header?.length ?? 0);
contin = offset < size && (frame?.header?.length ?? 0) != 0;
offset = offset + _headerLength + (frame.header?.length ?? 0);
contin = offset < size && (frame.header?.length ?? 0) != 0;
}

return tags;
Expand Down
Loading