rcbench
Servo and ESC test bench: panel, IOmcu and shared C
Loading...
Searching...
No Matches
wa_zip.c File Reference

The card as a ZIP archive. See wa_zip.h. More...

#include "wa_zip.h"
#include <string.h>
#include "wall_clock.h"

Macros

#define SIG_LOCAL   0x04034b50u
#define SIG_DESC   0x08074b50u
#define SIG_CENTRAL   0x02014b50u
#define SIG_END64   0x06064b50u
#define SIG_LOC64   0x07064b50u
#define SIG_END   0x06054b50u
#define FLAGS   0x0808u
#define VERSION_20   20u
#define VERSION_45   45u
#define ATTR_DIR   0x10u
#define DOS_FIRST   315532800
#define DOS_LAST   4354819198

Enumerations

enum  {
  PH_ENTRIES = 0 , PH_CENTRAL , PH_END , PH_DONE ,
  PH_FAILED
}

Functions

uint32_t wa_crc32 (uint32_t crc, const void *data, size_t n)
void wa_dos_time (int64_t t, uint16_t *time, uint16_t *date)
static uint8_t * put16 (uint8_t *p, uint32_t v)
static uint8_t * put32 (uint8_t *p, uint32_t v)
static uint8_t * put64 (uint8_t *p, uint64_t v)
static uint32_t clamp32 (uint64_t v)
bool wa_zip_entry64 (uint64_t size)
bool wa_zip_end64 (uint64_t entries, uint64_t cd_bytes, uint64_t cd_offset)
uint32_t wa_zip_local_bytes (size_t name_len, uint64_t size)
uint32_t wa_zip_desc_bytes (uint64_t size)
static bool central_sizes64 (uint64_t size, uint64_t offset)
static unsigned central_fields (uint64_t size, uint64_t offset)
uint32_t wa_zip_central_bytes (size_t name_len, uint64_t size, uint64_t offset)
uint32_t wa_zip_end_bytes (uint64_t entries, uint64_t cd_bytes, uint64_t cd_offset)
size_t wa_zip_local (uint8_t *out, const char *name, size_t name_len, uint64_t size, int64_t mtime, bool dir)
size_t wa_zip_desc (uint8_t *out, uint32_t crc, uint64_t size)
size_t wa_zip_central (uint8_t *out, const char *name, size_t name_len, uint64_t size, uint32_t crc, uint64_t offset, int64_t mtime, bool dir)
size_t wa_zip_end (uint8_t *out, uint64_t entries, uint64_t cd_bytes, uint64_t cd_offset)
void wa_zip_len_init (wa_zip_len_t *l)
void wa_zip_len_add (wa_zip_len_t *l, size_t name_len, uint64_t size)
uint64_t wa_zip_len_total (const wa_zip_len_t *l)
static bool entry_of (const wa_walk_t *w, wa_walk_ev_t ev, size_t *len, bool *dir)
static uint32_t path_hash (const wa_walk_t *w, bool dir)
 FNV-1a hash of the path of the entry a walk is at.
static uint32_t mtime_pack (int64_t t)
 A time as a slot keeps it: clamped to the DOS range, in seconds since its start, which 32 bits hold.
static int64_t mtime_unpack (uint32_t m)
 A slot's time back in seconds since 1970.
static wa_zip_err_t plan_walk (wa_walk_t *w, const wa_fs_t *fs, wa_zip_plan_t *out, wa_zip_slot_t *slot, uint64_t slots)
 The first walk: add up the archive's length, and keep each entry's size, time, name length and path hash when slot is given.
wa_zip_err_t wa_zip_plan (const wa_fs_t *fs, wa_zip_plan_t *out)
 Walk the card and add up the archive it makes, keeping nothing per entry: the counts the page shows, and the slots wa_zip_begin() needs.
wa_zip_err_t wa_zip_begin (wa_zip_t *z, const wa_fs_t *fs, wa_zip_slot_t *slot, uint64_t slots)
 Begin the archive: the first walk, which fills z->plan and a slot for each entry. Nothing is sent; the response announces z->plan.bytes.
void wa_zip_end_early (wa_zip_t *z)
static int32_t fail (wa_zip_t *z, wa_zip_err_t e)
static wa_zip_err_t walk_err (wa_walk_ev_t ev)
static void queue (wa_zip_t *z, size_t n)
static wa_zip_slot_t * planned (wa_zip_t *z, size_t len, bool dir)
 The slot of the entry a later walk is at.
static bool next_entry (wa_zip_t *z)
 The next piece of the second walk: a local header, a folder's with its descriptor, and a file opened for its data.
static bool next_central (wa_zip_t *z)
 The next piece of the third walk: a central header, or the end.
static int32_t fail_after (wa_zip_t *z, wa_zip_err_t e, uint32_t got)
 Fail the archive part way through a call of wa_zip_next().
int32_t wa_zip_next (wa_zip_t *z, uint8_t *buf, uint32_t cap)
 The next bytes of the archive.

Variables

static uint32_t s_table [256]
static bool s_table_made

Detailed Description

The card as a ZIP archive. See wa_zip.h.

Layouts from PKWARE's APPNOTE.TXT 6.3.10: local file header 4.3.7, data descriptor 4.3.9, central directory header 4.3.12, ZIP64 end of central directory record 4.3.14 and locator 4.3.15, end of central directory record 4.3.16, ZIP64 extended information 4.5.3.

SPDX-License-Identifier: MIT

Macro Definition Documentation

◆ DOS_FIRST

#define DOS_FIRST   315532800

1980-01-01 00:00:00, s since 1970

◆ DOS_LAST

#define DOS_LAST   4354819198

2107-12-31 23:59:58, s since 1970

Function Documentation

◆ fail_after()

int32_t fail_after ( wa_zip_t * z,
wa_zip_err_t e,
uint32_t got )
static

Fail the archive part way through a call of wa_zip_next().

Parameters
zthe archive
ewhy
gotbytes already in the caller's buffer
Returns
got when there are some, all inside the announced length, as wa_zip_next() never passes it: they are the archive's up to the failure and go out, and the next call returns -1. Otherwise -1.

◆ mtime_pack()

uint32_t mtime_pack ( int64_t t)
static

A time as a slot keeps it: clamped to the DOS range, in seconds since its start, which 32 bits hold.

Parameters
tseconds since 1970
Returns
Seconds since 1980-01-01 00:00:00.

◆ mtime_unpack()

int64_t mtime_unpack ( uint32_t m)
static

A slot's time back in seconds since 1970.

Parameters
mwhat mtime_pack() made
Returns
Seconds since 1970, the same DOS time as the time packed.

◆ next_central()

bool next_central ( wa_zip_t * z)
static

The next piece of the third walk: a central header, or the end.

Parameters
zthe archive
Returns
true with a piece queued; false with z->err set.

◆ next_entry()

bool next_entry ( wa_zip_t * z)
static

The next piece of the second walk: a local header, a folder's with its descriptor, and a file opened for its data.

Parameters
zthe archive
Returns
true with a piece queued or the third walk begun; false with z->err set.

◆ path_hash()

uint32_t path_hash ( const wa_walk_t * w,
bool dir )
static

FNV-1a hash of the path of the entry a walk is at.

Parameters
wthe walk, its path without a folder's "/"
dirwhether the entry is a folder, hashed as a "/" after the path
Returns
The hash.

◆ plan_walk()

wa_zip_err_t plan_walk ( wa_walk_t * w,
const wa_fs_t * fs,
wa_zip_plan_t * out,
wa_zip_slot_t * slot,
uint64_t slots )
static

The first walk: add up the archive's length, and keep each entry's size, time, name length and path hash when slot is given.

Parameters
wthe walk to use
fsthe card
outthe plan, filled
slotthe slots, or NULL to keep nothing
slotshow many slot holds
Returns
WA_ZIP_OK; WA_ZIP_NO_CARD or WA_ZIP_READ when the walk fails; WA_ZIP_MEMORY when slot is given and the card has more entries than slots. Nothing is left open.

◆ planned()

wa_zip_slot_t * planned ( wa_zip_t * z,
size_t len,
bool dir )
static

The slot of the entry a later walk is at.

Parameters
zthe archive, its walk at a file or folder
lenthe entry's name length, a folder's with its "/"
dirwhether the entry is a folder
Returns
The next slot when the entry is the one the first walk found there, by name length and path hash; NULL for an entry added since, which the walk passes by.

◆ wa_crc32()

uint32_t wa_crc32 ( uint32_t crc,
const void * data,
size_t n )

CRC-32 as ZIP takes it, continued from crc (0 to start).

◆ wa_dos_time()

void wa_dos_time ( int64_t t,
uint16_t * time,
uint16_t * date )

t seconds since 1970 as DOS time and date; before 1980 is 1980-01-01 00:00:00, after 2107 is 2107-12-31 23:59:58.

◆ wa_zip_begin()

wa_zip_err_t wa_zip_begin ( wa_zip_t * z,
const wa_fs_t * fs,
wa_zip_slot_t * slot,
uint64_t slots )

Begin the archive: the first walk, which fills z->plan and a slot for each entry. Nothing is sent; the response announces z->plan.bytes.

Parameters
zthe archive
fsthe card
slotslots slots, or NULL for none
slotshow many slot holds
Returns
WA_ZIP_OK; WA_ZIP_MEMORY when the card has more entries than slots; WA_ZIP_NO_CARD or WA_ZIP_READ when the walk fails. On anything but WA_ZIP_OK nothing is left open and wa_zip_next() returns -1.

◆ wa_zip_end64()

bool wa_zip_end64 ( uint64_t entries,
uint64_t cd_bytes,
uint64_t cd_offset )

Whether the end of an archive needs the ZIP64 records.

◆ wa_zip_end_early()

void wa_zip_end_early ( wa_zip_t * z)

Close what is open; for an archive given up part way.

◆ wa_zip_entry64()

bool wa_zip_entry64 ( uint64_t size)

Whether an entry of size bytes needs ZIP64 in its own headers.

◆ wa_zip_len_add()

void wa_zip_len_add ( wa_zip_len_t * l,
size_t name_len,
uint64_t size )

One entry, its name name_len bytes (a folder's with its "/").

◆ wa_zip_len_total()

uint64_t wa_zip_len_total ( const wa_zip_len_t * l)

The archive's length with what was added.

◆ wa_zip_next()

int32_t wa_zip_next ( wa_zip_t * z,
uint8_t * buf,
uint32_t cap )

The next bytes of the archive.

Parameters
zthe archive
bufwhere they go
caphow many buf holds
Returns
How many, 0 when the archive is whole, -1 when it failed (wa_zip_t.err). A failure part way through buf returns the bytes before it first, and -1 on the next call. The bytes add up to plan.bytes exactly, or the archive fails.

◆ wa_zip_plan()

wa_zip_err_t wa_zip_plan ( const wa_fs_t * fs,
wa_zip_plan_t * out )

Walk the card and add up the archive it makes, keeping nothing per entry: the counts the page shows, and the slots wa_zip_begin() needs.

Parameters
fsthe card
outthe plan, filled
Returns
WA_ZIP_OK with out filled, WA_ZIP_NO_CARD or WA_ZIP_READ.