19e982dfdSDmitri Tikhonov#ifndef LSXPACK_HEADER_H_v206
29e982dfdSDmitri Tikhonov#define LSXPACK_HEADER_H_v206
360620859SDmitri Tikhonov
460620859SDmitri Tikhonov#ifdef __cplusplus
560620859SDmitri Tikhonovextern "C" {
660620859SDmitri Tikhonov#endif
760620859SDmitri Tikhonov
860620859SDmitri Tikhonov#include <assert.h>
960620859SDmitri Tikhonov#include <stdint.h>
1060620859SDmitri Tikhonov#include <string.h>
1160620859SDmitri Tikhonov
1260620859SDmitri Tikhonov#ifndef LSXPACK_MAX_STRLEN
1360620859SDmitri Tikhonov#define LSXPACK_MAX_STRLEN UINT16_MAX
1460620859SDmitri Tikhonov#endif
1560620859SDmitri Tikhonov
1660620859SDmitri Tikhonov#if LSXPACK_MAX_STRLEN == UINT16_MAX
1760620859SDmitri Tikhonovtypedef uint16_t lsxpack_strlen_t;
1860620859SDmitri Tikhonov#elif LSXPACK_MAX_STRLEN == UINT32_MAX
1960620859SDmitri Tikhonovtypedef uint32_t lsxpack_strlen_t;
2060620859SDmitri Tikhonov#else
2160620859SDmitri Tikhonov#error unexpected LSXPACK_MAX_STRLEN
2260620859SDmitri Tikhonov#endif
2360620859SDmitri Tikhonov
2460620859SDmitri Tikhonov#define LSXPACK_DEL  ((char *)NULL)
2560620859SDmitri Tikhonov
2660620859SDmitri Tikhonovenum lsxpack_flag
2760620859SDmitri Tikhonov{
289e982dfdSDmitri Tikhonov    LSXPACK_HPACK_VAL_MATCHED = 1,
2960620859SDmitri Tikhonov    LSXPACK_QPACK_IDX = 2,
3060620859SDmitri Tikhonov    LSXPACK_APP_IDX   = 4,
3160620859SDmitri Tikhonov    LSXPACK_NAME_HASH = 8,
3260620859SDmitri Tikhonov    LSXPACK_NAMEVAL_HASH = 16,
3360620859SDmitri Tikhonov    LSXPACK_VAL_MATCHED = 32,
3460620859SDmitri Tikhonov    LSXPACK_NEVER_INDEX = 64,
3560620859SDmitri Tikhonov};
3660620859SDmitri Tikhonov
3760620859SDmitri Tikhonov/**
3860620859SDmitri Tikhonov * When header are decoded, it should be stored to @buf starting from @name_offset,
3960620859SDmitri Tikhonov *    <name>: <value>\r\n
4060620859SDmitri Tikhonov * So, it can be used directly as HTTP/1.1 header. there are 4 extra characters
4160620859SDmitri Tikhonov * added.
4260620859SDmitri Tikhonov *
4360620859SDmitri Tikhonov * limitation: we currently does not support total header size > 64KB.
4460620859SDmitri Tikhonov */
4560620859SDmitri Tikhonov
4660620859SDmitri Tikhonovstruct lsxpack_header
4760620859SDmitri Tikhonov{
4860620859SDmitri Tikhonov    char             *buf;          /* the buffer for headers */
4960620859SDmitri Tikhonov    uint32_t          name_hash;    /* hash value for name */
5060620859SDmitri Tikhonov    uint32_t          nameval_hash; /* hash value for name + value */
5160620859SDmitri Tikhonov    lsxpack_strlen_t  name_offset;  /* the offset for name in the buffer */
5260620859SDmitri Tikhonov    lsxpack_strlen_t  name_len;     /* the length of name */
5360620859SDmitri Tikhonov    lsxpack_strlen_t  val_offset;   /* the offset for value in the buffer */
5460620859SDmitri Tikhonov    lsxpack_strlen_t  val_len;      /* the length of value */
5560620859SDmitri Tikhonov    uint16_t          chain_next_idx; /* mainly for cookie value chain */
5660620859SDmitri Tikhonov    uint8_t           hpack_index;  /* HPACK static table index */
5760620859SDmitri Tikhonov    uint8_t           qpack_index;  /* QPACK static table index */
5860620859SDmitri Tikhonov    uint8_t           app_index;    /* APP header index */
5960620859SDmitri Tikhonov    enum lsxpack_flag flags:8;      /* combination of lsxpack_flag */
6060620859SDmitri Tikhonov    uint8_t           indexed_type; /* control to disable index or not */
6160620859SDmitri Tikhonov    uint8_t           dec_overhead; /* num of extra bytes written to decoded buffer */
6260620859SDmitri Tikhonov};
6360620859SDmitri Tikhonov
6460620859SDmitri Tikhonovtypedef struct lsxpack_header lsxpack_header_t;
6560620859SDmitri Tikhonov
6660620859SDmitri Tikhonov
6760620859SDmitri Tikhonovstatic inline void
6860620859SDmitri Tikhonovlsxpack_header_set_idx(lsxpack_header_t *hdr, int hpack_idx,
6960620859SDmitri Tikhonov                       const char *val, size_t val_len)
7060620859SDmitri Tikhonov{
7160620859SDmitri Tikhonov    memset(hdr, 0, sizeof(*hdr));
7260620859SDmitri Tikhonov    hdr->buf = (char *)val;
7360620859SDmitri Tikhonov    hdr->hpack_index = hpack_idx;
7460620859SDmitri Tikhonov    assert(hpack_idx != 0);
7560620859SDmitri Tikhonov    assert(val_len <= LSXPACK_MAX_STRLEN);
7660620859SDmitri Tikhonov    hdr->val_len = val_len;
7760620859SDmitri Tikhonov}
7860620859SDmitri Tikhonov
7960620859SDmitri Tikhonov
8060620859SDmitri Tikhonovstatic inline void
8160620859SDmitri Tikhonovlsxpack_header_set_qpack_idx(lsxpack_header_t *hdr, int qpack_idx,
8260620859SDmitri Tikhonov                       const char *val, size_t val_len)
8360620859SDmitri Tikhonov{
8460620859SDmitri Tikhonov    memset(hdr, 0, sizeof(*hdr));
8560620859SDmitri Tikhonov    hdr->buf = (char *)val;
8660620859SDmitri Tikhonov    hdr->qpack_index = qpack_idx;
8760620859SDmitri Tikhonov    assert(qpack_idx != -1);
8860620859SDmitri Tikhonov    hdr->flags = LSXPACK_QPACK_IDX;
8960620859SDmitri Tikhonov    assert(val_len <= LSXPACK_MAX_STRLEN);
9060620859SDmitri Tikhonov    hdr->val_len = val_len;
9160620859SDmitri Tikhonov}
9260620859SDmitri Tikhonov
9360620859SDmitri Tikhonov
9460620859SDmitri Tikhonovstatic inline void
9560620859SDmitri Tikhonovlsxpack_header_set_offset(lsxpack_header_t *hdr, const char *buf,
9660620859SDmitri Tikhonov                          size_t name_offset, size_t name_len,
9760620859SDmitri Tikhonov                          size_t val_len)
9860620859SDmitri Tikhonov{
9960620859SDmitri Tikhonov    memset(hdr, 0, sizeof(*hdr));
10060620859SDmitri Tikhonov    hdr->buf = (char *)buf;
10160620859SDmitri Tikhonov    hdr->name_offset = name_offset;
10260620859SDmitri Tikhonov    assert(name_len <= LSXPACK_MAX_STRLEN);
10360620859SDmitri Tikhonov    hdr->name_len = name_len;
10460620859SDmitri Tikhonov    assert(name_offset + name_len + 2 <= LSXPACK_MAX_STRLEN);
10560620859SDmitri Tikhonov    hdr->val_offset = name_offset + name_len + 2;
10660620859SDmitri Tikhonov    assert(val_len <= LSXPACK_MAX_STRLEN);
10760620859SDmitri Tikhonov    hdr->val_len = val_len;
10860620859SDmitri Tikhonov}
10960620859SDmitri Tikhonov
11060620859SDmitri Tikhonov
11160620859SDmitri Tikhonovstatic inline void
11260620859SDmitri Tikhonovlsxpack_header_set_offset2(lsxpack_header_t *hdr, const char *buf,
11360620859SDmitri Tikhonov                           size_t name_offset, size_t name_len,
11460620859SDmitri Tikhonov                           size_t val_offset, size_t val_len)
11560620859SDmitri Tikhonov{
11660620859SDmitri Tikhonov    memset(hdr, 0, sizeof(*hdr));
11760620859SDmitri Tikhonov    hdr->buf = (char *)buf;
11860620859SDmitri Tikhonov    hdr->name_offset = name_offset;
11960620859SDmitri Tikhonov    assert(name_len <= LSXPACK_MAX_STRLEN);
12060620859SDmitri Tikhonov    hdr->name_len = name_len;
12160620859SDmitri Tikhonov    assert(val_offset <= LSXPACK_MAX_STRLEN);
12260620859SDmitri Tikhonov    hdr->val_offset = val_offset;
12360620859SDmitri Tikhonov    assert(val_len <= LSXPACK_MAX_STRLEN);
12460620859SDmitri Tikhonov    hdr->val_len = val_len;
12560620859SDmitri Tikhonov}
12660620859SDmitri Tikhonov
12760620859SDmitri Tikhonov
12860620859SDmitri Tikhonovstatic inline void
12960620859SDmitri Tikhonovlsxpack_header_prepare_decode(lsxpack_header_t *hdr,
13060620859SDmitri Tikhonov                              char *out, size_t offset, size_t len)
13160620859SDmitri Tikhonov{
13260620859SDmitri Tikhonov    memset(hdr, 0, sizeof(*hdr));
13360620859SDmitri Tikhonov    hdr->buf = out;
13460620859SDmitri Tikhonov    assert(offset <= LSXPACK_MAX_STRLEN);
13560620859SDmitri Tikhonov    hdr->name_offset = offset;
13660620859SDmitri Tikhonov    if (len > LSXPACK_MAX_STRLEN)
13760620859SDmitri Tikhonov        hdr->val_len = LSXPACK_MAX_STRLEN;
13860620859SDmitri Tikhonov    else
13960620859SDmitri Tikhonov        hdr->val_len = len;
14060620859SDmitri Tikhonov}
14160620859SDmitri Tikhonov
14260620859SDmitri Tikhonov
14360620859SDmitri Tikhonovstatic inline const char *
14460620859SDmitri Tikhonovlsxpack_header_get_name(const lsxpack_header_t *hdr)
14560620859SDmitri Tikhonov{
1469e982dfdSDmitri Tikhonov    return (hdr->name_len)? hdr->buf + hdr->name_offset : NULL;
14760620859SDmitri Tikhonov}
14860620859SDmitri Tikhonov
14960620859SDmitri Tikhonov
15060620859SDmitri Tikhonovstatic inline const char *
15160620859SDmitri Tikhonovlsxpack_header_get_value(const lsxpack_header_t *hdr)
15260620859SDmitri Tikhonov{   return hdr->buf + hdr->val_offset;  }
15360620859SDmitri Tikhonov
15460620859SDmitri Tikhonovstatic inline size_t
15560620859SDmitri Tikhonovlsxpack_header_get_dec_size(const lsxpack_header_t *hdr)
15660620859SDmitri Tikhonov{   return hdr->name_len + hdr->val_len + hdr->dec_overhead;    }
15760620859SDmitri Tikhonov
158b2617913SDmitri Tikhonovstatic inline void
159b2617913SDmitri Tikhonovlsxpack_header_mark_val_changed(lsxpack_header_t *hdr)
160b2617913SDmitri Tikhonov{
161b2617913SDmitri Tikhonov    hdr->flags = (enum lsxpack_flag)(hdr->flags &
1629e982dfdSDmitri Tikhonov       ~(LSXPACK_HPACK_VAL_MATCHED|LSXPACK_VAL_MATCHED|LSXPACK_NAMEVAL_HASH));
163b2617913SDmitri Tikhonov}
16460620859SDmitri Tikhonov#ifdef __cplusplus
16560620859SDmitri Tikhonov}
16660620859SDmitri Tikhonov#endif
16760620859SDmitri Tikhonov
1689e982dfdSDmitri Tikhonov#endif //LSXPACK_HEADER_H_v206
169