1# SPDX-License-Identifier: GPL-2.0+ 2# Copyright 2022 Google LLC 3# 4"""Bintool implementation for lz4 5 6lz4 allows compression and decompression of files. 7 8Documentation is available via:: 9 10 man lz4 11 12Here is the help: 13 14*** LZ4 command line interface 64-bits v1.9.3, by Yann Collet *** 15Usage : 16 lz4 [arg] [input] [output] 17 18input : a filename 19 with no FILE, or when FILE is - or stdin, read standard input 20Arguments : 21 -1 : Fast compression (default) 22 -9 : High compression 23 -d : decompression (default for .lz4 extension) 24 -z : force compression 25 -D FILE: use FILE as dictionary 26 -f : overwrite output without prompting 27 -k : preserve source files(s) (default) 28--rm : remove source file(s) after successful de/compression 29 -h/-H : display help/long help and exit 30 31Advanced arguments : 32 -V : display Version number and exit 33 -v : verbose mode 34 -q : suppress warnings; specify twice to suppress errors too 35 -c : force write to standard output, even if it is the console 36 -t : test compressed file integrity 37 -m : multiple input files (implies automatic output filenames) 38 -r : operate recursively on directories (sets also -m) 39 -l : compress using Legacy format (Linux kernel compression) 40 -B# : cut file into blocks of size # bytes [32+] 41 or predefined block size [4-7] (default: 7) 42 -BI : Block Independence (default) 43 -BD : Block dependency (improves compression ratio) 44 -BX : enable block checksum (default:disabled) 45--no-frame-crc : disable stream checksum (default:enabled) 46--content-size : compressed frame includes original size (default:not present) 47--list FILE : lists information about .lz4 files (useful for files compressed 48 with --content-size flag) 49--[no-]sparse : sparse mode (default:enabled on file, disabled on stdout) 50--favor-decSpeed: compressed files decompress faster, but are less compressed 51--fast[=#]: switch to ultra fast compression level (default: 1) 52--best : same as -12 53Benchmark arguments : 54 -b# : benchmark file(s), using # compression level (default : 1) 55 -e# : test all compression levels from -bX to # (default : 1) 56 -i# : minimum evaluation time in seconds (default : 3s) 57""" 58 59import re 60import tempfile 61 62from binman import bintool 63from u_boot_pylib import tools 64 65# pylint: disable=C0103 66class Bintoollz4(bintool.Bintool): 67 """Compression/decompression using the LZ4 algorithm 68 69 This bintool supports running `lz4` to compress and decompress data, as 70 used by binman. 71 72 It is also possible to fetch the tool, which uses `apt` to install it. 73 74 Documentation is available via:: 75 76 man lz4 77 """ 78 def __init__(self, name): 79 super().__init__(name, 'lz4 compression', r'.* (v[0-9.]*),.*') 80 81 def compress(self, indata): 82 """Compress data with lz4 83 84 Args: 85 indata (bytes): Data to compress 86 87 Returns: 88 bytes: Compressed data 89 """ 90 with tempfile.NamedTemporaryFile(prefix='comp.tmp', 91 dir=tools.get_output_dir()) as tmp: 92 tools.write_file(tmp.name, indata) 93 args = ['--no-frame-crc', '-B4', '-5', '-c', tmp.name] 94 return self.run_cmd(*args, binary=True) 95 96 def decompress(self, indata): 97 """Decompress data with lz4 98 99 Args: 100 indata (bytes): Data to decompress 101 102 Returns: 103 bytes: Decompressed data 104 """ 105 with tempfile.NamedTemporaryFile(prefix='decomp.tmp', 106 dir=tools.get_output_dir()) as inf: 107 tools.write_file(inf.name, indata) 108 args = ['-cd', inf.name] 109 return self.run_cmd(*args, binary=True) 110 111 def fetch(self, method): 112 """Fetch handler for lz4 113 114 This installs the lz4 package using the apt utility. 115 116 Args: 117 method (FETCH_...): Method to use 118 119 Returns: 120 True if the file was fetched and now installed, None if a method 121 other than FETCH_BIN was requested 122 123 Raises: 124 Valuerror: Fetching could not be completed 125 """ 126 if method != bintool.FETCH_BIN: 127 return None 128 return self.apt_install('lz4') 129