Skip to content

Commit

Permalink
lzep4: decompress an LZ4 file (block or frame) to stdout
Browse files Browse the repository at this point in the history
  • Loading branch information
hydrargyrum committed Dec 12, 2024
1 parent 66e1d1a commit 338353b
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ This repository hosts various small personal tools.
- [`links2markdown`](links2markdown): fetch title of links in a text file and replace to build Markdown links
- [`log-snippet`](log-snippet): parse compilation-log and show snippets of files with context
- [`log-ts-diff`](log-ts-diff): parse log and replace timestamps with diff to previous timestamp
- [`lzep4`](lzep4): decompress an LZ4 file (block or frame) to stdout
- [`mediadims`](mediadims): get audio/video duration or video width/height of a file with [mediainfo](https://mediaarea.net/)
- [`morse`](morse): text from/to Morse code converter, and optional beep player
- [`morsehtml`](morsehtml): HTML page with its background flashing a Morse code message
Expand Down
3 changes: 3 additions & 0 deletions lzep4/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[*.py{,.jinja}]
indent_style = space
indent_size = 4
9 changes: 9 additions & 0 deletions lzep4/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# lzep4

Extract LZ4 files to stdout

## Example

```
lzep4 --moz --block ~/.mozilla/firefox/my.profile/sessionstore.jsonlz4
```
71 changes: 71 additions & 0 deletions lzep4/lzep4.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#!/usr/bin/env python3

# /// script
# dependencies = ["lz4"]
# ///

import argparse
import locale
import signal
import sys

import lz4.block
import lz4.frame


__version__ = "0.1.0"


def do_block(args, in_fp, out_fp):
data = in_fp.read()
if args.moz:
data = data[8:]
data = lz4.block.decompress(data)
out_fp.write(data)


def do_frame(args, in_fp, out_fp):
with lz4.frame.LZ4FrameDecompressor() as decompressor:
while True:
buf = in_fp.read(10240)
if not buf:
break
buf = decompressor.decompress(buf)
out_fp.buffer.write(buf)


def main():
locale.setlocale(locale.LC_ALL, "")

signal.signal(signal.SIGINT, signal.SIG_DFL)
signal.signal(signal.SIGPIPE, signal.SIG_DFL)

parser = argparse.ArgumentParser()
parser.add_argument(
"--block", action="store_true",
help="Extract 'block' LZ4 instead of 'frame' LZ4",
)
parser.add_argument(
"--moz", action="store_true",
help="Extract Mozilla .jsonlz4 files",
)
parser.add_argument(
"file", type=argparse.FileType(mode="rb"), nargs="?",
default=sys.stdin.buffer,
)
parser.add_argument("--version", action="version", version=__version__)
args = parser.parse_args()

if args.file.isatty():
print(f"warning: {parser.prog} is reading stdin", file=sys.stderr)

proc_func = do_frame
if args.block:
proc_func = do_block

with args.file:
proc_func(args, args.file, sys.stdout.buffer)


if __name__ == "__main__":
main()
1 change: 1 addition & 0 deletions lzep4/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
lz4
23 changes: 23 additions & 0 deletions lzep4/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/bin/sh -eu
# SPDX-License-Identifier: WTFPL
# shellcheck enable=

cd "$(dirname "$0")"

got=$(mktemp lzep4.XXXXXX)
trap 'rm "$got"' EXIT


init () {
./lzep4.py "$@" > "$got"
}

check () {
diff -u - "$got"
}


# basic test
printf '\025\000\000\000\033A\001\000PAAAA\n' | init --block

echo AAAAAAAAAAAAAAAAAAAA | check

0 comments on commit 338353b

Please sign in to comment.