Add lz4diff CLI util
For quickly run lz4diff on CLI
Test: th
Bug: 206729162
Change-Id: I18a78f5b5a5382f3dcb698af4e041689ede47b1e
diff --git a/scripts/scan_lz4.py b/scripts/scan_lz4.py
new file mode 100644
index 0000000..d2b4fb5
--- /dev/null
+++ b/scripts/scan_lz4.py
@@ -0,0 +1,82 @@
+# import mmap
+
+import struct
+
+LZ4_FRAME_MAGIC = b"\x04\x22\x4D\x18"
+
+
+def scan_legacy_lz4_frames(data):
+ LZ4_LEGACY_FRAME_MAGIC = b"\x02\x21\x4C\x18"
+ index = 0
+ while index < len(data):
+ try:
+ index = data.index(LZ4_LEGACY_FRAME_MAGIC, index)
+ print("Legacy Lz4 frame at {}".format(index))
+ index += 4
+ while index < len(data):
+ magic = data[index:index+4]
+ if magic == LZ4_LEGACY_FRAME_MAGIC or magic == LZ4_FRAME_MAGIC:
+ break
+ (csize,) = struct.unpack("<L", magic)
+ if index + 4 + csize >= len(data) or csize == 0:
+ break
+ print("Legacy lz4 block at {}, compressed data size {}".format(index, csize))
+ index += csize
+
+ except ValueError:
+ break
+
+
+def scan_lz4_frames(data):
+ index = 0
+ while index < len(data):
+ try:
+ index = data.index(LZ4_FRAME_MAGIC, index)
+ frame_offset = index
+ index += 4
+ flag = data[index]
+ block_descriptor = data[index+1]
+ block_checksum_present = flag & 0x10 != 0
+ content_size_present = flag & 0x8 != 0
+ content_checksum_present = flag & 0x4 != 0
+ dictionary_id = flag & 0x1 != 0
+ index += 2
+ content_size = None
+ if content_size_present:
+ content_size = struct.unpack("<Q", data[index:index+8])
+ index += 8
+ if dictionary_id:
+ dictionary_id = struct.unpack("<L", data[index:index+4])
+ index += 4
+ header_checksum = data[index:index+1]
+ index += 1
+ print("Lz4 frame at {}, content size: {}".format(
+ frame_offset, content_size))
+ while index < len(data):
+ (block_size,) = struct.unpack("<L", data[index:index+4])
+ uncompressed = block_size & 0x80000000 != 0
+ block_size &= 0x7FFFFFFF
+ index += 4
+ index += block_size
+ if index >= len(data) or block_size == 0:
+ break
+ print("Block uncompressed: {}, size: {}".format(uncompressed, block_size))
+ except ValueError:
+ break
+
+
+def main(argv):
+ if len(argv) != 2:
+ print("Usage:", argv[0], "<path to a file>")
+ return 1
+ path = argv[1]
+
+ with open(path, "rb") as fp:
+ data = fp.read()
+ scan_legacy_lz4_frames(data)
+ scan_lz4_frames(data)
+
+
+if __name__ == '__main__':
+ import sys
+ sys.exit(main(sys.argv))