from static method

Future<ZipPackage?> from(
  1. File file
)

Implementation

static Future<ZipPackage?> from(File file) async {
  if (!(await file.exists())) return null;

  final zp = ZipPackage(file);
  final package = await FileBuffer.from(file);
  try {
    final entries = <ZipLocalFile>[];
    final cds = <ZipCentralDirectory>[];

    while (!package.isEnd) {
      final pk = await package.readUint16();
      if (pk != 0x4b50) {
        // print(jsonEncode(zp));
        throw UnsupportedError('Unsupported format');
      }

      final sign = await package.readUint16();
      final ZipHeader? header = await ZipHeader.readNext(package, sign);

      /*
      if (sign == 0x0806) {
        // 0608: Archive extra data record
        print('[Archive extra data record]');
        break;
      } else if (sign == 0x0505) {
        // 0505: Digital signature
        print('[Digital signature]');
        break;
      } else if (sign == 0x0606) {
        // 0x0606: Zip64 end of central directory record
        print('[Zip64 end of central directory record]');
        break;
      } else if (sign == 0x0706) {
        // 0x0607: Zip64 end of central directory locator
        print('[Zip64 end of central directory locator]');
        break;
      } else if (sign == 0x0605) {
        // 0x0506: End of central directory record
        print('[End of central directory record]');
        break;
      }
      */
      if (header == null) {
        throw UnsupportedError(
            'Unsupported Header: ${sign.toRadixString(16).padLeft(4, '0')}');
      }

      if (header.isCentralDirectoryEnd) {
        zp.cdEnd = header as ZipEndCentralDirectory;
        zp.stopOffset = package.position;
        break;
      }

      if (header.isLocalFile) {
        final ZipLocalFile f = header as ZipLocalFile;
        entries.add(f);
        package.addToPosition(f.compressedSize);
      } else if (header.isCentralDirectory) {
        final ZipCentralDirectory cd = header as ZipCentralDirectory;
        cds.add(cd);
      }
    }

    zp.entries = Map.fromEntries(entries.map((f) => MapEntry(f.filename, f)));
    zp.centralDirectories = cds;
    return zp;
  } finally {
    await package.close();
  }
}