1600751b9SDmitri Tikhonov#ifndef LSXPACK_HEADER_H_v206 2600751b9SDmitri Tikhonov#define LSXPACK_HEADER_H_v206 3226eedebSDmitri Tikhonov 4226eedebSDmitri Tikhonov#ifdef __cplusplus 5226eedebSDmitri Tikhonovextern "C" { 6226eedebSDmitri Tikhonov#endif 7226eedebSDmitri Tikhonov 8226eedebSDmitri Tikhonov#include <assert.h> 9226eedebSDmitri Tikhonov#include <stdint.h> 10226eedebSDmitri Tikhonov#include <string.h> 11226eedebSDmitri Tikhonov 12226eedebSDmitri Tikhonov#ifndef LSXPACK_MAX_STRLEN 13226eedebSDmitri Tikhonov#define LSXPACK_MAX_STRLEN UINT16_MAX 14226eedebSDmitri Tikhonov#endif 15226eedebSDmitri Tikhonov 16226eedebSDmitri Tikhonov#if LSXPACK_MAX_STRLEN == UINT16_MAX 17226eedebSDmitri Tikhonovtypedef uint16_t lsxpack_strlen_t; 18226eedebSDmitri Tikhonov#elif LSXPACK_MAX_STRLEN == UINT32_MAX 19226eedebSDmitri Tikhonovtypedef uint32_t lsxpack_strlen_t; 20226eedebSDmitri Tikhonov#else 21226eedebSDmitri Tikhonov#error unexpected LSXPACK_MAX_STRLEN 22226eedebSDmitri Tikhonov#endif 23226eedebSDmitri Tikhonov 24d3fda3e7SGeorge Wang#define LSXPACK_DEL ((char *)NULL) 25d3fda3e7SGeorge Wang 26226eedebSDmitri Tikhonovenum lsxpack_flag 27226eedebSDmitri Tikhonov{ 28600751b9SDmitri Tikhonov LSXPACK_HPACK_VAL_MATCHED = 1, 29226eedebSDmitri Tikhonov LSXPACK_QPACK_IDX = 2, 30226eedebSDmitri Tikhonov LSXPACK_APP_IDX = 4, 31226eedebSDmitri Tikhonov LSXPACK_NAME_HASH = 8, 32226eedebSDmitri Tikhonov LSXPACK_NAMEVAL_HASH = 16, 33226eedebSDmitri Tikhonov LSXPACK_VAL_MATCHED = 32, 34226eedebSDmitri Tikhonov LSXPACK_NEVER_INDEX = 64, 35226eedebSDmitri Tikhonov}; 36226eedebSDmitri Tikhonov 37226eedebSDmitri Tikhonov/** 38226eedebSDmitri Tikhonov * When header are decoded, it should be stored to @buf starting from @name_offset, 39226eedebSDmitri Tikhonov * <name>: <value>\r\n 40226eedebSDmitri Tikhonov * So, it can be used directly as HTTP/1.1 header. there are 4 extra characters 41226eedebSDmitri Tikhonov * added. 42226eedebSDmitri Tikhonov * 43226eedebSDmitri Tikhonov * limitation: we currently does not support total header size > 64KB. 44226eedebSDmitri Tikhonov */ 45226eedebSDmitri Tikhonov 46226eedebSDmitri Tikhonovstruct lsxpack_header 47226eedebSDmitri Tikhonov{ 48226eedebSDmitri Tikhonov char *buf; /* the buffer for headers */ 49226eedebSDmitri Tikhonov uint32_t name_hash; /* hash value for name */ 50226eedebSDmitri Tikhonov uint32_t nameval_hash; /* hash value for name + value */ 51226eedebSDmitri Tikhonov lsxpack_strlen_t name_offset; /* the offset for name in the buffer */ 52226eedebSDmitri Tikhonov lsxpack_strlen_t name_len; /* the length of name */ 53226eedebSDmitri Tikhonov lsxpack_strlen_t val_offset; /* the offset for value in the buffer */ 54226eedebSDmitri Tikhonov lsxpack_strlen_t val_len; /* the length of value */ 55d3fda3e7SGeorge Wang uint16_t chain_next_idx; /* mainly for cookie value chain */ 56226eedebSDmitri Tikhonov uint8_t hpack_index; /* HPACK static table index */ 57226eedebSDmitri Tikhonov uint8_t qpack_index; /* QPACK static table index */ 58226eedebSDmitri Tikhonov uint8_t app_index; /* APP header index */ 59226eedebSDmitri Tikhonov enum lsxpack_flag flags:8; /* combination of lsxpack_flag */ 60226eedebSDmitri Tikhonov uint8_t indexed_type; /* control to disable index or not */ 61226eedebSDmitri Tikhonov uint8_t dec_overhead; /* num of extra bytes written to decoded buffer */ 62226eedebSDmitri Tikhonov}; 63226eedebSDmitri Tikhonov 64226eedebSDmitri Tikhonovtypedef struct lsxpack_header lsxpack_header_t; 65226eedebSDmitri Tikhonov 66226eedebSDmitri Tikhonov 67226eedebSDmitri Tikhonovstatic inline void 68226eedebSDmitri Tikhonovlsxpack_header_set_idx(lsxpack_header_t *hdr, int hpack_idx, 69226eedebSDmitri Tikhonov const char *val, size_t val_len) 70226eedebSDmitri Tikhonov{ 71226eedebSDmitri Tikhonov memset(hdr, 0, sizeof(*hdr)); 72226eedebSDmitri Tikhonov hdr->buf = (char *)val; 73226eedebSDmitri Tikhonov hdr->hpack_index = hpack_idx; 74226eedebSDmitri Tikhonov assert(hpack_idx != 0); 75226eedebSDmitri Tikhonov assert(val_len <= LSXPACK_MAX_STRLEN); 76226eedebSDmitri Tikhonov hdr->val_len = val_len; 77226eedebSDmitri Tikhonov} 78226eedebSDmitri Tikhonov 79226eedebSDmitri Tikhonov 80226eedebSDmitri Tikhonovstatic inline void 81d3fda3e7SGeorge Wanglsxpack_header_set_qpack_idx(lsxpack_header_t *hdr, int qpack_idx, 82d3fda3e7SGeorge Wang const char *val, size_t val_len) 83d3fda3e7SGeorge Wang{ 84d3fda3e7SGeorge Wang memset(hdr, 0, sizeof(*hdr)); 85d3fda3e7SGeorge Wang hdr->buf = (char *)val; 86d3fda3e7SGeorge Wang hdr->qpack_index = qpack_idx; 87d3fda3e7SGeorge Wang assert(qpack_idx != -1); 88d3fda3e7SGeorge Wang hdr->flags = LSXPACK_QPACK_IDX; 89d3fda3e7SGeorge Wang assert(val_len <= LSXPACK_MAX_STRLEN); 90d3fda3e7SGeorge Wang hdr->val_len = val_len; 91d3fda3e7SGeorge Wang} 92d3fda3e7SGeorge Wang 93d3fda3e7SGeorge Wang 94d3fda3e7SGeorge Wangstatic inline void 95226eedebSDmitri Tikhonovlsxpack_header_set_offset(lsxpack_header_t *hdr, const char *buf, 96226eedebSDmitri Tikhonov size_t name_offset, size_t name_len, 97226eedebSDmitri Tikhonov size_t val_len) 98226eedebSDmitri Tikhonov{ 99226eedebSDmitri Tikhonov memset(hdr, 0, sizeof(*hdr)); 100226eedebSDmitri Tikhonov hdr->buf = (char *)buf; 101226eedebSDmitri Tikhonov hdr->name_offset = name_offset; 102226eedebSDmitri Tikhonov assert(name_len <= LSXPACK_MAX_STRLEN); 103226eedebSDmitri Tikhonov hdr->name_len = name_len; 104226eedebSDmitri Tikhonov assert(name_offset + name_len + 2 <= LSXPACK_MAX_STRLEN); 105226eedebSDmitri Tikhonov hdr->val_offset = name_offset + name_len + 2; 106226eedebSDmitri Tikhonov assert(val_len <= LSXPACK_MAX_STRLEN); 107226eedebSDmitri Tikhonov hdr->val_len = val_len; 108226eedebSDmitri Tikhonov} 109226eedebSDmitri Tikhonov 110226eedebSDmitri Tikhonov 111226eedebSDmitri Tikhonovstatic inline void 112226eedebSDmitri Tikhonovlsxpack_header_set_offset2(lsxpack_header_t *hdr, const char *buf, 113226eedebSDmitri Tikhonov size_t name_offset, size_t name_len, 114226eedebSDmitri Tikhonov size_t val_offset, size_t val_len) 115226eedebSDmitri Tikhonov{ 116226eedebSDmitri Tikhonov memset(hdr, 0, sizeof(*hdr)); 117226eedebSDmitri Tikhonov hdr->buf = (char *)buf; 118226eedebSDmitri Tikhonov hdr->name_offset = name_offset; 119226eedebSDmitri Tikhonov assert(name_len <= LSXPACK_MAX_STRLEN); 120226eedebSDmitri Tikhonov hdr->name_len = name_len; 121226eedebSDmitri Tikhonov assert(val_offset <= LSXPACK_MAX_STRLEN); 122226eedebSDmitri Tikhonov hdr->val_offset = val_offset; 123226eedebSDmitri Tikhonov assert(val_len <= LSXPACK_MAX_STRLEN); 124226eedebSDmitri Tikhonov hdr->val_len = val_len; 125226eedebSDmitri Tikhonov} 126226eedebSDmitri Tikhonov 127226eedebSDmitri Tikhonov 128226eedebSDmitri Tikhonovstatic inline void 129226eedebSDmitri Tikhonovlsxpack_header_prepare_decode(lsxpack_header_t *hdr, 130226eedebSDmitri Tikhonov char *out, size_t offset, size_t len) 131226eedebSDmitri Tikhonov{ 132226eedebSDmitri Tikhonov memset(hdr, 0, sizeof(*hdr)); 133226eedebSDmitri Tikhonov hdr->buf = out; 134226eedebSDmitri Tikhonov assert(offset <= LSXPACK_MAX_STRLEN); 135226eedebSDmitri Tikhonov hdr->name_offset = offset; 136226eedebSDmitri Tikhonov if (len > LSXPACK_MAX_STRLEN) 137226eedebSDmitri Tikhonov hdr->val_len = LSXPACK_MAX_STRLEN; 138226eedebSDmitri Tikhonov else 139226eedebSDmitri Tikhonov hdr->val_len = len; 140226eedebSDmitri Tikhonov} 141226eedebSDmitri Tikhonov 142226eedebSDmitri Tikhonov 143226eedebSDmitri Tikhonovstatic inline const char * 144226eedebSDmitri Tikhonovlsxpack_header_get_name(const lsxpack_header_t *hdr) 145226eedebSDmitri Tikhonov{ 146600751b9SDmitri Tikhonov return (hdr->name_len)? hdr->buf + hdr->name_offset : NULL; 147226eedebSDmitri Tikhonov} 148226eedebSDmitri Tikhonov 149226eedebSDmitri Tikhonov 150226eedebSDmitri Tikhonovstatic inline const char * 151226eedebSDmitri Tikhonovlsxpack_header_get_value(const lsxpack_header_t *hdr) 152226eedebSDmitri Tikhonov{ return hdr->buf + hdr->val_offset; } 153226eedebSDmitri Tikhonov 154226eedebSDmitri Tikhonovstatic inline size_t 155226eedebSDmitri Tikhonovlsxpack_header_get_dec_size(const lsxpack_header_t *hdr) 156226eedebSDmitri Tikhonov{ return hdr->name_len + hdr->val_len + hdr->dec_overhead; } 157226eedebSDmitri Tikhonov 15892ff7cc6SGeorge Wangstatic inline void 15992ff7cc6SGeorge Wanglsxpack_header_mark_val_changed(lsxpack_header_t *hdr) 16092ff7cc6SGeorge Wang{ 16192ff7cc6SGeorge Wang hdr->flags = (enum lsxpack_flag)(hdr->flags & 162600751b9SDmitri Tikhonov ~(LSXPACK_HPACK_VAL_MATCHED|LSXPACK_VAL_MATCHED|LSXPACK_NAMEVAL_HASH)); 16392ff7cc6SGeorge Wang} 164226eedebSDmitri Tikhonov#ifdef __cplusplus 165226eedebSDmitri Tikhonov} 166226eedebSDmitri Tikhonov#endif 167226eedebSDmitri Tikhonov 168600751b9SDmitri Tikhonov#endif //LSXPACK_HEADER_H_v206 169