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

The whole card as one ZIP archive, written as it is sent. More...

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "wa_walk.h"

Go to the source code of this file.

Data Structures

struct  wa_zip_len_t
struct  wa_zip_plan_t
struct  wa_zip_slot_t
 One entry as the first walk found it, 24 bytes. More...
struct  wa_zip_t
 One archive being sent. The fields are wa_zip.c's. More...

Macros

#define WA_ZIP_MAX32   0xFFFFFFFFu
#define WA_ZIP_MAX16   0xFFFFu
#define WA_ZIP_PIECE_MAX   (46u + (WA_PATH_MAX + 1u) + 28u + 56u + 20u + 22u)
#define WA_ZIP_SPARE   16u
 Slots to allocate beyond the entries wa_zip_plan() counted: entries added to the card before wa_zip_begin() walks it again.

Enumerations

enum  wa_zip_err_t { WA_ZIP_OK = 0 , WA_ZIP_NO_CARD , WA_ZIP_READ , WA_ZIP_MEMORY }

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)
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)
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)
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.
int32_t wa_zip_next (wa_zip_t *z, uint8_t *buf, uint32_t cap)
 The next bytes of the archive.
void wa_zip_end_early (wa_zip_t *z)

Detailed Description

The whole card as one ZIP archive, written as it is sent.

Stored, not compressed (method 0): deflate would cost the panel's cores and time, and log files are what the card mostly holds. No temporary file and no copy of the archive: each file is read off the card once, a piece at a time, and its CRC-32 (cyclic redundancy check) is taken on the way and written after it in a data descriptor (general purpose bit 3). Names are UTF-8 (bit 11), paths relative to the card's root, a folder an entry of its own ending in "/", times the files' own as DOS (Disk Operating System) date and time, 1980-01-01 00:00:00 for anything older.

Three walks of the card (wa_walk.h), after wa_zip_plan() has counted its entries. The first, in wa_zip_begin(), adds up the archive's length, which is known before a byte is read because stored sizes are the files' sizes: the response announces it, and the browser shows progress. It keeps each entry's size, time, name length and a hash of its path in a slot, 24 bytes an entry. The second sends the entries, the third the central directory; both take each entry's size and time from its slot, and the third the CRC the second kept there.

A file that grows after the first walk is sent at the size the first walk found, its first bytes as they are when the second walk reads them: a file only added to, as a log is, is sent as it was when the download started. An entry whose name length or path hash is not the next slot's, a file or folder added after the first walk, is left out of both later walks. A walk can meet one anywhere, since a folder lists its entries in the card's own order.

ZIP64 where the format runs out: an entry of 0xFFFFFFFF bytes or more, a local header at or past that offset, 0xFFFF entries or more, and a central directory that large or that far in. The value itself is the format's "see ZIP64" mark, so it counts as past the limit.

A read error, a card pulled, a file that shrank, and an entry removed or renamed after the first walk end the archive as failed; the response is cut off after the bytes made up to the failure, and the browser reports the download failed.

Pure C, no ESP-IDF (Espressif Internet-of-Things Development Framework).

SPDX-License-Identifier: MIT

Macro Definition Documentation

◆ WA_ZIP_PIECE_MAX

#define WA_ZIP_PIECE_MAX   (46u + (WA_PATH_MAX + 1u) + 28u + 56u + 20u + 22u)

The largest any one piece is.

Enumeration Type Documentation

◆ wa_zip_err_t

Enumerator
WA_ZIP_READ 

a read failed, or the card changed under it

WA_ZIP_MEMORY 

too few slots for the entries

Function Documentation

◆ 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.