127 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			127 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Python
		
	
	
	
| # SPDX-License-Identifier: GPL-2.0+
 | |
| # Copyright 2022 Google LLC
 | |
| #
 | |
| """Bintool implementation for lzma_alone
 | |
| 
 | |
| lzma_alone allows compression and decompression of files, using an older version
 | |
| of lzma.
 | |
| 
 | |
| Documentation is available via::
 | |
| 
 | |
|    man lzma_alone
 | |
| 
 | |
| Here is the help:
 | |
| 
 | |
| LZMA 9.22 beta : Igor Pavlov : Public domain : 2011-04-18
 | |
| 
 | |
| Usage:  LZMA <e|d> inputFile outputFile [<switches>...]
 | |
|   e: encode file
 | |
|   d: decode file
 | |
|   b: Benchmark
 | |
| <Switches>
 | |
|   -a{N}:  set compression mode - [0, 1], default: 1 (max)
 | |
|   -d{N}:  set dictionary size - [12, 30], default: 23 (8MB)
 | |
|   -fb{N}: set number of fast bytes - [5, 273], default: 128
 | |
|   -mc{N}: set number of cycles for match finder
 | |
|   -lc{N}: set number of literal context bits - [0, 8], default: 3
 | |
|   -lp{N}: set number of literal pos bits - [0, 4], default: 0
 | |
|   -pb{N}: set number of pos bits - [0, 4], default: 2
 | |
|   -mf{MF_ID}: set Match Finder: [bt2, bt3, bt4, hc4], default: bt4
 | |
|   -mt{N}: set number of CPU threads
 | |
|   -eos:   write End Of Stream marker
 | |
|   -si:    read data from stdin
 | |
|   -so:    write data to stdout
 | |
| """
 | |
| 
 | |
| import re
 | |
| import tempfile
 | |
| 
 | |
| from binman import bintool
 | |
| from patman import tools
 | |
| 
 | |
| # pylint: disable=C0103
 | |
| class Bintoollzma_alone(bintool.Bintool):
 | |
|     """Compression/decompression using the LZMA algorithm
 | |
| 
 | |
|     This bintool supports running `lzma_alone` to compress and decompress data,
 | |
|     as used by binman.
 | |
| 
 | |
|     It is also possible to fetch the tool, which uses `apt` to install it.
 | |
| 
 | |
|     Documentation is available via::
 | |
| 
 | |
|         man lzma_alone
 | |
|     """
 | |
|     def __init__(self, name):
 | |
|         super().__init__(name, 'lzma_alone compression')
 | |
| 
 | |
|     def compress(self, indata):
 | |
|         """Compress data with lzma_alone
 | |
| 
 | |
|         Args:
 | |
|             indata (bytes): Data to compress
 | |
| 
 | |
|         Returns:
 | |
|             bytes: Compressed data
 | |
|         """
 | |
|         with tempfile.NamedTemporaryFile(prefix='comp.tmp',
 | |
|                                          dir=tools.get_output_dir()) as inf:
 | |
|             tools.write_file(inf.name, indata)
 | |
|             with tempfile.NamedTemporaryFile(prefix='compo.otmp',
 | |
|                                              dir=tools.get_output_dir()) as outf:
 | |
|                 args = ['e', inf.name, outf.name, '-lc1', '-lp0', '-pb0', '-d8']
 | |
|                 self.run_cmd(*args, binary=True)
 | |
|                 return tools.read_file(outf.name)
 | |
| 
 | |
|     def decompress(self, indata):
 | |
|         """Decompress data with lzma_alone
 | |
| 
 | |
|         Args:
 | |
|             indata (bytes): Data to decompress
 | |
| 
 | |
|         Returns:
 | |
|             bytes: Decompressed data
 | |
|         """
 | |
|         with tempfile.NamedTemporaryFile(prefix='decomp.tmp',
 | |
|                                          dir=tools.get_output_dir()) as inf:
 | |
|             tools.write_file(inf.name, indata)
 | |
|             with tempfile.NamedTemporaryFile(prefix='compo.otmp',
 | |
|                                              dir=tools.get_output_dir()) as outf:
 | |
|                 args = ['d', inf.name, outf.name]
 | |
|                 self.run_cmd(*args, binary=True)
 | |
|                 return tools.read_file(outf.name, binary=True)
 | |
| 
 | |
|     def fetch(self, method):
 | |
|         """Fetch handler for lzma_alone
 | |
| 
 | |
|         This installs the lzma-alone package using the apt utility.
 | |
| 
 | |
|         Args:
 | |
|             method (FETCH_...): Method to use
 | |
| 
 | |
|         Returns:
 | |
|             True if the file was fetched and now installed, None if a method
 | |
|             other than FETCH_BIN was requested
 | |
| 
 | |
|         Raises:
 | |
|             Valuerror: Fetching could not be completed
 | |
|         """
 | |
|         if method != bintool.FETCH_BIN:
 | |
|             return None
 | |
|         return self.apt_install('lzma-alone')
 | |
| 
 | |
|     def version(self):
 | |
|         """Version handler
 | |
| 
 | |
|         Returns:
 | |
|             str: Version number of lzma_alone
 | |
|         """
 | |
|         out = self.run_cmd_result('', raise_on_error=False).stderr.strip()
 | |
|         lines = out.splitlines()
 | |
|         if not lines:
 | |
|             return super().version()
 | |
|         out = lines[0]
 | |
|         # e.g. LZMA 9.22 beta : Igor Pavlov : Public domain : 2011-04-18
 | |
|         m_version = re.match(r'LZMA ([^:]*).*', out)
 | |
|         return m_version.group(1).strip() if m_version else out
 |