get method
- String? url,
- String? checksum,
- dynamic onReceiveProgress()?,
- CancelToken? cancelToken,
- Future<
void> onForbidden()?, - CacheResponseType responseType = CacheResponseType.bytes,
Returns the bytes of File identified by its checksum
.
At least one of url
or checksum
arguments must be provided.
Retries itself using exponential backoff algorithm on a failure, which can
be canceled with a cancelToken
.
Implementation
FutureOr<CacheEntry> get({
String? url,
String? checksum,
Function(int count, int total)? onReceiveProgress,
CancelToken? cancelToken,
Future<void> Function()? onForbidden,
CacheResponseType responseType = CacheResponseType.bytes,
}) {
// Web does not support file caching.
if (PlatformUtils.isWeb) {
responseType = CacheResponseType.bytes;
}
// Try to retrieve the [CacheEntry] by URL as well, yet [checksum] is still
// more preferred.
final String? key = checksum ?? url;
if (key != null && FIFOCache.exists(key)) {
final Uint8List? bytes = FIFOCache.get(key);
if (bytes != null) {
switch (responseType) {
case CacheResponseType.file:
// If [CacheEntry] is supposed to contain a [File], and we don't
// have a [checksum], then there won't be a [File], thus we should
// break and proceed to fetch the [File] by the [url] provided.
if (checksum == null) {
break;
}
return Future(
() async => CacheEntry(file: await add(bytes, checksum, url)),
);
case CacheResponseType.bytes:
return CacheEntry(bytes: bytes);
}
}
}
return Future(() async {
if (checksum != null) {
final Directory? cache = await PlatformUtils.cacheDirectory;
if (cache != null) {
final File file = File('${cache.path}/$checksum');
if (await file.exists()) {
switch (responseType) {
case CacheResponseType.file:
return CacheEntry(file: file);
case CacheResponseType.bytes:
final Uint8List bytes = await file.readAsBytes();
FIFOCache.set(checksum, bytes);
return CacheEntry(bytes: bytes);
}
}
}
}
if (url != null) {
try {
final Uint8List? data = await Backoff.run(() async {
Response? data;
try {
data = await (await PlatformUtils.dio).get(
url,
options: Options(responseType: ResponseType.bytes),
cancelToken: cancelToken,
onReceiveProgress: onReceiveProgress,
);
} on DioException catch (e) {
if (e.response?.statusCode == 403) {
await onForbidden?.call();
return null;
}
}
if (data?.data != null && data!.statusCode == 200) {
return data.data as Uint8List;
} else {
throw Exception('Data is not loaded');
}
}, cancelToken);
switch (responseType) {
case CacheResponseType.file:
return Future(
() async => CacheEntry(
file: data == null ? null : await add(data, checksum, url),
),
);
case CacheResponseType.bytes:
if (data != null) {
add(data, checksum, url);
}
return CacheEntry(bytes: data);
}
} on OperationCanceledException catch (_) {
return CacheEntry();
}
}
return CacheEntry();
});
}