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

SPDX-License-Identifier: MIT. More...

#include "kst_store.h"
#include <string.h>

Data Structures

struct  find_t
 State of a search for one file name. More...
struct  list_t
 State of one list: the sorted entries kept so far. More...

Macros

#define PRESET   "KST"
 Prefix of a proposed base name.
#define PRESET_LEN   3u
 Length of the prefix, characters.
#define EXT_LEN   (sizeof(KST_STORE_EXT) - 1u)
 Length of the file extension, characters.
#define NUMBER_BYTES   ((KST_STORE_LAST / 8) + 1)
 Bytes of a bit set that holds one flag per number 0 to KST_STORE_LAST.

Functions

static char lower (char c)
 Fold an ASCII capital letter to lower case.
static int name_cmp (const char *a, const char *b)
 Order of two names without case; the case decides between names that are equal without it.
static bool same_name (const char *a, const char *b)
 Whether two names are equal without case.
static bool reserved (const char *s, size_t n)
 Whether the first n characters of s are a device name.
static bool record (const char *s, size_t n)
 Whether the first n characters of s are KST_STORE_RECORD.
static kst_store_name_t check (const char *base, size_t n)
 Check a base name of known length.
kst_store_name_t kst_store_name_check (const char *base)
 Whether base is a base name this layer writes.
bool kst_store_file_name (const char *base, char *out, size_t out_size)
 The file name of base: the base name and KST_STORE_EXT.
static size_t base_len (const char *name)
 Length of the base name in a file name with the extension; 0 when the name does not end with it.
static int preset_number (const char *name)
 The number in "KSTnnn.TXT", in any case; 0 for any other name.
static void mark_number (const char *name, bool is_dir, void *visit_ctx)
 Set the bit of a directory entry's proposed number.
kst_store_t kst_store_preset (const kst_store_io_t *io, char *base, size_t base_size)
 Propose a base name: "KST" and 3 digits, one above the highest number the directory holds.
static void find_name (const char *name, bool is_dir, void *visit_ctx)
 Set found when a directory entry has the searched name.
kst_store_t kst_store_save (const kst_store_io_t *io, const char *base, const char *text, size_t len, kst_store_name_t *why)
 Write len bytes of text as the file of base.
static bool before_presets (const char *name)
 Whether a name that is no proposed one stands in front of the proposed names: at or before "KST000.TXT" in the order without case.
static int list_cmp (const char *a, const char *b)
 Order of two file names in a list: by name without case, with the proposed names in one run where "KST000.TXT" would stand, the highest number first.
static void list_name (const char *name, bool is_dir, void *visit_ctx)
 Insert one directory entry into the sorted list.
kst_store_t kst_store_list (const kst_store_io_t *io, kst_store_entry_t *entries, size_t cap, size_t *count, size_t *total, size_t *skipped)
 List the files with KST_STORE_EXT.
kst_store_t kst_store_list_after (const kst_store_io_t *io, const char *after, kst_store_entry_t *entries, size_t cap, size_t *count, size_t *total, size_t *skipped)
 kst_store_list() from the file behind after on: entries receives the first cap files the order has behind the name after, a file name with its extension that need not exist.
kst_store_t kst_store_load (const kst_store_io_t *io, const char *name, char *buf, size_t cap, size_t *len)
 Read the file name, a name as kst_store_list() gives it, into buf. len receives the number of bytes.

Detailed Description

SPDX-License-Identifier: MIT.

Function Documentation

◆ base_len()

size_t base_len ( const char * name)
static

Length of the base name in a file name with the extension; 0 when the name does not end with it.

Parameters
nameThe file name, with the extension.
Returns
The length of the base name, characters, or 0.

◆ before_presets()

bool before_presets ( const char * name)
static

Whether a name that is no proposed one stands in front of the proposed names: at or before "KST000.TXT" in the order without case.

Parameters
nameThe file name.
Returns
true when the name sorts at or before "KST000.TXT".

◆ check()

kst_store_name_t check ( const char * base,
size_t n )
static

Check a base name of known length.

Parameters
baseThe base name.
nLength of the base name, characters.
Returns
KST_STORE_NAME_OK, or the first rule the name breaks.

◆ find_name()

void find_name ( const char * name,
bool is_dir,
void * visit_ctx )
static

Set found when a directory entry has the searched name.

Parameters
nameThe entry name.
is_dirWhether the entry is a directory; ignored.
visit_ctxThe find_t state.

◆ kst_store_file_name()

bool kst_store_file_name ( const char * base,
char * out,
size_t out_size )

The file name of base: the base name and KST_STORE_EXT.

False, with an empty string in out, for a base name that fails kst_store_name_check() and for an out_size under KST_STORE_NAME_MAX.

Parameters
baseThe base name.
outReceives the file name.
out_sizeSize of out, bytes.
Returns
true when out holds the file name.

◆ kst_store_list()

kst_store_t kst_store_list ( const kst_store_io_t * io,
kst_store_entry_t * entries,
size_t cap,
size_t * count,
size_t * total,
size_t * skipped )

List the files with KST_STORE_EXT.

The order: by name without case. The files named "KST" and 3 digits stand in one run at the place of "KST000", by falling number. kst_store_preset() gives a later file the higher number until KST999 is taken, so the run starts with the latest of them.

entries receives the first cap of them. count is the number written, total the number of files that qualify, skipped the number of files with the extension whose base name fails kst_store_name_check(): those are not listed and not loaded. The file named KST_STORE_RECORD is in none of the 3 numbers. Each of the 3 may be NULL. Directories are not listed. A directory without a file gives KST_STORE_OK and a count of 0.

Parameters
ioThe card functions.
entriesReceives the listed names.
capCapacity of entries, in entries.
countReceives the number of entries written, or NULL.
totalReceives the number of qualifying files, or NULL.
skippedReceives the number of files with a bad name, or NULL.
Returns
KST_STORE_OK, or the reason the directory did not list.

◆ kst_store_list_after()

kst_store_t kst_store_list_after ( const kst_store_io_t * io,
const char * after,
kst_store_entry_t * entries,
size_t cap,
size_t * count,
size_t * total,
size_t * skipped )

kst_store_list() from the file behind after on: entries receives the first cap files the order has behind the name after, a file name with its extension that need not exist.

NULL lists from the first file on. total and skipped count the whole directory as kst_store_list() does.

A caller reaches every file of a directory in a buffer of cap entries by passing the last name of one call to the next; each call walks the directory once.

Parameters
ioThe card functions.
afterThe file name to list after, or NULL.
entriesReceives the listed names.
capCapacity of entries, in entries.
countReceives the number of entries written, or NULL.
totalReceives the number of qualifying files, or NULL.
skippedReceives the number of files with a bad name, or NULL.
Returns
KST_STORE_OK, or the reason the directory did not list.

◆ kst_store_load()

kst_store_t kst_store_load ( const kst_store_io_t * io,
const char * name,
char * buf,
size_t cap,
size_t * len )

Read the file name, a name as kst_store_list() gives it, into buf. len receives the number of bytes.

No terminator is written.

Parameters
ioThe card functions.
nameThe file name.
bufReceives the bytes.
capCapacity of buf, bytes.
lenReceives the number of bytes read.
Returns
KST_STORE_OK, or the reason the file was not read.

◆ kst_store_name_check()

kst_store_name_t kst_store_name_check ( const char * base)

Whether base is a base name this layer writes.

Parameters
baseThe base name, without extension.
Returns
KST_STORE_NAME_OK, or the first rule the name breaks.

◆ kst_store_preset()

kst_store_t kst_store_preset ( const kst_store_io_t * io,
char * base,
size_t base_size )

Propose a base name: "KST" and 3 digits, one above the highest number the directory holds.

A gap below the highest number is not filled, so a higher number is a later file. With KST999 taken the lowest free number is proposed. Files and directories count, in any case; a file with another name counts for nothing.

base_size is KST_STORE_PRESET_MAX or more.

Parameters
ioThe card functions.
baseReceives the proposed base name.
base_sizeSize of base, bytes.
Returns
KST_STORE_OK, or the reason no name was proposed.

◆ kst_store_save()

kst_store_t kst_store_save ( const kst_store_io_t * io,
const char * base,
const char * text,
size_t len,
kst_store_name_t * why )

Write len bytes of text as the file of base.

KST_STORE_BAD_NAME leaves the reason in why, when not NULL. A name the directory holds, compared without case, gives KST_STORE_EXISTS and the file stays as it is.

Parameters
ioThe card functions.
baseThe base name of the file.
textThe bytes to write.
lenNumber of bytes in text.
whyReceives the name reason when refused, or NULL.
Returns
KST_STORE_OK, or the reason the file was not written.

◆ list_cmp()

int list_cmp ( const char * a,
const char * b )
static

Order of two file names in a list: by name without case, with the proposed names in one run where "KST000.TXT" would stand, the highest number first.

Parameters
aThe first file name.
bThe second file name.
Returns
Negative, zero or positive as a sorts before, with or after b.

◆ list_name()

void list_name ( const char * name,
bool is_dir,
void * visit_ctx )
static

Insert one directory entry into the sorted list.

Parameters
nameThe entry name.
is_dirWhether the entry is a directory; directories are skipped.
visit_ctxThe list_t state.

◆ lower()

char lower ( char c)
static

Fold an ASCII capital letter to lower case.

Parameters
cThe character.
Returns
The lower-case letter for A to Z; every other character unchanged.

◆ mark_number()

void mark_number ( const char * name,
bool is_dir,
void * visit_ctx )
static

Set the bit of a directory entry's proposed number.

Parameters
nameThe entry name.
is_dirWhether the entry is a directory; ignored.
visit_ctxThe bit set, NUMBER_BYTES bytes.

◆ name_cmp()

int name_cmp ( const char * a,
const char * b )
static

Order of two names without case; the case decides between names that are equal without it.

Parameters
aThe first name.
bThe second name.
Returns
Negative, zero or positive as a sorts before, with or after b.

◆ preset_number()

int preset_number ( const char * name)
static

The number in "KSTnnn.TXT", in any case; 0 for any other name.

Parameters
nameThe file name.
Returns
The number 1 to 999, or 0.

◆ record()

bool record ( const char * s,
size_t n )
static

Whether the first n characters of s are KST_STORE_RECORD.

Parameters
sThe name.
nNumber of characters in the base name.
Returns
true when the base name is KST_STORE_RECORD, in any case.

◆ reserved()

bool reserved ( const char * s,
size_t n )
static

Whether the first n characters of s are a device name.

Parameters
sThe name.
nNumber of characters to test: 3 or 4.
Returns
true for CON, PRN, AUX, NUL, COM1 to COM9 and LPT1 to LPT9.

◆ same_name()

bool same_name ( const char * a,
const char * b )
static

Whether two names are equal without case.

Parameters
aThe first name.
bThe second name.
Returns
true when the names match without regard to case.