Standard library · Encoding and data

archive

Making and opening zip and tar archives, reading RAR, and gzipping a file.

import archive
On this page
  1. Types
  2. Functions

An archive gathers several files into one. Zip compresses each file on its own; tar only puts the files one after another and is usually gzipped afterwards (.tar.gz).

The functions work both in memory and on files. They take the archive data as an address and a length, such as b.data and b.len of a byte buffer.

Types

TarFileInput

struct TarFileInput
One file to put in a tar.
NameTypeDescription
namestr = ""The name inside the archive.
data_ptrvoid*The address of the contents.
data_lenint = 0The length of the contents.
is_dirbool = falseThe input is a directory.
archive-Tar.salam
import archive
import compress

func main:
    b := compress.BufFromStr("first line\nsecond line\n")
    mut files := Vector {} as Vector<archive.TarFileInput>
    files.push(archive.MakeTarFileInput("notes", null, 0, true))
    files.push(archive.MakeTarFileInput("notes/a.txt", b.data, b.len, false))
    t := archive.TarCreate(files)
    println t.len % 512
    mut entries := archive.TarList(t.data, t.len)
    each e in entries:
        println e.name, e.size, e.is_dir
    end
    archive.FreeEntries(entries)
    mut ok := false
    a := archive.TarExtractByName(t.data, t.len, "notes/a.txt", ok)
    println ok, compress.BufToStrUnsafe(a)
    println archive.TarCreateFile(files, "out.tar"), archive.TarExtractAll(t.data, t.len, "untarred")
    println archive.GzipCompressFile("out.tar", "out.tar.gz"), archive.GzipDecompressFile("out.tar.gz", "back.tar")
    back := archive.ReadBinaryFile("back.tar", ok)
    println ok, back.len == t.len
    archive.EnsureDir("a/b/c")
    println archive.WriteBinaryFile("a/b/c/x.bin", b.data, 3), archive.WriteBinaryFileBuf("a/b/c/y.bin", b)
    mut b2 := compress.NewByteBuf()
    archive.LEPut16(b2, 513)
    archive.LEPut32(b2, 70000)
    println archive.LEGet16(b2.data, 0), archive.LEGet32(b2.data, 2)
end
Output0 notes 0 true notes/a.txt 23 false true first line second line true true true true true true true true 513 70000

Entry

struct Entry
One archive entry.
NameTypeDescription
namestr = ""The name and path inside the archive.
sizei64 = 0The original size in bytes.
compressed_sizei64 = 0The compressed size.
is_dirbool = falseThe entry is a directory.
methodint = 0The compression method: zero for plain storage, 8 for DEFLATE.
crc32u32 = 0The checksum of the contents.
mtimei64 = 0The modification time in seconds since the Unix epoch.
archive-Zip.salam
import archive
import compress

func main:
    text := "hello archive, hello archive, hello archive"
    b := compress.BufFromStr(text)
    mut files := Vector {} as Vector<archive.ZipFileInput>
    files.push(archive.MakeZipFileInput("docs/", null, 0, 0))
    files.push(archive.MakeZipFileInput("docs/a.txt", b.data, b.len, 8))
    files.push(archive.MakeZipFileInput("b.txt", b.data, 5, 0))
    z := archive.ZipCreate(files)
    mut entries := archive.ZipList(z.data, z.len)
    each e in entries:
        println e.name, e.size, e.compressed_size < e.size, e.is_dir, e.method
    end
    archive.FreeEntries(entries)
    mut ok := false
    a := archive.ZipExtractByName(z.data, z.len, "docs/a.txt", ok)
    println ok, compress.BufToStrUnsafe(a) == text
    _ := archive.ZipExtractByName(z.data, z.len, "missing", ok)
    println ok
    println archive.ZipCreateFile(files, "out.zip"), archive.ZipExtractAll(z.data, z.len, "unzipped")
    read := archive.ReadBinaryFile("unzipped/docs/a.txt", ok)
    println ok, read.len == b.len
    println archive.IsRar(z.data, z.len), archive.RarList(z.data, z.len).len()
    _ := archive.RarExtractByName(z.data, z.len, "x", ok)
    println ok, archive.RarExtractAll(z.data, z.len, "rar-out")
end
Outputdocs/ 0 false true 0 docs/a.txt 43 true false 8 b.txt 5 false false 0 true true false true true true true false 0 false true

ZipFileInput

struct ZipFileInput
One file to put in a zip.
NameTypeDescription
namestr = ""The name inside the archive; a directory name ends with /.
data_ptrvoid*The address of the contents.
data_lenint = 0The length of the contents.
methodint = 8Zero for plain storage, 8 for DEFLATE.

The example for this item is shown with the ones above: archive-Zip.salam

Functions

GzipCompressFile

func GzipCompressFile(inpath: str, outpath: str): bool
Gzips a file.

The example for this item is shown with the ones above: archive-Tar.salam

GzipDecompressFile

func GzipDecompressFile(inpath: str, outpath: str): bool
Decompresses a gzip file.

The example for this item is shown with the ones above: archive-Tar.salam

MakeTarFileInput

func MakeTarFileInput(name: str, data_ptr: void*, data_len: int, is_dir: bool): TarFileInput
Makes one tar input.

The example for this item is shown with the ones above: archive-Tar.salam

TarCreate

func TarCreate(files: Vector<TarFileInput>): compress.ByteBuf
Builds a tar archive in memory, in the ustar format; tar does not compress, so gzip the result for that.

The example for this item is shown with the ones above: archive-Tar.salam

TarCreateFile

func TarCreateFile(files: Vector<TarFileInput>, outpath: str): bool
Writes a tar archive to a file.

The example for this item is shown with the ones above: archive-Tar.salam

TarList

func TarList(p: void*, n: int): Vector<Entry>
The entries of a tar in memory.

The example for this item is shown with the ones above: archive-Tar.salam

TarExtractByName

func TarExtractByName(p: void*, n: int, name: str, ok &: bool): compress.ByteBuf
The contents of one tar entry.

The example for this item is shown with the ones above: archive-Tar.salam

TarExtractAll

func TarExtractAll(p: void*, n: int, destdir: str): bool
Writes every tar entry into the target directory.

The example for this item is shown with the ones above: archive-Tar.salam

ReadBinaryFile

func ReadBinaryFile(path: str, ok &: bool): compress.ByteBuf
Reads every byte of a file into a buffer.

The example for this item is shown with the ones above: archive-Zip.salam

WriteBinaryFile

func WriteBinaryFile(path: str, p: void*, n: int): bool
Writes n bytes to a file.

The example for this item is shown with the ones above: archive-Tar.salam

WriteBinaryFileBuf

func WriteBinaryFileBuf(path: str, b: compress.ByteBuf): bool
Writes a buffer to a file.

The example for this item is shown with the ones above: archive-Tar.salam

EnsureDir

func EnsureDir(dir: str)
Makes the directory and the ones above it, when they are not there.

The example for this item is shown with the ones above: archive-Tar.salam

LEGet16

func LEGet16(p: void*, off: int): int
Reads a 16 bit little-endian integer from the given place in memory.

The example for this item is shown with the ones above: archive-Tar.salam

LEGet32

func LEGet32(p: void*, off: int): int
Reads a 32 bit little-endian integer.

The example for this item is shown with the ones above: archive-Tar.salam

LEPut16

func LEPut16(b &: compress.ByteBuf, v: int)
Adds a 16 bit integer to a buffer, little-endian.

The example for this item is shown with the ones above: archive-Tar.salam

LEPut32

func LEPut32(b &: compress.ByteBuf, v: int)
Adds a 32 bit integer, little-endian.

The example for this item is shown with the ones above: archive-Tar.salam

FreeEntries

func FreeEntries(v &: Vector<Entry>)
Frees the memory of the entry list.

The example for this item is shown with the ones above: archive-Zip.salam

MakeZipFileInput

func MakeZipFileInput(name: str, data_ptr: void*, data_len: int, method: int): ZipFileInput
Makes one zip input.

The example for this item is shown with the ones above: archive-Zip.salam

ZipCreate

func ZipCreate(files: Vector<ZipFileInput>): compress.ByteBuf
Builds a zip archive in memory.

The example for this item is shown with the ones above: archive-Zip.salam

ZipCreateFile

func ZipCreateFile(files: Vector<ZipFileInput>, outpath: str): bool
Writes a zip archive to a file.

The example for this item is shown with the ones above: archive-Zip.salam

ZipList

func ZipList(p: void*, n: int): Vector<Entry>
The entries of a zip in memory.

The example for this item is shown with the ones above: archive-Zip.salam

ZipExtractByName

func ZipExtractByName(p: void*, n: int, name: str, ok &: bool): compress.ByteBuf
Pulls out the contents of one entry; ok becomes false when the name is not found.

The example for this item is shown with the ones above: archive-Zip.salam

ZipExtractAll

func ZipExtractAll(p: void*, n: int, destdir: str): bool
Writes every entry into the target directory. When the data is not a zip it has no entries and nothing is written.

The example for this item is shown with the ones above: archive-Zip.salam

IsRar

func IsRar(p: void*, n: int): bool
True when the data starts with the RAR signature.

The example for this item is shown with the ones above: archive-Zip.salam

RarList

func RarList(p: void*, n: int): Vector<Entry>
The entries of a RAR archive.

The example for this item is shown with the ones above: archive-Zip.salam

RarExtractByName

func RarExtractByName(p: void*, n: int, name: str, ok &: bool): compress.ByteBuf
The contents of a RAR entry that was stored without compression.

The example for this item is shown with the ones above: archive-Zip.salam

RarExtractAll

func RarExtractAll(p: void*, n: int, destdir: str): bool
Pulls out every RAR entry.

The example for this item is shown with the ones above: archive-Zip.salam