1a74702c6SGeorge Wang/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc. See LICENSE. */ 25392f7a3SLiteSpeed Tech#ifndef LSQUIC_VARINT_H 35392f7a3SLiteSpeed Tech#define LSQUIC_VARINT_H 1 45392f7a3SLiteSpeed Tech 55392f7a3SLiteSpeed Tech#define VINT_MASK ((1 << 6) - 1) 65392f7a3SLiteSpeed Tech 75392f7a3SLiteSpeed Tech/* See [draft-ietf-quic-transport-11], section-7.1 */ 85392f7a3SLiteSpeed Tech#define vint_val2bits(val) ( \ 9bc520ef7SDmitri Tikhonov ((val) >= (1 << 6)) + ((val) >= (1 << 14)) + ((val) >= (1 << 30))) 105392f7a3SLiteSpeed Tech 115392f7a3SLiteSpeed Tech#define vint_size(val) (1u << vint_val2bits(val)) 125392f7a3SLiteSpeed Tech 135392f7a3SLiteSpeed Tech#define VINT_MAX_VALUE ((1ull << 62) - 1) 145392f7a3SLiteSpeed Tech 155392f7a3SLiteSpeed Tech/* Map 165392f7a3SLiteSpeed Tech * 0 -> 6 175392f7a3SLiteSpeed Tech * 1 -> 14 185392f7a3SLiteSpeed Tech * 2 -> 30 195392f7a3SLiteSpeed Tech * 3 -> 62 205392f7a3SLiteSpeed Tech */ 215392f7a3SLiteSpeed Tech#define vint_bits2shift(bits) ((1 << (3 + (bits))) - 2) 225392f7a3SLiteSpeed Tech 235392f7a3SLiteSpeed Tech#define VINT_MAX_B(bits_) ((1ull << (vint_bits2shift(bits_))) - 1) 245392f7a3SLiteSpeed Tech 255392f7a3SLiteSpeed Tech/* Maximum value that can be encoded as one byte: */ 265392f7a3SLiteSpeed Tech#define VINT_MAX_ONE_BYTE VINT_MAX_B(0) 275392f7a3SLiteSpeed Tech 285392f7a3SLiteSpeed Techint 295392f7a3SLiteSpeed Techlsquic_varint_read (const unsigned char *p, const unsigned char *end, 305392f7a3SLiteSpeed Tech uint64_t *valp); 315392f7a3SLiteSpeed Tech 325392f7a3SLiteSpeed Tech#define vint_read lsquic_varint_read 335392f7a3SLiteSpeed Tech 345392f7a3SLiteSpeed Techstruct varint_read_state 355392f7a3SLiteSpeed Tech{ 365392f7a3SLiteSpeed Tech uint64_t val; 375392f7a3SLiteSpeed Tech int pos; 385392f7a3SLiteSpeed Tech}; 395392f7a3SLiteSpeed Tech 405392f7a3SLiteSpeed Techint 415392f7a3SLiteSpeed Techlsquic_varint_read_nb (const unsigned char **p, const unsigned char *end, 425392f7a3SLiteSpeed Tech struct varint_read_state *); 435392f7a3SLiteSpeed Tech 445392f7a3SLiteSpeed Techstruct varint_read2_state 455392f7a3SLiteSpeed Tech{ 465392f7a3SLiteSpeed Tech uint64_t vr2s_one; 475392f7a3SLiteSpeed Tech struct varint_read_state vr2s_varint_state; 485392f7a3SLiteSpeed Tech#define vr2s_two vr2s_varint_state.val 495392f7a3SLiteSpeed Tech enum { 505392f7a3SLiteSpeed Tech VR2S_READ_ONE_BEGIN = 0, 515392f7a3SLiteSpeed Tech VR2S_READ_ONE_CONTINUE, 525392f7a3SLiteSpeed Tech VR2S_READ_TWO_BEGIN, 535392f7a3SLiteSpeed Tech VR2S_READ_TWO_CONTINUE, 545392f7a3SLiteSpeed Tech } vr2s_state; 555392f7a3SLiteSpeed Tech}; 565392f7a3SLiteSpeed Tech 575392f7a3SLiteSpeed Tech/* When first called, vr2s_state must be set to 0. 585392f7a3SLiteSpeed Tech * 595392f7a3SLiteSpeed Tech * Returns 0 when both varint values have been read. They are available 605392f7a3SLiteSpeed Tech * in vr2s_one and vr2s_two. 615392f7a3SLiteSpeed Tech * 625392f7a3SLiteSpeed Tech * Returns -1 when more input is needed. 635392f7a3SLiteSpeed Tech */ 645392f7a3SLiteSpeed Techint 655392f7a3SLiteSpeed Techlsquic_varint_read_two (const unsigned char **p, const unsigned char *end, 665392f7a3SLiteSpeed Tech struct varint_read2_state *); 675392f7a3SLiteSpeed Tech 685392f7a3SLiteSpeed Tech#if __BYTE_ORDER == __LITTLE_ENDIAN 695392f7a3SLiteSpeed Tech#define vint_write(dst, val, bits, len) do { \ 705392f7a3SLiteSpeed Tech uint64_t buf_ = (val) \ 715392f7a3SLiteSpeed Tech | (uint64_t) (bits) << vint_bits2shift(bits); \ 725392f7a3SLiteSpeed Tech buf_ = bswap_64(buf_); \ 735392f7a3SLiteSpeed Tech memcpy(dst, (unsigned char *) &buf_ + 8 - (len), (len)); \ 745392f7a3SLiteSpeed Tech} while (0) 755392f7a3SLiteSpeed Tech#else 765392f7a3SLiteSpeed Tech#define vint_write(dst, val, bits, len) do { \ 775392f7a3SLiteSpeed Tech uint64_t buf_ = (val) \ 785392f7a3SLiteSpeed Tech | (uint64_t) (bits) << vint_bits2shift(bits); \ 795392f7a3SLiteSpeed Tech memcpy(dst, (unsigned char *) &buf_ + 8 - (len), (len)); \ 805392f7a3SLiteSpeed Tech} while (0) 815392f7a3SLiteSpeed Tech#endif 825392f7a3SLiteSpeed Tech 835392f7a3SLiteSpeed Tech#endif 84