mirror of
https://gitlab.com/TheOneWithTheBraid/dart_pkpass.git
synced 2025-07-06 05:18:47 +00:00
fix: support compressed archives and advanced character encoding
Signed-off-by: The one with the braid <info@braid.business>
This commit is contained in:
parent
6e34b5220c
commit
0863580b23
4 changed files with 70 additions and 33 deletions
|
@ -2,6 +2,7 @@ import 'dart:convert';
|
|||
import 'dart:typed_data';
|
||||
|
||||
import 'package:archive/archive.dart';
|
||||
import 'package:charset/charset.dart';
|
||||
import 'package:crypto/crypto.dart';
|
||||
import 'package:intl/locale.dart';
|
||||
|
||||
|
@ -9,9 +10,6 @@ import 'package:pkpass/pkpass.dart';
|
|||
import 'package:pkpass/pkpass/utils/file_matcher.dart';
|
||||
import 'package:pkpass/pkpass/utils/lproj_parser.dart';
|
||||
|
||||
final _utf8codec = Utf8Codec();
|
||||
final _jsonCodec = JsonCodec();
|
||||
|
||||
class PassFile {
|
||||
const PassFile(this.metadata, this._folder);
|
||||
|
||||
|
@ -26,18 +24,9 @@ class PassFile {
|
|||
|
||||
Map<String, String> manifest;
|
||||
|
||||
try {
|
||||
final file = archive.files
|
||||
.singleWhere((element) => element.name == 'manifest.json');
|
||||
manifest = (_jsonCodec.decode(
|
||||
_utf8codec.decode(
|
||||
file.rawContent?.toUint8List() ?? (file.content as Uint8List),
|
||||
),
|
||||
) as Map)
|
||||
.cast<String, String>();
|
||||
} catch (e) {
|
||||
throw ManifestNotFoundError();
|
||||
}
|
||||
final file =
|
||||
archive.files.singleWhere((element) => element.name == 'manifest.json');
|
||||
manifest = (json.decode(file.stringContent) as Map).cast<String, String>();
|
||||
|
||||
final folder = <ArchiveFile>[];
|
||||
|
||||
|
@ -47,8 +36,7 @@ class PassFile {
|
|||
final file = archive.files
|
||||
.singleWhere((element) => element.name == manifestEntry.key);
|
||||
|
||||
final content =
|
||||
file.rawContent?.toUint8List() ?? file.content as Uint8List;
|
||||
final content = file.byteContent;
|
||||
|
||||
String hash = sha1.convert(content).toString();
|
||||
|
||||
|
@ -67,7 +55,7 @@ class PassFile {
|
|||
archive.singleWhere((element) => element.name == 'pass.json');
|
||||
|
||||
final PassMetadata metadata = PassMetadata.fromJson(
|
||||
_jsonCodec.decode(passFile.stringContent) as Map<String, Object?>,
|
||||
json.decode(passFile.stringContent) as Map<String, Object?>,
|
||||
);
|
||||
|
||||
return PassFile(metadata, folder);
|
||||
|
@ -77,7 +65,7 @@ class PassFile {
|
|||
|
||||
final List<ArchiveFile> _folder;
|
||||
|
||||
Uint8List? _matchUtf8List({
|
||||
Uint8List? _matchUint8ListFile({
|
||||
required String name,
|
||||
required Locale? locale,
|
||||
required int scale,
|
||||
|
@ -92,27 +80,27 @@ class PassFile {
|
|||
);
|
||||
if (path == null) return null;
|
||||
final file = _folder.singleWhere((element) => element.name == path);
|
||||
final content = file.rawContent?.toUint8List() ?? file.content as Uint8List;
|
||||
final content = file.byteContent;
|
||||
return content;
|
||||
}
|
||||
|
||||
Uint8List? getBackground({Locale? locale, int scale = 1}) =>
|
||||
_matchUtf8List(name: 'background', locale: locale, scale: scale);
|
||||
_matchUint8ListFile(name: 'background', locale: locale, scale: scale);
|
||||
|
||||
Uint8List? getFooter({Locale? locale, int scale = 1}) =>
|
||||
_matchUtf8List(name: 'footer', locale: locale, scale: scale);
|
||||
_matchUint8ListFile(name: 'footer', locale: locale, scale: scale);
|
||||
|
||||
Uint8List? getIcon({Locale? locale, int scale = 1}) =>
|
||||
_matchUtf8List(name: 'icon', locale: locale, scale: scale);
|
||||
_matchUint8ListFile(name: 'icon', locale: locale, scale: scale);
|
||||
|
||||
Uint8List? getLogo({Locale? locale, int scale = 1}) =>
|
||||
_matchUtf8List(name: 'logo', locale: locale, scale: scale);
|
||||
_matchUint8ListFile(name: 'logo', locale: locale, scale: scale);
|
||||
|
||||
Uint8List? getStrip({Locale? locale, int scale = 1}) =>
|
||||
_matchUtf8List(name: 'strip', locale: locale, scale: scale);
|
||||
_matchUint8ListFile(name: 'strip', locale: locale, scale: scale);
|
||||
|
||||
Uint8List? getThumbnail({Locale? locale, int scale = 1}) =>
|
||||
_matchUtf8List(name: 'thumbnail', locale: locale, scale: scale);
|
||||
_matchUint8ListFile(name: 'thumbnail', locale: locale, scale: scale);
|
||||
|
||||
Map<String, String>? getLocalizations(Locale? locale) {
|
||||
final files = _folder.map((e) => e.name).toList();
|
||||
|
@ -129,6 +117,31 @@ class PassFile {
|
|||
}
|
||||
|
||||
extension on ArchiveFile {
|
||||
String get stringContent =>
|
||||
_utf8codec.decode(rawContent?.toUint8List() ?? (content as Uint8List));
|
||||
String get stringContent {
|
||||
final codec = Charset.detect(
|
||||
byteContent,
|
||||
defaultEncoding: utf8,
|
||||
orders: [
|
||||
utf8,
|
||||
ascii,
|
||||
gbk,
|
||||
latin1,
|
||||
],
|
||||
) ??
|
||||
utf8;
|
||||
return codec.decode(content);
|
||||
}
|
||||
|
||||
Uint8List get byteContent {
|
||||
decompress();
|
||||
|
||||
final content = this.content;
|
||||
if (content is String) {
|
||||
return utf8.encode(content);
|
||||
} else if (content is Iterable) {
|
||||
return Uint8List.fromList(content.cast<int>().toList());
|
||||
} else {
|
||||
return rawContent!.toUint8List();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue