Sign in

    lzma-mbt

    Independent MoonBit implementation of liblzma core functionality

    lzma
    xz
    compression
    Download zip
    Version
    0.1.0
    License
    Apache-2.0
    Last updated
    24 days ago
    Downloads
    404

    No dependencies

    #lzma-mbt

    MoonBit 实现的 LZMA / LZMA2 / XZ 编解码库,目标对齐 liblzma 的外部可观察行为(格式、校验、错误语义),而不是翻译 C 代码。

    模块名:aurora0x27/lzma-mbt。开发约定见 AGENTS.md,分层与接口见 docs/。

    #状态

    • 默认编码:.xz + preset 6 + CRC64
    • 默认解码:Format::Auto(.xz / LZMA_Alone;裸 LZMA2 须显式指定),内存上限 128 MiB(字典,不是明文长度)
    • LZMA1 / LZMA2 / XZ 可 round-trip;.xz 解码支持同一 Stream 内多个 Block(编码仍写单个 Block);解码侧有嵌入的 liblzma 向量;编码侧由 CI 交给 xz -d / Python lzma 解回
    • Preset.extreme 尚未实现(UnsupportedFeature);.xz Block Header 过滤器链支持 LZMA2、Delta -> LZMA2 与全部 BCJ(x86/PowerPC/IA-64/ARM/ARM-Thumb/SPARC/ARM64)-> LZMA2;其它未实现的 filter ID(如 RISC-V)仍 UnsupportedFeature
    • 默认拒绝 .xz Footer 之后或裸 LZMA2 结束标记之后的多余字节;DecodeOptions.concatenated=true 时支持连接的多 .xz Stream 与规范 Stream Padding
    • 编码器是贪心匹配,不保证与 xz -6 字节相同

    兼容性矩阵:docs/compatibility.md

    #使用

    import {
    "aurora0x27/lzma-mbt" @lzma,
    }

    let src = b"hello"
    let compressed = @lzma.encode(src[:])
    let roundtrip = @lzma.decode(compressed[:])

    流式(write + finish 保持分块等价;编码器在 Finish 前缓冲,解码器完整流到达后可提前排出):

    let dec = @lzma.Decoder::new()
    dec.write(chunk0[:])
    dec.write(chunk1[:])
    let roundtrip = dec.finish()

    指定 LZMA_Alone:

    let enc = @lzma.encode(src[:], options={
    ..@lzma.EncodeOptions::default(),
    format: @lzma.Format::Lzma,
    })

    #构建

    需要 MoonBit toolchain(本仓库 CI 使用 chawyehsu/setup-moonup@v1,版本号见仓库根 moonbit-version)。强制工具链版本 moon 0.1.20260904(内置 core 0.10.12+1634b282e,对应 moonup 发行标识 0.10.12+1634b282e),见 docs/research/toolchain.md;用其它版本时不要静默适配,先停下来确认。编码差分还需要 Python 3(标准库 lzma)以及 xz。

    moon check --deny-warn moon fmt --check moon test --deny-warn python3 scripts/diff_encode.py

    LzmaError

    pub suberror LzmaError {
    InvalidInput(String)
    UnexpectedEof
    InvalidConfiguration(String)
    UnsupportedFeature(String)
    MemoryLimit
    DataError
    BufferTooSmall
    FormatError
    } derive(Eq,
    Debug
    )

    Public error type. Error is a MoonBit reserved name. Match on the tag (err is DataError); string payloads are not a stable API.

    Action

    pub(all) enum Action {
    Run
    SyncFlush
    FullFlush
    Finish
    } derive(Eq,
    Debug
    )

    Check

    pub(all) enum Check {
    None
    Crc32
    Crc64
    Sha256
    } derive(Eq,
    Debug
    )

    CodeResult

    pub(all) struct CodeResult {
    consumed : Int
    produced : Int
    status : Status
    } derive(Eq,
    Debug
    )

    DecodeOptions

    pub(all) struct DecodeOptions {
    format : Format
    memlimit : UInt64?
    concatenated : Bool
    ignore_check : Bool
    filters : Array[FilterSpec]
    } derive(Eq,
    Debug
    )

    DecodeOptions::default

    fn DecodeOptions::default() -> DecodeOptions

    DecodeOptions::validate

    fn DecodeOptions::validate(self : DecodeOptions) -> Unit raise LzmaError

    Decoder

    type Decoder

    Decoder::code

    fn Decoder::code(self : Decoder, input : BytesView, output : OutputBuf, action : Action) -> CodeResult raise LzmaError

    Decoder::finish

    fn Decoder::finish(self : Decoder) -> Bytes raise LzmaError

    Decoder::new

    fn Decoder::new(options? : DecodeOptions) -> Decoder raise LzmaError

    Decoder::reset

    fn Decoder::reset(self : Decoder) -> Unit raise LzmaError

    Decoder::total_in

    fn Decoder::total_in(self : Decoder) -> UInt64

    Decoder::total_out

    fn Decoder::total_out(self : Decoder) -> UInt64

    Decoder::write

    fn Decoder::write(self : Decoder, input : BytesView) -> Unit raise LzmaError

    EncodeOptions

    pub(all) struct EncodeOptions {
    format : Format
    preset : Preset
    check : Check
    props : LzmaProps?
    filters : Array[FilterSpec]
    } derive(Eq,
    Debug
    )

    EncodeOptions::default

    fn EncodeOptions::default() -> EncodeOptions

    EncodeOptions::resolved_props

    fn EncodeOptions::resolved_props(self : EncodeOptions) -> LzmaProps raise LzmaError

    EncodeOptions::validate

    fn EncodeOptions::validate(self : EncodeOptions) -> Unit raise LzmaError

    Encoder

    type Encoder

    Encoder::code

    fn Encoder::code(self : Encoder, input : BytesView, output : OutputBuf, action : Action) -> CodeResult raise LzmaError

    Encoder::finish

    fn Encoder::finish(self : Encoder) -> Bytes raise LzmaError

    Encoder::new

    fn Encoder::new(options? : EncodeOptions) -> Encoder raise LzmaError

    Encoder::reset

    fn Encoder::reset(self : Encoder) -> Unit raise LzmaError

    Encoder::total_in

    fn Encoder::total_in(self : Encoder) -> UInt64

    Encoder::total_out

    fn Encoder::total_out(self : Encoder) -> UInt64

    Encoder::write

    fn Encoder::write(self : Encoder, input : BytesView) -> Unit raise LzmaError

    FilterSpec

    pub(all) enum FilterSpec {
    Lzma1(LzmaProps)
    Lzma2(LzmaProps)
    Delta(distance~ : Int)
    BcjX86(start_offset~ : UInt)
    } derive(Eq,
    Debug
    )

    Extra pre/post filters around the codec. Lzma1/Lzma2 here are configuration errors.

    Format

    pub(all) enum Format {
    Auto
    Lzma
    Lzma2
    Xz
    } derive(Eq,
    Debug
    )

    Compressed container / filter format. Auto is decode-only.

    LzmaProps

    pub(all) struct LzmaProps {
    lc : Int
    lp : Int
    pb : Int
    dict_size : UInt
    } derive(Eq,
    Debug
    )

    LZMA1 properties. All fields are required; lc + lp must be at most 4.

    LzmaProps::from_preset

    fn LzmaProps::from_preset(preset : Preset) -> LzmaProps raise LzmaError

    liblzma preset dictionary sizes: 1 << [18,20,21,22,22,23,23,24,25,26].

    LzmaProps::validate

    fn LzmaProps::validate(self : LzmaProps) -> Unit raise LzmaError

    OutputBuf

    pub(all) struct OutputBuf {
    data : Array[Byte]
    start : Int
    }

    Caller-owned output slot. code writes at data[start] and advances start. size is the number of writable bytes (not a hint).

    OutputBuf::new

    fn OutputBuf::new(size? : Int) -> OutputBuf

    OutputBuf::remaining

    fn OutputBuf::remaining(self : OutputBuf) -> Int

    Writable bytes left (data.length() - start). Out-of-range start is 0.

    OutputBuf::written

    fn OutputBuf::written(self : OutputBuf) -> Bytes

    Bytes already written, data[0:start].

    Preset

    pub(all) struct Preset {
    level : Int
    extreme : Bool
    } derive(Eq,
    Debug
    )

    Preset::default

    fn Preset::default() -> Preset

    Preset::new

    fn Preset::new(level : Int, extreme? : Bool) -> Preset raise LzmaError

    Status

    pub(all) enum Status {
    Ok
    StreamEnd
    NeedInput
    NeedOutput
    } derive(Eq,
    Debug
    )

    DEFAULT_MEMLIMIT

    let DEFAULT_MEMLIMIT : UInt64

    Default decoder memory limit when DecodeOptions.memlimit is None.

    MAX_DICT_SIZE

    let MAX_DICT_SIZE : UInt

    MIN_DICT_SIZE

    let MIN_DICT_SIZE : UInt

    UNKNOWN_SIZE

    let UNKNOWN_SIZE : UInt64

    crc32

    fn crc32(data : BytesView, init? : UInt) -> UInt

    crc64

    fn crc64(data : BytesView, init? : UInt64) -> UInt64

    decode

    fn decode(input : BytesView, options? : DecodeOptions) -> Bytes raise LzmaError

    effective_memlimit

    fn effective_memlimit(limit : UInt64?) -> UInt64

    encode

    fn encode(input : BytesView, options? : EncodeOptions) -> Bytes raise LzmaError

    pack_props

    fn pack_props(lc : Int, lp : Int, pb : Int) -> Byte raise LzmaError

    sha256

    fn sha256(data : BytesView) -> Bytes

    unpack_props

    fn unpack_props(props : Byte) -> (Int, Int, Int) raise LzmaError