pdfDocumentFromUri function
Future<PdfDocument>
pdfDocumentFromUri(
- Uri uri, {
- PdfPasswordProvider? passwordProvider,
- bool firstAttemptByEmptyPassword = true,
- int? blockSize,
- PdfFileCache? cache,
- PdfDownloadProgressCallback? progressCallback,
- PdfDownloadReportCallback? reportCallback,
- bool useRangeAccess = true,
- Map<
String, String> ? headers,
Open PDF file from uri
.
On web, unlike PdfDocument.openUri, this function uses HTTP's range request to download the file and uses PdfFileCache.
Implementation
Future<PdfDocument> pdfDocumentFromUri(
Uri uri, {
PdfPasswordProvider? passwordProvider,
bool firstAttemptByEmptyPassword = true,
int? blockSize,
PdfFileCache? cache,
PdfDownloadProgressCallback? progressCallback,
PdfDownloadReportCallback? reportCallback,
bool useRangeAccess = true,
Map<String, String>? headers,
}) async {
final startTime = reportCallback != null ? DateTime.now() : null;
void report() {
if (reportCallback != null && cache?.isInitialized == true) {
reportCallback(
cache?.cachedBytes ?? 0,
cache?.fileSize ?? 0,
DateTime.now().difference(startTime!),
);
}
}
progressCallback?.call(0);
cache ??= await PdfFileCache.fromUri(uri);
final httpClient = http.Client();
try {
if (!cache.isInitialized) {
cache.setBlockSize(blockSize ?? PdfFileCache.defaultBlockSize);
final result = await _downloadBlock(
httpClient,
uri,
cache,
progressCallback,
0,
useRangeAccess: useRangeAccess,
headers: headers,
);
if (result.isFullDownload) {
return await PdfDocument.openFile(
cache.filePath,
passwordProvider: passwordProvider,
firstAttemptByEmptyPassword: firstAttemptByEmptyPassword,
);
}
} else {
// Check if the file is fresh (no-need-to-reload).
if (cache.cacheControlState.cacheControl.mustRevalidate &&
cache.cacheControlState.isFresh(now: DateTime.now())) {
// cache is valid; no need to download.
} else {
final result = await _downloadBlock(
httpClient,
uri,
cache,
progressCallback,
0,
addCacheControlHeaders: true,
useRangeAccess: useRangeAccess,
headers: headers,
);
if (result.isFullDownload) {
cache.close(); // close the cache file before opening it.
httpClient.close();
return await PdfDocument.openFile(
cache.filePath,
passwordProvider: passwordProvider,
firstAttemptByEmptyPassword: firstAttemptByEmptyPassword,
);
}
}
}
return await PdfDocument.openCustom(
read: (buffer, position, size) async {
final totalSize = size;
final end = position + size;
int bufferPosition = 0;
for (int p = position; p < end;) {
final blockId = p ~/ cache!.blockSize;
final isAvailable = cache.isCached(blockId);
if (!isAvailable) {
await _downloadBlock(
httpClient,
uri,
cache,
progressCallback,
blockId,
headers: headers,
);
}
final readEnd = min(p + size, (blockId + 1) * cache.blockSize);
final sizeToRead = readEnd - p;
await cache.read(buffer, bufferPosition, p, sizeToRead);
p += sizeToRead;
bufferPosition += sizeToRead;
size -= sizeToRead;
}
return totalSize;
},
passwordProvider: passwordProvider,
firstAttemptByEmptyPassword: firstAttemptByEmptyPassword,
fileSize: cache.fileSize,
sourceName: uri.toString(),
onDispose: () {
cache!.close();
httpClient.close();
},
);
} catch (e) {
cache.close();
httpClient.close();
rethrow;
} finally {
report();
}
}