diff --git a/config.toml b/config.toml index 32f26af..858e575 100644 --- a/config.toml +++ b/config.toml @@ -475,6 +475,12 @@ theme = "doc-theme" identifier = "tutorials@advanced" parent = "tutorials" weight = 60 +[[menu.main]] + name= "File decompression" + url= "/tutorials/advanced/uzlib/" + identifier = "tutorials@advanced@uzlib" + parent = "tutorials@advanced" + weight=10 # *** Firmware & API Reference [[menu.main]] @@ -934,6 +940,12 @@ theme = "doc-theme" identifier = "firmwareapi@micropython@ustruct" parent = "firmwareapi@micropython" weight = 180 +[[menu.main]] + name = "uzlib" + url = "/firmwareapi/micropython/uzlib/" + identifier = "firmwareapi@micropython@uzlib" + parent = "firmwareapi@micropython" + weight = 190 [[menu.main]] name = "_thread" diff --git a/content/firmwareapi/micropython/uzlib.md b/content/firmwareapi/micropython/uzlib.md index 41d347c..7101dfa 100644 --- a/content/firmwareapi/micropython/uzlib.md +++ b/content/firmwareapi/micropython/uzlib.md @@ -7,20 +7,14 @@ aliases: --- _This module implements a subset of the corresponding_ `CPython` _module, as described below. For more information, refer to the original CPython documentation:_ `zlib`. -This module allows to decompress binary data compressed with [DEFLATE algorithm](https://en.wikipedia.org/wiki/DEFLATE) (commonly used in zlib library and gzip archiver). Compression is not yet implemented. +This module allows to decompress binary data compressed with [DEFLATE algorithm](https://en.wikipedia.org/wiki/DEFLATE) (commonly used in zlib library and gzip archiver). Compression is not yet implemented. See [Compressed Files](/tutorials/advanced/uzlib/) for examples. -## **Methods** +## Methods -**uzlib.decompress(data, wbits=0, bufsize=0)** +### uzlib.decompress(data, wbits=0, bufsize=0) Return decompressed data as bytes. wbits is DEFLATE dictionary window size used during compression (8-15, the dictionary size is power of 2 of that value). Additionally, if value is positive, data is assumed to be zlib stream (with zlib header). Otherwise, if it's negative, it's assumed to be raw DEFLATE stream. bufsize parameter is for compatibility with CPython and is ignored. -**class uzlib.DecompIO(stream, wbits=0)** +### class uzlib.DecompIO(stream, wbits=0) -Create a `stream` wrapper which allows transparent decompression of compressed data in another stream. This allows to process compressed streams with data larger than available heap size. In addition to values described in `decompress()`, wbits may take values 24..31 (16 + 8..15), meaning that input stream has gzip header. - -{{% hint style="info" %}} -**Difference to CPython** - -This class is MicroPython extension. It's included on provisional basis and may be changed considerably or removed in later versions. -{{% /hint %}} +Create a `stream` wrapper which allows transparent decompression of compressed data in another stream. This allows to process compressed streams with data larger than available heap size. In addition to values described in `decompress()`, wbits may take values 24..31 (16 + 8..15), meaning that input stream has gzip header. \ No newline at end of file diff --git a/content/tutorials/advanced/uzlib.md b/content/tutorials/advanced/uzlib.md new file mode 100644 index 0000000..ff8476d --- /dev/null +++ b/content/tutorials/advanced/uzlib.md @@ -0,0 +1,59 @@ +--- +title: "Compressed files" +--- +The Pycom firmware includes the [`uzlib`](/firmwareapi/micropython/uzlib/) module by default, which supports the decompression of files and streams. Below, two usage examples are highlighted: +* [Decompressing a zlib file](decompressing-a-zlib-file) +* [Decompressing a gzip file](#decompressing-a-gzip-file) + +## Decompressing a zlib file +While the micropython firmware does not support the compression of a file, the equivalent Python library does. You can use the following snippet in Python to compress a file: +```python +# run this with python3 on the computer +# then upload test.txt.z to the pycom device (adjust 'Project settings' in Pymakr) +import zlib +import os + +s = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n' +b = bytes(s, "utf-8") +z = zlib.compress(b) +with open('test.txt.z', 'wb') as f: + f.write(z) +print('ratio', len(z)/len(s)) +``` +This will create a file called `test.txt.z` with some content. Paste this file in your project and adjust the Pymakr settings to allow the uploading of this file type (Pymakr Settings --> Global settings --> Upload file types, add `.z` in the list). On your device, you can use the following example to decompress the file and print its contents: +```python +import zlib +import os + +# verify that the file has been uploaded +file = 'test.txt.z' +print('dir', os.listdir()) +print(file, os.stat(file)) + +# read contents, decompress and print +with open(file, 'r') as f: + z = f.read() +b = zlib.decompress(z) +s = b.decode('utf-8') +print('ratio', len(z)/len(s)) +print(s) +``` + +## Decompressing a gzip file +A `gzip` archive (not to be confused with a `zip` or `zlib` file) can be generated using the terminal in Linux or macOS. You can use the following commands to create and gzip a file in the terminal: +```bash +echo "Hello world" > test.txt +gzip test.txt +``` +This generates the file `test.txt.gz`. Now, you can copy the file over to your project and allow pymakr to upload the `.gz` file (Pymakr Settings --> Global settings --> Upload file types, add `.gz` in the list). On your device, you can run the following to decompress the file: +```python +#verify the presence of the file +file = 'test.txt.gz' +print('dir', os.listdir()) +print(file, os.stat(file)) + +with open('test.txt.gz', 'r') as file: + data = uzlib.DecompIO(file, 31) + #use data.readline() to read a single line + print(data.read()) +```