160 lines
5.8 KiB
C
160 lines
5.8 KiB
C
#ifndef VESSEL_WEB_PATH_H_
|
|
#define VESSEL_WEB_PATH_H_
|
|
|
|
#include "conf.h"
|
|
#include "http.h"
|
|
|
|
#include <vessel/log.h>
|
|
#include <vessel/def.h>
|
|
#include <vessel/hmap.h>
|
|
#include <vessel/array.h>
|
|
|
|
#define VW_PATTERN_MAX_KEY 32
|
|
#define VW_PATTERN_MAX_VALUE 256
|
|
|
|
typedef struct {
|
|
char *path;
|
|
size_t len;
|
|
vs_HMap args;
|
|
} vw_Path;
|
|
|
|
bool vw_Path_init(vw_Path *path);
|
|
bool vw_Path_parse(vw_Path *path, const char *src);
|
|
bool vw_Path_destroy(vw_Path *path);
|
|
|
|
#define VW_PATH_SEGMENT_FLAG_NOCONV ((uint8_t)0x80) /* 1000 0000 => ! */
|
|
#define VW_PATH_SEGMENT_FLAG_OPTIONAL ((uint8_t)0x40) /* 0100 0000 => ? */
|
|
#define VW_PATH_SEGMENT_FLAG_STATIC ((uint8_t)0x20) /* 0010 0000 => static */
|
|
|
|
#define VW_PATH_TYPE_FLAG_LAST ((uint16_t)0x8000) /* 1000 0000 0000 0000: Last token */
|
|
#define VW_PATH_TYPE_FLAG_BOUND \
|
|
((uint16_t)0x2000) /* 0010 0000 0000 0000: Strictly bound (cannot be used \
|
|
next to adjacent dynamic segments) */
|
|
#define VW_PATH_TYPE_FLAG_NOCONV ((uint16_t)0x1000) /* 0001 0000 0000 0000: No-convert type */
|
|
#define VW_PATH_TYPE_FLAG_ALARG ((uint16_t)0x0800) /* 0000 1000 0000 0000: Require argument */
|
|
#define VW_PATH_TYPE_FLAG_REQUIRED ((uint16_t)0x0400) /* 0000 0100 0000 0000: Always required */
|
|
#define VW_PATH_TYPE_FLAG_VALIDATE_ONLY \
|
|
((uint16_t)0x0200) /* 0000 0010 0000 0000: Validate-only type */
|
|
#define VW_PATH_TYPE_FLAG_NODEFAULT \
|
|
((uint16_t)0x0100) /* 0000 0001 0000 0000: Disable default values */
|
|
#define VW_PATH_TYPE_FLAG_STRIP_SPACES_ARG \
|
|
((uint16_t)0x0080) /* 0000 0000 1000 0000: Enable space stripping in \
|
|
arguments */
|
|
#define VW_PATH_TYPE_FLAG_LOWERCASE_ARG \
|
|
((uint16_t)0x0040) /* 0000 0000 0100 0000: Enable lowercase in arguments \
|
|
*/
|
|
#define VW_PATH_TYPE_FLAG_STRIP_SPACES_VALUE \
|
|
((uint16_t)0x0040) /* 0000 0000 0010 0000: Enable space stripping in \
|
|
values */
|
|
#define VW_PATH_TYPE_FLAG_LOWERCASE_VALUE \
|
|
((uint16_t)0x0020) /* 0000 0000 0001 0000: Enable lowercase in values */
|
|
#define VW_PATH_TYPE_FLAG_ALCOMP ((uint16_t)0x0010) /* 0000 0000 0000 1000: Always compile */
|
|
#define VW_PATH_TYPE_FLAG_NOARG ((uint16_t)0x0008) /* 0000 0000 0000 0100: No argument */
|
|
|
|
#define vw__VW_PATH_TYPE_FLAG_BUILTIN_CAUTION \
|
|
((uint16_t)0x0001) /* 0000 0000 0000 0001: Built-in type (NOTE: Use with \
|
|
caution) */
|
|
|
|
/* <type[!][(arg)][:key][(?[=default]]> */
|
|
|
|
typedef struct {
|
|
char *key;
|
|
size_t key_len;
|
|
|
|
char *def; /* NOTE: Either actual default or static part */
|
|
size_t def_len;
|
|
void *def_conv;
|
|
size_t def_reqb;
|
|
bool always_insert;
|
|
|
|
uint8_t flags; /* !, ?, and static tokens are flags */
|
|
vs_HMapID type;
|
|
|
|
void *compiled;
|
|
} vw_PathSegment;
|
|
|
|
typedef struct {
|
|
const char *src;
|
|
const size_t len;
|
|
const vw_PathSegment *seg;
|
|
const bool full;
|
|
} vw_PathSource;
|
|
|
|
typedef struct {
|
|
const char *src;
|
|
const size_t len;
|
|
} vw_ArgSource;
|
|
|
|
typedef bool (*vw_PathTypeCompileFunc)(const vw_ArgSource *arg, void **comp);
|
|
typedef bool (*vw_PathTypeConsumeFunc)(const vw_PathSource *src, size_t *size, size_t *reqb);
|
|
typedef bool (*vw_PathTypeConvertFunc)(const vw_PathSource *src, size_t reqb, void *out);
|
|
typedef bool (*vw_PathTypeCleanupFunc)(void *comp);
|
|
typedef bool (*vw_PathTypePrintFunc)(const void *comp);
|
|
|
|
/*
|
|
* Flow:
|
|
*
|
|
* 1. compile() - called once to compile `arg` into memory to be used in other
|
|
* functions. Useful to compile for example regex for optimization.
|
|
* NOTE: Only called once during path compilation.
|
|
* 2. consume() - find the length of a valid matching segment. Returns false on
|
|
* no match< filling in `reqb` for required object memory in bytes and `size` to
|
|
* describe how large the matched segment is. `src` includes: src (from where to
|
|
* begin parsing), len (how many bytes max to parse), compiled (see compile()).
|
|
* NOTE: Might also get called during compilation to check default values.
|
|
* 3. convert() - convert consumed string into a native type.
|
|
* NOTE: convert() won't always get called (noconv)
|
|
* 4. cleanup() - clean up any memory allocated by compile().
|
|
* NOTE: Only called once during cleanup.
|
|
* 5. print() - called only for debug purposes to print compiled stuff.
|
|
*
|
|
* You don't need to do NULL checks.
|
|
*/
|
|
typedef struct {
|
|
uint16_t flags;
|
|
|
|
vw_PathTypeCompileFunc compile;
|
|
vw_PathTypeConsumeFunc consume;
|
|
vw_PathTypeConvertFunc convert;
|
|
vw_PathTypeCleanupFunc cleanup;
|
|
vw_PathTypePrintFunc print;
|
|
} vw_PathType;
|
|
|
|
typedef struct {
|
|
vw_PathSegment **items;
|
|
size_t size;
|
|
size_t cap;
|
|
} vw_PathPattern;
|
|
|
|
typedef struct {
|
|
char *str;
|
|
size_t size;
|
|
|
|
void *conv;
|
|
size_t reqb;
|
|
} vw_PathMatch;
|
|
|
|
vw_PathPattern *vw_PathPattern_new(void);
|
|
vw_PathSegment *vw_PathSegment_new(void);
|
|
|
|
bool vw_PathType_new(const char *name,
|
|
uint16_t flags,
|
|
vw_PathTypeCompileFunc compile,
|
|
vw_PathTypeConsumeFunc consume,
|
|
vw_PathTypeConvertFunc convert,
|
|
vw_PathTypeCleanupFunc cleanup,
|
|
vw_PathTypePrintFunc print);
|
|
|
|
vw_PathPattern *vw_PathPattern_compile(const vs_Logger *lg, const char *pat);
|
|
|
|
size_t vw_PathPattern_matchn(const vw_PathPattern *pat, vs_HMap *out, const char *src, size_t len);
|
|
|
|
bool vw_PathPattern_print(const vw_PathPattern *pat, bool show_static_bounds);
|
|
bool vw_PathPattern_destroy(vw_PathPattern *pat);
|
|
|
|
bool vw_PathPattern_matchn_destroy(vs_HMap *out);
|
|
bool vw_PathPattern_matchn_clear(vs_HMap *out);
|
|
|
|
void vw_PathPattern_matchn_print(const vs_HMap *out);
|
|
|
|
#endif /* VESSEL_WEB_PATH_H_ */
|