migrate to null safety (#37)
diff --git a/.travis.yml b/.travis.yml
index e1bb9d9..2acf002 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,7 +1,6 @@
language: dart
dart:
-- 2.1.0
- dev
dart_task:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a0ca552..648f9d5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,9 @@
+# 1.0.0-nullsafety.0
+
+* Update to null safety
+
# 0.9.7
+
* Add `extensionFromMime` utility function.
# 0.9.6+3
diff --git a/lib/src/bound_multipart_stream.dart b/lib/src/bound_multipart_stream.dart
index 71c77f9..73bc495 100644
--- a/lib/src/bound_multipart_stream.dart
+++ b/lib/src/bound_multipart_stream.dart
@@ -62,8 +62,8 @@
_MimeMultipart(this.headers, this._stream);
@override
- StreamSubscription<List<int>> listen(void Function(List<int> data) onData,
- {void Function() onDone, Function onError, bool cancelOnError}) {
+ StreamSubscription<List<int>> listen(void Function(List<int> data)? onData,
+ {void Function()? onDone, Function? onError, bool? cancelOnError}) {
return _stream.listen(onData,
onDone: onDone, onError: onError, cancelOnError: cancelOnError);
}
@@ -105,10 +105,10 @@
Stream<MimeMultipart> get stream => _controller.stream;
- StreamSubscription _subscription;
+ late StreamSubscription _subscription;
- StreamController<List<int>> _multipartController;
- Map<String, String> _headers;
+ StreamController<List<int>>? _multipartController;
+ Map<String, String>? _headers;
int _state = _START;
int _boundaryIndex = 2;
@@ -117,8 +117,8 @@
///
/// If index is negative then it is the index into the artificial prefix of
/// the boundary string.
- int _index;
- List<int> _buffer;
+ int _index = 0;
+ List<int> _buffer = _placeholderBuffer;
BoundMultipartStream(this._boundary, Stream<List<int>> stream) {
_controller
@@ -131,7 +131,7 @@
..onListen = () {
_controllerState = _CONTROLLER_STATE_ACTIVE;
_subscription = stream.listen((data) {
- assert(_buffer == null);
+ assert(_buffer == _placeholderBuffer);
_subscription.pause();
_buffer = data;
_index = 0;
@@ -193,18 +193,18 @@
// prefix of the boundary both the content start index and index
// can be negative.
void reportData() {
- if (contentStartIndex < 0) {
+ if (contentStartIndex! < 0) {
var contentLength = boundaryPrefix + _index - _boundaryIndex;
if (contentLength <= boundaryPrefix) {
- _multipartController.add(_boundary.sublist(0, contentLength));
+ _multipartController!.add(_boundary.sublist(0, contentLength));
} else {
- _multipartController.add(_boundary.sublist(0, boundaryPrefix));
- _multipartController
+ _multipartController!.add(_boundary.sublist(0, boundaryPrefix));
+ _multipartController!
.add(_buffer.sublist(0, contentLength - boundaryPrefix));
}
} else {
var contentEndIndex = _index - _boundaryIndex;
- _multipartController
+ _multipartController!
.add(_buffer.sublist(contentStartIndex, contentEndIndex));
}
}
@@ -239,8 +239,8 @@
case _BOUNDARY_END:
_expectByteValue(byte, CharCode.LF);
+ _multipartController?.close();
if (_multipartController != null) {
- _multipartController.close();
_multipartController = null;
_tryPropagateControllerState();
}
@@ -298,7 +298,7 @@
} else {
var headerField = utf8.decode(_headerField);
var headerValue = utf8.decode(_headerValue);
- _headers[headerField.toLowerCase()] = headerValue;
+ _headers![headerField.toLowerCase()] = headerValue;
_headerField.clear();
_headerValue.clear();
if (byte == CharCode.CR) {
@@ -321,7 +321,7 @@
onPause: _subscription.pause,
onResume: _subscription.resume);
_controller
- .add(_MimeMultipart(_headers, _multipartController.stream));
+ .add(_MimeMultipart(_headers!, _multipartController!.stream));
_headers = null;
_state = _CONTENT;
contentStartIndex = _index + 1;
@@ -336,7 +336,7 @@
reportData();
_index--;
}
- _multipartController.close();
+ _multipartController!.close();
_multipartController = null;
_tryPropagateControllerState();
_boundaryIndex = 0;
@@ -365,8 +365,8 @@
case _LAST_BOUNDARY_END:
_expectByteValue(byte, CharCode.LF);
+ _multipartController?.close();
if (_multipartController != null) {
- _multipartController.close();
_multipartController = null;
_tryPropagateControllerState();
}
@@ -390,9 +390,12 @@
// Resume if at end.
if (_index == _buffer.length) {
- _buffer = null;
- _index = null;
+ _buffer = _placeholderBuffer;
+ _index = 0;
_subscription.resume();
}
}
}
+
+// Used as a placeholder instead of having a nullable buffer.
+const _placeholderBuffer = <int>[];
diff --git a/lib/src/magic_number.dart b/lib/src/magic_number.dart
index 50be18a..8933677 100644
--- a/lib/src/magic_number.dart
+++ b/lib/src/magic_number.dart
@@ -7,7 +7,7 @@
class MagicNumber {
final String mimeType;
final List<int> numbers;
- final List<int> mask;
+ final List<int>? mask;
const MagicNumber(this.mimeType, this.numbers, {this.mask});
@@ -16,7 +16,7 @@
for (var i = 0; i < numbers.length; i++) {
if (mask != null) {
- if ((mask[i] & numbers[i]) != (mask[i] & header[i])) return false;
+ if ((mask![i] & numbers[i]) != (mask![i] & header[i])) return false;
} else {
if (numbers[i] != header[i]) return false;
}
diff --git a/lib/src/mime_type.dart b/lib/src/mime_type.dart
index 3b220e7..14db942 100644
--- a/lib/src/mime_type.dart
+++ b/lib/src/mime_type.dart
@@ -22,7 +22,7 @@
/// a file have been saved using the wrong file-name extension. If less than
/// [defaultMagicNumbersMaxLength] bytes was provided, some magic-numbers won't
/// be matched against.
-String lookupMimeType(String path, {List<int> headerBytes}) =>
+String? lookupMimeType(String path, {List<int>? headerBytes}) =>
_globalResolver.lookup(path, headerBytes: headerBytes);
/// Returns the extension for the given MIME type.
@@ -69,8 +69,8 @@
/// though a file have been saved using the wrong file-name extension. If less
/// than [magicNumbersMaxLength] bytes was provided, some magic-numbers won't
/// be matched against.
- String lookup(String path, {List<int> headerBytes}) {
- String result;
+ String? lookup(String path, {List<int>? headerBytes}) {
+ String? result;
if (headerBytes != null) {
result = _matchMagic(headerBytes, _magicNumbers);
if (result != null) return result;
@@ -99,7 +99,7 @@
///
/// If [mask] is present,the [mask] is used to only perform matching on
/// selective bits. The [mask] must have the same length as [bytes].
- void addMagicNumber(List<int> bytes, String mimeType, {List<int> mask}) {
+ void addMagicNumber(List<int> bytes, String mimeType, {List<int>? mask}) {
if (mask != null && bytes.length != mask.length) {
throw ArgumentError('Bytes and mask are of different lengths');
}
@@ -109,7 +109,7 @@
_magicNumbers.add(MagicNumber(mimeType, bytes, mask: mask));
}
- static String _matchMagic(
+ static String? _matchMagic(
List<int> headerBytes, List<MagicNumber> magicNumbers) {
for (var mn in magicNumbers) {
if (mn.matches(headerBytes)) return mn.mimeType;
diff --git a/pubspec.yaml b/pubspec.yaml
index 17d31e1..6840fa9 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
name: mime
-version: 0.9.8-dev
+version: 1.0.0-nullsafety.0
description: >-
Utilities for handling media (MIME) types, including determining a type from
@@ -7,8 +7,12 @@
homepage: https://github.com/dart-lang/mime
environment:
- sdk: '>=2.1.0 <3.0.0'
+ sdk: '>=2.12.0-0 <3.0.0'
dev_dependencies:
- pedantic: ^1.0.0
- test: ^1.2.0
+ pedantic: ^1.10.0-nullsafety
+ test: ^1.16.0-nullsafety
+
+dependency_overrides:
+ # Required due to package:test cycle.
+ shelf_static: ^0.2.8
diff --git a/test/mime_multipart_transformer_test.dart b/test/mime_multipart_transformer_test.dart
index fbfe2b6..6043d60 100644
--- a/test/mime_multipart_transformer_test.dart
+++ b/test/mime_multipart_transformer_test.dart
@@ -23,7 +23,9 @@
enum TestMode { IMMEDIATE_LISTEN, DELAY_LISTEN, PAUSE_RESUME }
void _runParseTest(String message, String boundary, TestMode mode,
- [List<Map> expectedHeaders, List expectedParts, bool expectError = false]) {
+ [List<Map>? expectedHeaders,
+ List? expectedParts,
+ bool expectError = false]) {
Future testWrite(List<int> data, [int chunkSize = -1]) {
var controller = StreamController<List<int>>(sync: true);
@@ -39,20 +41,20 @@
}
switch (mode) {
case TestMode.IMMEDIATE_LISTEN:
- futures.add(multipart
- .fold([], (buffer, data) => buffer..addAll(data)).then((data) {
- if (expectedParts[part] != null) {
- expect(data, equals(expectedParts[part].codeUnits));
+ futures.add(multipart.fold<List<int>>(
+ [], (buffer, data) => buffer..addAll(data)).then((data) {
+ if (expectedParts?[part] != null) {
+ expect(data, equals(expectedParts?[part].codeUnits));
}
}));
break;
case TestMode.DELAY_LISTEN:
futures.add(Future(() {
- return multipart
- .fold([], (buffer, data) => buffer..addAll(data)).then((data) {
- if (expectedParts[part] != null) {
- expect(data, equals(expectedParts[part].codeUnits));
+ return multipart.fold<List<int>>(
+ [], (buffer, data) => buffer..addAll(data)).then((data) {
+ if (expectedParts?[part] != null) {
+ expect(data, equals(expectedParts?[part].codeUnits));
}
});
}));
@@ -68,14 +70,14 @@
subscription.pause();
Future(() => subscription.resume());
}, onDone: () {
- if (expectedParts[part] != null) {
- expect(buffer, equals(expectedParts[part].codeUnits));
+ if (expectedParts?[part] != null) {
+ expect(buffer, equals(expectedParts?[part].codeUnits));
}
completer.complete();
});
break;
}
- }, onError: (error) {
+ }, onError: (Object error) {
if (!expectError) throw error;
}, onDone: () {
if (expectedParts != null) {
@@ -100,7 +102,8 @@
if (expectedHeaders != null) {
expect(multipart.headers, equals(expectedHeaders[0]));
}
- return (multipart.fold([], (b, d) => b..addAll(d)).then((data) {
+ return (multipart
+ .fold<List<int>>([], (b, d) => b..addAll(d)).then((data) {
if (expectedParts != null && expectedParts[0] != null) {
expect(data, equals(expectedParts[0].codeUnits));
}
@@ -133,7 +136,8 @@
if (expectedHeaders != null) {
expect(multipart.headers, equals(expectedHeaders[partIndex]));
}
- futures.add((multipart.fold([], (b, d) => b..addAll(d)).then((data) {
+ futures.add(
+ (multipart.fold<List<int>>([], (b, d) => b..addAll(d)).then((data) {
if (expectedParts != null && expectedParts[partIndex] != null) {
expect(data, equals(expectedParts[partIndex].codeUnits));
}
@@ -165,7 +169,7 @@
completes);
});
- if (expectedParts.isNotEmpty) {
+ if (expectedParts!.isNotEmpty) {
test('test-first-part-only', () {
expect(
Future.wait([
@@ -194,7 +198,9 @@
}
void _testParse(String message, String boundary,
- [List<Map> expectedHeaders, List expectedParts, bool expectError = false]) {
+ [List<Map>? expectedHeaders,
+ List? expectedParts,
+ bool expectError = false]) {
_runParseTest(message, boundary, TestMode.IMMEDIATE_LISTEN, expectedHeaders,
expectedParts, expectError);
_runParseTest(message, boundary, TestMode.DELAY_LISTEN, expectedHeaders,
diff --git a/test/mime_type_test.dart b/test/mime_type_test.dart
index 7f9169c..992b73d 100644
--- a/test/mime_type_test.dart
+++ b/test/mime_type_test.dart
@@ -8,9 +8,9 @@
import 'package:mime/mime.dart';
import 'package:mime/src/magic_number.dart';
-void _expectMimeType(String path, String expectedMimeType,
- {List<int> headerBytes, MimeTypeResolver resolver}) {
- String mimeType;
+void _expectMimeType(String path, String? expectedMimeType,
+ {List<int>? headerBytes, MimeTypeResolver? resolver}) {
+ String? mimeType;
if (resolver == null) {
mimeType = lookupMimeType(path, headerBytes: headerBytes);
} else {