1*cda5da8dSAndroid Build Coastguard Worker"""Interface to the liblzma compression library. 2*cda5da8dSAndroid Build Coastguard Worker 3*cda5da8dSAndroid Build Coastguard WorkerThis module provides a class for reading and writing compressed files, 4*cda5da8dSAndroid Build Coastguard Workerclasses for incremental (de)compression, and convenience functions for 5*cda5da8dSAndroid Build Coastguard Workerone-shot (de)compression. 6*cda5da8dSAndroid Build Coastguard Worker 7*cda5da8dSAndroid Build Coastguard WorkerThese classes and functions support both the XZ and legacy LZMA 8*cda5da8dSAndroid Build Coastguard Workercontainer formats, as well as raw compressed data streams. 9*cda5da8dSAndroid Build Coastguard Worker""" 10*cda5da8dSAndroid Build Coastguard Worker 11*cda5da8dSAndroid Build Coastguard Worker__all__ = [ 12*cda5da8dSAndroid Build Coastguard Worker "CHECK_NONE", "CHECK_CRC32", "CHECK_CRC64", "CHECK_SHA256", 13*cda5da8dSAndroid Build Coastguard Worker "CHECK_ID_MAX", "CHECK_UNKNOWN", 14*cda5da8dSAndroid Build Coastguard Worker "FILTER_LZMA1", "FILTER_LZMA2", "FILTER_DELTA", "FILTER_X86", "FILTER_IA64", 15*cda5da8dSAndroid Build Coastguard Worker "FILTER_ARM", "FILTER_ARMTHUMB", "FILTER_POWERPC", "FILTER_SPARC", 16*cda5da8dSAndroid Build Coastguard Worker "FORMAT_AUTO", "FORMAT_XZ", "FORMAT_ALONE", "FORMAT_RAW", 17*cda5da8dSAndroid Build Coastguard Worker "MF_HC3", "MF_HC4", "MF_BT2", "MF_BT3", "MF_BT4", 18*cda5da8dSAndroid Build Coastguard Worker "MODE_FAST", "MODE_NORMAL", "PRESET_DEFAULT", "PRESET_EXTREME", 19*cda5da8dSAndroid Build Coastguard Worker 20*cda5da8dSAndroid Build Coastguard Worker "LZMACompressor", "LZMADecompressor", "LZMAFile", "LZMAError", 21*cda5da8dSAndroid Build Coastguard Worker "open", "compress", "decompress", "is_check_supported", 22*cda5da8dSAndroid Build Coastguard Worker] 23*cda5da8dSAndroid Build Coastguard Worker 24*cda5da8dSAndroid Build Coastguard Workerimport builtins 25*cda5da8dSAndroid Build Coastguard Workerimport io 26*cda5da8dSAndroid Build Coastguard Workerimport os 27*cda5da8dSAndroid Build Coastguard Workerfrom _lzma import * 28*cda5da8dSAndroid Build Coastguard Workerfrom _lzma import _encode_filter_properties, _decode_filter_properties 29*cda5da8dSAndroid Build Coastguard Workerimport _compression 30*cda5da8dSAndroid Build Coastguard Worker 31*cda5da8dSAndroid Build Coastguard Worker 32*cda5da8dSAndroid Build Coastguard Worker_MODE_CLOSED = 0 33*cda5da8dSAndroid Build Coastguard Worker_MODE_READ = 1 34*cda5da8dSAndroid Build Coastguard Worker# Value 2 no longer used 35*cda5da8dSAndroid Build Coastguard Worker_MODE_WRITE = 3 36*cda5da8dSAndroid Build Coastguard Worker 37*cda5da8dSAndroid Build Coastguard Worker 38*cda5da8dSAndroid Build Coastguard Workerclass LZMAFile(_compression.BaseStream): 39*cda5da8dSAndroid Build Coastguard Worker 40*cda5da8dSAndroid Build Coastguard Worker """A file object providing transparent LZMA (de)compression. 41*cda5da8dSAndroid Build Coastguard Worker 42*cda5da8dSAndroid Build Coastguard Worker An LZMAFile can act as a wrapper for an existing file object, or 43*cda5da8dSAndroid Build Coastguard Worker refer directly to a named file on disk. 44*cda5da8dSAndroid Build Coastguard Worker 45*cda5da8dSAndroid Build Coastguard Worker Note that LZMAFile provides a *binary* file interface - data read 46*cda5da8dSAndroid Build Coastguard Worker is returned as bytes, and data to be written must be given as bytes. 47*cda5da8dSAndroid Build Coastguard Worker """ 48*cda5da8dSAndroid Build Coastguard Worker 49*cda5da8dSAndroid Build Coastguard Worker def __init__(self, filename=None, mode="r", *, 50*cda5da8dSAndroid Build Coastguard Worker format=None, check=-1, preset=None, filters=None): 51*cda5da8dSAndroid Build Coastguard Worker """Open an LZMA-compressed file in binary mode. 52*cda5da8dSAndroid Build Coastguard Worker 53*cda5da8dSAndroid Build Coastguard Worker filename can be either an actual file name (given as a str, 54*cda5da8dSAndroid Build Coastguard Worker bytes, or PathLike object), in which case the named file is 55*cda5da8dSAndroid Build Coastguard Worker opened, or it can be an existing file object to read from or 56*cda5da8dSAndroid Build Coastguard Worker write to. 57*cda5da8dSAndroid Build Coastguard Worker 58*cda5da8dSAndroid Build Coastguard Worker mode can be "r" for reading (default), "w" for (over)writing, 59*cda5da8dSAndroid Build Coastguard Worker "x" for creating exclusively, or "a" for appending. These can 60*cda5da8dSAndroid Build Coastguard Worker equivalently be given as "rb", "wb", "xb" and "ab" respectively. 61*cda5da8dSAndroid Build Coastguard Worker 62*cda5da8dSAndroid Build Coastguard Worker format specifies the container format to use for the file. 63*cda5da8dSAndroid Build Coastguard Worker If mode is "r", this defaults to FORMAT_AUTO. Otherwise, the 64*cda5da8dSAndroid Build Coastguard Worker default is FORMAT_XZ. 65*cda5da8dSAndroid Build Coastguard Worker 66*cda5da8dSAndroid Build Coastguard Worker check specifies the integrity check to use. This argument can 67*cda5da8dSAndroid Build Coastguard Worker only be used when opening a file for writing. For FORMAT_XZ, 68*cda5da8dSAndroid Build Coastguard Worker the default is CHECK_CRC64. FORMAT_ALONE and FORMAT_RAW do not 69*cda5da8dSAndroid Build Coastguard Worker support integrity checks - for these formats, check must be 70*cda5da8dSAndroid Build Coastguard Worker omitted, or be CHECK_NONE. 71*cda5da8dSAndroid Build Coastguard Worker 72*cda5da8dSAndroid Build Coastguard Worker When opening a file for reading, the *preset* argument is not 73*cda5da8dSAndroid Build Coastguard Worker meaningful, and should be omitted. The *filters* argument should 74*cda5da8dSAndroid Build Coastguard Worker also be omitted, except when format is FORMAT_RAW (in which case 75*cda5da8dSAndroid Build Coastguard Worker it is required). 76*cda5da8dSAndroid Build Coastguard Worker 77*cda5da8dSAndroid Build Coastguard Worker When opening a file for writing, the settings used by the 78*cda5da8dSAndroid Build Coastguard Worker compressor can be specified either as a preset compression 79*cda5da8dSAndroid Build Coastguard Worker level (with the *preset* argument), or in detail as a custom 80*cda5da8dSAndroid Build Coastguard Worker filter chain (with the *filters* argument). For FORMAT_XZ and 81*cda5da8dSAndroid Build Coastguard Worker FORMAT_ALONE, the default is to use the PRESET_DEFAULT preset 82*cda5da8dSAndroid Build Coastguard Worker level. For FORMAT_RAW, the caller must always specify a filter 83*cda5da8dSAndroid Build Coastguard Worker chain; the raw compressor does not support preset compression 84*cda5da8dSAndroid Build Coastguard Worker levels. 85*cda5da8dSAndroid Build Coastguard Worker 86*cda5da8dSAndroid Build Coastguard Worker preset (if provided) should be an integer in the range 0-9, 87*cda5da8dSAndroid Build Coastguard Worker optionally OR-ed with the constant PRESET_EXTREME. 88*cda5da8dSAndroid Build Coastguard Worker 89*cda5da8dSAndroid Build Coastguard Worker filters (if provided) should be a sequence of dicts. Each dict 90*cda5da8dSAndroid Build Coastguard Worker should have an entry for "id" indicating ID of the filter, plus 91*cda5da8dSAndroid Build Coastguard Worker additional entries for options to the filter. 92*cda5da8dSAndroid Build Coastguard Worker """ 93*cda5da8dSAndroid Build Coastguard Worker self._fp = None 94*cda5da8dSAndroid Build Coastguard Worker self._closefp = False 95*cda5da8dSAndroid Build Coastguard Worker self._mode = _MODE_CLOSED 96*cda5da8dSAndroid Build Coastguard Worker 97*cda5da8dSAndroid Build Coastguard Worker if mode in ("r", "rb"): 98*cda5da8dSAndroid Build Coastguard Worker if check != -1: 99*cda5da8dSAndroid Build Coastguard Worker raise ValueError("Cannot specify an integrity check " 100*cda5da8dSAndroid Build Coastguard Worker "when opening a file for reading") 101*cda5da8dSAndroid Build Coastguard Worker if preset is not None: 102*cda5da8dSAndroid Build Coastguard Worker raise ValueError("Cannot specify a preset compression " 103*cda5da8dSAndroid Build Coastguard Worker "level when opening a file for reading") 104*cda5da8dSAndroid Build Coastguard Worker if format is None: 105*cda5da8dSAndroid Build Coastguard Worker format = FORMAT_AUTO 106*cda5da8dSAndroid Build Coastguard Worker mode_code = _MODE_READ 107*cda5da8dSAndroid Build Coastguard Worker elif mode in ("w", "wb", "a", "ab", "x", "xb"): 108*cda5da8dSAndroid Build Coastguard Worker if format is None: 109*cda5da8dSAndroid Build Coastguard Worker format = FORMAT_XZ 110*cda5da8dSAndroid Build Coastguard Worker mode_code = _MODE_WRITE 111*cda5da8dSAndroid Build Coastguard Worker self._compressor = LZMACompressor(format=format, check=check, 112*cda5da8dSAndroid Build Coastguard Worker preset=preset, filters=filters) 113*cda5da8dSAndroid Build Coastguard Worker self._pos = 0 114*cda5da8dSAndroid Build Coastguard Worker else: 115*cda5da8dSAndroid Build Coastguard Worker raise ValueError("Invalid mode: {!r}".format(mode)) 116*cda5da8dSAndroid Build Coastguard Worker 117*cda5da8dSAndroid Build Coastguard Worker if isinstance(filename, (str, bytes, os.PathLike)): 118*cda5da8dSAndroid Build Coastguard Worker if "b" not in mode: 119*cda5da8dSAndroid Build Coastguard Worker mode += "b" 120*cda5da8dSAndroid Build Coastguard Worker self._fp = builtins.open(filename, mode) 121*cda5da8dSAndroid Build Coastguard Worker self._closefp = True 122*cda5da8dSAndroid Build Coastguard Worker self._mode = mode_code 123*cda5da8dSAndroid Build Coastguard Worker elif hasattr(filename, "read") or hasattr(filename, "write"): 124*cda5da8dSAndroid Build Coastguard Worker self._fp = filename 125*cda5da8dSAndroid Build Coastguard Worker self._mode = mode_code 126*cda5da8dSAndroid Build Coastguard Worker else: 127*cda5da8dSAndroid Build Coastguard Worker raise TypeError("filename must be a str, bytes, file or PathLike object") 128*cda5da8dSAndroid Build Coastguard Worker 129*cda5da8dSAndroid Build Coastguard Worker if self._mode == _MODE_READ: 130*cda5da8dSAndroid Build Coastguard Worker raw = _compression.DecompressReader(self._fp, LZMADecompressor, 131*cda5da8dSAndroid Build Coastguard Worker trailing_error=LZMAError, format=format, filters=filters) 132*cda5da8dSAndroid Build Coastguard Worker self._buffer = io.BufferedReader(raw) 133*cda5da8dSAndroid Build Coastguard Worker 134*cda5da8dSAndroid Build Coastguard Worker def close(self): 135*cda5da8dSAndroid Build Coastguard Worker """Flush and close the file. 136*cda5da8dSAndroid Build Coastguard Worker 137*cda5da8dSAndroid Build Coastguard Worker May be called more than once without error. Once the file is 138*cda5da8dSAndroid Build Coastguard Worker closed, any other operation on it will raise a ValueError. 139*cda5da8dSAndroid Build Coastguard Worker """ 140*cda5da8dSAndroid Build Coastguard Worker if self._mode == _MODE_CLOSED: 141*cda5da8dSAndroid Build Coastguard Worker return 142*cda5da8dSAndroid Build Coastguard Worker try: 143*cda5da8dSAndroid Build Coastguard Worker if self._mode == _MODE_READ: 144*cda5da8dSAndroid Build Coastguard Worker self._buffer.close() 145*cda5da8dSAndroid Build Coastguard Worker self._buffer = None 146*cda5da8dSAndroid Build Coastguard Worker elif self._mode == _MODE_WRITE: 147*cda5da8dSAndroid Build Coastguard Worker self._fp.write(self._compressor.flush()) 148*cda5da8dSAndroid Build Coastguard Worker self._compressor = None 149*cda5da8dSAndroid Build Coastguard Worker finally: 150*cda5da8dSAndroid Build Coastguard Worker try: 151*cda5da8dSAndroid Build Coastguard Worker if self._closefp: 152*cda5da8dSAndroid Build Coastguard Worker self._fp.close() 153*cda5da8dSAndroid Build Coastguard Worker finally: 154*cda5da8dSAndroid Build Coastguard Worker self._fp = None 155*cda5da8dSAndroid Build Coastguard Worker self._closefp = False 156*cda5da8dSAndroid Build Coastguard Worker self._mode = _MODE_CLOSED 157*cda5da8dSAndroid Build Coastguard Worker 158*cda5da8dSAndroid Build Coastguard Worker @property 159*cda5da8dSAndroid Build Coastguard Worker def closed(self): 160*cda5da8dSAndroid Build Coastguard Worker """True if this file is closed.""" 161*cda5da8dSAndroid Build Coastguard Worker return self._mode == _MODE_CLOSED 162*cda5da8dSAndroid Build Coastguard Worker 163*cda5da8dSAndroid Build Coastguard Worker def fileno(self): 164*cda5da8dSAndroid Build Coastguard Worker """Return the file descriptor for the underlying file.""" 165*cda5da8dSAndroid Build Coastguard Worker self._check_not_closed() 166*cda5da8dSAndroid Build Coastguard Worker return self._fp.fileno() 167*cda5da8dSAndroid Build Coastguard Worker 168*cda5da8dSAndroid Build Coastguard Worker def seekable(self): 169*cda5da8dSAndroid Build Coastguard Worker """Return whether the file supports seeking.""" 170*cda5da8dSAndroid Build Coastguard Worker return self.readable() and self._buffer.seekable() 171*cda5da8dSAndroid Build Coastguard Worker 172*cda5da8dSAndroid Build Coastguard Worker def readable(self): 173*cda5da8dSAndroid Build Coastguard Worker """Return whether the file was opened for reading.""" 174*cda5da8dSAndroid Build Coastguard Worker self._check_not_closed() 175*cda5da8dSAndroid Build Coastguard Worker return self._mode == _MODE_READ 176*cda5da8dSAndroid Build Coastguard Worker 177*cda5da8dSAndroid Build Coastguard Worker def writable(self): 178*cda5da8dSAndroid Build Coastguard Worker """Return whether the file was opened for writing.""" 179*cda5da8dSAndroid Build Coastguard Worker self._check_not_closed() 180*cda5da8dSAndroid Build Coastguard Worker return self._mode == _MODE_WRITE 181*cda5da8dSAndroid Build Coastguard Worker 182*cda5da8dSAndroid Build Coastguard Worker def peek(self, size=-1): 183*cda5da8dSAndroid Build Coastguard Worker """Return buffered data without advancing the file position. 184*cda5da8dSAndroid Build Coastguard Worker 185*cda5da8dSAndroid Build Coastguard Worker Always returns at least one byte of data, unless at EOF. 186*cda5da8dSAndroid Build Coastguard Worker The exact number of bytes returned is unspecified. 187*cda5da8dSAndroid Build Coastguard Worker """ 188*cda5da8dSAndroid Build Coastguard Worker self._check_can_read() 189*cda5da8dSAndroid Build Coastguard Worker # Relies on the undocumented fact that BufferedReader.peek() always 190*cda5da8dSAndroid Build Coastguard Worker # returns at least one byte (except at EOF) 191*cda5da8dSAndroid Build Coastguard Worker return self._buffer.peek(size) 192*cda5da8dSAndroid Build Coastguard Worker 193*cda5da8dSAndroid Build Coastguard Worker def read(self, size=-1): 194*cda5da8dSAndroid Build Coastguard Worker """Read up to size uncompressed bytes from the file. 195*cda5da8dSAndroid Build Coastguard Worker 196*cda5da8dSAndroid Build Coastguard Worker If size is negative or omitted, read until EOF is reached. 197*cda5da8dSAndroid Build Coastguard Worker Returns b"" if the file is already at EOF. 198*cda5da8dSAndroid Build Coastguard Worker """ 199*cda5da8dSAndroid Build Coastguard Worker self._check_can_read() 200*cda5da8dSAndroid Build Coastguard Worker return self._buffer.read(size) 201*cda5da8dSAndroid Build Coastguard Worker 202*cda5da8dSAndroid Build Coastguard Worker def read1(self, size=-1): 203*cda5da8dSAndroid Build Coastguard Worker """Read up to size uncompressed bytes, while trying to avoid 204*cda5da8dSAndroid Build Coastguard Worker making multiple reads from the underlying stream. Reads up to a 205*cda5da8dSAndroid Build Coastguard Worker buffer's worth of data if size is negative. 206*cda5da8dSAndroid Build Coastguard Worker 207*cda5da8dSAndroid Build Coastguard Worker Returns b"" if the file is at EOF. 208*cda5da8dSAndroid Build Coastguard Worker """ 209*cda5da8dSAndroid Build Coastguard Worker self._check_can_read() 210*cda5da8dSAndroid Build Coastguard Worker if size < 0: 211*cda5da8dSAndroid Build Coastguard Worker size = io.DEFAULT_BUFFER_SIZE 212*cda5da8dSAndroid Build Coastguard Worker return self._buffer.read1(size) 213*cda5da8dSAndroid Build Coastguard Worker 214*cda5da8dSAndroid Build Coastguard Worker def readline(self, size=-1): 215*cda5da8dSAndroid Build Coastguard Worker """Read a line of uncompressed bytes from the file. 216*cda5da8dSAndroid Build Coastguard Worker 217*cda5da8dSAndroid Build Coastguard Worker The terminating newline (if present) is retained. If size is 218*cda5da8dSAndroid Build Coastguard Worker non-negative, no more than size bytes will be read (in which 219*cda5da8dSAndroid Build Coastguard Worker case the line may be incomplete). Returns b'' if already at EOF. 220*cda5da8dSAndroid Build Coastguard Worker """ 221*cda5da8dSAndroid Build Coastguard Worker self._check_can_read() 222*cda5da8dSAndroid Build Coastguard Worker return self._buffer.readline(size) 223*cda5da8dSAndroid Build Coastguard Worker 224*cda5da8dSAndroid Build Coastguard Worker def write(self, data): 225*cda5da8dSAndroid Build Coastguard Worker """Write a bytes object to the file. 226*cda5da8dSAndroid Build Coastguard Worker 227*cda5da8dSAndroid Build Coastguard Worker Returns the number of uncompressed bytes written, which is 228*cda5da8dSAndroid Build Coastguard Worker always the length of data in bytes. Note that due to buffering, 229*cda5da8dSAndroid Build Coastguard Worker the file on disk may not reflect the data written until close() 230*cda5da8dSAndroid Build Coastguard Worker is called. 231*cda5da8dSAndroid Build Coastguard Worker """ 232*cda5da8dSAndroid Build Coastguard Worker self._check_can_write() 233*cda5da8dSAndroid Build Coastguard Worker if isinstance(data, (bytes, bytearray)): 234*cda5da8dSAndroid Build Coastguard Worker length = len(data) 235*cda5da8dSAndroid Build Coastguard Worker else: 236*cda5da8dSAndroid Build Coastguard Worker # accept any data that supports the buffer protocol 237*cda5da8dSAndroid Build Coastguard Worker data = memoryview(data) 238*cda5da8dSAndroid Build Coastguard Worker length = data.nbytes 239*cda5da8dSAndroid Build Coastguard Worker 240*cda5da8dSAndroid Build Coastguard Worker compressed = self._compressor.compress(data) 241*cda5da8dSAndroid Build Coastguard Worker self._fp.write(compressed) 242*cda5da8dSAndroid Build Coastguard Worker self._pos += length 243*cda5da8dSAndroid Build Coastguard Worker return length 244*cda5da8dSAndroid Build Coastguard Worker 245*cda5da8dSAndroid Build Coastguard Worker def seek(self, offset, whence=io.SEEK_SET): 246*cda5da8dSAndroid Build Coastguard Worker """Change the file position. 247*cda5da8dSAndroid Build Coastguard Worker 248*cda5da8dSAndroid Build Coastguard Worker The new position is specified by offset, relative to the 249*cda5da8dSAndroid Build Coastguard Worker position indicated by whence. Possible values for whence are: 250*cda5da8dSAndroid Build Coastguard Worker 251*cda5da8dSAndroid Build Coastguard Worker 0: start of stream (default): offset must not be negative 252*cda5da8dSAndroid Build Coastguard Worker 1: current stream position 253*cda5da8dSAndroid Build Coastguard Worker 2: end of stream; offset must not be positive 254*cda5da8dSAndroid Build Coastguard Worker 255*cda5da8dSAndroid Build Coastguard Worker Returns the new file position. 256*cda5da8dSAndroid Build Coastguard Worker 257*cda5da8dSAndroid Build Coastguard Worker Note that seeking is emulated, so depending on the parameters, 258*cda5da8dSAndroid Build Coastguard Worker this operation may be extremely slow. 259*cda5da8dSAndroid Build Coastguard Worker """ 260*cda5da8dSAndroid Build Coastguard Worker self._check_can_seek() 261*cda5da8dSAndroid Build Coastguard Worker return self._buffer.seek(offset, whence) 262*cda5da8dSAndroid Build Coastguard Worker 263*cda5da8dSAndroid Build Coastguard Worker def tell(self): 264*cda5da8dSAndroid Build Coastguard Worker """Return the current file position.""" 265*cda5da8dSAndroid Build Coastguard Worker self._check_not_closed() 266*cda5da8dSAndroid Build Coastguard Worker if self._mode == _MODE_READ: 267*cda5da8dSAndroid Build Coastguard Worker return self._buffer.tell() 268*cda5da8dSAndroid Build Coastguard Worker return self._pos 269*cda5da8dSAndroid Build Coastguard Worker 270*cda5da8dSAndroid Build Coastguard Worker 271*cda5da8dSAndroid Build Coastguard Workerdef open(filename, mode="rb", *, 272*cda5da8dSAndroid Build Coastguard Worker format=None, check=-1, preset=None, filters=None, 273*cda5da8dSAndroid Build Coastguard Worker encoding=None, errors=None, newline=None): 274*cda5da8dSAndroid Build Coastguard Worker """Open an LZMA-compressed file in binary or text mode. 275*cda5da8dSAndroid Build Coastguard Worker 276*cda5da8dSAndroid Build Coastguard Worker filename can be either an actual file name (given as a str, bytes, 277*cda5da8dSAndroid Build Coastguard Worker or PathLike object), in which case the named file is opened, or it 278*cda5da8dSAndroid Build Coastguard Worker can be an existing file object to read from or write to. 279*cda5da8dSAndroid Build Coastguard Worker 280*cda5da8dSAndroid Build Coastguard Worker The mode argument can be "r", "rb" (default), "w", "wb", "x", "xb", 281*cda5da8dSAndroid Build Coastguard Worker "a", or "ab" for binary mode, or "rt", "wt", "xt", or "at" for text 282*cda5da8dSAndroid Build Coastguard Worker mode. 283*cda5da8dSAndroid Build Coastguard Worker 284*cda5da8dSAndroid Build Coastguard Worker The format, check, preset and filters arguments specify the 285*cda5da8dSAndroid Build Coastguard Worker compression settings, as for LZMACompressor, LZMADecompressor and 286*cda5da8dSAndroid Build Coastguard Worker LZMAFile. 287*cda5da8dSAndroid Build Coastguard Worker 288*cda5da8dSAndroid Build Coastguard Worker For binary mode, this function is equivalent to the LZMAFile 289*cda5da8dSAndroid Build Coastguard Worker constructor: LZMAFile(filename, mode, ...). In this case, the 290*cda5da8dSAndroid Build Coastguard Worker encoding, errors and newline arguments must not be provided. 291*cda5da8dSAndroid Build Coastguard Worker 292*cda5da8dSAndroid Build Coastguard Worker For text mode, an LZMAFile object is created, and wrapped in an 293*cda5da8dSAndroid Build Coastguard Worker io.TextIOWrapper instance with the specified encoding, error 294*cda5da8dSAndroid Build Coastguard Worker handling behavior, and line ending(s). 295*cda5da8dSAndroid Build Coastguard Worker 296*cda5da8dSAndroid Build Coastguard Worker """ 297*cda5da8dSAndroid Build Coastguard Worker if "t" in mode: 298*cda5da8dSAndroid Build Coastguard Worker if "b" in mode: 299*cda5da8dSAndroid Build Coastguard Worker raise ValueError("Invalid mode: %r" % (mode,)) 300*cda5da8dSAndroid Build Coastguard Worker else: 301*cda5da8dSAndroid Build Coastguard Worker if encoding is not None: 302*cda5da8dSAndroid Build Coastguard Worker raise ValueError("Argument 'encoding' not supported in binary mode") 303*cda5da8dSAndroid Build Coastguard Worker if errors is not None: 304*cda5da8dSAndroid Build Coastguard Worker raise ValueError("Argument 'errors' not supported in binary mode") 305*cda5da8dSAndroid Build Coastguard Worker if newline is not None: 306*cda5da8dSAndroid Build Coastguard Worker raise ValueError("Argument 'newline' not supported in binary mode") 307*cda5da8dSAndroid Build Coastguard Worker 308*cda5da8dSAndroid Build Coastguard Worker lz_mode = mode.replace("t", "") 309*cda5da8dSAndroid Build Coastguard Worker binary_file = LZMAFile(filename, lz_mode, format=format, check=check, 310*cda5da8dSAndroid Build Coastguard Worker preset=preset, filters=filters) 311*cda5da8dSAndroid Build Coastguard Worker 312*cda5da8dSAndroid Build Coastguard Worker if "t" in mode: 313*cda5da8dSAndroid Build Coastguard Worker encoding = io.text_encoding(encoding) 314*cda5da8dSAndroid Build Coastguard Worker return io.TextIOWrapper(binary_file, encoding, errors, newline) 315*cda5da8dSAndroid Build Coastguard Worker else: 316*cda5da8dSAndroid Build Coastguard Worker return binary_file 317*cda5da8dSAndroid Build Coastguard Worker 318*cda5da8dSAndroid Build Coastguard Worker 319*cda5da8dSAndroid Build Coastguard Workerdef compress(data, format=FORMAT_XZ, check=-1, preset=None, filters=None): 320*cda5da8dSAndroid Build Coastguard Worker """Compress a block of data. 321*cda5da8dSAndroid Build Coastguard Worker 322*cda5da8dSAndroid Build Coastguard Worker Refer to LZMACompressor's docstring for a description of the 323*cda5da8dSAndroid Build Coastguard Worker optional arguments *format*, *check*, *preset* and *filters*. 324*cda5da8dSAndroid Build Coastguard Worker 325*cda5da8dSAndroid Build Coastguard Worker For incremental compression, use an LZMACompressor instead. 326*cda5da8dSAndroid Build Coastguard Worker """ 327*cda5da8dSAndroid Build Coastguard Worker comp = LZMACompressor(format, check, preset, filters) 328*cda5da8dSAndroid Build Coastguard Worker return comp.compress(data) + comp.flush() 329*cda5da8dSAndroid Build Coastguard Worker 330*cda5da8dSAndroid Build Coastguard Worker 331*cda5da8dSAndroid Build Coastguard Workerdef decompress(data, format=FORMAT_AUTO, memlimit=None, filters=None): 332*cda5da8dSAndroid Build Coastguard Worker """Decompress a block of data. 333*cda5da8dSAndroid Build Coastguard Worker 334*cda5da8dSAndroid Build Coastguard Worker Refer to LZMADecompressor's docstring for a description of the 335*cda5da8dSAndroid Build Coastguard Worker optional arguments *format*, *check* and *filters*. 336*cda5da8dSAndroid Build Coastguard Worker 337*cda5da8dSAndroid Build Coastguard Worker For incremental decompression, use an LZMADecompressor instead. 338*cda5da8dSAndroid Build Coastguard Worker """ 339*cda5da8dSAndroid Build Coastguard Worker results = [] 340*cda5da8dSAndroid Build Coastguard Worker while True: 341*cda5da8dSAndroid Build Coastguard Worker decomp = LZMADecompressor(format, memlimit, filters) 342*cda5da8dSAndroid Build Coastguard Worker try: 343*cda5da8dSAndroid Build Coastguard Worker res = decomp.decompress(data) 344*cda5da8dSAndroid Build Coastguard Worker except LZMAError: 345*cda5da8dSAndroid Build Coastguard Worker if results: 346*cda5da8dSAndroid Build Coastguard Worker break # Leftover data is not a valid LZMA/XZ stream; ignore it. 347*cda5da8dSAndroid Build Coastguard Worker else: 348*cda5da8dSAndroid Build Coastguard Worker raise # Error on the first iteration; bail out. 349*cda5da8dSAndroid Build Coastguard Worker results.append(res) 350*cda5da8dSAndroid Build Coastguard Worker if not decomp.eof: 351*cda5da8dSAndroid Build Coastguard Worker raise LZMAError("Compressed data ended before the " 352*cda5da8dSAndroid Build Coastguard Worker "end-of-stream marker was reached") 353*cda5da8dSAndroid Build Coastguard Worker data = decomp.unused_data 354*cda5da8dSAndroid Build Coastguard Worker if not data: 355*cda5da8dSAndroid Build Coastguard Worker break 356*cda5da8dSAndroid Build Coastguard Worker return b"".join(results) 357