import 'dart:collection'; import 'archive_file.dart'; /// A collection of files class Archive extends IterableBase { /// The list of files in the archive. final List _files = []; final Map _fileMap = {}; /// A global comment for the archive. String? comment; /// Unmodifiable view of the files in the archive. List get files => UnmodifiableListView(_files); /// Add a file to the archive. void addFile(ArchiveFile file) { // Adding a file with the same path as one that's already in the archive // will replace the previous file. var index = _fileMap[file.name]; if (index != null) { _files[index] = file; return; } // No existing file was in the archive with the same path, add it to the // archive. _files.add(file); _fileMap[file.name] = _files.length - 1; } void removeFile(ArchiveFile file) { final index = _fileMap[file.name]; if (index != null) { _files.removeAt(index); _fileMap.remove(file.name); } } void removeAt(int index) { if (index < 0 || index >= _files.length) { return; } _fileMap.remove(_files[index].name); _files.removeAt(index); } Future clear() async { var futures = >[]; for (var fp in _files) { futures.add(fp.close()); } _files.clear(); _fileMap.clear(); comment = null; await Future.wait(futures); } void clearSync() { for (var fp in _files) { fp.closeSync(); } _files.clear(); _fileMap.clear(); comment = null; } /// The number of files in the archive. @override int get length => _files.length; /// Get a file from the archive. ArchiveFile operator [](int index) => _files[index]; /// Set a file in the archive. void operator []=(int index, ArchiveFile file) { if (index < 0 || index >= _files.length) { return; } _fileMap.remove(_files[index].name); _files[index] = file; _fileMap[file.name] = index; } /// Find a file with the given [name] in the archive. If the file isn't found, /// null will be returned. ArchiveFile? findFile(String name) { var index = _fileMap[name]; return index != null ? _files[index] : null; } /// The number of files in the archive. int numberOfFiles() { return _files.length; } /// The name of the file at the given [index]. String fileName(int index) { return _files[index].name; } /// The decompressed size of the file at the given [index]. int fileSize(int index) { return _files[index].size; } /// The decompressed data of the file at the given [index]. List fileData(int index) { return _files[index].content as List; } @override ArchiveFile get first => _files.first; @override ArchiveFile get last => _files.last; @override bool get isEmpty => _files.isEmpty; // Returns true if there is at least one element in this collection. @override bool get isNotEmpty => _files.isNotEmpty; @override Iterator get iterator => _files.iterator; }