Sign in

    moonbit-community/flate/zip does not have a README file

    ZipError

    pub suberror ZipError {
    ZipError(ZipErrorKind, String)
    }

    Structured ZIP failure: a stable category plus a human-readable diagnostic.

    Archive

    pub struct Archive {
    // private fields
    }

    An in-memory ZIP archive: an ordered list of entries plus an archive comment. Reading a ZIP materializes this; writing serializes it back.

    Archive::Archive

    fn Archive::Archive() -> Archive

    Create an empty archive.

    Archive::add

    fn Archive::add(self : Archive, name : String, data : BytesView, compression? : Compression) -> Unit

    Append a new entry, retaining its payload as Bytes. The default method is Deflate; pass Store to keep the payload verbatim. Serialization chooses the local-header and descriptor layout; use Writer for chunked input.

    Archive::clone

    fn Archive::clone(self : Archive) -> Archive

    Returns an independently mutable snapshot of this archive. The clone shares entry payloads and source storage but owns a fresh entries array, so add/replace/remove on either side never affects the other.

    Archive::comment

    fn Archive::comment(self : Archive) -> BytesView

    The archive-level comment bytes (empty when none).

    Archive::entries

    fn Archive::entries(self : Archive) -> ArrayView[Entry]

    The archive's entry list in order.

    Archive::get

    fn Archive::get(self : Archive, name : StringView) -> BytesView?

    A read-only view of an entry payload, or None when absent.

    Archive::remove

    fn Archive::remove(self : Archive, name : StringView) -> Bool

    Remove the entry named name. Returns false when no such entry exists.

    Archive::replace

    fn Archive::replace(self : Archive, name : StringView, data : BytesView) -> Bool

    Replace the payload of the entry named name. The entry keeps its method policy but drops its raw source records (the next write re-encodes it). Its original position in the archive is retained, so a byte-preserving write keeps the entry where it was. Returns false when no such entry exists.

    Archive::set_comment

    fn Archive::set_comment(self : Archive, comment : BytesView) -> Unit

    Replace the archive-level comment. Long comments (over 65535 bytes) are rejected at write time. Changing the comment invalidates a retained end-record template, so a later byte-preserving write regenerates the trailer with the new comment.

    Compression

    pub(all) enum Compression {
    Store
    Deflate
    } derive(Eq,
    Debug
    )

    The ZIP compression methods this package can read and write.

    Compression::equal

    fn Compression::equal(Compression, Compression) -> Bool

    Directory

    pub struct Directory {
    // private fields
    }

    A directory listing in central-directory order, including duplicate names. Owns metadata only. A successful listing does not validate local headers, decompress payloads, or verify their CRC-32 values.

    Directory::comment

    fn Directory::comment(self : Directory) -> BytesView

    The archive comment, owned independently of supplied read buffers.

    Directory::entries

    Entries in central-directory order. This view cannot modify the listing.

    Directory::open_entry

    fn Directory::open_entry(self : Directory, index : Int, limits? : EntryReadLimits) -> EntryReader raise ZipError

    Open an entry by directory index, preserving the identity of duplicate names. No I/O occurs here. Unknown methods, unsupported flags, encryption, and declared output exceeding the limit are rejected before requesting data.

    DirectoryEntry

    pub struct DirectoryEntry {
    // private fields
    }

    Metadata declared by a central-directory entry, without its payload. Sizes remain 64-bit even when the payload cannot fit in a MoonBit Bytes. Unknown compression methods and encrypted payloads can still be listed.

    DirectoryEntry::compressed_size

    fn DirectoryEntry::compressed_size(self : DirectoryEntry) -> UInt64

    The declared compressed payload size, excluding headers and descriptors.

    DirectoryEntry::crc32

    fn DirectoryEntry::crc32(self : DirectoryEntry) -> UInt

    The declared CRC-32. Directory reading does not verify payload integrity.

    DirectoryEntry::creator_system

    fn DirectoryEntry::creator_system(self : DirectoryEntry) -> Int

    The host-system identifier from the entry's version-made-by field.

    DirectoryEntry::dos_date

    fn DirectoryEntry::dos_date(self : DirectoryEntry) -> Int

    Original packed DOS modification date (year/month/day); no timezone is stored.

    DirectoryEntry::dos_time

    fn DirectoryEntry::dos_time(self : DirectoryEntry) -> Int

    Original packed DOS modification time (hour/minute/two-second units).

    DirectoryEntry::external_attributes

    fn DirectoryEntry::external_attributes(self : DirectoryEntry) -> UInt

    Original external file attributes, interpreted according to creator_system.

    DirectoryEntry::is_directory

    fn DirectoryEntry::is_directory(self : DirectoryEntry) -> Bool

    Whether the name or DOS/Unix file attributes identify a directory.

    DirectoryEntry::is_encrypted

    fn DirectoryEntry::is_encrypted(self : DirectoryEntry) -> Bool

    Whether the entry's general-purpose flag declares payload encryption. This does not imply support for decrypting it or for encrypted directories.

    DirectoryEntry::method_id

    fn DirectoryEntry::method_id(self : DirectoryEntry) -> Int

    The ZIP compression method number, including methods this library cannot decode.

    DirectoryEntry::name

    fn DirectoryEntry::name(self : DirectoryEntry) -> String

    The entry name, decoded using the same UTF-8 policy as read.

    DirectoryEntry::uncompressed_size

    fn DirectoryEntry::uncompressed_size(self : DirectoryEntry) -> UInt64

    The declared uncompressed size; listing never allocates this many bytes.

    DirectoryLimits

    pub struct DirectoryLimits {
    // private fields
    }

    Resource bounds for metadata-only directory reads. These bound encoded directory bytes and retained entry count, never declared payload sizes. Defaults permit any directory byte size and at most 2^31 - 1 entries; callers should select bounds appropriate to their metadata memory budget.

    DirectoryLimits::DirectoryLimits

    fn DirectoryLimits::DirectoryLimits(max_directory_bytes? : UInt64, max_entries? : UInt64) -> DirectoryLimits

    Construct directory bounds. A zero ceiling permits only an empty resource.

    DirectoryReader

    pub struct DirectoryReader {
    // private fields
    }

    Metadata-only ZIP reader driven by caller-supplied byte ranges. Supports classic ZIP and ZIP64 beyond 2 GiB without retaining the archive or inflating payloads. Retains owned metadata plus a bounded incomplete directory record. File reads, HTTP requests, source consistency, and cancellation between calls belong to the caller. No I/O callback is retained or invoked.

    DirectoryReader::DirectoryReader

    fn DirectoryReader::DirectoryReader(archive_size : UInt64, limits? : DirectoryLimits) -> DirectoryReader

    Start reading an archive of the supplied total byte size. No bytes are read until the caller drives advance and fulfills the returned ranges.

    DirectoryReader::advance

    fn DirectoryReader::advance(self : DirectoryReader, input : BytesView) -> DirectoryStep raise ZipError

    Initially supply empty input; thereafter supply exactly the bytes requested by the preceding NeedRead. Accumulate transport short reads before calling. All ranges must refer to the same immutable archive. Input is borrowed only for this call; retained metadata and incomplete records are copied. Requests are at most 65,557 bytes, and directory chunks at most 64 KiB. Done validates directory structure and referenced bounds, not local headers or payload integrity. Empty calls after completion return the same listing. Any error is latched and rethrown on subsequent calls.

    DirectoryStep

    pub(all) enum DirectoryStep {
    NeedRead(ReadRange)
    Done(Directory)
    }

    The next range to read, or a completed, independently owned metadata listing.

    Entry

    pub struct Entry {
    // private fields
    }

    A single archive entry: its decoded payload plus the metadata the central directory carried for it. Entries produced by read retain their source records for byte-preserving rewrites; entries built with Archive::add do not.

    Entry::compression

    fn Entry::compression(self : Entry) -> Compression

    The compression method used for this entry.

    Entry::crc32

    fn Entry::crc32(self : Entry) -> UInt

    The entry's stored CRC-32: the central-directory value for entries read from an archive, or computed at add time for entries created in memory.

    Entry::data

    fn Entry::data(self : Entry) -> BytesView

    A read-only view of the decompressed payload.

    Entry::name

    fn Entry::name(self : Entry) -> String

    The entry name decoded as UTF-8.

    EntryReadLimits

    pub struct EntryReadLimits {
    // private fields
    }

    Bounds for streaming one entry. The ceiling applies to actual decoded bytes and also rejects an oversized directory declaration before reading payloads.

    EntryReadLimits::EntryReadLimits

    fn EntryReadLimits::EntryReadLimits(max_output_bytes? : UInt64) -> EntryReadLimits

    Construct a decoded-output ceiling. Omission permits any UInt64 byte count.

    EntryReader

    pub struct EntryReader {
    // private fields
    }

    Range-driven extraction of one Store or Deflate entry. Created by Directory::open_entry so metadata and archive bounds cannot be forged. Retains at most one 64 KiB compressed response, bounded local metadata, and the inflater's workspace. Sizes and cumulative progress remain 64-bit.

    EntryReader::last_produced

    fn EntryReader::last_produced(self : EntryReader) -> Int

    Output written by the latest successful step, including NeedRead and Done.

    EntryReader::step

    fn EntryReader::step(self : EntryReader, input : BytesView, output : FixedArray[Byte]) -> EntryStep raise ZipError

    Initially supply empty input. After NeedRead, supply exactly the requested bytes from the same immutable archive used for the directory listing. After NeedMoreOutput, supply empty input and another output array; accepted input is retained internally and must not be replayed. Read last_produced after every normal return and process output[:last_produced()] before reusing it. Input and output buffers are released before returning. An empty output array suspends payload decoding. Requests are at most 65,535 bytes for local metadata and 64 KiB for payloads. Cancel by stopping between calls. Done verifies the local header, exact compressed/decoded sizes, CRC-32 and any data descriptor. Earlier output is unverified until Done. On error the output is unspecified, last_produced is zero, and the error remains latched.

    EntryReader::total_consumed

    fn EntryReader::total_consumed(self : EntryReader) -> UInt64

    Cumulative compressed payload bytes consumed, excluding headers/descriptors.

    EntryReader::total_produced

    fn EntryReader::total_produced(self : EntryReader) -> UInt64

    Cumulative decoded bytes. Integrity is established only after Done.

    EntryStep

    pub(all) enum EntryStep {
    NeedRead(ReadRange)
    NeedMoreOutput
    Done
    }

    Supply the requested range, resume with empty input and another output buffer, or finish after all integrity checks have succeeded. Every successful step may produce output, including a step returning NeedRead or Done.

    LimitKind

    pub(all) enum LimitKind {
    PackageBytes
    Entries
    EntryUncompressedBytes
    TotalUncompressedBytes
    DirectoryBytes
    OutputBytes
    } derive(Eq,
    Debug
    )

    Which bounded resource was exceeded during a bounded read or write. The payload-related kinds guard decoded allocations; DirectoryBytes bounds metadata-only directory input; OutputBytes bounds serialization size.

    LimitKind::equal

    fn LimitKind::equal(LimitKind, LimitKind) -> Bool

    ReadLimits

    pub struct ReadLimits {
    max_package_bytes : Int
    max_entries : Int
    max_entry_uncompressed_bytes : Int
    max_total_uncompressed_bytes : Int
    }

    Resource bounds applied to a bounded read. Every field is a ceiling in bytes (or, for max_entries, a count); ReadLimits() imposes no limits beyond the in-memory Int32 capacity. max_package_bytes also bounds the complete source retained for byte-preserving rewrites.

    ReadLimits::ReadLimits

    fn ReadLimits::ReadLimits(max_package_bytes? : Int, max_entries? : Int, max_entry_uncompressed_bytes? : Int, max_total_uncompressed_bytes? : Int) -> ReadLimits

    Construct resource bounds. Omitted ceilings default to the largest Int. Each supplied ceiling must be non-negative; read raises InvalidArgument for a negative one and rejects an exceeded ceiling before accepting the corresponding resource.

    ReadRange

    pub struct ReadRange {
    // private fields
    }

    One bounded request into the same immutable archive supplied to the reader. The offset is absolute; the length describes a single in-memory buffer.

    ReadRange::length

    fn ReadRange::length(self : ReadRange) -> Int

    Exact byte count to supply on the next call, at most 65,557 bytes.

    ReadRange::offset

    fn ReadRange::offset(self : ReadRange) -> UInt64

    Absolute byte offset from the start of the archive.

    Writer

    pub struct Writer {
    // private fields
    }

    An incremental ZIP writer over a synchronous byte sink. add handles an already loaded file; begin_entry/write/end_entry handle bounded chunks. Retains central-directory records, current-entry metadata and codec buffers. The sink must consume each view before returning. A sink exception poisons the writer and is propagated unchanged; no further output can be emitted.

    Writer::Writer

    fn Writer::Writer(sink : (BytesView) -> Unit raise, level? : Int, fast_store? : Bool) -> Writer

    Create a ZIP writer. The sink supplies file/socket I/O or collects chunks; this package itself performs no I/O. Calling finish writes the directory. level 0-9 (clamped) applies to Deflate entries; 6 is the default. Writer methods raise ZipError for their own failures and propagate sink errors unchanged. Optional fast_store applies to Deflate entries: whole-file detection for add, per-block detection for chunked writes. It is off by default and may increase output size. ZIP entry methods are unchanged.

    Writer::add

    fn Writer::add(self : Writer, name : String, data : BytesView, compression? : Compression) -> Unit raise

    Compress and emit one complete file immediately. Reuses a whole-buffer compressor, avoiding the staging overhead of chunked DEFLATE for small files. Stored files are sent directly to the sink without an intermediate copy.

    Writer::begin_entry

    fn Writer::begin_entry(self : Writer, name : String, compression? : Compression, size? : UInt64) -> Unit raise

    Open a chunked entry. Supply the known uncompressed size to use classic headers when it fits safely; unknown sizes reserve ZIP64 fields up front. The declared size is checked before accepting input and before closing.

    Writer::end_entry

    fn Writer::end_entry(self : Writer) -> Unit raise

    Finish the current entry and emit its data descriptor. The next file may then be started. Codec buffers are retained for reuse across entries.

    Writer::finish

    fn Writer::finish(self : Writer, comment? : BytesView) -> Unit raise

    Write the central directory and close the ZIP. Further writes are rejected. The optional archive comment must fit the ZIP 16-bit comment length.

    Writer::is_failed

    fn Writer::is_failed(self : Writer) -> Bool

    Whether an emission failure has made this writer unusable.

    Writer::is_finished

    fn Writer::is_finished(self : Writer) -> Bool

    Whether the directory and archive trailer have been successfully emitted.

    Writer::position

    fn Writer::position(self : Writer) -> UInt64

    Number of successfully emitted bytes, including headers and descriptors.

    Writer::write

    fn Writer::write(self : Writer, bytes : BytesView) -> Unit raise

    Consume a chunk of the current entry, updating CRC while its bytes are hot. Produced compressed blocks are sent to the sink before this call returns.

    ZipErrorKind

    pub(all) enum ZipErrorKind {
    Truncated
    InvalidSignature
    MissingEndOfCentral
    UnsupportedCompression(Int)
    InvalidUtf8
    UnsupportedFeature
    InvalidDeflate
    InvalidRead
    InvalidEntryIndex(Int)
    SizeMismatch
    ChecksumMismatch
    LimitExceeded(LimitKind, UInt64, UInt64)
    Cancelled
    InvalidArgument
    InvalidState
    } derive(Eq,
    Debug
    )

    Machine-readable category for a ZIP container failure. The accompanying ZipError message is intended for diagnostics rather than branching.

    ZipErrorKind::equal

    read

    fn read(bytes : BytesView, limits? : ReadLimits, cancelled? : () -> Bool) -> Archive raise ZipError

    Read a ZIP archive from bytes, decoding every entry. limits bounds the package size, entry count, per-entry and total decompressed bytes, and the complete source retained for byte-preserving rewrites; cancelled is polled across parsing, decoding, and CRC-32 verification. Every decoded entry must match its stored CRC-32. Failures carry a stable ZipErrorKind plus a diagnostic.

    write

    fn write(archive : Archive, preserve? : Bool, max_output_bytes? : Int, level? : Int, fast_store? : Bool) -> Bytes raise ZipError

    Serialize archive into a ZIP byte stream.

    By default every entry is encoded fresh. With preserve=true, unchanged entries reuse their source records with updated offsets. A pristine archive round-trips byte-for-byte, including prefixes, gaps and directory ordering. After any edit, records are rebuilt in their respective local and directory orders; bytes outside records (such as prefixes and gaps) are not retained in the output. Replaced and newly added entries are encoded normally. level is clamped to 0-9. fast_store opts into a speed/ratio heuristic. If max_output_bytes is supplied, the output is sized before allocation and an oversized archive raises LimitExceeded(OutputBytes, ...). A negative limit raises InvalidArgument.