mirror of
https://github.com/nodejs/node.git
synced 2026-11-09 15:11:11 -05:00
deps: update nghttp3 to 1.6.0
PR-URL: https://github.com/nodejs/node/pull/56258 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>
This commit is contained in:
1 parent
12806e9697
commit
2a3fc98c4b
54 files changed
+7378
-6870
No files matched your search
+70
-40
@@ -31,11 +31,11 @@
|
||||
libcurl) */
|
||||
#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
|
||||
# define WIN32
|
||||
#endif
|
||||
#endif /* (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif /* defined(__cplusplus) */
|
||||
|
||||
#include <stdlib.h>
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1800)
|
||||
@@ -43,9 +43,9 @@ extern "C" {
|
||||
compliant. See compiler macros and version number in
|
||||
https://sourceforge.net/p/predef/wiki/Compilers/ */
|
||||
# include <stdint.h>
|
||||
#else /* !defined(_MSC_VER) || (_MSC_VER >= 1800) */
|
||||
#else /* !(defined(_MSC_VER) && (_MSC_VER < 1800)) */
|
||||
# include <inttypes.h>
|
||||
#endif /* !defined(_MSC_VER) || (_MSC_VER >= 1800) */
|
||||
#endif /* !(defined(_MSC_VER) && (_MSC_VER < 1800)) */
|
||||
#include <sys/types.h>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
@@ -57,22 +57,22 @@ extern "C" {
|
||||
#elif defined(WIN32)
|
||||
# ifdef BUILDING_NGHTTP3
|
||||
# define NGHTTP3_EXTERN __declspec(dllexport)
|
||||
# else /* !BUILDING_NGHTTP3 */
|
||||
# else /* !defined(BUILDING_NGHTTP3) */
|
||||
# define NGHTTP3_EXTERN __declspec(dllimport)
|
||||
# endif /* !BUILDING_NGHTTP3 */
|
||||
#else /* !defined(WIN32) */
|
||||
# endif /* !defined(BUILDING_NGHTTP3) */
|
||||
#else /* !(defined(NGHTTP3_STATICLIB) || defined(WIN32)) */
|
||||
# ifdef BUILDING_NGHTTP3
|
||||
# define NGHTTP3_EXTERN __attribute__((visibility("default")))
|
||||
# else /* !BUILDING_NGHTTP3 */
|
||||
# else /* !defined(BUILDING_NGHTTP3) */
|
||||
# define NGHTTP3_EXTERN
|
||||
# endif /* !BUILDING_NGHTTP3 */
|
||||
#endif /* !defined(WIN32) */
|
||||
# endif /* !defined(BUILDING_NGHTTP3) */
|
||||
#endif /* !(defined(NGHTTP3_STATICLIB) || defined(WIN32)) */
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# define NGHTTP3_ALIGN(N) __declspec(align(N))
|
||||
#else /* !_MSC_VER */
|
||||
#else /* !defined(_MSC_VER) */
|
||||
# define NGHTTP3_ALIGN(N) __attribute__((aligned(N)))
|
||||
#endif /* !_MSC_VER */
|
||||
#endif /* !defined(_MSC_VER) */
|
||||
|
||||
/**
|
||||
* @typedef
|
||||
@@ -624,7 +624,7 @@ typedef struct nghttp3_buf {
|
||||
*/
|
||||
uint8_t *end;
|
||||
/**
|
||||
* :member:`pos` pointers to the start of data. Typically, this
|
||||
* :member:`pos` points to the start of data. Typically, this
|
||||
* points to the address that next data should be read. Initially,
|
||||
* it points to :member:`begin`.
|
||||
*/
|
||||
@@ -1161,8 +1161,8 @@ NGHTTP3_EXTERN void nghttp3_qpack_encoder_del(nghttp3_qpack_encoder *encoder);
|
||||
* anymore.
|
||||
*/
|
||||
NGHTTP3_EXTERN int nghttp3_qpack_encoder_encode(
|
||||
nghttp3_qpack_encoder *encoder, nghttp3_buf *pbuf, nghttp3_buf *rbuf,
|
||||
nghttp3_buf *ebuf, int64_t stream_id, const nghttp3_nv *nva, size_t nvlen);
|
||||
nghttp3_qpack_encoder *encoder, nghttp3_buf *pbuf, nghttp3_buf *rbuf,
|
||||
nghttp3_buf *ebuf, int64_t stream_id, const nghttp3_nv *nva, size_t nvlen);
|
||||
|
||||
/**
|
||||
* @function
|
||||
@@ -1182,7 +1182,7 @@ NGHTTP3_EXTERN int nghttp3_qpack_encoder_encode(
|
||||
* |encoder| is unable to process input because it is malformed.
|
||||
*/
|
||||
NGHTTP3_EXTERN nghttp3_ssize nghttp3_qpack_encoder_read_decoder(
|
||||
nghttp3_qpack_encoder *encoder, const uint8_t *src, size_t srclen);
|
||||
nghttp3_qpack_encoder *encoder, const uint8_t *src, size_t srclen);
|
||||
|
||||
/**
|
||||
* @function
|
||||
@@ -1343,7 +1343,7 @@ NGHTTP3_EXTERN void nghttp3_qpack_decoder_del(nghttp3_qpack_decoder *decoder);
|
||||
* Could not interpret encoder stream instruction.
|
||||
*/
|
||||
NGHTTP3_EXTERN nghttp3_ssize nghttp3_qpack_decoder_read_encoder(
|
||||
nghttp3_qpack_decoder *decoder, const uint8_t *src, size_t srclen);
|
||||
nghttp3_qpack_decoder *decoder, const uint8_t *src, size_t srclen);
|
||||
|
||||
/**
|
||||
* @function
|
||||
@@ -1436,9 +1436,9 @@ nghttp3_qpack_decoder_get_icnt(const nghttp3_qpack_decoder *decoder);
|
||||
* HTTP field is too large.
|
||||
*/
|
||||
NGHTTP3_EXTERN nghttp3_ssize nghttp3_qpack_decoder_read_request(
|
||||
nghttp3_qpack_decoder *decoder, nghttp3_qpack_stream_context *sctx,
|
||||
nghttp3_qpack_nv *nv, uint8_t *pflags, const uint8_t *src, size_t srclen,
|
||||
int fin);
|
||||
nghttp3_qpack_decoder *decoder, nghttp3_qpack_stream_context *sctx,
|
||||
nghttp3_qpack_nv *nv, uint8_t *pflags, const uint8_t *src, size_t srclen,
|
||||
int fin);
|
||||
|
||||
/**
|
||||
* @function
|
||||
@@ -1568,7 +1568,7 @@ typedef void (*nghttp3_debug_vprintf_callback)(const char *format,
|
||||
* times because this is important.
|
||||
*/
|
||||
NGHTTP3_EXTERN void nghttp3_set_debug_vprintf_callback(
|
||||
nghttp3_debug_vprintf_callback debug_vprintf_callback);
|
||||
nghttp3_debug_vprintf_callback debug_vprintf_callback);
|
||||
|
||||
/**
|
||||
* @macrosection
|
||||
@@ -2118,9 +2118,10 @@ NGHTTP3_EXTERN int nghttp3_conn_bind_qpack_streams(nghttp3_conn *conn,
|
||||
* :macro:`NGHTTP3_ERR_CALLBACK_FAILURE`
|
||||
* User callback failed.
|
||||
*
|
||||
* It may return the other error codes. In general, the negative
|
||||
* error code means that |conn| encountered a connection error, and
|
||||
* the connection should be closed.
|
||||
* It may return the other error codes. The negative error code means
|
||||
* that |conn| encountered a connection error, and the connection must
|
||||
* be closed. Calling nghttp3 API other than `nghttp3_conn_del`
|
||||
* causes undefined behavior.
|
||||
*/
|
||||
NGHTTP3_EXTERN nghttp3_ssize nghttp3_conn_read_stream(nghttp3_conn *conn,
|
||||
int64_t stream_id,
|
||||
@@ -2152,9 +2153,10 @@ NGHTTP3_EXTERN nghttp3_ssize nghttp3_conn_read_stream(nghttp3_conn *conn,
|
||||
* :macro:`NGHTTP3_ERR_CALLBACK_FAILURE`
|
||||
* User callback failed.
|
||||
*
|
||||
* It may return the other error codes. In general, the negative
|
||||
* error code means that |conn| encountered a connection error, and
|
||||
* the connection should be closed.
|
||||
* It may return the other error codes. The negative error code means
|
||||
* that |conn| encountered a connection error, and the connection must
|
||||
* be closed. Calling nghttp3 API other than `nghttp3_conn_del`
|
||||
* causes undefined behavior.
|
||||
*/
|
||||
NGHTTP3_EXTERN nghttp3_ssize nghttp3_conn_writev_stream(nghttp3_conn *conn,
|
||||
int64_t *pstream_id,
|
||||
@@ -2198,6 +2200,9 @@ NGHTTP3_EXTERN int nghttp3_conn_add_write_offset(nghttp3_conn *conn,
|
||||
* If a stream denoted by |stream_id| is not found, this function
|
||||
* returns 0.
|
||||
*
|
||||
* Alternatively, `nghttp3_conn_update_ack_offset` can be used to
|
||||
* accomplish the same thing.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
@@ -2207,6 +2212,31 @@ NGHTTP3_EXTERN int nghttp3_conn_add_write_offset(nghttp3_conn *conn,
|
||||
NGHTTP3_EXTERN int nghttp3_conn_add_ack_offset(nghttp3_conn *conn,
|
||||
int64_t stream_id, uint64_t n);
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
* `nghttp3_conn_update_ack_offset` tells |conn| that QUIC stack has
|
||||
* acknowledged the stream data up to |offset| for a stream denoted by
|
||||
* |stream_id|.
|
||||
*
|
||||
* If a stream denoted by |stream_id| is not found, this function
|
||||
* returns 0.
|
||||
*
|
||||
* Alternatively, `nghttp3_conn_add_ack_offset` can be used to
|
||||
* accomplish the same thing.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* :macro:`NGHTTP3_ERR_INVALID_ARGUMENT`
|
||||
* |offset| is less than the number of bytes acknowledged so far.
|
||||
* :macro:`NGHTTP3_ERR_CALLBACK_FAILURE`
|
||||
* User callback failed.
|
||||
*/
|
||||
NGHTTP3_EXTERN int nghttp3_conn_update_ack_offset(nghttp3_conn *conn,
|
||||
int64_t stream_id,
|
||||
uint64_t offset);
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
@@ -2314,9 +2344,9 @@ NGHTTP3_EXTERN int nghttp3_conn_resume_stream(nghttp3_conn *conn,
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
* `nghttp3_conn_close_stream` closes stream identified by
|
||||
* |stream_id|. QUIC application error code |app_error_code| is the
|
||||
* reason of the closure.
|
||||
* `nghttp3_conn_close_stream` tells the library that a stream
|
||||
* identified by |stream_id| has been closed. QUIC application error
|
||||
* code |app_error_code| is the reason of the closure.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
@@ -2419,8 +2449,8 @@ nghttp3_conn_set_max_concurrent_streams(nghttp3_conn *conn,
|
||||
* stream.
|
||||
*/
|
||||
typedef nghttp3_ssize (*nghttp3_read_data_callback)(
|
||||
nghttp3_conn *conn, int64_t stream_id, nghttp3_vec *vec, size_t veccnt,
|
||||
uint32_t *pflags, void *conn_user_data, void *stream_user_data);
|
||||
nghttp3_conn *conn, int64_t stream_id, nghttp3_vec *vec, size_t veccnt,
|
||||
uint32_t *pflags, void *conn_user_data, void *stream_user_data);
|
||||
|
||||
/**
|
||||
* @struct
|
||||
@@ -2460,8 +2490,8 @@ typedef struct nghttp3_data_reader {
|
||||
* Out of memory.
|
||||
*/
|
||||
NGHTTP3_EXTERN int nghttp3_conn_submit_request(
|
||||
nghttp3_conn *conn, int64_t stream_id, const nghttp3_nv *nva, size_t nvlen,
|
||||
const nghttp3_data_reader *dr, void *stream_user_data);
|
||||
nghttp3_conn *conn, int64_t stream_id, const nghttp3_nv *nva, size_t nvlen,
|
||||
const nghttp3_data_reader *dr, void *stream_user_data);
|
||||
|
||||
/**
|
||||
* @function
|
||||
@@ -2667,7 +2697,7 @@ typedef struct NGHTTP3_ALIGN(8) nghttp3_pri {
|
||||
* Stream not found.
|
||||
*/
|
||||
NGHTTP3_EXTERN int nghttp3_conn_get_stream_priority_versioned(
|
||||
nghttp3_conn *conn, int pri_version, nghttp3_pri *dest, int64_t stream_id);
|
||||
nghttp3_conn *conn, int pri_version, nghttp3_pri *dest, int64_t stream_id);
|
||||
|
||||
/**
|
||||
* @function
|
||||
@@ -2720,8 +2750,8 @@ NGHTTP3_EXTERN int nghttp3_conn_set_client_stream_priority(nghttp3_conn *conn,
|
||||
* Out of memory.
|
||||
*/
|
||||
NGHTTP3_EXTERN int nghttp3_conn_set_server_stream_priority_versioned(
|
||||
nghttp3_conn *conn, int64_t stream_id, int pri_version,
|
||||
const nghttp3_pri *pri);
|
||||
nghttp3_conn *conn, int64_t stream_id, int pri_version,
|
||||
const nghttp3_pri *pri);
|
||||
|
||||
/**
|
||||
* @function
|
||||
@@ -2884,7 +2914,7 @@ NGHTTP3_EXTERN int nghttp3_err_is_fatal(int liberr);
|
||||
*/
|
||||
#define nghttp3_conn_set_server_stream_priority(CONN, STREAM_ID, PRI) \
|
||||
nghttp3_conn_set_server_stream_priority_versioned( \
|
||||
(CONN), (STREAM_ID), NGHTTP3_PRI_VERSION, (PRI))
|
||||
(CONN), (STREAM_ID), NGHTTP3_PRI_VERSION, (PRI))
|
||||
|
||||
/*
|
||||
* `nghttp3_conn_get_stream_priority` is a wrapper around
|
||||
@@ -2906,6 +2936,6 @@ NGHTTP3_EXTERN int nghttp3_err_is_fatal(int liberr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* defined(__cplusplus) */
|
||||
|
||||
#endif /* NGHTTP3_H */
|
||||
#endif /* !defined(NGHTTP3_H) */
|
||||
+3
-3
@@ -31,7 +31,7 @@
|
||||
*
|
||||
* Version number of the nghttp3 library release.
|
||||
*/
|
||||
#define NGHTTP3_VERSION "0.7.0"
|
||||
#define NGHTTP3_VERSION "1.6.0"
|
||||
|
||||
/**
|
||||
* @macro
|
||||
@@ -41,6 +41,6 @@
|
||||
* number, 8 bits for minor and 8 bits for patch. Version 1.2.3
|
||||
* becomes 0x010203.
|
||||
*/
|
||||
#define NGHTTP3_VERSION_NUM 0x000700
|
||||
#define NGHTTP3_VERSION_NUM 0x010600
|
||||
|
||||
#endif /* NGHTTP3_VERSION_H */
|
||||
#endif /* !defined(NGHTTP3_VERSION_H) */
|
||||
+6
-6
@@ -66,8 +66,8 @@ int nghttp3_balloc_get(nghttp3_balloc *balloc, void **pbuf, size_t n) {
|
||||
assert(n <= balloc->blklen);
|
||||
|
||||
if (nghttp3_buf_left(&balloc->buf) < n) {
|
||||
p = nghttp3_mem_malloc(balloc->mem, sizeof(nghttp3_memblock_hd) + 0x10u +
|
||||
balloc->blklen);
|
||||
p = nghttp3_mem_malloc(balloc->mem,
|
||||
sizeof(nghttp3_memblock_hd) + 0x8u + balloc->blklen);
|
||||
if (p == NULL) {
|
||||
return NGHTTP3_ERR_NOMEM;
|
||||
}
|
||||
@@ -76,10 +76,10 @@ int nghttp3_balloc_get(nghttp3_balloc *balloc, void **pbuf, size_t n) {
|
||||
hd->next = balloc->head;
|
||||
balloc->head = hd;
|
||||
nghttp3_buf_wrap_init(
|
||||
&balloc->buf,
|
||||
(uint8_t *)(((uintptr_t)p + sizeof(nghttp3_memblock_hd) + 0xfu) &
|
||||
~(uintptr_t)0xfu),
|
||||
balloc->blklen);
|
||||
&balloc->buf,
|
||||
(uint8_t *)(((uintptr_t)p + sizeof(nghttp3_memblock_hd) + 0xfu) &
|
||||
~(uintptr_t)0xfu),
|
||||
balloc->blklen);
|
||||
}
|
||||
|
||||
assert(((uintptr_t)balloc->buf.last & 0xfu) == 0);
|
||||
|
||||
+6
-3
@@ -28,7 +28,7 @@
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#endif /* defined(HAVE_CONFIG_H) */
|
||||
|
||||
#include <nghttp3/nghttp3.h>
|
||||
|
||||
@@ -40,7 +40,10 @@ typedef struct nghttp3_memblock_hd nghttp3_memblock_hd;
|
||||
* nghttp3_memblock_hd is the header of memory block.
|
||||
*/
|
||||
struct nghttp3_memblock_hd {
|
||||
nghttp3_memblock_hd *next;
|
||||
union {
|
||||
nghttp3_memblock_hd *next;
|
||||
uint64_t pad;
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -89,4 +92,4 @@ int nghttp3_balloc_get(nghttp3_balloc *balloc, void **pbuf, size_t n);
|
||||
*/
|
||||
void nghttp3_balloc_clear(nghttp3_balloc *balloc);
|
||||
|
||||
#endif /* NGHTTP3_BALLOC_H */
|
||||
#endif /* !defined(NGHTTP3_BALLOC_H) */
|
||||
+2
-2
@@ -28,7 +28,7 @@
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#endif /* defined(HAVE_CONFIG_H) */
|
||||
|
||||
#include <nghttp3/nghttp3.h>
|
||||
|
||||
@@ -71,4 +71,4 @@ void nghttp3_typed_buf_init(nghttp3_typed_buf *tbuf, const nghttp3_buf *buf,
|
||||
|
||||
void nghttp3_typed_buf_free(nghttp3_typed_buf *tbuf);
|
||||
|
||||
#endif /* NGHTTP3_BUF_H */
|
||||
#endif /* !defined(NGHTTP3_BUF_H) */
|
||||
+73
-58
@@ -210,9 +210,9 @@ static int conn_call_recv_settings(nghttp3_conn *conn) {
|
||||
static int ricnt_less(const nghttp3_pq_entry *lhsx,
|
||||
const nghttp3_pq_entry *rhsx) {
|
||||
nghttp3_stream *lhs =
|
||||
nghttp3_struct_of(lhsx, nghttp3_stream, qpack_blocked_pe);
|
||||
nghttp3_struct_of(lhsx, nghttp3_stream, qpack_blocked_pe);
|
||||
nghttp3_stream *rhs =
|
||||
nghttp3_struct_of(rhsx, nghttp3_stream, qpack_blocked_pe);
|
||||
nghttp3_struct_of(rhsx, nghttp3_stream, qpack_blocked_pe);
|
||||
|
||||
return lhs->qpack_sctx.ricnt < rhs->qpack_sctx.ricnt;
|
||||
}
|
||||
@@ -250,19 +250,19 @@ static int conn_new(nghttp3_conn **pconn, int server, int callbacks_version,
|
||||
|
||||
nghttp3_objalloc_init(&conn->out_chunk_objalloc,
|
||||
NGHTTP3_STREAM_MIN_CHUNK_SIZE * 16, mem);
|
||||
nghttp3_objalloc_stream_init(&conn->stream_objalloc, 64, mem);
|
||||
nghttp3_objalloc_stream_init(&conn->stream_objalloc, 8, mem);
|
||||
|
||||
nghttp3_map_init(&conn->streams, mem);
|
||||
|
||||
rv = nghttp3_qpack_decoder_init(&conn->qdec,
|
||||
settings->qpack_max_dtable_capacity,
|
||||
settings->qpack_blocked_streams, mem);
|
||||
rv =
|
||||
nghttp3_qpack_decoder_init(&conn->qdec, settings->qpack_max_dtable_capacity,
|
||||
settings->qpack_blocked_streams, mem);
|
||||
if (rv != 0) {
|
||||
goto qdec_init_fail;
|
||||
}
|
||||
|
||||
rv = nghttp3_qpack_encoder_init(
|
||||
&conn->qenc, settings->qpack_encoder_max_dtable_capacity, mem);
|
||||
&conn->qenc, settings->qpack_encoder_max_dtable_capacity, mem);
|
||||
if (rv != 0) {
|
||||
goto qenc_init_fail;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ static int conn_new(nghttp3_conn **pconn, int server, int callbacks_version,
|
||||
nghttp3_pq_init(&conn->sched[i].spq, cycle_less, mem);
|
||||
}
|
||||
|
||||
nghttp3_idtr_init(&conn->remote.bidi.idtr, server, mem);
|
||||
nghttp3_idtr_init(&conn->remote.bidi.idtr, mem);
|
||||
|
||||
conn->callbacks = *callbacks;
|
||||
conn->local.settings = *settings;
|
||||
@@ -368,7 +368,7 @@ void nghttp3_conn_del(nghttp3_conn *conn) {
|
||||
nghttp3_qpack_encoder_free(&conn->qenc);
|
||||
nghttp3_qpack_decoder_free(&conn->qdec);
|
||||
|
||||
nghttp3_map_each_free(&conn->streams, free_stream, NULL);
|
||||
nghttp3_map_each(&conn->streams, free_stream, NULL);
|
||||
nghttp3_map_free(&conn->streams);
|
||||
|
||||
nghttp3_objalloc_free(&conn->stream_objalloc);
|
||||
@@ -419,7 +419,7 @@ nghttp3_ssize nghttp3_conn_read_stream(nghttp3_conn *conn, int64_t stream_id,
|
||||
}
|
||||
|
||||
conn->rx.max_stream_id_bidi =
|
||||
nghttp3_max(conn->rx.max_stream_id_bidi, stream_id);
|
||||
nghttp3_max_int64(conn->rx.max_stream_id_bidi, stream_id);
|
||||
rv = nghttp3_conn_create_stream(conn, &stream, stream_id);
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
@@ -498,7 +498,7 @@ static nghttp3_ssize conn_read_type(nghttp3_conn *conn, nghttp3_stream *stream,
|
||||
|
||||
assert(srclen);
|
||||
|
||||
nread = nghttp3_read_varint(rvint, src, srclen, fin);
|
||||
nread = nghttp3_read_varint(rvint, src, src + srclen, fin);
|
||||
if (nread < 0) {
|
||||
return NGHTTP3_ERR_H3_GENERAL_PROTOCOL_ERROR;
|
||||
}
|
||||
@@ -650,7 +650,7 @@ nghttp3_ssize nghttp3_conn_read_control(nghttp3_conn *conn,
|
||||
switch (rstate->state) {
|
||||
case NGHTTP3_CTRL_STREAM_STATE_FRAME_TYPE:
|
||||
assert(end - p > 0);
|
||||
nread = nghttp3_read_varint(rvint, p, (size_t)(end - p), /* fin = */ 0);
|
||||
nread = nghttp3_read_varint(rvint, p, end, /* fin = */ 0);
|
||||
if (nread < 0) {
|
||||
return NGHTTP3_ERR_H3_GENERAL_PROTOCOL_ERROR;
|
||||
}
|
||||
@@ -670,7 +670,7 @@ nghttp3_ssize nghttp3_conn_read_control(nghttp3_conn *conn,
|
||||
/* Fall through */
|
||||
case NGHTTP3_CTRL_STREAM_STATE_FRAME_LENGTH:
|
||||
assert(end - p > 0);
|
||||
nread = nghttp3_read_varint(rvint, p, (size_t)(end - p), /* fin = */ 0);
|
||||
nread = nghttp3_read_varint(rvint, p, end, /* fin = */ 0);
|
||||
if (nread < 0) {
|
||||
return NGHTTP3_ERR_H3_FRAME_ERROR;
|
||||
}
|
||||
@@ -767,9 +767,9 @@ nghttp3_ssize nghttp3_conn_read_control(nghttp3_conn *conn,
|
||||
}
|
||||
|
||||
/* Read Identifier */
|
||||
len = (size_t)nghttp3_min(rstate->left, (int64_t)(end - p));
|
||||
len = (size_t)nghttp3_min_int64(rstate->left, (int64_t)(end - p));
|
||||
assert(len > 0);
|
||||
nread = nghttp3_read_varint(rvint, p, len, frame_fin(rstate, len));
|
||||
nread = nghttp3_read_varint(rvint, p, p + len, frame_fin(rstate, len));
|
||||
if (nread < 0) {
|
||||
return NGHTTP3_ERR_H3_FRAME_ERROR;
|
||||
}
|
||||
@@ -795,7 +795,7 @@ nghttp3_ssize nghttp3_conn_read_control(nghttp3_conn *conn,
|
||||
break;
|
||||
}
|
||||
|
||||
nread = nghttp3_read_varint(rvint, p, len, frame_fin(rstate, len));
|
||||
nread = nghttp3_read_varint(rvint, p, p + len, frame_fin(rstate, len));
|
||||
if (nread < 0) {
|
||||
return NGHTTP3_ERR_H3_FRAME_ERROR;
|
||||
}
|
||||
@@ -811,16 +811,16 @@ nghttp3_ssize nghttp3_conn_read_control(nghttp3_conn *conn,
|
||||
nghttp3_varint_read_state_reset(rvint);
|
||||
|
||||
rv =
|
||||
nghttp3_conn_on_settings_entry_received(conn, &rstate->fr.settings);
|
||||
nghttp3_conn_on_settings_entry_received(conn, &rstate->fr.settings);
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NGHTTP3_CTRL_STREAM_STATE_SETTINGS_ID:
|
||||
len = (size_t)nghttp3_min(rstate->left, (int64_t)(end - p));
|
||||
len = (size_t)nghttp3_min_int64(rstate->left, (int64_t)(end - p));
|
||||
assert(len > 0);
|
||||
nread = nghttp3_read_varint(rvint, p, len, frame_fin(rstate, len));
|
||||
nread = nghttp3_read_varint(rvint, p, p + len, frame_fin(rstate, len));
|
||||
if (nread < 0) {
|
||||
return NGHTTP3_ERR_H3_FRAME_ERROR;
|
||||
}
|
||||
@@ -845,9 +845,9 @@ nghttp3_ssize nghttp3_conn_read_control(nghttp3_conn *conn,
|
||||
}
|
||||
/* Fall through */
|
||||
case NGHTTP3_CTRL_STREAM_STATE_SETTINGS_VALUE:
|
||||
len = (size_t)nghttp3_min(rstate->left, (int64_t)(end - p));
|
||||
len = (size_t)nghttp3_min_int64(rstate->left, (int64_t)(end - p));
|
||||
assert(len > 0);
|
||||
nread = nghttp3_read_varint(rvint, p, len, frame_fin(rstate, len));
|
||||
nread = nghttp3_read_varint(rvint, p, p + len, frame_fin(rstate, len));
|
||||
if (nread < 0) {
|
||||
return NGHTTP3_ERR_H3_FRAME_ERROR;
|
||||
}
|
||||
@@ -879,9 +879,9 @@ nghttp3_ssize nghttp3_conn_read_control(nghttp3_conn *conn,
|
||||
nghttp3_stream_read_state_reset(rstate);
|
||||
break;
|
||||
case NGHTTP3_CTRL_STREAM_STATE_GOAWAY:
|
||||
len = (size_t)nghttp3_min(rstate->left, (int64_t)(end - p));
|
||||
len = (size_t)nghttp3_min_int64(rstate->left, (int64_t)(end - p));
|
||||
assert(len > 0);
|
||||
nread = nghttp3_read_varint(rvint, p, len, frame_fin(rstate, len));
|
||||
nread = nghttp3_read_varint(rvint, p, p + len, frame_fin(rstate, len));
|
||||
if (nread < 0) {
|
||||
return NGHTTP3_ERR_H3_FRAME_ERROR;
|
||||
}
|
||||
@@ -906,7 +906,7 @@ nghttp3_ssize nghttp3_conn_read_control(nghttp3_conn *conn,
|
||||
|
||||
if (conn->callbacks.shutdown) {
|
||||
rv =
|
||||
conn->callbacks.shutdown(conn, conn->rx.goaway_id, conn->user_data);
|
||||
conn->callbacks.shutdown(conn, conn->rx.goaway_id, conn->user_data);
|
||||
if (rv != 0) {
|
||||
return NGHTTP3_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
@@ -916,9 +916,9 @@ nghttp3_ssize nghttp3_conn_read_control(nghttp3_conn *conn,
|
||||
break;
|
||||
case NGHTTP3_CTRL_STREAM_STATE_MAX_PUSH_ID:
|
||||
/* server side only */
|
||||
len = (size_t)nghttp3_min(rstate->left, (int64_t)(end - p));
|
||||
len = (size_t)nghttp3_min_int64(rstate->left, (int64_t)(end - p));
|
||||
assert(len > 0);
|
||||
nread = nghttp3_read_varint(rvint, p, len, frame_fin(rstate, len));
|
||||
nread = nghttp3_read_varint(rvint, p, p + len, frame_fin(rstate, len));
|
||||
if (nread < 0) {
|
||||
return NGHTTP3_ERR_H3_FRAME_ERROR;
|
||||
}
|
||||
@@ -941,9 +941,9 @@ nghttp3_ssize nghttp3_conn_read_control(nghttp3_conn *conn,
|
||||
break;
|
||||
case NGHTTP3_CTRL_STREAM_STATE_PRIORITY_UPDATE_PRI_ELEM_ID:
|
||||
/* server side only */
|
||||
len = (size_t)nghttp3_min(rstate->left, (int64_t)(end - p));
|
||||
len = (size_t)nghttp3_min_int64(rstate->left, (int64_t)(end - p));
|
||||
assert(len > 0);
|
||||
nread = nghttp3_read_varint(rvint, p, len, frame_fin(rstate, len));
|
||||
nread = nghttp3_read_varint(rvint, p, p + len, frame_fin(rstate, len));
|
||||
if (nread < 0) {
|
||||
return NGHTTP3_ERR_H3_FRAME_ERROR;
|
||||
}
|
||||
@@ -977,7 +977,7 @@ nghttp3_ssize nghttp3_conn_read_control(nghttp3_conn *conn,
|
||||
case NGHTTP3_CTRL_STREAM_STATE_PRIORITY_UPDATE:
|
||||
/* We need to buffer Priority Field Value because it might be
|
||||
fragmented. */
|
||||
len = (size_t)nghttp3_min(rstate->left, (int64_t)(end - p));
|
||||
len = (size_t)nghttp3_min_int64(rstate->left, (int64_t)(end - p));
|
||||
assert(len > 0);
|
||||
if (conn->rx.pri_fieldbuflen == 0 && rstate->left == (int64_t)len) {
|
||||
/* Everything is in the input buffer. Apply same length
|
||||
@@ -1032,7 +1032,7 @@ nghttp3_ssize nghttp3_conn_read_control(nghttp3_conn *conn,
|
||||
nghttp3_stream_read_state_reset(rstate);
|
||||
break;
|
||||
case NGHTTP3_CTRL_STREAM_STATE_IGN_FRAME:
|
||||
len = (size_t)nghttp3_min(rstate->left, (int64_t)(end - p));
|
||||
len = (size_t)nghttp3_min_int64(rstate->left, (int64_t)(end - p));
|
||||
p += len;
|
||||
nconsumed += len;
|
||||
rstate->left -= (int64_t)len;
|
||||
@@ -1076,7 +1076,7 @@ static int conn_delete_stream(nghttp3_conn *conn, nghttp3_stream *stream) {
|
||||
}
|
||||
|
||||
rv =
|
||||
nghttp3_map_remove(&conn->streams, (nghttp3_map_key_type)stream->node.id);
|
||||
nghttp3_map_remove(&conn->streams, (nghttp3_map_key_type)stream->node.id);
|
||||
|
||||
assert(0 == rv);
|
||||
|
||||
@@ -1104,8 +1104,8 @@ static int conn_process_blocked_stream_data(nghttp3_conn *conn,
|
||||
buf = nghttp3_ringbuf_get(&stream->inq, 0);
|
||||
|
||||
nconsumed = nghttp3_conn_read_bidi(
|
||||
conn, &nproc, stream, buf->pos, nghttp3_buf_len(buf),
|
||||
len == 1 && (stream->flags & NGHTTP3_STREAM_FLAG_READ_EOF));
|
||||
conn, &nproc, stream, buf->pos, nghttp3_buf_len(buf),
|
||||
len == 1 && (stream->flags & NGHTTP3_STREAM_FLAG_READ_EOF));
|
||||
if (nconsumed < 0) {
|
||||
return (int)nconsumed;
|
||||
}
|
||||
@@ -1144,7 +1144,7 @@ nghttp3_ssize nghttp3_conn_read_qpack_encoder(nghttp3_conn *conn,
|
||||
const uint8_t *src,
|
||||
size_t srclen) {
|
||||
nghttp3_ssize nconsumed =
|
||||
nghttp3_qpack_decoder_read_encoder(&conn->qdec, src, srclen);
|
||||
nghttp3_qpack_decoder_read_encoder(&conn->qdec, src, srclen);
|
||||
nghttp3_stream *stream;
|
||||
int rv;
|
||||
|
||||
@@ -1240,7 +1240,7 @@ nghttp3_ssize nghttp3_conn_read_bidi(nghttp3_conn *conn, size_t *pnproc,
|
||||
switch (rstate->state) {
|
||||
case NGHTTP3_REQ_STREAM_STATE_FRAME_TYPE:
|
||||
assert(end - p > 0);
|
||||
nread = nghttp3_read_varint(rvint, p, (size_t)(end - p), fin);
|
||||
nread = nghttp3_read_varint(rvint, p, end, fin);
|
||||
if (nread < 0) {
|
||||
return NGHTTP3_ERR_H3_GENERAL_PROTOCOL_ERROR;
|
||||
}
|
||||
@@ -1260,7 +1260,7 @@ nghttp3_ssize nghttp3_conn_read_bidi(nghttp3_conn *conn, size_t *pnproc,
|
||||
/* Fall through */
|
||||
case NGHTTP3_REQ_STREAM_STATE_FRAME_LENGTH:
|
||||
assert(end - p > 0);
|
||||
nread = nghttp3_read_varint(rvint, p, (size_t)(end - p), fin);
|
||||
nread = nghttp3_read_varint(rvint, p, end, fin);
|
||||
if (nread < 0) {
|
||||
return NGHTTP3_ERR_H3_FRAME_ERROR;
|
||||
}
|
||||
@@ -1277,14 +1277,14 @@ nghttp3_ssize nghttp3_conn_read_bidi(nghttp3_conn *conn, size_t *pnproc,
|
||||
switch (rstate->fr.hd.type) {
|
||||
case NGHTTP3_FRAME_DATA:
|
||||
rv = nghttp3_stream_transit_rx_http_state(
|
||||
stream, NGHTTP3_HTTP_EVENT_DATA_BEGIN);
|
||||
stream, NGHTTP3_HTTP_EVENT_DATA_BEGIN);
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
/* DATA frame might be empty. */
|
||||
if (rstate->left == 0) {
|
||||
rv = nghttp3_stream_transit_rx_http_state(
|
||||
stream, NGHTTP3_HTTP_EVENT_DATA_END);
|
||||
stream, NGHTTP3_HTTP_EVENT_DATA_END);
|
||||
assert(0 == rv);
|
||||
|
||||
nghttp3_stream_read_state_reset(rstate);
|
||||
@@ -1294,7 +1294,7 @@ nghttp3_ssize nghttp3_conn_read_bidi(nghttp3_conn *conn, size_t *pnproc,
|
||||
break;
|
||||
case NGHTTP3_FRAME_HEADERS:
|
||||
rv = nghttp3_stream_transit_rx_http_state(
|
||||
stream, NGHTTP3_HTTP_EVENT_HEADERS_BEGIN);
|
||||
stream, NGHTTP3_HTTP_EVENT_HEADERS_BEGIN);
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
@@ -1305,7 +1305,7 @@ nghttp3_ssize nghttp3_conn_read_bidi(nghttp3_conn *conn, size_t *pnproc,
|
||||
}
|
||||
|
||||
rv = nghttp3_stream_transit_rx_http_state(
|
||||
stream, NGHTTP3_HTTP_EVENT_HEADERS_END);
|
||||
stream, NGHTTP3_HTTP_EVENT_HEADERS_END);
|
||||
assert(0 == rv);
|
||||
|
||||
nghttp3_stream_read_state_reset(rstate);
|
||||
@@ -1351,7 +1351,7 @@ nghttp3_ssize nghttp3_conn_read_bidi(nghttp3_conn *conn, size_t *pnproc,
|
||||
}
|
||||
break;
|
||||
case NGHTTP3_REQ_STREAM_STATE_DATA:
|
||||
len = (size_t)nghttp3_min(rstate->left, (int64_t)(end - p));
|
||||
len = (size_t)nghttp3_min_int64(rstate->left, (int64_t)(end - p));
|
||||
rv = nghttp3_conn_on_data(conn, stream, p, len);
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
@@ -1370,7 +1370,7 @@ nghttp3_ssize nghttp3_conn_read_bidi(nghttp3_conn *conn, size_t *pnproc,
|
||||
nghttp3_stream_read_state_reset(rstate);
|
||||
break;
|
||||
case NGHTTP3_REQ_STREAM_STATE_HEADERS:
|
||||
len = (size_t)nghttp3_min(rstate->left, (int64_t)(end - p));
|
||||
len = (size_t)nghttp3_min_int64(rstate->left, (int64_t)(end - p));
|
||||
nread = nghttp3_conn_on_headers(conn, stream, p, len,
|
||||
(int64_t)len == rstate->left);
|
||||
if (nread < 0) {
|
||||
@@ -1478,7 +1478,7 @@ nghttp3_ssize nghttp3_conn_read_bidi(nghttp3_conn *conn, size_t *pnproc,
|
||||
|
||||
break;
|
||||
case NGHTTP3_REQ_STREAM_STATE_IGN_FRAME:
|
||||
len = (size_t)nghttp3_min(rstate->left, (int64_t)(end - p));
|
||||
len = (size_t)nghttp3_min_int64(rstate->left, (int64_t)(end - p));
|
||||
p += len;
|
||||
nconsumed += len;
|
||||
rstate->left -= (int64_t)len;
|
||||
@@ -1590,9 +1590,9 @@ static nghttp3_ssize conn_decode_headers(nghttp3_conn *conn,
|
||||
buf.last = buf.end;
|
||||
|
||||
for (;;) {
|
||||
nread = nghttp3_qpack_decoder_read_request(qdec, &stream->qpack_sctx, &nv,
|
||||
&flags, buf.pos,
|
||||
nghttp3_buf_len(&buf), fin);
|
||||
nread =
|
||||
nghttp3_qpack_decoder_read_request(qdec, &stream->qpack_sctx, &nv, &flags,
|
||||
buf.pos, nghttp3_buf_len(&buf), fin);
|
||||
|
||||
if (nread < 0) {
|
||||
return (int)nread;
|
||||
@@ -1625,8 +1625,8 @@ static nghttp3_ssize conn_decode_headers(nghttp3_conn *conn,
|
||||
|
||||
if (flags & NGHTTP3_QPACK_DECODE_FLAG_EMIT) {
|
||||
rv = nghttp3_http_on_header(
|
||||
http, &nv, request, trailers,
|
||||
conn->server && conn->local.settings.enable_connect_protocol);
|
||||
http, &nv, request, trailers,
|
||||
conn->server && conn->local.settings.enable_connect_protocol);
|
||||
switch (rv) {
|
||||
case NGHTTP3_ERR_MALFORMED_HTTP_HEADER:
|
||||
break;
|
||||
@@ -1705,7 +1705,7 @@ int nghttp3_conn_on_settings_entry_received(nghttp3_conn *conn,
|
||||
dest->qpack_blocked_streams = (size_t)ent->value;
|
||||
|
||||
nghttp3_qpack_encoder_set_max_blocked_streams(
|
||||
&conn->qenc, (size_t)nghttp3_min(100, ent->value));
|
||||
&conn->qenc, (size_t)nghttp3_min_uint64(100, ent->value));
|
||||
break;
|
||||
case NGHTTP3_SETTINGS_ID_ENABLE_CONNECT_PROTOCOL:
|
||||
if (!conn->server) {
|
||||
@@ -1784,7 +1784,7 @@ conn_on_priority_update_stream(nghttp3_conn *conn,
|
||||
}
|
||||
|
||||
conn->rx.max_stream_id_bidi =
|
||||
nghttp3_max(conn->rx.max_stream_id_bidi, stream_id);
|
||||
nghttp3_max_int64(conn->rx.max_stream_id_bidi, stream_id);
|
||||
rv = nghttp3_conn_create_stream(conn, &stream, stream_id);
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
@@ -1836,7 +1836,7 @@ int nghttp3_conn_create_stream(nghttp3_conn *conn, nghttp3_stream **pstream,
|
||||
nghttp3_stream *stream;
|
||||
int rv;
|
||||
nghttp3_stream_callbacks callbacks = {
|
||||
conn_stream_acked_data,
|
||||
conn_stream_acked_data,
|
||||
};
|
||||
|
||||
rv = nghttp3_stream_new(&stream, stream_id, &callbacks,
|
||||
@@ -1995,7 +1995,7 @@ nghttp3_ssize nghttp3_conn_writev_stream(nghttp3_conn *conn,
|
||||
|
||||
if (conn->tx.ctrl && !nghttp3_stream_is_blocked(conn->tx.ctrl)) {
|
||||
ncnt =
|
||||
conn_writev_stream(conn, pstream_id, pfin, vec, veccnt, conn->tx.ctrl);
|
||||
conn_writev_stream(conn, pstream_id, pfin, vec, veccnt, conn->tx.ctrl);
|
||||
if (ncnt) {
|
||||
return ncnt;
|
||||
}
|
||||
@@ -2008,7 +2008,7 @@ nghttp3_ssize nghttp3_conn_writev_stream(nghttp3_conn *conn,
|
||||
}
|
||||
|
||||
ncnt =
|
||||
conn_writev_stream(conn, pstream_id, pfin, vec, veccnt, conn->tx.qdec);
|
||||
conn_writev_stream(conn, pstream_id, pfin, vec, veccnt, conn->tx.qdec);
|
||||
if (ncnt) {
|
||||
return ncnt;
|
||||
}
|
||||
@@ -2016,7 +2016,7 @@ nghttp3_ssize nghttp3_conn_writev_stream(nghttp3_conn *conn,
|
||||
|
||||
if (conn->tx.qenc && !nghttp3_stream_is_blocked(conn->tx.qenc)) {
|
||||
ncnt =
|
||||
conn_writev_stream(conn, pstream_id, pfin, vec, veccnt, conn->tx.qenc);
|
||||
conn_writev_stream(conn, pstream_id, pfin, vec, veccnt, conn->tx.qenc);
|
||||
if (ncnt) {
|
||||
return ncnt;
|
||||
}
|
||||
@@ -2095,7 +2095,22 @@ int nghttp3_conn_add_ack_offset(nghttp3_conn *conn, int64_t stream_id,
|
||||
return 0;
|
||||
}
|
||||
|
||||
return nghttp3_stream_add_ack_offset(stream, n);
|
||||
return nghttp3_stream_update_ack_offset(stream, stream->ack_offset + n);
|
||||
}
|
||||
|
||||
int nghttp3_conn_update_ack_offset(nghttp3_conn *conn, int64_t stream_id,
|
||||
uint64_t offset) {
|
||||
nghttp3_stream *stream = nghttp3_conn_find_stream(conn, stream_id);
|
||||
|
||||
if (stream == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (stream->ack_offset > offset) {
|
||||
return NGHTTP3_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
return nghttp3_stream_update_ack_offset(stream, offset);
|
||||
}
|
||||
|
||||
static int conn_submit_headers_data(nghttp3_conn *conn, nghttp3_stream *stream,
|
||||
@@ -2304,7 +2319,7 @@ int nghttp3_conn_shutdown(nghttp3_conn *conn) {
|
||||
frent.fr.hd.type = NGHTTP3_FRAME_GOAWAY;
|
||||
if (conn->server) {
|
||||
frent.fr.goaway.id =
|
||||
nghttp3_min((1ll << 62) - 4, conn->rx.max_stream_id_bidi + 4);
|
||||
nghttp3_min_int64((1ll << 62) - 4, conn->rx.max_stream_id_bidi + 4);
|
||||
} else {
|
||||
frent.fr.goaway.id = 0;
|
||||
}
|
||||
@@ -2318,7 +2333,7 @@ int nghttp3_conn_shutdown(nghttp3_conn *conn) {
|
||||
|
||||
conn->tx.goaway_id = frent.fr.goaway.id;
|
||||
conn->flags |=
|
||||
NGHTTP3_CONN_FLAG_GOAWAY_QUEUED | NGHTTP3_CONN_FLAG_SHUTDOWN_COMMENCED;
|
||||
NGHTTP3_CONN_FLAG_GOAWAY_QUEUED | NGHTTP3_CONN_FLAG_SHUTDOWN_COMMENCED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2619,5 +2634,5 @@ void nghttp3_settings_default_versioned(int settings_version,
|
||||
memset(settings, 0, sizeof(nghttp3_settings));
|
||||
settings->max_field_section_size = NGHTTP3_VARINT_MAX;
|
||||
settings->qpack_encoder_max_dtable_capacity =
|
||||
NGHTTP3_QPACK_ENCODER_MAX_DTABLE_CAPACITY;
|
||||
NGHTTP3_QPACK_ENCODER_MAX_DTABLE_CAPACITY;
|
||||
}
|
||||
+2
-2
@@ -27,7 +27,7 @@
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#endif /* defined(HAVE_CONFIG_H) */
|
||||
|
||||
#include <nghttp3/nghttp3.h>
|
||||
|
||||
@@ -204,4 +204,4 @@ int nghttp3_conn_reject_stream(nghttp3_conn *conn, nghttp3_stream *stream);
|
||||
*/
|
||||
nghttp3_stream *nghttp3_conn_get_next_tx_stream(nghttp3_conn *conn);
|
||||
|
||||
#endif /* NGHTTP3_CONN_H */
|
||||
#endif /* !defined(NGHTTP3_CONN_H) */
|
||||
+24
-19
@@ -31,34 +31,39 @@
|
||||
#include "nghttp3_str.h"
|
||||
#include "nghttp3_unreachable.h"
|
||||
|
||||
int64_t nghttp3_get_varint(size_t *plen, const uint8_t *p) {
|
||||
const uint8_t *nghttp3_get_varint(int64_t *dest, const uint8_t *p) {
|
||||
union {
|
||||
char b[8];
|
||||
uint8_t n8;
|
||||
uint16_t n16;
|
||||
uint32_t n32;
|
||||
uint64_t n64;
|
||||
} n;
|
||||
|
||||
*plen = (size_t)(1u << (*p >> 6));
|
||||
|
||||
switch (*plen) {
|
||||
switch (*p >> 6) {
|
||||
case 0:
|
||||
*dest = *p++;
|
||||
return p;
|
||||
case 1:
|
||||
return (int64_t)*p;
|
||||
case 2:
|
||||
memcpy(&n, p, 2);
|
||||
n.b[0] &= 0x3f;
|
||||
return (int64_t)ntohs(n.n16);
|
||||
case 4:
|
||||
memcpy(&n, p, 4);
|
||||
n.b[0] &= 0x3f;
|
||||
return (int64_t)ntohl(n.n32);
|
||||
case 8:
|
||||
memcpy(&n, p, 8);
|
||||
n.b[0] &= 0x3f;
|
||||
return (int64_t)nghttp3_ntohl64(n.n64);
|
||||
}
|
||||
n.n8 &= 0x3f;
|
||||
*dest = ntohs(n.n16);
|
||||
|
||||
nghttp3_unreachable();
|
||||
return p + 2;
|
||||
case 2:
|
||||
memcpy(&n, p, 4);
|
||||
n.n8 &= 0x3f;
|
||||
*dest = ntohl(n.n32);
|
||||
|
||||
return p + 4;
|
||||
case 3:
|
||||
memcpy(&n, p, 8);
|
||||
n.n8 &= 0x3f;
|
||||
*dest = (int64_t)nghttp3_ntohl64(n.n64);
|
||||
|
||||
return p + 8;
|
||||
default:
|
||||
nghttp3_unreachable();
|
||||
}
|
||||
}
|
||||
|
||||
int64_t nghttp3_get_varint_fb(const uint8_t *p) { return *p & 0x3f; }
|
||||
|
||||
+26
-28
@@ -28,69 +28,67 @@
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#endif /* defined(HAVE_CONFIG_H) */
|
||||
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
# include <arpa/inet.h>
|
||||
#endif /* HAVE_ARPA_INET_H */
|
||||
#endif /* defined(HAVE_ARPA_INET_H) */
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
# include <netinet/in.h>
|
||||
#endif /* HAVE_NETINET_IN_H */
|
||||
#endif /* defined(HAVE_NETINET_IN_H) */
|
||||
|
||||
#ifdef HAVE_BYTESWAP_H
|
||||
# include <byteswap.h>
|
||||
#endif /* HAVE_BYTESWAP_H */
|
||||
#endif /* defined(HAVE_BYTESWAP_H) */
|
||||
|
||||
#ifdef HAVE_ENDIAN_H
|
||||
# include <endian.h>
|
||||
#endif /* HAVE_ENDIAN_H */
|
||||
#endif /* defined(HAVE_ENDIAN_H) */
|
||||
|
||||
#ifdef HAVE_SYS_ENDIAN_H
|
||||
# include <sys/endian.h>
|
||||
#endif /* HAVE_SYS_ENDIAN_H */
|
||||
#endif /* defined(HAVE_SYS_ENDIAN_H) */
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#ifdef __APPLE__
|
||||
# include <libkern/OSByteOrder.h>
|
||||
#endif // __APPLE__
|
||||
#endif /* defined(__APPLE__) */
|
||||
|
||||
#include <nghttp3/nghttp3.h>
|
||||
|
||||
#if defined(HAVE_BE64TOH) || \
|
||||
(defined(HAVE_DECL_BE64TOH) && HAVE_DECL_BE64TOH > 0)
|
||||
#if HAVE_DECL_BE64TOH
|
||||
# define nghttp3_ntohl64(N) be64toh(N)
|
||||
# define nghttp3_htonl64(N) htobe64(N)
|
||||
#else /* !HAVE_BE64TOH */
|
||||
# if defined(WORDS_BIGENDIAN)
|
||||
#else /* !HAVE_DECL_BE64TOH */
|
||||
# ifdef WORDS_BIGENDIAN
|
||||
# define nghttp3_ntohl64(N) (N)
|
||||
# define nghttp3_htonl64(N) (N)
|
||||
# else /* !WORDS_BIGENDIAN */
|
||||
# if defined(HAVE_BSWAP_64) || \
|
||||
(defined(HAVE_DECL_BSWAP_64) && HAVE_DECL_BSWAP_64 > 0)
|
||||
# else /* !defined(WORDS_BIGENDIAN) */
|
||||
# if HAVE_DECL_BSWAP_64
|
||||
# define nghttp3_bswap64 bswap_64
|
||||
# elif defined(WIN32)
|
||||
# define nghttp3_bswap64 _byteswap_uint64
|
||||
# elif defined(__APPLE__)
|
||||
# define nghttp3_bswap64 OSSwapInt64
|
||||
# else /* !HAVE_BSWAP_64 && !WIN32 && !__APPLE__ */
|
||||
# else /* !(HAVE_DECL_BSWAP_64 || defined(WIN32) || defined(__APPLE__)) */
|
||||
# define nghttp3_bswap64(N) \
|
||||
((uint64_t)(ntohl((uint32_t)(N))) << 32 | ntohl((uint32_t)((N) >> 32)))
|
||||
# endif /* !HAVE_BSWAP_64 && !WIN32 && !__APPLE__ */
|
||||
# endif /* !(HAVE_DECL_BSWAP_64 || defined(WIN32) || defined(__APPLE__)) */
|
||||
# define nghttp3_ntohl64(N) nghttp3_bswap64(N)
|
||||
# define nghttp3_htonl64(N) nghttp3_bswap64(N)
|
||||
# endif /* !WORDS_BIGENDIAN */
|
||||
#endif /* !HAVE_BE64TOH */
|
||||
# endif /* !defined(WORDS_BIGENDIAN) */
|
||||
#endif /* !HAVE_DECL_BE64TOH */
|
||||
|
||||
#if defined(WIN32)
|
||||
#ifdef WIN32
|
||||
/* Windows requires ws2_32 library for ntonl family of functions. We
|
||||
define inline functions for those functions so that we don't have
|
||||
dependency on that lib. */
|
||||
|
||||
# ifdef _MSC_VER
|
||||
# define STIN static __inline
|
||||
# else
|
||||
# else /* !defined(_MSC_VER) */
|
||||
# define STIN static inline
|
||||
# endif
|
||||
# endif /* !defined(_MSC_VER) */
|
||||
|
||||
STIN uint32_t htonl(uint32_t hostlong) {
|
||||
uint32_t res;
|
||||
@@ -128,14 +126,14 @@ STIN uint16_t ntohs(uint16_t netshort) {
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif /* WIN32 */
|
||||
#endif /* defined(WIN32) */
|
||||
|
||||
/*
|
||||
* nghttp3_get_varint reads variable-length integer from |p|, and
|
||||
* returns it in host byte order. The number of bytes read is stored
|
||||
* in |*plen|.
|
||||
* nghttp3_get_varint reads variable-length unsigned integer from |p|,
|
||||
* and stores it in the buffer pointed by |dest| in host byte order.
|
||||
* It returns |p| plus the number of bytes read from |p|.
|
||||
*/
|
||||
int64_t nghttp3_get_varint(size_t *plen, const uint8_t *p);
|
||||
const uint8_t *nghttp3_get_varint(int64_t *dest, const uint8_t *p);
|
||||
|
||||
/*
|
||||
* nghttp3_get_varint_fb reads first byte of encoded variable-length
|
||||
@@ -193,4 +191,4 @@ uint64_t nghttp3_ord_stream_id(int64_t stream_id);
|
||||
*/
|
||||
#define NGHTTP3_PRI_INC_MASK (1 << 7)
|
||||
|
||||
#endif /* NGHTTP3_CONV_H */
|
||||
#endif /* !defined(NGHTTP3_CONV_H) */
|
||||
+5
-5
@@ -35,7 +35,7 @@ static void nghttp3_default_debug_vfprintf_callback(const char *fmt,
|
||||
}
|
||||
|
||||
static nghttp3_debug_vprintf_callback static_debug_vprintf_callback =
|
||||
nghttp3_default_debug_vfprintf_callback;
|
||||
nghttp3_default_debug_vfprintf_callback;
|
||||
|
||||
void nghttp3_debug_vprintf(const char *format, ...) {
|
||||
if (static_debug_vprintf_callback) {
|
||||
@@ -47,15 +47,15 @@ void nghttp3_debug_vprintf(const char *format, ...) {
|
||||
}
|
||||
|
||||
void nghttp3_set_debug_vprintf_callback(
|
||||
nghttp3_debug_vprintf_callback debug_vprintf_callback) {
|
||||
nghttp3_debug_vprintf_callback debug_vprintf_callback) {
|
||||
static_debug_vprintf_callback = debug_vprintf_callback;
|
||||
}
|
||||
|
||||
#else /* !DEBUGBUILD */
|
||||
#else /* !defined(DEBUGBUILD) */
|
||||
|
||||
void nghttp3_set_debug_vprintf_callback(
|
||||
nghttp3_debug_vprintf_callback debug_vprintf_callback) {
|
||||
nghttp3_debug_vprintf_callback debug_vprintf_callback) {
|
||||
(void)debug_vprintf_callback;
|
||||
}
|
||||
|
||||
#endif /* !DEBUGBUILD */
|
||||
#endif /* !defined(DEBUGBUILD) */
|
||||
+4
-4
@@ -28,17 +28,17 @@
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#endif /* defined(HAVE_CONFIG_H) */
|
||||
|
||||
#include <nghttp3/nghttp3.h>
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
# define DEBUGF(...) nghttp3_debug_vprintf(__VA_ARGS__)
|
||||
void nghttp3_debug_vprintf(const char *format, ...);
|
||||
#else
|
||||
#else /* !defined(DEBUGBUILD) */
|
||||
# define DEBUGF(...) \
|
||||
do { \
|
||||
} while (0)
|
||||
#endif
|
||||
#endif /* !defined(DEBUGBUILD) */
|
||||
|
||||
#endif /* NGHTTP3_DEBUG_H */
|
||||
#endif /* !defined(NGHTTP3_DEBUG_H) */
|
||||
+2
-2
@@ -27,8 +27,8 @@
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#endif /* defined(HAVE_CONFIG_H) */
|
||||
|
||||
#include <nghttp3/nghttp3.h>
|
||||
|
||||
#endif /* NGHTTP3_ERR_H */
|
||||
#endif /* !defined(NGHTTP3_ERR_H) */
|
||||
+1
-1
@@ -102,7 +102,7 @@ nghttp3_frame_write_priority_update(uint8_t *p,
|
||||
}
|
||||
|
||||
size_t nghttp3_frame_write_priority_update_len(
|
||||
int64_t *ppayloadlen, const nghttp3_frame_priority_update *fr) {
|
||||
int64_t *ppayloadlen, const nghttp3_frame_priority_update *fr) {
|
||||
size_t payloadlen = nghttp3_put_varintlen(fr->pri_elem_id) + fr->datalen;
|
||||
|
||||
*ppayloadlen = (int64_t)payloadlen;
|
||||
|
||||
+3
-3
@@ -28,7 +28,7 @@
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#endif /* defined(HAVE_CONFIG_H) */
|
||||
|
||||
#include <nghttp3/nghttp3.h>
|
||||
|
||||
@@ -188,7 +188,7 @@ nghttp3_frame_write_priority_update(uint8_t *dest,
|
||||
* stores payload length in |*ppayloadlen|.
|
||||
*/
|
||||
size_t nghttp3_frame_write_priority_update_len(
|
||||
int64_t *ppayloadlen, const nghttp3_frame_priority_update *fr);
|
||||
int64_t *ppayloadlen, const nghttp3_frame_priority_update *fr);
|
||||
|
||||
/*
|
||||
* nghttp3_nva_copy copies name/value pairs from |nva|, which contains
|
||||
@@ -227,4 +227,4 @@ void nghttp3_frame_headers_free(nghttp3_frame_headers *fr,
|
||||
void nghttp3_frame_priority_update_free(nghttp3_frame_priority_update *fr,
|
||||
const nghttp3_mem *mem);
|
||||
|
||||
#endif /* NGHTTP3_FRAME_H */
|
||||
#endif /* !defined(NGHTTP3_FRAME_H) */
|
||||
+7
-13
@@ -37,14 +37,8 @@ void nghttp3_gaptr_init(nghttp3_gaptr *gaptr, const nghttp3_mem *mem) {
|
||||
|
||||
static int gaptr_gap_init(nghttp3_gaptr *gaptr) {
|
||||
nghttp3_range range = {0, UINT64_MAX};
|
||||
int rv;
|
||||
|
||||
rv = nghttp3_ksl_insert(&gaptr->gap, NULL, &range, NULL);
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return nghttp3_ksl_insert(&gaptr->gap, NULL, &range, NULL);
|
||||
}
|
||||
|
||||
void nghttp3_gaptr_free(nghttp3_gaptr *gaptr) {
|
||||
@@ -82,7 +76,9 @@ int nghttp3_gaptr_push(nghttp3_gaptr *gaptr, uint64_t offset,
|
||||
nghttp3_ksl_remove_hint(&gaptr->gap, &it, &it, &k);
|
||||
continue;
|
||||
}
|
||||
|
||||
nghttp3_range_cut(&l, &r, &k, &m);
|
||||
|
||||
if (nghttp3_range_len(&l)) {
|
||||
nghttp3_ksl_update_key(&gaptr->gap, &k, &l);
|
||||
|
||||
@@ -95,23 +91,23 @@ int nghttp3_gaptr_push(nghttp3_gaptr *gaptr, uint64_t offset,
|
||||
} else if (nghttp3_range_len(&r)) {
|
||||
nghttp3_ksl_update_key(&gaptr->gap, &k, &r);
|
||||
}
|
||||
|
||||
nghttp3_ksl_it_next(&it);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t nghttp3_gaptr_first_gap_offset(nghttp3_gaptr *gaptr) {
|
||||
nghttp3_ksl_it it;
|
||||
nghttp3_range r;
|
||||
|
||||
if (nghttp3_ksl_len(&gaptr->gap) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
it = nghttp3_ksl_begin(&gaptr->gap);
|
||||
r = *(nghttp3_range *)nghttp3_ksl_it_key(&it);
|
||||
|
||||
return r.begin;
|
||||
return ((nghttp3_range *)nghttp3_ksl_it_key(&it))->begin;
|
||||
}
|
||||
|
||||
nghttp3_range nghttp3_gaptr_get_first_gap_after(nghttp3_gaptr *gaptr,
|
||||
@@ -136,7 +132,6 @@ int nghttp3_gaptr_is_pushed(nghttp3_gaptr *gaptr, uint64_t offset,
|
||||
uint64_t datalen) {
|
||||
nghttp3_range q = {offset, offset + datalen};
|
||||
nghttp3_ksl_it it;
|
||||
nghttp3_range k;
|
||||
nghttp3_range m;
|
||||
|
||||
if (nghttp3_ksl_len(&gaptr->gap) == 0) {
|
||||
@@ -145,8 +140,7 @@ int nghttp3_gaptr_is_pushed(nghttp3_gaptr *gaptr, uint64_t offset,
|
||||
|
||||
it = nghttp3_ksl_lower_bound_compar(&gaptr->gap, &q,
|
||||
nghttp3_ksl_range_exclusive_compar);
|
||||
k = *(nghttp3_range *)nghttp3_ksl_it_key(&it);
|
||||
m = nghttp3_range_intersect(&q, &k);
|
||||
m = nghttp3_range_intersect(&q, (nghttp3_range *)nghttp3_ksl_it_key(&it));
|
||||
|
||||
return nghttp3_range_len(&m) == 0;
|
||||
}
|
||||
|
||||
+7
-7
@@ -28,7 +28,7 @@
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#endif /* defined(HAVE_CONFIG_H) */
|
||||
|
||||
#include <nghttp3/nghttp3.h>
|
||||
|
||||
@@ -40,8 +40,9 @@
|
||||
* nghttp3_gaptr maintains the gap in the range [0, UINT64_MAX).
|
||||
*/
|
||||
typedef struct nghttp3_gaptr {
|
||||
/* gap maintains the range of offset which is not received
|
||||
yet. Initially, its range is [0, UINT64_MAX). */
|
||||
/* gap maintains the range of offset which is not pushed
|
||||
yet. Initially, its range is [0, UINT64_MAX). "gap" is the range
|
||||
that is not pushed yet. */
|
||||
nghttp3_ksl gap;
|
||||
/* mem is custom memory allocator */
|
||||
const nghttp3_mem *mem;
|
||||
@@ -58,8 +59,7 @@ void nghttp3_gaptr_init(nghttp3_gaptr *gaptr, const nghttp3_mem *mem);
|
||||
void nghttp3_gaptr_free(nghttp3_gaptr *gaptr);
|
||||
|
||||
/*
|
||||
* nghttp3_gaptr_push adds new data of length |datalen| at the stream
|
||||
* offset |offset|.
|
||||
* nghttp3_gaptr_push pushes the range [offset, offset + datalen).
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
@@ -77,7 +77,7 @@ uint64_t nghttp3_gaptr_first_gap_offset(nghttp3_gaptr *gaptr);
|
||||
|
||||
/*
|
||||
* nghttp3_gaptr_get_first_gap_after returns the first gap which
|
||||
* overlaps or comes after |offset|.
|
||||
* includes or comes after |offset|.
|
||||
*/
|
||||
nghttp3_range nghttp3_gaptr_get_first_gap_after(nghttp3_gaptr *gaptr,
|
||||
uint64_t offset);
|
||||
@@ -96,4 +96,4 @@ int nghttp3_gaptr_is_pushed(nghttp3_gaptr *gaptr, uint64_t offset,
|
||||
*/
|
||||
void nghttp3_gaptr_drop_first_gap(nghttp3_gaptr *gaptr);
|
||||
|
||||
#endif /* NGHTTP3_GAPTR_H */
|
||||
#endif /* !defined(NGHTTP3_GAPTR_H) */
|
||||
+612
-598
File diff suppressed because it is too large.
Load diff
+2
-2
@@ -28,7 +28,7 @@
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#endif /* defined(HAVE_CONFIG_H) */
|
||||
|
||||
#include <nghttp3/nghttp3.h>
|
||||
|
||||
@@ -170,4 +170,4 @@ int nghttp3_http_parse_priority(nghttp3_pri *dest, const uint8_t *value,
|
||||
|
||||
int nghttp3_pri_eq(const nghttp3_pri *a, const nghttp3_pri *b);
|
||||
|
||||
#endif /* NGHTTP3_HTTP_H */
|
||||
#endif /* !defined(NGHTTP3_HTTP_H) */
|
||||
+2
-15
@@ -27,10 +27,8 @@
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
void nghttp3_idtr_init(nghttp3_idtr *idtr, int server, const nghttp3_mem *mem) {
|
||||
void nghttp3_idtr_init(nghttp3_idtr *idtr, const nghttp3_mem *mem) {
|
||||
nghttp3_gaptr_init(&idtr->gap, mem);
|
||||
|
||||
idtr->server = server;
|
||||
}
|
||||
|
||||
void nghttp3_idtr_free(nghttp3_idtr *idtr) {
|
||||
@@ -42,8 +40,7 @@ void nghttp3_idtr_free(nghttp3_idtr *idtr) {
|
||||
}
|
||||
|
||||
/*
|
||||
* id_from_stream_id translates |stream_id| to id space used by
|
||||
* nghttp3_idtr.
|
||||
* id_from_stream_id translates |stream_id| to an internal ID.
|
||||
*/
|
||||
static uint64_t id_from_stream_id(int64_t stream_id) {
|
||||
return (uint64_t)(stream_id >> 2);
|
||||
@@ -52,9 +49,6 @@ static uint64_t id_from_stream_id(int64_t stream_id) {
|
||||
int nghttp3_idtr_open(nghttp3_idtr *idtr, int64_t stream_id) {
|
||||
uint64_t q;
|
||||
|
||||
assert((idtr->server && (stream_id % 2)) ||
|
||||
(!idtr->server && (stream_id % 2)) == 0);
|
||||
|
||||
q = id_from_stream_id(stream_id);
|
||||
|
||||
if (nghttp3_gaptr_is_pushed(&idtr->gap, q, 1)) {
|
||||
@@ -67,14 +61,7 @@ int nghttp3_idtr_open(nghttp3_idtr *idtr, int64_t stream_id) {
|
||||
int nghttp3_idtr_is_open(nghttp3_idtr *idtr, int64_t stream_id) {
|
||||
uint64_t q;
|
||||
|
||||
assert((idtr->server && (stream_id % 2)) ||
|
||||
(!idtr->server && (stream_id % 2)) == 0);
|
||||
|
||||
q = id_from_stream_id(stream_id);
|
||||
|
||||
return nghttp3_gaptr_is_pushed(&idtr->gap, q, 1);
|
||||
}
|
||||
|
||||
uint64_t nghttp3_idtr_first_gap(nghttp3_idtr *idtr) {
|
||||
return nghttp3_gaptr_first_gap_offset(&idtr->gap);
|
||||
}
|
||||
+10
-23
@@ -28,7 +28,7 @@
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#endif /* defined(HAVE_CONFIG_H) */
|
||||
|
||||
#include <nghttp3/nghttp3.h>
|
||||
|
||||
@@ -39,21 +39,17 @@
|
||||
* nghttp3_idtr tracks the usage of stream ID.
|
||||
*/
|
||||
typedef struct nghttp3_idtr {
|
||||
/* gap maintains the range of ID which is not used yet. Initially,
|
||||
its range is [0, UINT64_MAX). */
|
||||
/* gap maintains the range of an internal ID which is not used yet.
|
||||
Initially, its range is [0, UINT64_MAX). The internal ID and
|
||||
stream ID are in the different number spaces. See
|
||||
id_from_stream_id to convert a stream ID to an internal ID. */
|
||||
nghttp3_gaptr gap;
|
||||
/* server is nonzero if this object records server initiated stream
|
||||
ID. */
|
||||
int server;
|
||||
} nghttp3_idtr;
|
||||
|
||||
/*
|
||||
* nghttp3_idtr_init initializes |idtr|.
|
||||
*
|
||||
* If this object records server initiated ID (even number), set
|
||||
* |server| to nonzero.
|
||||
*/
|
||||
void nghttp3_idtr_init(nghttp3_idtr *idtr, int server, const nghttp3_mem *mem);
|
||||
void nghttp3_idtr_init(nghttp3_idtr *idtr, const nghttp3_mem *mem);
|
||||
|
||||
/*
|
||||
* nghttp3_idtr_free frees resources allocated for |idtr|.
|
||||
@@ -61,30 +57,21 @@ void nghttp3_idtr_init(nghttp3_idtr *idtr, int server, const nghttp3_mem *mem);
|
||||
void nghttp3_idtr_free(nghttp3_idtr *idtr);
|
||||
|
||||
/*
|
||||
* nghttp3_idtr_open claims that |stream_id| is in used.
|
||||
* nghttp3_idtr_open claims that |stream_id| is in use.
|
||||
*
|
||||
* It returns 0 if it succeeds, or one of the following negative error
|
||||
* codes:
|
||||
*
|
||||
* NGHTTP3_ERR_STREAM_IN_USE
|
||||
* ID has already been used.
|
||||
* |stream_id| has already been used.
|
||||
* NGHTTP3_ERR_NOMEM
|
||||
* Out of memory.
|
||||
*/
|
||||
int nghttp3_idtr_open(nghttp3_idtr *idtr, int64_t stream_id);
|
||||
|
||||
/*
|
||||
* nghttp3_idtr_open tells whether ID |stream_id| is in used or not.
|
||||
*
|
||||
* It returns nonzero if |stream_id| is used.
|
||||
* nghttp3_idtr_open returns nonzero if |stream_id| is in use.
|
||||
*/
|
||||
int nghttp3_idtr_is_open(nghttp3_idtr *idtr, int64_t stream_id);
|
||||
|
||||
/*
|
||||
* nghttp3_idtr_first_gap returns the first id of first gap. If there
|
||||
* is no gap, it returns UINT64_MAX. The returned id is an id space
|
||||
* used in this object internally, and not stream ID.
|
||||
*/
|
||||
uint64_t nghttp3_idtr_first_gap(nghttp3_idtr *idtr);
|
||||
|
||||
#endif /* NGHTTP3_IDTR_H */
|
||||
#endif /* !defined(NGHTTP3_IDTR_H) */
|
||||
+111
-109
@@ -39,8 +39,10 @@ static nghttp3_ksl_blk null_blk = {{{NULL, NULL, 0, 0, {0}}}};
|
||||
nghttp3_objalloc_def(ksl_blk, nghttp3_ksl_blk, oplent);
|
||||
|
||||
static size_t ksl_nodelen(size_t keylen) {
|
||||
return (sizeof(nghttp3_ksl_node) + keylen - sizeof(uint64_t) + 0xfu) &
|
||||
~(uintptr_t)0xfu;
|
||||
assert(keylen >= sizeof(uint64_t));
|
||||
|
||||
return (sizeof(nghttp3_ksl_node) + keylen - sizeof(uint64_t) + 0x7u) &
|
||||
~(uintptr_t)0x7u;
|
||||
}
|
||||
|
||||
static size_t ksl_blklen(size_t nodelen) {
|
||||
@@ -61,15 +63,14 @@ void nghttp3_ksl_init(nghttp3_ksl *ksl, nghttp3_ksl_compar compar,
|
||||
size_t nodelen = ksl_nodelen(keylen);
|
||||
|
||||
nghttp3_objalloc_init(&ksl->blkalloc,
|
||||
((ksl_blklen(nodelen) + 0xfu) & ~(uintptr_t)0xfu) * 8,
|
||||
mem);
|
||||
(ksl_blklen(nodelen) + 0xfu) & ~(uintptr_t)0xfu, mem);
|
||||
|
||||
ksl->head = NULL;
|
||||
ksl->front = ksl->back = NULL;
|
||||
ksl->compar = compar;
|
||||
ksl->n = 0;
|
||||
ksl->keylen = keylen;
|
||||
ksl->nodelen = nodelen;
|
||||
ksl->n = 0;
|
||||
}
|
||||
|
||||
static nghttp3_ksl_blk *ksl_blk_objalloc_new(nghttp3_ksl *ksl) {
|
||||
@@ -83,6 +84,7 @@ static void ksl_blk_objalloc_del(nghttp3_ksl *ksl, nghttp3_ksl_blk *blk) {
|
||||
|
||||
static int ksl_head_init(nghttp3_ksl *ksl) {
|
||||
nghttp3_ksl_blk *head = ksl_blk_objalloc_new(ksl);
|
||||
|
||||
if (!head) {
|
||||
return NGHTTP3_ERR_NOMEM;
|
||||
}
|
||||
@@ -112,7 +114,7 @@ static void ksl_free_blk(nghttp3_ksl *ksl, nghttp3_ksl_blk *blk) {
|
||||
|
||||
ksl_blk_objalloc_del(ksl, blk);
|
||||
}
|
||||
#endif /* NOMEMPOOL */
|
||||
#endif /* defined(NOMEMPOOL) */
|
||||
|
||||
void nghttp3_ksl_free(nghttp3_ksl *ksl) {
|
||||
if (!ksl || !ksl->head) {
|
||||
@@ -121,7 +123,7 @@ void nghttp3_ksl_free(nghttp3_ksl *ksl) {
|
||||
|
||||
#ifdef NOMEMPOOL
|
||||
ksl_free_blk(ksl, ksl->head);
|
||||
#endif /* NOMEMPOOL */
|
||||
#endif /* defined(NOMEMPOOL) */
|
||||
|
||||
nghttp3_objalloc_free(&ksl->blkalloc);
|
||||
}
|
||||
@@ -144,21 +146,22 @@ static nghttp3_ksl_blk *ksl_split_blk(nghttp3_ksl *ksl, nghttp3_ksl_blk *blk) {
|
||||
|
||||
rblk->next = blk->next;
|
||||
blk->next = rblk;
|
||||
|
||||
if (rblk->next) {
|
||||
rblk->next->prev = rblk;
|
||||
} else if (ksl->back == blk) {
|
||||
ksl->back = rblk;
|
||||
}
|
||||
|
||||
rblk->prev = blk;
|
||||
rblk->leaf = blk->leaf;
|
||||
|
||||
rblk->n = blk->n / 2;
|
||||
|
||||
memcpy(rblk->nodes, blk->nodes + ksl->nodelen * (blk->n - rblk->n),
|
||||
ksl->nodelen * rblk->n);
|
||||
|
||||
blk->n -= rblk->n;
|
||||
|
||||
memcpy(rblk->nodes, blk->nodes + ksl->nodelen * blk->n,
|
||||
ksl->nodelen * rblk->n);
|
||||
|
||||
assert(blk->n >= NGHTTP3_KSL_MIN_NBLK);
|
||||
assert(rblk->n >= NGHTTP3_KSL_MIN_NBLK);
|
||||
|
||||
@@ -174,7 +177,7 @@ static nghttp3_ksl_blk *ksl_split_blk(nghttp3_ksl *ksl, nghttp3_ksl_blk *blk) {
|
||||
* codes:
|
||||
*
|
||||
* NGHTTP3_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* Out of memory.
|
||||
*/
|
||||
static int ksl_split_node(nghttp3_ksl *ksl, nghttp3_ksl_blk *blk, size_t i) {
|
||||
nghttp3_ksl_node *node;
|
||||
@@ -210,7 +213,7 @@ static int ksl_split_node(nghttp3_ksl *ksl, nghttp3_ksl_blk *blk, size_t i) {
|
||||
* codes:
|
||||
*
|
||||
* NGHTTP3_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* Out of memory.
|
||||
*/
|
||||
static int ksl_split_head(nghttp3_ksl *ksl) {
|
||||
nghttp3_ksl_blk *rblk = NULL, *lblk, *nhead = NULL;
|
||||
@@ -224,10 +227,12 @@ static int ksl_split_head(nghttp3_ksl *ksl) {
|
||||
lblk = ksl->head;
|
||||
|
||||
nhead = ksl_blk_objalloc_new(ksl);
|
||||
|
||||
if (nhead == NULL) {
|
||||
ksl_blk_objalloc_del(ksl, rblk);
|
||||
return NGHTTP3_ERR_NOMEM;
|
||||
}
|
||||
|
||||
nhead->next = nhead->prev = NULL;
|
||||
nhead->n = 2;
|
||||
nhead->leaf = 0;
|
||||
@@ -248,9 +253,9 @@ static int ksl_split_head(nghttp3_ksl *ksl) {
|
||||
}
|
||||
|
||||
/*
|
||||
* insert_node inserts a node whose key is |key| with the associated
|
||||
* |data| at the index of |i|. This function assumes that the number
|
||||
* of nodes contained by |blk| is strictly less than
|
||||
* ksl_insert_node inserts a node whose key is |key| with the
|
||||
* associated |data| at the index of |i|. This function assumes that
|
||||
* the number of nodes contained by |blk| is strictly less than
|
||||
* NGHTTP3_KSL_MAX_NBLK.
|
||||
*/
|
||||
static void ksl_insert_node(nghttp3_ksl *ksl, nghttp3_ksl_blk *blk, size_t i,
|
||||
@@ -269,9 +274,9 @@ static void ksl_insert_node(nghttp3_ksl *ksl, nghttp3_ksl_blk *blk, size_t i,
|
||||
++blk->n;
|
||||
}
|
||||
|
||||
static size_t ksl_bsearch(nghttp3_ksl *ksl, nghttp3_ksl_blk *blk,
|
||||
const nghttp3_ksl_key *key,
|
||||
nghttp3_ksl_compar compar) {
|
||||
static size_t ksl_search(const nghttp3_ksl *ksl, nghttp3_ksl_blk *blk,
|
||||
const nghttp3_ksl_key *key,
|
||||
nghttp3_ksl_compar compar) {
|
||||
size_t i;
|
||||
nghttp3_ksl_node *node;
|
||||
|
||||
@@ -297,18 +302,17 @@ int nghttp3_ksl_insert(nghttp3_ksl *ksl, nghttp3_ksl_it *it,
|
||||
}
|
||||
}
|
||||
|
||||
blk = ksl->head;
|
||||
|
||||
if (blk->n == NGHTTP3_KSL_MAX_NBLK) {
|
||||
if (ksl->head->n == NGHTTP3_KSL_MAX_NBLK) {
|
||||
rv = ksl_split_head(ksl);
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
blk = ksl->head;
|
||||
}
|
||||
|
||||
blk = ksl->head;
|
||||
|
||||
for (;;) {
|
||||
i = ksl_bsearch(ksl, blk, key, ksl->compar);
|
||||
i = ksl_search(ksl, blk, key, ksl->compar);
|
||||
|
||||
if (blk->leaf) {
|
||||
if (i < blk->n &&
|
||||
@@ -316,13 +320,17 @@ int nghttp3_ksl_insert(nghttp3_ksl *ksl, nghttp3_ksl_it *it,
|
||||
if (it) {
|
||||
*it = nghttp3_ksl_end(ksl);
|
||||
}
|
||||
|
||||
return NGHTTP3_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
ksl_insert_node(ksl, blk, i, key, data);
|
||||
++ksl->n;
|
||||
|
||||
if (it) {
|
||||
nghttp3_ksl_it_init(it, ksl, blk, i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -335,16 +343,21 @@ int nghttp3_ksl_insert(nghttp3_ksl *ksl, nghttp3_ksl_it *it,
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
node = nghttp3_ksl_nth_node(ksl, blk, blk->n - 1);
|
||||
}
|
||||
|
||||
ksl_node_set_key(ksl, node, key);
|
||||
blk = node->blk;
|
||||
}
|
||||
|
||||
ksl_insert_node(ksl, blk, blk->n, key, data);
|
||||
++ksl->n;
|
||||
|
||||
if (it) {
|
||||
nghttp3_ksl_it_init(it, ksl, blk, blk->n - 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -355,8 +368,10 @@ int nghttp3_ksl_insert(nghttp3_ksl *ksl, nghttp3_ksl_it *it,
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (ksl->compar((nghttp3_ksl_key *)node->key, key)) {
|
||||
node = nghttp3_ksl_nth_node(ksl, blk, i + 1);
|
||||
|
||||
if (ksl->compar((nghttp3_ksl_key *)node->key, key)) {
|
||||
ksl_node_set_key(ksl, node, key);
|
||||
}
|
||||
@@ -382,19 +397,22 @@ static void ksl_remove_node(nghttp3_ksl *ksl, nghttp3_ksl_blk *blk, size_t i) {
|
||||
* ksl_merge_node merges 2 nodes which are the nodes at the index of
|
||||
* |i| and |i + 1|.
|
||||
*
|
||||
* If |blk| is the direct descendant of head (root) block and the head
|
||||
* block contains just 2 nodes, the merged block becomes head block,
|
||||
* which decreases the height of |ksl| by 1.
|
||||
* If |blk| is the head (root) block and it contains just 2 nodes
|
||||
* before merging nodes, the merged block becomes head block, which
|
||||
* decreases the height of |ksl| by 1.
|
||||
*
|
||||
* This function returns the pointer to the merged block.
|
||||
*/
|
||||
static nghttp3_ksl_blk *ksl_merge_node(nghttp3_ksl *ksl, nghttp3_ksl_blk *blk,
|
||||
size_t i) {
|
||||
nghttp3_ksl_node *lnode;
|
||||
nghttp3_ksl_blk *lblk, *rblk;
|
||||
|
||||
assert(i + 1 < blk->n);
|
||||
|
||||
lblk = nghttp3_ksl_nth_node(ksl, blk, i)->blk;
|
||||
lnode = nghttp3_ksl_nth_node(ksl, blk, i);
|
||||
|
||||
lblk = lnode->blk;
|
||||
rblk = nghttp3_ksl_nth_node(ksl, blk, i + 1)->blk;
|
||||
|
||||
assert(lblk->n + rblk->n < NGHTTP3_KSL_MAX_NBLK);
|
||||
@@ -404,6 +422,7 @@ static nghttp3_ksl_blk *ksl_merge_node(nghttp3_ksl *ksl, nghttp3_ksl_blk *blk,
|
||||
|
||||
lblk->n += rblk->n;
|
||||
lblk->next = rblk->next;
|
||||
|
||||
if (lblk->next) {
|
||||
lblk->next->prev = lblk;
|
||||
} else if (ksl->back == rblk) {
|
||||
@@ -417,7 +436,7 @@ static nghttp3_ksl_blk *ksl_merge_node(nghttp3_ksl *ksl, nghttp3_ksl_blk *blk,
|
||||
ksl->head = lblk;
|
||||
} else {
|
||||
ksl_remove_node(ksl, blk, i + 1);
|
||||
ksl_node_set_key(ksl, nghttp3_ksl_nth_node(ksl, blk, i),
|
||||
ksl_node_set_key(ksl, lnode,
|
||||
nghttp3_ksl_nth_node(ksl, lblk, lblk->n - 1)->key);
|
||||
}
|
||||
|
||||
@@ -431,6 +450,7 @@ static nghttp3_ksl_blk *ksl_merge_node(nghttp3_ksl *ksl, nghttp3_ksl_blk *blk,
|
||||
*/
|
||||
static void ksl_shift_left(nghttp3_ksl *ksl, nghttp3_ksl_blk *blk, size_t i) {
|
||||
nghttp3_ksl_node *lnode, *rnode;
|
||||
nghttp3_ksl_blk *lblk, *rblk;
|
||||
size_t n;
|
||||
|
||||
assert(i > 0);
|
||||
@@ -438,36 +458,37 @@ static void ksl_shift_left(nghttp3_ksl *ksl, nghttp3_ksl_blk *blk, size_t i) {
|
||||
lnode = nghttp3_ksl_nth_node(ksl, blk, i - 1);
|
||||
rnode = nghttp3_ksl_nth_node(ksl, blk, i);
|
||||
|
||||
assert(lnode->blk->n < NGHTTP3_KSL_MAX_NBLK);
|
||||
assert(rnode->blk->n > NGHTTP3_KSL_MIN_NBLK);
|
||||
lblk = lnode->blk;
|
||||
rblk = rnode->blk;
|
||||
|
||||
n = (lnode->blk->n + rnode->blk->n + 1) / 2 - lnode->blk->n;
|
||||
assert(lblk->n < NGHTTP3_KSL_MAX_NBLK);
|
||||
assert(rblk->n > NGHTTP3_KSL_MIN_NBLK);
|
||||
|
||||
n = (lblk->n + rblk->n + 1) / 2 - lblk->n;
|
||||
|
||||
assert(n > 0);
|
||||
assert(lnode->blk->n <= NGHTTP3_KSL_MAX_NBLK - n);
|
||||
assert(rnode->blk->n >= NGHTTP3_KSL_MIN_NBLK + n);
|
||||
assert(lblk->n <= NGHTTP3_KSL_MAX_NBLK - n);
|
||||
assert(rblk->n >= NGHTTP3_KSL_MIN_NBLK + n);
|
||||
|
||||
memcpy(lnode->blk->nodes + ksl->nodelen * lnode->blk->n, rnode->blk->nodes,
|
||||
ksl->nodelen * n);
|
||||
memcpy(lblk->nodes + ksl->nodelen * lblk->n, rblk->nodes, ksl->nodelen * n);
|
||||
|
||||
lnode->blk->n += (uint32_t)n;
|
||||
rnode->blk->n -= (uint32_t)n;
|
||||
lblk->n += (uint32_t)n;
|
||||
rblk->n -= (uint32_t)n;
|
||||
|
||||
ksl_node_set_key(
|
||||
ksl, lnode,
|
||||
nghttp3_ksl_nth_node(ksl, lnode->blk, lnode->blk->n - 1)->key);
|
||||
ksl_node_set_key(ksl, lnode,
|
||||
nghttp3_ksl_nth_node(ksl, lblk, lblk->n - 1)->key);
|
||||
|
||||
memmove(rnode->blk->nodes, rnode->blk->nodes + ksl->nodelen * n,
|
||||
ksl->nodelen * rnode->blk->n);
|
||||
memmove(rblk->nodes, rblk->nodes + ksl->nodelen * n, ksl->nodelen * rblk->n);
|
||||
}
|
||||
|
||||
/*
|
||||
* ksl_shift_right moves the last nodes in blk->nodes[i]->blk->nodes
|
||||
* to blk->nodes[i + 1]->blk->nodes in a manner that they have the
|
||||
* same amount of nodes as much as possible..
|
||||
* same amount of nodes as much as possible.
|
||||
*/
|
||||
static void ksl_shift_right(nghttp3_ksl *ksl, nghttp3_ksl_blk *blk, size_t i) {
|
||||
nghttp3_ksl_node *lnode, *rnode;
|
||||
nghttp3_ksl_blk *lblk, *rblk;
|
||||
size_t n;
|
||||
|
||||
assert(i < blk->n - 1);
|
||||
@@ -475,27 +496,27 @@ static void ksl_shift_right(nghttp3_ksl *ksl, nghttp3_ksl_blk *blk, size_t i) {
|
||||
lnode = nghttp3_ksl_nth_node(ksl, blk, i);
|
||||
rnode = nghttp3_ksl_nth_node(ksl, blk, i + 1);
|
||||
|
||||
assert(lnode->blk->n > NGHTTP3_KSL_MIN_NBLK);
|
||||
assert(rnode->blk->n < NGHTTP3_KSL_MAX_NBLK);
|
||||
lblk = lnode->blk;
|
||||
rblk = rnode->blk;
|
||||
|
||||
n = (lnode->blk->n + rnode->blk->n + 1) / 2 - rnode->blk->n;
|
||||
assert(lblk->n > NGHTTP3_KSL_MIN_NBLK);
|
||||
assert(rblk->n < NGHTTP3_KSL_MAX_NBLK);
|
||||
|
||||
n = (lblk->n + rblk->n + 1) / 2 - rblk->n;
|
||||
|
||||
assert(n > 0);
|
||||
assert(lnode->blk->n >= NGHTTP3_KSL_MIN_NBLK + n);
|
||||
assert(rnode->blk->n <= NGHTTP3_KSL_MAX_NBLK - n);
|
||||
assert(lblk->n >= NGHTTP3_KSL_MIN_NBLK + n);
|
||||
assert(rblk->n <= NGHTTP3_KSL_MAX_NBLK - n);
|
||||
|
||||
memmove(rnode->blk->nodes + ksl->nodelen * n, rnode->blk->nodes,
|
||||
ksl->nodelen * rnode->blk->n);
|
||||
memmove(rblk->nodes + ksl->nodelen * n, rblk->nodes, ksl->nodelen * rblk->n);
|
||||
|
||||
rnode->blk->n += (uint32_t)n;
|
||||
lnode->blk->n -= (uint32_t)n;
|
||||
rblk->n += (uint32_t)n;
|
||||
lblk->n -= (uint32_t)n;
|
||||
|
||||
memcpy(rnode->blk->nodes, lnode->blk->nodes + ksl->nodelen * lnode->blk->n,
|
||||
ksl->nodelen * n);
|
||||
memcpy(rblk->nodes, lblk->nodes + ksl->nodelen * lblk->n, ksl->nodelen * n);
|
||||
|
||||
ksl_node_set_key(
|
||||
ksl, lnode,
|
||||
nghttp3_ksl_nth_node(ksl, lnode->blk, lnode->blk->n - 1)->key);
|
||||
ksl_node_set_key(ksl, lnode,
|
||||
nghttp3_ksl_nth_node(ksl, lblk, lblk->n - 1)->key);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -539,23 +560,24 @@ int nghttp3_ksl_remove(nghttp3_ksl *ksl, nghttp3_ksl_it *it,
|
||||
nghttp3_ksl_node *node;
|
||||
size_t i;
|
||||
|
||||
if (!ksl->head) {
|
||||
if (!blk) {
|
||||
return NGHTTP3_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (!blk->leaf && blk->n == 2 &&
|
||||
nghttp3_ksl_nth_node(ksl, blk, 0)->blk->n == NGHTTP3_KSL_MIN_NBLK &&
|
||||
nghttp3_ksl_nth_node(ksl, blk, 1)->blk->n == NGHTTP3_KSL_MIN_NBLK) {
|
||||
blk = ksl_merge_node(ksl, ksl->head, 0);
|
||||
blk = ksl_merge_node(ksl, blk, 0);
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
i = ksl_bsearch(ksl, blk, key, ksl->compar);
|
||||
i = ksl_search(ksl, blk, key, ksl->compar);
|
||||
|
||||
if (i == blk->n) {
|
||||
if (it) {
|
||||
*it = nghttp3_ksl_end(ksl);
|
||||
}
|
||||
|
||||
return NGHTTP3_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
@@ -564,10 +586,13 @@ int nghttp3_ksl_remove(nghttp3_ksl *ksl, nghttp3_ksl_it *it,
|
||||
if (it) {
|
||||
*it = nghttp3_ksl_end(ksl);
|
||||
}
|
||||
|
||||
return NGHTTP3_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
ksl_remove_node(ksl, blk, i);
|
||||
--ksl->n;
|
||||
|
||||
if (it) {
|
||||
if (blk->n == i && blk->next) {
|
||||
nghttp3_ksl_it_init(it, ksl, blk->next, 0);
|
||||
@@ -575,6 +600,7 @@ int nghttp3_ksl_remove(nghttp3_ksl *ksl, nghttp3_ksl_it *it,
|
||||
nghttp3_ksl_it_init(it, ksl, blk, i);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -591,6 +617,7 @@ int nghttp3_ksl_remove(nghttp3_ksl *ksl, nghttp3_ksl_it *it,
|
||||
nghttp3_ksl_nth_node(ksl, blk, i + 1)->blk->n > NGHTTP3_KSL_MIN_NBLK) {
|
||||
ksl_shift_left(ksl, blk, i + 1);
|
||||
blk = node->blk;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -598,6 +625,7 @@ int nghttp3_ksl_remove(nghttp3_ksl *ksl, nghttp3_ksl_it *it,
|
||||
nghttp3_ksl_nth_node(ksl, blk, i - 1)->blk->n > NGHTTP3_KSL_MIN_NBLK) {
|
||||
ksl_shift_right(ksl, blk, i - 1);
|
||||
blk = node->blk;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -612,48 +640,12 @@ int nghttp3_ksl_remove(nghttp3_ksl *ksl, nghttp3_ksl_it *it,
|
||||
}
|
||||
}
|
||||
|
||||
nghttp3_ksl_it nghttp3_ksl_lower_bound(nghttp3_ksl *ksl,
|
||||
nghttp3_ksl_it nghttp3_ksl_lower_bound(const nghttp3_ksl *ksl,
|
||||
const nghttp3_ksl_key *key) {
|
||||
nghttp3_ksl_blk *blk = ksl->head;
|
||||
nghttp3_ksl_it it;
|
||||
size_t i;
|
||||
|
||||
if (!blk) {
|
||||
nghttp3_ksl_it_init(&it, ksl, &null_blk, 0);
|
||||
return it;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
i = ksl_bsearch(ksl, blk, key, ksl->compar);
|
||||
|
||||
if (blk->leaf) {
|
||||
if (i == blk->n && blk->next) {
|
||||
blk = blk->next;
|
||||
i = 0;
|
||||
}
|
||||
nghttp3_ksl_it_init(&it, ksl, blk, i);
|
||||
return it;
|
||||
}
|
||||
|
||||
if (i == blk->n) {
|
||||
/* This happens if descendant has smaller key. Fast forward to
|
||||
find last node in this subtree. */
|
||||
for (; !blk->leaf; blk = nghttp3_ksl_nth_node(ksl, blk, blk->n - 1)->blk)
|
||||
;
|
||||
if (blk->next) {
|
||||
blk = blk->next;
|
||||
i = 0;
|
||||
} else {
|
||||
i = blk->n;
|
||||
}
|
||||
nghttp3_ksl_it_init(&it, ksl, blk, i);
|
||||
return it;
|
||||
}
|
||||
blk = nghttp3_ksl_nth_node(ksl, blk, i)->blk;
|
||||
}
|
||||
return nghttp3_ksl_lower_bound_compar(ksl, key, ksl->compar);
|
||||
}
|
||||
|
||||
nghttp3_ksl_it nghttp3_ksl_lower_bound_compar(nghttp3_ksl *ksl,
|
||||
nghttp3_ksl_it nghttp3_ksl_lower_bound_compar(const nghttp3_ksl *ksl,
|
||||
const nghttp3_ksl_key *key,
|
||||
nghttp3_ksl_compar compar) {
|
||||
nghttp3_ksl_blk *blk = ksl->head;
|
||||
@@ -666,14 +658,16 @@ nghttp3_ksl_it nghttp3_ksl_lower_bound_compar(nghttp3_ksl *ksl,
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
i = ksl_bsearch(ksl, blk, key, compar);
|
||||
i = ksl_search(ksl, blk, key, compar);
|
||||
|
||||
if (blk->leaf) {
|
||||
if (i == blk->n && blk->next) {
|
||||
blk = blk->next;
|
||||
i = 0;
|
||||
}
|
||||
|
||||
nghttp3_ksl_it_init(&it, ksl, blk, i);
|
||||
|
||||
return it;
|
||||
}
|
||||
|
||||
@@ -682,15 +676,19 @@ nghttp3_ksl_it nghttp3_ksl_lower_bound_compar(nghttp3_ksl *ksl,
|
||||
find last node in this subtree. */
|
||||
for (; !blk->leaf; blk = nghttp3_ksl_nth_node(ksl, blk, blk->n - 1)->blk)
|
||||
;
|
||||
|
||||
if (blk->next) {
|
||||
blk = blk->next;
|
||||
i = 0;
|
||||
} else {
|
||||
i = blk->n;
|
||||
}
|
||||
|
||||
nghttp3_ksl_it_init(&it, ksl, blk, i);
|
||||
|
||||
return it;
|
||||
}
|
||||
|
||||
blk = nghttp3_ksl_nth_node(ksl, blk, i)->blk;
|
||||
}
|
||||
}
|
||||
@@ -704,7 +702,7 @@ void nghttp3_ksl_update_key(nghttp3_ksl *ksl, const nghttp3_ksl_key *old_key,
|
||||
assert(ksl->head);
|
||||
|
||||
for (;;) {
|
||||
i = ksl_bsearch(ksl, blk, old_key, ksl->compar);
|
||||
i = ksl_search(ksl, blk, old_key, ksl->compar);
|
||||
|
||||
assert(i < blk->n);
|
||||
node = nghttp3_ksl_nth_node(ksl, blk, i);
|
||||
@@ -712,6 +710,7 @@ void nghttp3_ksl_update_key(nghttp3_ksl *ksl, const nghttp3_ksl_key *old_key,
|
||||
if (blk->leaf) {
|
||||
assert(key_equal(ksl->compar, (nghttp3_ksl_key *)node->key, old_key));
|
||||
ksl_node_set_key(ksl, node, new_key);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -724,7 +723,7 @@ void nghttp3_ksl_update_key(nghttp3_ksl *ksl, const nghttp3_ksl_key *old_key,
|
||||
}
|
||||
}
|
||||
|
||||
size_t nghttp3_ksl_len(nghttp3_ksl *ksl) { return ksl->n; }
|
||||
size_t nghttp3_ksl_len(const nghttp3_ksl *ksl) { return ksl->n; }
|
||||
|
||||
void nghttp3_ksl_clear(nghttp3_ksl *ksl) {
|
||||
if (!ksl->head) {
|
||||
@@ -733,7 +732,7 @@ void nghttp3_ksl_clear(nghttp3_ksl *ksl) {
|
||||
|
||||
#ifdef NOMEMPOOL
|
||||
ksl_free_blk(ksl, ksl->head);
|
||||
#endif /* NOMEMPOOL */
|
||||
#endif /* defined(NOMEMPOOL) */
|
||||
|
||||
ksl->front = ksl->back = ksl->head = NULL;
|
||||
ksl->n = 0;
|
||||
@@ -742,7 +741,8 @@ void nghttp3_ksl_clear(nghttp3_ksl *ksl) {
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
static void ksl_print(nghttp3_ksl *ksl, nghttp3_ksl_blk *blk, size_t level) {
|
||||
static void ksl_print(const nghttp3_ksl *ksl, nghttp3_ksl_blk *blk,
|
||||
size_t level) {
|
||||
size_t i;
|
||||
nghttp3_ksl_node *node;
|
||||
|
||||
@@ -753,7 +753,9 @@ static void ksl_print(nghttp3_ksl *ksl, nghttp3_ksl_blk *blk, size_t level) {
|
||||
node = nghttp3_ksl_nth_node(ksl, blk, i);
|
||||
fprintf(stderr, " %" PRId64, *(int64_t *)(void *)node->key);
|
||||
}
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -762,14 +764,14 @@ static void ksl_print(nghttp3_ksl *ksl, nghttp3_ksl_blk *blk, size_t level) {
|
||||
}
|
||||
}
|
||||
|
||||
void nghttp3_ksl_print(nghttp3_ksl *ksl) {
|
||||
void nghttp3_ksl_print(const nghttp3_ksl *ksl) {
|
||||
if (!ksl->head) {
|
||||
return;
|
||||
}
|
||||
|
||||
ksl_print(ksl, ksl->head, 0);
|
||||
}
|
||||
#endif /* !WIN32 */
|
||||
#endif /* !defined(WIN32) */
|
||||
|
||||
nghttp3_ksl_it nghttp3_ksl_begin(const nghttp3_ksl *ksl) {
|
||||
nghttp3_ksl_it it;
|
||||
@@ -826,6 +828,6 @@ int nghttp3_ksl_range_compar(const nghttp3_ksl_key *lhs,
|
||||
int nghttp3_ksl_range_exclusive_compar(const nghttp3_ksl_key *lhs,
|
||||
const nghttp3_ksl_key *rhs) {
|
||||
const nghttp3_range *a = lhs, *b = rhs;
|
||||
return a->begin < b->begin &&
|
||||
!(nghttp3_max(a->begin, b->begin) < nghttp3_min(a->end, b->end));
|
||||
return a->begin < b->begin && !(nghttp3_max_uint64(a->begin, b->begin) <
|
||||
nghttp3_min_uint64(a->end, b->end));
|
||||
}
|
||||
+33
-32
@@ -28,7 +28,7 @@
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#endif /* defined(HAVE_CONFIG_H) */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -36,16 +36,12 @@
|
||||
|
||||
#include "nghttp3_objalloc.h"
|
||||
|
||||
/*
|
||||
* Skip List using single key instead of range.
|
||||
*/
|
||||
|
||||
#define NGHTTP3_KSL_DEGR 16
|
||||
/* NGHTTP3_KSL_MAX_NBLK is the maximum number of nodes which a single
|
||||
block can contain. */
|
||||
#define NGHTTP3_KSL_MAX_NBLK (2 * NGHTTP3_KSL_DEGR - 1)
|
||||
/* NGHTTP3_KSL_MIN_NBLK is the minimum number of nodes which a single
|
||||
block other than root must contains. */
|
||||
block other than root must contain. */
|
||||
#define NGHTTP3_KSL_MIN_NBLK (NGHTTP3_KSL_DEGR - 1)
|
||||
|
||||
/*
|
||||
@@ -122,7 +118,7 @@ typedef struct nghttp3_ksl nghttp3_ksl;
|
||||
typedef struct nghttp3_ksl_it nghttp3_ksl_it;
|
||||
|
||||
/*
|
||||
* nghttp3_ksl_it is a forward iterator to iterate nodes.
|
||||
* nghttp3_ksl_it is a bidirectional iterator to iterate nodes.
|
||||
*/
|
||||
struct nghttp3_ksl_it {
|
||||
const nghttp3_ksl *ksl;
|
||||
@@ -142,6 +138,7 @@ struct nghttp3_ksl {
|
||||
/* back points to the last leaf block. */
|
||||
nghttp3_ksl_blk *back;
|
||||
nghttp3_ksl_compar compar;
|
||||
/* n is the number of elements stored. */
|
||||
size_t n;
|
||||
/* keylen is the size of key */
|
||||
size_t keylen;
|
||||
@@ -152,7 +149,8 @@ struct nghttp3_ksl {
|
||||
|
||||
/*
|
||||
* nghttp3_ksl_init initializes |ksl|. |compar| specifies compare
|
||||
* function. |keylen| is the length of key.
|
||||
* function. |keylen| is the length of key and must be at least
|
||||
* sizeof(uint64_t).
|
||||
*/
|
||||
void nghttp3_ksl_init(nghttp3_ksl *ksl, nghttp3_ksl_compar compar,
|
||||
size_t keylen, const nghttp3_mem *mem);
|
||||
@@ -167,15 +165,15 @@ void nghttp3_ksl_free(nghttp3_ksl *ksl);
|
||||
/*
|
||||
* nghttp3_ksl_insert inserts |key| with its associated |data|. On
|
||||
* successful insertion, the iterator points to the inserted node is
|
||||
* stored in |*it|.
|
||||
* stored in |*it| if |it| is not NULL.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP3_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* Out of memory.
|
||||
* NGHTTP3_ERR_INVALID_ARGUMENT
|
||||
* |key| already exists.
|
||||
* |key| already exists.
|
||||
*/
|
||||
int nghttp3_ksl_insert(nghttp3_ksl *ksl, nghttp3_ksl_it *it,
|
||||
const nghttp3_ksl_key *key, void *data);
|
||||
@@ -186,13 +184,14 @@ int nghttp3_ksl_insert(nghttp3_ksl *ksl, nghttp3_ksl_it *it,
|
||||
* This function assigns the iterator to |*it|, which points to the
|
||||
* node which is located at the right next of the removed node if |it|
|
||||
* is not NULL. If |key| is not found, no deletion takes place and
|
||||
* the return value of nghttp3_ksl_end(ksl) is assigned to |*it|.
|
||||
* the return value of nghttp3_ksl_end(ksl) is assigned to |*it| if
|
||||
* |it| is not NULL.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP3_ERR_INVALID_ARGUMENT
|
||||
* |key| does not exist.
|
||||
* |key| does not exist.
|
||||
*/
|
||||
int nghttp3_ksl_remove(nghttp3_ksl *ksl, nghttp3_ksl_it *it,
|
||||
const nghttp3_ksl_key *key);
|
||||
@@ -212,24 +211,24 @@ int nghttp3_ksl_remove_hint(nghttp3_ksl *ksl, nghttp3_ksl_it *it,
|
||||
* nghttp3_ksl_lower_bound returns the iterator which points to the
|
||||
* first node which has the key which is equal to |key| or the last
|
||||
* node which satisfies !compar(&node->key, key). If there is no such
|
||||
* node, it returns the iterator which satisfies nghttp3_ksl_it_end(it)
|
||||
* != 0.
|
||||
* node, it returns the iterator which satisfies
|
||||
* nghttp3_ksl_it_end(it) != 0.
|
||||
*/
|
||||
nghttp3_ksl_it nghttp3_ksl_lower_bound(nghttp3_ksl *ksl,
|
||||
nghttp3_ksl_it nghttp3_ksl_lower_bound(const nghttp3_ksl *ksl,
|
||||
const nghttp3_ksl_key *key);
|
||||
|
||||
/*
|
||||
* nghttp3_ksl_lower_bound_compar works like nghttp3_ksl_lower_bound,
|
||||
* but it takes custom function |compar| to do lower bound search.
|
||||
*/
|
||||
nghttp3_ksl_it nghttp3_ksl_lower_bound_compar(nghttp3_ksl *ksl,
|
||||
nghttp3_ksl_it nghttp3_ksl_lower_bound_compar(const nghttp3_ksl *ksl,
|
||||
const nghttp3_ksl_key *key,
|
||||
nghttp3_ksl_compar compar);
|
||||
|
||||
/*
|
||||
* nghttp3_ksl_update_key replaces the key of nodes which has |old_key|
|
||||
* with |new_key|. |new_key| must be strictly greater than the
|
||||
* previous node and strictly smaller than the next node.
|
||||
* nghttp3_ksl_update_key replaces the key of nodes which has
|
||||
* |old_key| with |new_key|. |new_key| must be strictly greater than
|
||||
* the previous node and strictly smaller than the next node.
|
||||
*/
|
||||
void nghttp3_ksl_update_key(nghttp3_ksl *ksl, const nghttp3_ksl_key *old_key,
|
||||
const nghttp3_ksl_key *new_key);
|
||||
@@ -237,7 +236,8 @@ void nghttp3_ksl_update_key(nghttp3_ksl *ksl, const nghttp3_ksl_key *old_key,
|
||||
/*
|
||||
* nghttp3_ksl_begin returns the iterator which points to the first
|
||||
* node. If there is no node in |ksl|, it returns the iterator which
|
||||
* satisfies nghttp3_ksl_it_end(it) != 0.
|
||||
* satisfies both nghttp3_ksl_it_begin(it) != 0 and
|
||||
* nghttp3_ksl_it_end(it) != 0.
|
||||
*/
|
||||
nghttp3_ksl_it nghttp3_ksl_begin(const nghttp3_ksl *ksl);
|
||||
|
||||
@@ -245,14 +245,15 @@ nghttp3_ksl_it nghttp3_ksl_begin(const nghttp3_ksl *ksl);
|
||||
* nghttp3_ksl_end returns the iterator which points to the node
|
||||
* following the last node. The returned object satisfies
|
||||
* nghttp3_ksl_it_end(). If there is no node in |ksl|, it returns the
|
||||
* iterator which satisfies nghttp3_ksl_it_begin(it) != 0.
|
||||
* iterator which satisfies nghttp3_ksl_it_begin(it) != 0 and
|
||||
* nghttp3_ksl_it_end(it) != 0.
|
||||
*/
|
||||
nghttp3_ksl_it nghttp3_ksl_end(const nghttp3_ksl *ksl);
|
||||
|
||||
/*
|
||||
* nghttp3_ksl_len returns the number of elements stored in |ksl|.
|
||||
*/
|
||||
size_t nghttp3_ksl_len(nghttp3_ksl *ksl);
|
||||
size_t nghttp3_ksl_len(const nghttp3_ksl *ksl);
|
||||
|
||||
/*
|
||||
* nghttp3_ksl_clear removes all elements stored in |ksl|.
|
||||
@@ -271,8 +272,8 @@ void nghttp3_ksl_clear(nghttp3_ksl *ksl);
|
||||
* that the key is of type int64_t. This function should be used for
|
||||
* the debugging purpose only.
|
||||
*/
|
||||
void nghttp3_ksl_print(nghttp3_ksl *ksl);
|
||||
#endif /* !WIN32 */
|
||||
void nghttp3_ksl_print(const nghttp3_ksl *ksl);
|
||||
#endif /* !defined(WIN32) */
|
||||
|
||||
/*
|
||||
* nghttp3_ksl_it_init initializes |it|.
|
||||
@@ -295,8 +296,8 @@ void nghttp3_ksl_it_init(nghttp3_ksl_it *it, const nghttp3_ksl *ksl,
|
||||
*/
|
||||
#define nghttp3_ksl_it_next(IT) \
|
||||
(++(IT)->i == (IT)->blk->n && (IT)->blk->next \
|
||||
? ((IT)->blk = (IT)->blk->next, (IT)->i = 0) \
|
||||
: 0)
|
||||
? ((IT)->blk = (IT)->blk->next, (IT)->i = 0) \
|
||||
: 0)
|
||||
|
||||
/*
|
||||
* nghttp3_ksl_it_prev moves backward the iterator by one. It is
|
||||
@@ -306,16 +307,16 @@ void nghttp3_ksl_it_init(nghttp3_ksl_it *it, const nghttp3_ksl *ksl,
|
||||
void nghttp3_ksl_it_prev(nghttp3_ksl_it *it);
|
||||
|
||||
/*
|
||||
* nghttp3_ksl_it_end returns nonzero if |it| points to the beyond the
|
||||
* last node.
|
||||
* nghttp3_ksl_it_end returns nonzero if |it| points to the one beyond
|
||||
* the last node.
|
||||
*/
|
||||
#define nghttp3_ksl_it_end(IT) \
|
||||
((IT)->blk->n == (IT)->i && (IT)->blk->next == NULL)
|
||||
|
||||
/*
|
||||
* nghttp3_ksl_it_begin returns nonzero if |it| points to the first
|
||||
* node. |it| might satisfy both nghttp3_ksl_it_begin(&it) and
|
||||
* nghttp3_ksl_it_end(&it) if the skip list has no node.
|
||||
* node. |it| might satisfy both nghttp3_ksl_it_begin(it) != 0 and
|
||||
* nghttp3_ksl_it_end(it) != 0 if the skip list has no node.
|
||||
*/
|
||||
int nghttp3_ksl_it_begin(const nghttp3_ksl_it *it);
|
||||
|
||||
@@ -347,4 +348,4 @@ int nghttp3_ksl_range_compar(const nghttp3_ksl_key *lhs,
|
||||
int nghttp3_ksl_range_exclusive_compar(const nghttp3_ksl_key *lhs,
|
||||
const nghttp3_ksl_key *rhs);
|
||||
|
||||
#endif /* NGHTTP3_KSL_H */
|
||||
#endif /* !defined(NGHTTP3_KSL_H) */
|
||||
+29
-6
@@ -28,17 +28,14 @@
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#endif /* defined(HAVE_CONFIG_H) */
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <nghttp3/nghttp3.h>
|
||||
|
||||
#define nghttp3_min(A, B) ((A) < (B) ? (A) : (B))
|
||||
#define nghttp3_max(A, B) ((A) > (B) ? (A) : (B))
|
||||
|
||||
#define nghttp3_struct_of(ptr, type, member) \
|
||||
((type *)(void *)((char *)(ptr)-offsetof(type, member)))
|
||||
((type *)(void *)((char *)(ptr) - offsetof(type, member)))
|
||||
|
||||
#define nghttp3_arraylen(A) (sizeof(A) / sizeof(*(A)))
|
||||
|
||||
@@ -48,4 +45,30 @@
|
||||
variable-length integer encoding. */
|
||||
#define NGHTTP3_MAX_VARINT ((1ULL << 62) - 1)
|
||||
|
||||
#endif /* NGHTTP3_MACRO_H */
|
||||
#define nghttp3_max_def(SUFFIX, T) \
|
||||
static inline T nghttp3_max_##SUFFIX(T a, T b) { return a < b ? b : a; }
|
||||
|
||||
nghttp3_max_def(int8, int8_t);
|
||||
nghttp3_max_def(int16, int16_t);
|
||||
nghttp3_max_def(int32, int32_t);
|
||||
nghttp3_max_def(int64, int64_t);
|
||||
nghttp3_max_def(uint8, uint8_t);
|
||||
nghttp3_max_def(uint16, uint16_t);
|
||||
nghttp3_max_def(uint32, uint32_t);
|
||||
nghttp3_max_def(uint64, uint64_t);
|
||||
nghttp3_max_def(size, size_t);
|
||||
|
||||
#define nghttp3_min_def(SUFFIX, T) \
|
||||
static inline T nghttp3_min_##SUFFIX(T a, T b) { return a < b ? a : b; }
|
||||
|
||||
nghttp3_min_def(int8, int8_t);
|
||||
nghttp3_min_def(int16, int16_t);
|
||||
nghttp3_min_def(int32, int32_t);
|
||||
nghttp3_min_def(int64, int64_t);
|
||||
nghttp3_min_def(uint8, uint8_t);
|
||||
nghttp3_min_def(uint16, uint16_t);
|
||||
nghttp3_min_def(uint32, uint32_t);
|
||||
nghttp3_min_def(uint64, uint64_t);
|
||||
nghttp3_min_def(size, size_t);
|
||||
|
||||
#endif /* !defined(NGHTTP3_MACRO_H) */
|
||||
+92
-128
@@ -36,8 +36,7 @@
|
||||
|
||||
void nghttp3_map_init(nghttp3_map *map, const nghttp3_mem *mem) {
|
||||
map->mem = mem;
|
||||
map->tablelen = 0;
|
||||
map->tablelenbits = 0;
|
||||
map->hashbits = 0;
|
||||
map->table = NULL;
|
||||
map->size = 0;
|
||||
}
|
||||
@@ -50,33 +49,20 @@ void nghttp3_map_free(nghttp3_map *map) {
|
||||
nghttp3_mem_free(map->mem, map->table);
|
||||
}
|
||||
|
||||
void nghttp3_map_each_free(nghttp3_map *map, int (*func)(void *data, void *ptr),
|
||||
void *ptr) {
|
||||
uint32_t i;
|
||||
nghttp3_map_bucket *bkt;
|
||||
|
||||
for (i = 0; i < map->tablelen; ++i) {
|
||||
bkt = &map->table[i];
|
||||
|
||||
if (bkt->data == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
func(bkt->data, ptr);
|
||||
}
|
||||
}
|
||||
|
||||
int nghttp3_map_each(nghttp3_map *map, int (*func)(void *data, void *ptr),
|
||||
int nghttp3_map_each(const nghttp3_map *map, int (*func)(void *data, void *ptr),
|
||||
void *ptr) {
|
||||
int rv;
|
||||
uint32_t i;
|
||||
size_t i;
|
||||
nghttp3_map_bucket *bkt;
|
||||
size_t tablelen;
|
||||
|
||||
if (map->size == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < map->tablelen; ++i) {
|
||||
tablelen = 1u << map->hashbits;
|
||||
|
||||
for (i = 0; i < tablelen; ++i) {
|
||||
bkt = &map->table[i];
|
||||
|
||||
if (bkt->data == NULL) {
|
||||
@@ -92,82 +78,61 @@ int nghttp3_map_each(nghttp3_map *map, int (*func)(void *data, void *ptr),
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t hash(nghttp3_map_key_type key) {
|
||||
return (uint32_t)((key * 11400714819323198485llu) >> 32);
|
||||
static size_t hash(nghttp3_map_key_type key, size_t bits) {
|
||||
return (size_t)((key * 11400714819323198485llu) >> (64 - bits));
|
||||
}
|
||||
|
||||
static size_t h2idx(uint32_t hash, uint32_t bits) {
|
||||
return hash >> (32 - bits);
|
||||
}
|
||||
static void map_bucket_swap(nghttp3_map_bucket *a, nghttp3_map_bucket *b) {
|
||||
nghttp3_map_bucket c = *a;
|
||||
|
||||
static size_t distance(uint32_t tablelen, uint32_t tablelenbits,
|
||||
nghttp3_map_bucket *bkt, size_t idx) {
|
||||
return (idx - h2idx(bkt->hash, tablelenbits)) & (tablelen - 1);
|
||||
}
|
||||
|
||||
static void map_bucket_swap(nghttp3_map_bucket *bkt, uint32_t *phash,
|
||||
nghttp3_map_key_type *pkey, void **pdata) {
|
||||
uint32_t h = bkt->hash;
|
||||
nghttp3_map_key_type key = bkt->key;
|
||||
void *data = bkt->data;
|
||||
|
||||
bkt->hash = *phash;
|
||||
bkt->key = *pkey;
|
||||
bkt->data = *pdata;
|
||||
|
||||
*phash = h;
|
||||
*pkey = key;
|
||||
*pdata = data;
|
||||
}
|
||||
|
||||
static void map_bucket_set_data(nghttp3_map_bucket *bkt, uint32_t hash,
|
||||
nghttp3_map_key_type key, void *data) {
|
||||
bkt->hash = hash;
|
||||
bkt->key = key;
|
||||
bkt->data = data;
|
||||
*a = *b;
|
||||
*b = c;
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
void nghttp3_map_print_distance(nghttp3_map *map) {
|
||||
uint32_t i;
|
||||
void nghttp3_map_print_distance(const nghttp3_map *map) {
|
||||
size_t i;
|
||||
size_t idx;
|
||||
nghttp3_map_bucket *bkt;
|
||||
size_t tablelen;
|
||||
|
||||
for (i = 0; i < map->tablelen; ++i) {
|
||||
if (map->size == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
tablelen = 1u << map->hashbits;
|
||||
|
||||
for (i = 0; i < tablelen; ++i) {
|
||||
bkt = &map->table[i];
|
||||
|
||||
if (bkt->data == NULL) {
|
||||
fprintf(stderr, "@%u <EMPTY>\n", i);
|
||||
fprintf(stderr, "@%zu <EMPTY>\n", i);
|
||||
continue;
|
||||
}
|
||||
|
||||
idx = h2idx(bkt->hash, map->tablelenbits);
|
||||
fprintf(stderr, "@%u hash=%08x key=%" PRIu64 " base=%zu distance=%zu\n", i,
|
||||
bkt->hash, bkt->key, idx,
|
||||
distance(map->tablelen, map->tablelenbits, bkt, idx));
|
||||
idx = hash(bkt->key, map->hashbits);
|
||||
fprintf(stderr, "@%zu hash=%zu key=%" PRIu64 " base=%zu distance=%u\n", i,
|
||||
hash(bkt->key, map->hashbits), bkt->key, idx, bkt->psl);
|
||||
}
|
||||
}
|
||||
#endif /* !WIN32 */
|
||||
#endif /* !defined(WIN32) */
|
||||
|
||||
static int insert(nghttp3_map_bucket *table, uint32_t tablelen,
|
||||
uint32_t tablelenbits, uint32_t hash,
|
||||
static int insert(nghttp3_map_bucket *table, size_t hashbits,
|
||||
nghttp3_map_key_type key, void *data) {
|
||||
size_t idx = h2idx(hash, tablelenbits);
|
||||
size_t d = 0, dd;
|
||||
nghttp3_map_bucket *bkt;
|
||||
size_t idx = hash(key, hashbits);
|
||||
nghttp3_map_bucket b = {0, key, data}, *bkt;
|
||||
size_t mask = (1u << hashbits) - 1;
|
||||
|
||||
for (;;) {
|
||||
bkt = &table[idx];
|
||||
|
||||
if (bkt->data == NULL) {
|
||||
map_bucket_set_data(bkt, hash, key, data);
|
||||
*bkt = b;
|
||||
return 0;
|
||||
}
|
||||
|
||||
dd = distance(tablelen, tablelenbits, bkt, idx);
|
||||
if (d > dd) {
|
||||
map_bucket_swap(bkt, &hash, &key, &data);
|
||||
d = dd;
|
||||
if (b.psl > bkt->psl) {
|
||||
map_bucket_swap(bkt, &b);
|
||||
} else if (bkt->key == key) {
|
||||
/* TODO This check is just a waste after first swap or if this
|
||||
function is called from map_resize. That said, there is no
|
||||
@@ -176,41 +141,42 @@ static int insert(nghttp3_map_bucket *table, uint32_t tablelen,
|
||||
return NGHTTP3_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
++d;
|
||||
idx = (idx + 1) & (tablelen - 1);
|
||||
++b.psl;
|
||||
idx = (idx + 1) & mask;
|
||||
}
|
||||
}
|
||||
|
||||
/* new_tablelen must be power of 2 and new_tablelen == (1 <<
|
||||
new_tablelenbits) must hold. */
|
||||
static int map_resize(nghttp3_map *map, uint32_t new_tablelen,
|
||||
uint32_t new_tablelenbits) {
|
||||
uint32_t i;
|
||||
static int map_resize(nghttp3_map *map, size_t new_hashbits) {
|
||||
size_t i;
|
||||
nghttp3_map_bucket *new_table;
|
||||
nghttp3_map_bucket *bkt;
|
||||
size_t tablelen;
|
||||
int rv;
|
||||
(void)rv;
|
||||
|
||||
new_table =
|
||||
nghttp3_mem_calloc(map->mem, new_tablelen, sizeof(nghttp3_map_bucket));
|
||||
new_table = nghttp3_mem_calloc(map->mem, 1u << new_hashbits,
|
||||
sizeof(nghttp3_map_bucket));
|
||||
if (new_table == NULL) {
|
||||
return NGHTTP3_ERR_NOMEM;
|
||||
}
|
||||
|
||||
for (i = 0; i < map->tablelen; ++i) {
|
||||
bkt = &map->table[i];
|
||||
if (bkt->data == NULL) {
|
||||
continue;
|
||||
}
|
||||
rv = insert(new_table, new_tablelen, new_tablelenbits, bkt->hash, bkt->key,
|
||||
bkt->data);
|
||||
if (map->size) {
|
||||
tablelen = 1u << map->hashbits;
|
||||
|
||||
assert(0 == rv);
|
||||
for (i = 0; i < tablelen; ++i) {
|
||||
bkt = &map->table[i];
|
||||
if (bkt->data == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
rv = insert(new_table, new_hashbits, bkt->key, bkt->data);
|
||||
|
||||
assert(0 == rv);
|
||||
}
|
||||
}
|
||||
|
||||
nghttp3_mem_free(map->mem, map->table);
|
||||
map->tablelen = new_tablelen;
|
||||
map->tablelenbits = new_tablelenbits;
|
||||
map->hashbits = new_hashbits;
|
||||
map->table = new_table;
|
||||
|
||||
return 0;
|
||||
@@ -222,48 +188,49 @@ int nghttp3_map_insert(nghttp3_map *map, nghttp3_map_key_type key, void *data) {
|
||||
assert(data);
|
||||
|
||||
/* Load factor is 0.75 */
|
||||
if ((map->size + 1) * 4 > map->tablelen * 3) {
|
||||
if (map->tablelen) {
|
||||
rv = map_resize(map, map->tablelen * 2, map->tablelenbits + 1);
|
||||
/* Under the very initial condition, that is map->size == 0 and
|
||||
map->hashbits == 0, 4 > 3 still holds nicely. */
|
||||
if ((map->size + 1) * 4 > (1u << map->hashbits) * 3) {
|
||||
if (map->hashbits) {
|
||||
rv = map_resize(map, map->hashbits + 1);
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
} else {
|
||||
rv = map_resize(map, 1 << NGHTTP3_INITIAL_TABLE_LENBITS,
|
||||
NGHTTP3_INITIAL_TABLE_LENBITS);
|
||||
rv = map_resize(map, NGHTTP3_INITIAL_TABLE_LENBITS);
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rv = insert(map->table, map->tablelen, map->tablelenbits, hash(key), key,
|
||||
data);
|
||||
rv = insert(map->table, map->hashbits, key, data);
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
++map->size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *nghttp3_map_find(nghttp3_map *map, nghttp3_map_key_type key) {
|
||||
uint32_t h;
|
||||
void *nghttp3_map_find(const nghttp3_map *map, nghttp3_map_key_type key) {
|
||||
size_t idx;
|
||||
nghttp3_map_bucket *bkt;
|
||||
size_t d = 0;
|
||||
size_t psl = 0;
|
||||
size_t mask;
|
||||
|
||||
if (map->size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
h = hash(key);
|
||||
idx = h2idx(h, map->tablelenbits);
|
||||
idx = hash(key, map->hashbits);
|
||||
mask = (1u << map->hashbits) - 1;
|
||||
|
||||
for (;;) {
|
||||
bkt = &map->table[idx];
|
||||
|
||||
if (bkt->data == NULL ||
|
||||
d > distance(map->tablelen, map->tablelenbits, bkt, idx)) {
|
||||
if (bkt->data == NULL || psl > bkt->psl) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -271,50 +238,47 @@ void *nghttp3_map_find(nghttp3_map *map, nghttp3_map_key_type key) {
|
||||
return bkt->data;
|
||||
}
|
||||
|
||||
++d;
|
||||
idx = (idx + 1) & (map->tablelen - 1);
|
||||
++psl;
|
||||
idx = (idx + 1) & mask;
|
||||
}
|
||||
}
|
||||
|
||||
int nghttp3_map_remove(nghttp3_map *map, nghttp3_map_key_type key) {
|
||||
uint32_t h;
|
||||
size_t idx, didx;
|
||||
nghttp3_map_bucket *bkt;
|
||||
size_t d = 0;
|
||||
size_t idx;
|
||||
nghttp3_map_bucket *b, *bkt;
|
||||
size_t psl = 0;
|
||||
size_t mask;
|
||||
|
||||
if (map->size == 0) {
|
||||
return NGHTTP3_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
h = hash(key);
|
||||
idx = h2idx(h, map->tablelenbits);
|
||||
idx = hash(key, map->hashbits);
|
||||
mask = (1u << map->hashbits) - 1;
|
||||
|
||||
for (;;) {
|
||||
bkt = &map->table[idx];
|
||||
|
||||
if (bkt->data == NULL ||
|
||||
d > distance(map->tablelen, map->tablelenbits, bkt, idx)) {
|
||||
if (bkt->data == NULL || psl > bkt->psl) {
|
||||
return NGHTTP3_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (bkt->key == key) {
|
||||
map_bucket_set_data(bkt, 0, 0, NULL);
|
||||
|
||||
didx = idx;
|
||||
idx = (idx + 1) & (map->tablelen - 1);
|
||||
b = bkt;
|
||||
idx = (idx + 1) & mask;
|
||||
|
||||
for (;;) {
|
||||
bkt = &map->table[idx];
|
||||
if (bkt->data == NULL ||
|
||||
distance(map->tablelen, map->tablelenbits, bkt, idx) == 0) {
|
||||
if (bkt->data == NULL || bkt->psl == 0) {
|
||||
b->data = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
map->table[didx] = *bkt;
|
||||
map_bucket_set_data(bkt, 0, 0, NULL);
|
||||
didx = idx;
|
||||
--bkt->psl;
|
||||
*b = *bkt;
|
||||
b = bkt;
|
||||
|
||||
idx = (idx + 1) & (map->tablelen - 1);
|
||||
idx = (idx + 1) & mask;
|
||||
}
|
||||
|
||||
--map->size;
|
||||
@@ -322,18 +286,18 @@ int nghttp3_map_remove(nghttp3_map *map, nghttp3_map_key_type key) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
++d;
|
||||
idx = (idx + 1) & (map->tablelen - 1);
|
||||
++psl;
|
||||
idx = (idx + 1) & mask;
|
||||
}
|
||||
}
|
||||
|
||||
void nghttp3_map_clear(nghttp3_map *map) {
|
||||
if (map->tablelen == 0) {
|
||||
if (map->size == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
memset(map->table, 0, sizeof(*map->table) * map->tablelen);
|
||||
memset(map->table, 0, sizeof(*map->table) * (1u << map->hashbits));
|
||||
map->size = 0;
|
||||
}
|
||||
|
||||
size_t nghttp3_map_size(nghttp3_map *map) { return map->size; }
|
||||
size_t nghttp3_map_size(const nghttp3_map *map) { return map->size; }
|
||||
+28
-38
@@ -29,7 +29,7 @@
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#endif /* defined(HAVE_CONFIG_H) */
|
||||
|
||||
#include <nghttp3/nghttp3.h>
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
typedef uint64_t nghttp3_map_key_type;
|
||||
|
||||
typedef struct nghttp3_map_bucket {
|
||||
uint32_t hash;
|
||||
uint32_t psl;
|
||||
nghttp3_map_key_type key;
|
||||
void *data;
|
||||
} nghttp3_map_bucket;
|
||||
@@ -49,33 +49,24 @@ typedef struct nghttp3_map {
|
||||
nghttp3_map_bucket *table;
|
||||
const nghttp3_mem *mem;
|
||||
size_t size;
|
||||
uint32_t tablelen;
|
||||
uint32_t tablelenbits;
|
||||
size_t hashbits;
|
||||
} nghttp3_map;
|
||||
|
||||
/*
|
||||
* Initializes the map |map|.
|
||||
* nghttp3_map_init initializes the map |map|.
|
||||
*/
|
||||
void nghttp3_map_init(nghttp3_map *map, const nghttp3_mem *mem);
|
||||
|
||||
/*
|
||||
* Deallocates any resources allocated for |map|. The stored entries
|
||||
* are not freed by this function. Use nghttp3_map_each_free() to free
|
||||
* each entries.
|
||||
* nghttp3_map_free deallocates any resources allocated for |map|.
|
||||
* The stored entries are not freed by this function. Use
|
||||
* nghttp3_map_each() to free each entry.
|
||||
*/
|
||||
void nghttp3_map_free(nghttp3_map *map);
|
||||
|
||||
/*
|
||||
* Deallocates each entries using |func| function and any resources
|
||||
* allocated for |map|. The |func| function is responsible for freeing
|
||||
* given the |data| object. The |ptr| will be passed to the |func| as
|
||||
* send argument. The return value of the |func| will be ignored.
|
||||
*/
|
||||
void nghttp3_map_each_free(nghttp3_map *map, int (*func)(void *data, void *ptr),
|
||||
void *ptr);
|
||||
|
||||
/*
|
||||
* Inserts the new |data| with the |key| to the map |map|.
|
||||
* nghttp3_map_insert inserts the new |data| with the |key| to the map
|
||||
* |map|.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
@@ -83,57 +74,56 @@ void nghttp3_map_each_free(nghttp3_map *map, int (*func)(void *data, void *ptr),
|
||||
* NGHTTP3_ERR_INVALID_ARGUMENT
|
||||
* The item associated by |key| already exists.
|
||||
* NGHTTP3_ERR_NOMEM
|
||||
* Out of memory
|
||||
* Out of memory
|
||||
*/
|
||||
int nghttp3_map_insert(nghttp3_map *map, nghttp3_map_key_type key, void *data);
|
||||
|
||||
/*
|
||||
* Returns the data associated by the key |key|. If there is no such
|
||||
* data, this function returns NULL.
|
||||
* nghttp3_map_find returns the entry associated by the key |key|. If
|
||||
* there is no such entry, this function returns NULL.
|
||||
*/
|
||||
void *nghttp3_map_find(nghttp3_map *map, nghttp3_map_key_type key);
|
||||
void *nghttp3_map_find(const nghttp3_map *map, nghttp3_map_key_type key);
|
||||
|
||||
/*
|
||||
* Removes the data associated by the key |key| from the |map|. The
|
||||
* removed data is not freed by this function.
|
||||
* nghttp3_map_remove removes the entry associated by the key |key|
|
||||
* from the |map|. The removed entry is not freed by this function.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP3_ERR_INVALID_ARGUMENT
|
||||
* The data associated by |key| does not exist.
|
||||
* The entry associated by |key| does not exist.
|
||||
*/
|
||||
int nghttp3_map_remove(nghttp3_map *map, nghttp3_map_key_type key);
|
||||
|
||||
/*
|
||||
* Removes all entries from |map|.
|
||||
* nghttp3_map_clear removes all entries from |map|. The removed
|
||||
* entry is not freed by this function.
|
||||
*/
|
||||
void nghttp3_map_clear(nghttp3_map *map);
|
||||
|
||||
/*
|
||||
* Returns the number of items stored in the map |map|.
|
||||
* nghttp3_map_size returns the number of items stored in the map
|
||||
* |map|.
|
||||
*/
|
||||
size_t nghttp3_map_size(nghttp3_map *map);
|
||||
size_t nghttp3_map_size(const nghttp3_map *map);
|
||||
|
||||
/*
|
||||
* Applies the function |func| to each data in the |map| with the
|
||||
* optional user supplied pointer |ptr|.
|
||||
* nghttp3_map_each applies the function |func| to each entry in the
|
||||
* |map| with the optional user supplied pointer |ptr|.
|
||||
*
|
||||
* If the |func| returns 0, this function calls the |func| with the
|
||||
* next data. If the |func| returns nonzero, it will not call the
|
||||
* next entry. If the |func| returns nonzero, it will not call the
|
||||
* |func| for further entries and return the return value of the
|
||||
* |func| immediately. Thus, this function returns 0 if all the
|
||||
* invocations of the |func| return 0, or nonzero value which the last
|
||||
* invocation of |func| returns.
|
||||
*
|
||||
* Don't use this function to free each data. Use
|
||||
* nghttp3_map_each_free() instead.
|
||||
*/
|
||||
int nghttp3_map_each(nghttp3_map *map, int (*func)(void *data, void *ptr),
|
||||
int nghttp3_map_each(const nghttp3_map *map, int (*func)(void *data, void *ptr),
|
||||
void *ptr);
|
||||
|
||||
#ifndef WIN32
|
||||
void nghttp3_map_print_distance(nghttp3_map *map);
|
||||
#endif /* !WIN32 */
|
||||
void nghttp3_map_print_distance(const nghttp3_map *map);
|
||||
#endif /* !defined(WIN32) */
|
||||
|
||||
#endif /* NGHTTP3_MAP_H */
|
||||
#endif /* !defined(NGHTTP3_MAP_H) */
|
||||
+2
-2
@@ -73,7 +73,7 @@ void *nghttp3_mem_calloc(const nghttp3_mem *mem, size_t nmemb, size_t size) {
|
||||
void *nghttp3_mem_realloc(const nghttp3_mem *mem, void *ptr, size_t size) {
|
||||
return mem->realloc(ptr, size, mem->user_data);
|
||||
}
|
||||
#else /* MEMDEBUG */
|
||||
#else /* defined(MEMDEBUG) */
|
||||
void *nghttp3_mem_malloc_debug(const nghttp3_mem *mem, size_t size,
|
||||
const char *func, const char *file,
|
||||
size_t line) {
|
||||
@@ -121,4 +121,4 @@ void *nghttp3_mem_realloc_debug(const nghttp3_mem *mem, void *ptr, size_t size,
|
||||
|
||||
return nptr;
|
||||
}
|
||||
#endif /* MEMDEBUG */
|
||||
#endif /* defined(MEMDEBUG) */
|
||||
+4
-4
@@ -29,7 +29,7 @@
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#endif /* defined(HAVE_CONFIG_H) */
|
||||
|
||||
#include <nghttp3/nghttp3.h>
|
||||
|
||||
@@ -40,7 +40,7 @@ void *nghttp3_mem_malloc(const nghttp3_mem *mem, size_t size);
|
||||
void nghttp3_mem_free(const nghttp3_mem *mem, void *ptr);
|
||||
void *nghttp3_mem_calloc(const nghttp3_mem *mem, size_t nmemb, size_t size);
|
||||
void *nghttp3_mem_realloc(const nghttp3_mem *mem, void *ptr, size_t size);
|
||||
#else /* MEMDEBUG */
|
||||
#else /* defined(MEMDEBUG) */
|
||||
void *nghttp3_mem_malloc_debug(const nghttp3_mem *mem, size_t size,
|
||||
const char *func, const char *file, size_t line);
|
||||
|
||||
@@ -75,6 +75,6 @@ void *nghttp3_mem_realloc_debug(const nghttp3_mem *mem, void *ptr, size_t size,
|
||||
# define nghttp3_mem_realloc(MEM, PTR, SIZE) \
|
||||
nghttp3_mem_realloc_debug((MEM), (PTR), (SIZE), __func__, __FILE__, \
|
||||
__LINE__)
|
||||
#endif /* MEMDEBUG */
|
||||
#endif /* defined(MEMDEBUG) */
|
||||
|
||||
#endif /* NGHTTP3_MEM_H */
|
||||
#endif /* !defined(NGHTTP3_MEM_H) */
|
||||
+14
-14
@@ -28,7 +28,7 @@
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#endif /* defined(HAVE_CONFIG_H) */
|
||||
|
||||
#include <nghttp3/nghttp3.h>
|
||||
|
||||
@@ -68,9 +68,9 @@ void nghttp3_objalloc_clear(nghttp3_objalloc *objalloc);
|
||||
#ifndef NOMEMPOOL
|
||||
# define nghttp3_objalloc_decl(NAME, TYPE, OPLENTFIELD) \
|
||||
inline static void nghttp3_objalloc_##NAME##_init( \
|
||||
nghttp3_objalloc *objalloc, size_t nmemb, const nghttp3_mem *mem) { \
|
||||
nghttp3_objalloc *objalloc, size_t nmemb, const nghttp3_mem *mem) { \
|
||||
nghttp3_objalloc_init( \
|
||||
objalloc, ((sizeof(TYPE) + 0xfu) & ~(uintptr_t)0xfu) * nmemb, mem); \
|
||||
objalloc, ((sizeof(TYPE) + 0xfu) & ~(uintptr_t)0xfu) * nmemb, mem); \
|
||||
} \
|
||||
\
|
||||
TYPE *nghttp3_objalloc_##NAME##_get(nghttp3_objalloc *objalloc); \
|
||||
@@ -79,7 +79,7 @@ void nghttp3_objalloc_clear(nghttp3_objalloc *objalloc);
|
||||
size_t len); \
|
||||
\
|
||||
inline static void nghttp3_objalloc_##NAME##_release( \
|
||||
nghttp3_objalloc *objalloc, TYPE *obj) { \
|
||||
nghttp3_objalloc *objalloc, TYPE *obj) { \
|
||||
nghttp3_opl_push(&objalloc->opl, &obj->OPLENTFIELD); \
|
||||
}
|
||||
|
||||
@@ -90,8 +90,8 @@ void nghttp3_objalloc_clear(nghttp3_objalloc *objalloc);
|
||||
int rv; \
|
||||
\
|
||||
if (!oplent) { \
|
||||
rv = nghttp3_balloc_get(&objalloc->balloc, (void **)&obj, \
|
||||
sizeof(TYPE)); \
|
||||
rv = \
|
||||
nghttp3_balloc_get(&objalloc->balloc, (void **)&obj, sizeof(TYPE)); \
|
||||
if (rv != 0) { \
|
||||
return NULL; \
|
||||
} \
|
||||
@@ -119,30 +119,30 @@ void nghttp3_objalloc_clear(nghttp3_objalloc *objalloc);
|
||||
\
|
||||
return nghttp3_struct_of(oplent, TYPE, OPLENTFIELD); \
|
||||
}
|
||||
#else /* NOMEMPOOL */
|
||||
#else /* defined(NOMEMPOOL) */
|
||||
# define nghttp3_objalloc_decl(NAME, TYPE, OPLENTFIELD) \
|
||||
inline static void nghttp3_objalloc_##NAME##_init( \
|
||||
nghttp3_objalloc *objalloc, size_t nmemb, const nghttp3_mem *mem) { \
|
||||
nghttp3_objalloc *objalloc, size_t nmemb, const nghttp3_mem *mem) { \
|
||||
nghttp3_objalloc_init( \
|
||||
objalloc, ((sizeof(TYPE) + 0xfu) & ~(uintptr_t)0xfu) * nmemb, mem); \
|
||||
objalloc, ((sizeof(TYPE) + 0xfu) & ~(uintptr_t)0xfu) * nmemb, mem); \
|
||||
} \
|
||||
\
|
||||
inline static TYPE *nghttp3_objalloc_##NAME##_get( \
|
||||
nghttp3_objalloc *objalloc) { \
|
||||
nghttp3_objalloc *objalloc) { \
|
||||
return nghttp3_mem_malloc(objalloc->balloc.mem, sizeof(TYPE)); \
|
||||
} \
|
||||
\
|
||||
inline static TYPE *nghttp3_objalloc_##NAME##_len_get( \
|
||||
nghttp3_objalloc *objalloc, size_t len) { \
|
||||
nghttp3_objalloc *objalloc, size_t len) { \
|
||||
return nghttp3_mem_malloc(objalloc->balloc.mem, len); \
|
||||
} \
|
||||
\
|
||||
inline static void nghttp3_objalloc_##NAME##_release( \
|
||||
nghttp3_objalloc *objalloc, TYPE *obj) { \
|
||||
nghttp3_objalloc *objalloc, TYPE *obj) { \
|
||||
nghttp3_mem_free(objalloc->balloc.mem, obj); \
|
||||
}
|
||||
|
||||
# define nghttp3_objalloc_def(NAME, TYPE, OPLENTFIELD)
|
||||
#endif /* NOMEMPOOL */
|
||||
#endif /* defined(NOMEMPOOL) */
|
||||
|
||||
#endif /* NGHTTP3_OBJALLOC_H */
|
||||
#endif /* !defined(NGHTTP3_OBJALLOC_H) */
|
||||
+2
-2
@@ -28,7 +28,7 @@
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#endif /* defined(HAVE_CONFIG_H) */
|
||||
|
||||
#include <nghttp3/nghttp3.h>
|
||||
|
||||
@@ -63,4 +63,4 @@ nghttp3_opl_entry *nghttp3_opl_pop(nghttp3_opl *opl);
|
||||
|
||||
void nghttp3_opl_clear(nghttp3_opl *opl);
|
||||
|
||||
#endif /* NGHTTP3_OPL_H */
|
||||
#endif /* !defined(NGHTTP3_OPL_H) */
|
||||
Vendored
+28
-13
@@ -30,18 +30,21 @@
|
||||
|
||||
#include "nghttp3_macro.h"
|
||||
|
||||
void nghttp3_pq_init(nghttp3_pq *pq, nghttp3_less less,
|
||||
void nghttp3_pq_init(nghttp3_pq *pq, nghttp3_pq_less less,
|
||||
const nghttp3_mem *mem) {
|
||||
pq->mem = mem;
|
||||
pq->capacity = 0;
|
||||
pq->q = NULL;
|
||||
pq->mem = mem;
|
||||
pq->length = 0;
|
||||
pq->capacity = 0;
|
||||
pq->less = less;
|
||||
}
|
||||
|
||||
void nghttp3_pq_free(nghttp3_pq *pq) {
|
||||
if (!pq) {
|
||||
return;
|
||||
}
|
||||
|
||||
nghttp3_mem_free(pq->mem, pq->q);
|
||||
pq->q = NULL;
|
||||
}
|
||||
|
||||
static void swap(nghttp3_pq *pq, size_t i, size_t j) {
|
||||
@@ -56,11 +59,13 @@ static void swap(nghttp3_pq *pq, size_t i, size_t j) {
|
||||
|
||||
static void bubble_up(nghttp3_pq *pq, size_t index) {
|
||||
size_t parent;
|
||||
while (index != 0) {
|
||||
|
||||
while (index) {
|
||||
parent = (index - 1) / 2;
|
||||
if (!pq->less(pq->q[index], pq->q[parent])) {
|
||||
return;
|
||||
}
|
||||
|
||||
swap(pq, parent, index);
|
||||
index = parent;
|
||||
}
|
||||
@@ -71,20 +76,23 @@ int nghttp3_pq_push(nghttp3_pq *pq, nghttp3_pq_entry *item) {
|
||||
void *nq;
|
||||
size_t ncapacity;
|
||||
|
||||
ncapacity = nghttp3_max(4, (pq->capacity * 2));
|
||||
ncapacity = nghttp3_max_size(4, pq->capacity * 2);
|
||||
|
||||
nq = nghttp3_mem_realloc(pq->mem, pq->q,
|
||||
ncapacity * sizeof(nghttp3_pq_entry *));
|
||||
if (nq == NULL) {
|
||||
return NGHTTP3_ERR_NOMEM;
|
||||
}
|
||||
|
||||
pq->capacity = ncapacity;
|
||||
pq->q = nq;
|
||||
}
|
||||
|
||||
pq->q[pq->length] = item;
|
||||
item->index = pq->length;
|
||||
++pq->length;
|
||||
bubble_up(pq, pq->length - 1);
|
||||
bubble_up(pq, item->index);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -95,32 +103,37 @@ nghttp3_pq_entry *nghttp3_pq_top(const nghttp3_pq *pq) {
|
||||
|
||||
static void bubble_down(nghttp3_pq *pq, size_t index) {
|
||||
size_t i, j, minindex;
|
||||
|
||||
for (;;) {
|
||||
j = index * 2 + 1;
|
||||
minindex = index;
|
||||
|
||||
for (i = 0; i < 2; ++i, ++j) {
|
||||
if (j >= pq->length) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (pq->less(pq->q[j], pq->q[minindex])) {
|
||||
minindex = j;
|
||||
}
|
||||
}
|
||||
|
||||
if (minindex == index) {
|
||||
return;
|
||||
}
|
||||
|
||||
swap(pq, index, minindex);
|
||||
index = minindex;
|
||||
}
|
||||
}
|
||||
|
||||
void nghttp3_pq_pop(nghttp3_pq *pq) {
|
||||
if (pq->length > 0) {
|
||||
pq->q[0] = pq->q[pq->length - 1];
|
||||
pq->q[0]->index = 0;
|
||||
--pq->length;
|
||||
bubble_down(pq, 0);
|
||||
}
|
||||
assert(pq->length);
|
||||
|
||||
pq->q[0] = pq->q[pq->length - 1];
|
||||
pq->q[0]->index = 0;
|
||||
--pq->length;
|
||||
bubble_down(pq, 0);
|
||||
}
|
||||
|
||||
void nghttp3_pq_remove(nghttp3_pq *pq, nghttp3_pq_entry *item) {
|
||||
@@ -157,11 +170,13 @@ int nghttp3_pq_each(const nghttp3_pq *pq, nghttp3_pq_item_cb fun, void *arg) {
|
||||
if (pq->length == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < pq->length; ++i) {
|
||||
if ((*fun)(pq->q[i], arg)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Vendored
+38
-30
@@ -29,7 +29,7 @@
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#endif /* defined(HAVE_CONFIG_H) */
|
||||
|
||||
#include <nghttp3/nghttp3.h>
|
||||
|
||||
@@ -39,44 +39,48 @@
|
||||
|
||||
/* NGHTTP3_PQ_BAD_INDEX is the priority queue index which indicates
|
||||
that an entry is not queued. Assigning this value to
|
||||
nghttp3_pq_entry.index can check that the entry is queued or not. */
|
||||
nghttp3_pq_entry.index can check that the entry is queued or
|
||||
not. */
|
||||
#define NGHTTP3_PQ_BAD_INDEX SIZE_MAX
|
||||
|
||||
typedef struct nghttp3_pq_entry {
|
||||
size_t index;
|
||||
} nghttp3_pq_entry;
|
||||
|
||||
/* "less" function, return nonzero if |lhs| is less than |rhs|. */
|
||||
typedef int (*nghttp3_less)(const nghttp3_pq_entry *lhs,
|
||||
const nghttp3_pq_entry *rhs);
|
||||
/* nghttp3_pq_less is a "less" function, that returns nonzero if |lhs|
|
||||
is considered to be less than |rhs|. */
|
||||
typedef int (*nghttp3_pq_less)(const nghttp3_pq_entry *lhs,
|
||||
const nghttp3_pq_entry *rhs);
|
||||
|
||||
typedef struct nghttp3_pq {
|
||||
/* The pointer to the pointer to the item stored */
|
||||
/* q is a pointer to an array that stores the items. */
|
||||
nghttp3_pq_entry **q;
|
||||
/* Memory allocator */
|
||||
/* mem is a memory allocator. */
|
||||
const nghttp3_mem *mem;
|
||||
/* The number of items stored */
|
||||
/* length is the number of items stored. */
|
||||
size_t length;
|
||||
/* The maximum number of items this pq can store. This is
|
||||
automatically extended when length is reached to this value. */
|
||||
/* capacity is the maximum number of items this queue can store.
|
||||
This is automatically extended when length is reached to this
|
||||
limit. */
|
||||
size_t capacity;
|
||||
/* The less function between items */
|
||||
nghttp3_less less;
|
||||
/* less is the less function to compare items. */
|
||||
nghttp3_pq_less less;
|
||||
} nghttp3_pq;
|
||||
|
||||
/*
|
||||
* Initializes priority queue |pq| with compare function |cmp|.
|
||||
* nghttp3_pq_init initializes |pq| with compare function |cmp|.
|
||||
*/
|
||||
void nghttp3_pq_init(nghttp3_pq *pq, nghttp3_less less, const nghttp3_mem *mem);
|
||||
void nghttp3_pq_init(nghttp3_pq *pq, nghttp3_pq_less less,
|
||||
const nghttp3_mem *mem);
|
||||
|
||||
/*
|
||||
* Deallocates any resources allocated for |pq|. The stored items are
|
||||
* not freed by this function.
|
||||
* nghttp3_pq_free deallocates any resources allocated for |pq|. The
|
||||
* stored items are not freed by this function.
|
||||
*/
|
||||
void nghttp3_pq_free(nghttp3_pq *pq);
|
||||
|
||||
/*
|
||||
* Adds |item| to the priority queue |pq|.
|
||||
* nghttp3_pq_push adds |item| to |pq|.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
@@ -87,43 +91,47 @@ void nghttp3_pq_free(nghttp3_pq *pq);
|
||||
int nghttp3_pq_push(nghttp3_pq *pq, nghttp3_pq_entry *item);
|
||||
|
||||
/*
|
||||
* Returns item at the top of the queue |pq|. It is undefined if the
|
||||
* queue is empty.
|
||||
* nghttp3_pq_top returns item at the top of |pq|. It is undefined if
|
||||
* |pq| is empty.
|
||||
*/
|
||||
nghttp3_pq_entry *nghttp3_pq_top(const nghttp3_pq *pq);
|
||||
|
||||
/*
|
||||
* Pops item at the top of the queue |pq|. The popped item is not
|
||||
* freed by this function.
|
||||
* nghttp3_pq_pop pops item at the top of |pq|. The popped item is
|
||||
* not freed by this function. It is undefined if |pq| is empty.
|
||||
*/
|
||||
void nghttp3_pq_pop(nghttp3_pq *pq);
|
||||
|
||||
/*
|
||||
* Returns nonzero if the queue |pq| is empty.
|
||||
* nghttp3_pq_empty returns nonzero if |pq| is empty.
|
||||
*/
|
||||
int nghttp3_pq_empty(const nghttp3_pq *pq);
|
||||
|
||||
/*
|
||||
* Returns the number of items in the queue |pq|.
|
||||
* nghttp3_pq_size returns the number of items |pq| contains.
|
||||
*/
|
||||
size_t nghttp3_pq_size(const nghttp3_pq *pq);
|
||||
|
||||
typedef int (*nghttp3_pq_item_cb)(nghttp3_pq_entry *item, void *arg);
|
||||
|
||||
/*
|
||||
* Applies |fun| to each item in |pq|. The |arg| is passed as arg
|
||||
* parameter to callback function. This function must not change the
|
||||
* ordering key. If the return value from callback is nonzero, this
|
||||
* function returns 1 immediately without iterating remaining items.
|
||||
* Otherwise this function returns 0.
|
||||
* nghttp3_pq_each applies |fun| to each item in |pq|. The |arg| is
|
||||
* passed as arg parameter to callback function. This function must
|
||||
* not change the ordering key. If the return value from callback is
|
||||
* nonzero, this function returns 1 immediately without iterating
|
||||
* remaining items. Otherwise this function returns 0.
|
||||
*/
|
||||
int nghttp3_pq_each(const nghttp3_pq *pq, nghttp3_pq_item_cb fun, void *arg);
|
||||
|
||||
/*
|
||||
* Removes |item| from priority queue.
|
||||
* nghttp3_pq_remove removes |item| from |pq|. |pq| must contain
|
||||
* |item| otherwise the behavior is undefined.
|
||||
*/
|
||||
void nghttp3_pq_remove(nghttp3_pq *pq, nghttp3_pq_entry *item);
|
||||
|
||||
/*
|
||||
* nghttp3_pq_clear removes all items from |pq|.
|
||||
*/
|
||||
void nghttp3_pq_clear(nghttp3_pq *pq);
|
||||
|
||||
#endif /* NGHTTP3_PQ_H */
|
||||
#endif /* !defined(NGHTTP3_PQ_H) */
|
||||
+464
-416
File diff suppressed because it is too large.
Load diff
+30
-16
@@ -28,7 +28,7 @@
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#endif /* defined(HAVE_CONFIG_H) */
|
||||
|
||||
#include <nghttp3/nghttp3.h>
|
||||
|
||||
@@ -48,6 +48,14 @@
|
||||
/* NGHTTP3_QPACK_MAX_VALUELEN is the maximum (compressed) length of
|
||||
header value this library can decode. */
|
||||
#define NGHTTP3_QPACK_MAX_VALUELEN 65536
|
||||
/* NGHTTP3_QPACK_MAX_ENCODERLEN is the maximum encoder stream length
|
||||
that a decoder accepts without completely processing a single field
|
||||
section. */
|
||||
#define NGHTTP3_QPACK_MAX_ENCODERLEN (128 * 1024)
|
||||
/* NGHTTP3_QPACK_MAX_DECODERLEN is the maximum decoder stream length
|
||||
that an encoder accepts without completely encoding a single field
|
||||
section. */
|
||||
#define NGHTTP3_QPACK_MAX_DECODERLEN (4 * 1024)
|
||||
|
||||
/* nghttp3_qpack_indexing_mode is a indexing strategy. */
|
||||
typedef enum nghttp3_qpack_indexing_mode {
|
||||
@@ -250,6 +258,9 @@ struct nghttp3_qpack_encoder {
|
||||
/* last_max_dtable_update is the dynamic table size last
|
||||
requested. */
|
||||
size_t last_max_dtable_update;
|
||||
/* uninterrupted_decoderlen is the number of bytes read from decoder
|
||||
stream without encoding a single field section. */
|
||||
size_t uninterrupted_decoderlen;
|
||||
/* flags is bitwise OR of zero or more of
|
||||
NGHTTP3_QPACK_ENCODER_FLAG_*. */
|
||||
uint8_t flags;
|
||||
@@ -325,9 +336,9 @@ nghttp3_qpack_lookup_stable(const nghttp3_nv *nv, int32_t token,
|
||||
* blocked (or it has been blocked already).
|
||||
*/
|
||||
nghttp3_qpack_lookup_result nghttp3_qpack_encoder_lookup_dtable(
|
||||
nghttp3_qpack_encoder *encoder, const nghttp3_nv *nv, int32_t token,
|
||||
uint32_t hash, nghttp3_qpack_indexing_mode indexing_mode, uint64_t krcnt,
|
||||
int allow_blocking);
|
||||
nghttp3_qpack_encoder *encoder, const nghttp3_nv *nv, int32_t token,
|
||||
uint32_t hash, nghttp3_qpack_indexing_mode indexing_mode, uint64_t krcnt,
|
||||
int allow_blocking);
|
||||
|
||||
/*
|
||||
* nghttp3_qpack_encoder_write_field_section_prefix writes Encoded
|
||||
@@ -341,8 +352,8 @@ nghttp3_qpack_lookup_result nghttp3_qpack_encoder_lookup_dtable(
|
||||
* Out of memory.
|
||||
*/
|
||||
int nghttp3_qpack_encoder_write_field_section_prefix(
|
||||
nghttp3_qpack_encoder *encoder, nghttp3_buf *pbuf, uint64_t ricnt,
|
||||
uint64_t base);
|
||||
nghttp3_qpack_encoder *encoder, nghttp3_buf *pbuf, uint64_t ricnt,
|
||||
uint64_t base);
|
||||
|
||||
/*
|
||||
* nghttp3_qpack_encoder_write_static_indexed writes Indexed Header
|
||||
@@ -386,8 +397,8 @@ int nghttp3_qpack_encoder_write_dynamic_indexed(nghttp3_qpack_encoder *encoder,
|
||||
* Out of memory.
|
||||
*/
|
||||
int nghttp3_qpack_encoder_write_static_indexed_name(
|
||||
nghttp3_qpack_encoder *encoder, nghttp3_buf *rbuf, uint64_t absidx,
|
||||
const nghttp3_nv *nv);
|
||||
nghttp3_qpack_encoder *encoder, nghttp3_buf *rbuf, uint64_t absidx,
|
||||
const nghttp3_nv *nv);
|
||||
|
||||
/*
|
||||
* nghttp3_qpack_encoder_write_dynamic_indexed writes Literal Header
|
||||
@@ -402,8 +413,8 @@ int nghttp3_qpack_encoder_write_static_indexed_name(
|
||||
* Out of memory.
|
||||
*/
|
||||
int nghttp3_qpack_encoder_write_dynamic_indexed_name(
|
||||
nghttp3_qpack_encoder *encoder, nghttp3_buf *rbuf, uint64_t absidx,
|
||||
uint64_t base, const nghttp3_nv *nv);
|
||||
nghttp3_qpack_encoder *encoder, nghttp3_buf *rbuf, uint64_t absidx,
|
||||
uint64_t base, const nghttp3_nv *nv);
|
||||
|
||||
/*
|
||||
* nghttp3_qpack_encoder_write_literal writes Literal Header Field
|
||||
@@ -779,6 +790,9 @@ struct nghttp3_qpack_decoder {
|
||||
unidirectional streams which potentially receives QPACK encoded
|
||||
HEADER frame. */
|
||||
size_t max_concurrent_streams;
|
||||
/* uninterrupted_encoderlen is the number of bytes read from encoder
|
||||
stream without completing a single field section. */
|
||||
size_t uninterrupted_encoderlen;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -880,19 +894,19 @@ int nghttp3_qpack_decoder_dtable_duplicate_add(nghttp3_qpack_decoder *decoder);
|
||||
int nghttp3_qpack_decoder_dtable_literal_add(nghttp3_qpack_decoder *decoder);
|
||||
|
||||
struct nghttp3_qpack_stream_context {
|
||||
/* state is a current state of reading request stream. */
|
||||
nghttp3_qpack_request_stream_state state;
|
||||
/* rstate is a set of intermediate state which are used to process
|
||||
request stream. */
|
||||
nghttp3_qpack_read_state rstate;
|
||||
const nghttp3_mem *mem;
|
||||
/* opcode is a request stream opcode being processed. */
|
||||
nghttp3_qpack_request_stream_opcode opcode;
|
||||
int64_t stream_id;
|
||||
/* ricnt is Required Insert Count to decode this header block. */
|
||||
uint64_t ricnt;
|
||||
/* base is Base in Header Block Prefix. */
|
||||
uint64_t base;
|
||||
/* state is a current state of reading request stream. */
|
||||
nghttp3_qpack_request_stream_state state;
|
||||
/* opcode is a request stream opcode being processed. */
|
||||
nghttp3_qpack_request_stream_opcode opcode;
|
||||
/* dbase_sign is the delta base sign in Header Block Prefix. */
|
||||
int dbase_sign;
|
||||
};
|
||||
@@ -991,6 +1005,6 @@ void nghttp3_qpack_decoder_emit_literal(nghttp3_qpack_decoder *decoder,
|
||||
* Decoder stream overflow.
|
||||
*/
|
||||
int nghttp3_qpack_decoder_write_section_ack(
|
||||
nghttp3_qpack_decoder *decoder, const nghttp3_qpack_stream_context *sctx);
|
||||
nghttp3_qpack_decoder *decoder, const nghttp3_qpack_stream_context *sctx);
|
||||
|
||||
#endif /* NGHTTP3_QPACK_H */
|
||||
#endif /* !defined(NGHTTP3_QPACK_H) */
|
||||
+5
-3
@@ -78,7 +78,7 @@ uint8_t *nghttp3_qpack_huffman_encode(uint8_t *dest, const uint8_t *src,
|
||||
}
|
||||
|
||||
void nghttp3_qpack_huffman_decode_context_init(
|
||||
nghttp3_qpack_huffman_decode_context *ctx) {
|
||||
nghttp3_qpack_huffman_decode_context *ctx) {
|
||||
ctx->fstate = NGHTTP3_QPACK_HUFFMAN_ACCEPTED;
|
||||
}
|
||||
|
||||
@@ -93,7 +93,9 @@ nghttp3_qpack_huffman_decode(nghttp3_qpack_huffman_decode_context *ctx,
|
||||
uint8_t c;
|
||||
|
||||
/* We use the decoding algorithm described in
|
||||
http://graphics.ics.uci.edu/pub/Prefix.pdf */
|
||||
- http://graphics.ics.uci.edu/pub/Prefix.pdf [!!! NO LONGER VALID !!!]
|
||||
- https://ics.uci.edu/~dan/pubs/Prefix.pdf
|
||||
- https://github.com/nghttp2/nghttp2/files/15141264/Prefix.pdf */
|
||||
for (; src != end;) {
|
||||
c = *src++;
|
||||
t = &qpack_huffman_decode_table[t->fstate & 0x1ff][c >> 4];
|
||||
@@ -117,6 +119,6 @@ nghttp3_qpack_huffman_decode(nghttp3_qpack_huffman_decode_context *ctx,
|
||||
}
|
||||
|
||||
int nghttp3_qpack_huffman_decode_failure_state(
|
||||
nghttp3_qpack_huffman_decode_context *ctx) {
|
||||
nghttp3_qpack_huffman_decode_context *ctx) {
|
||||
return ctx->fstate == 0x100;
|
||||
}
|
||||
+4
-4
@@ -28,7 +28,7 @@
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#endif /* defined(HAVE_CONFIG_H) */
|
||||
|
||||
#include <nghttp3/nghttp3.h>
|
||||
|
||||
@@ -75,7 +75,7 @@ typedef struct nghttp3_qpack_huffman_decode_context {
|
||||
extern const nghttp3_qpack_huffman_decode_node qpack_huffman_decode_table[][16];
|
||||
|
||||
void nghttp3_qpack_huffman_decode_context_init(
|
||||
nghttp3_qpack_huffman_decode_context *ctx);
|
||||
nghttp3_qpack_huffman_decode_context *ctx);
|
||||
|
||||
/*
|
||||
* nghttp3_qpack_huffman_decode decodes huffman encoded byte string
|
||||
@@ -103,6 +103,6 @@ nghttp3_qpack_huffman_decode(nghttp3_qpack_huffman_decode_context *ctx,
|
||||
* indicates that huffman decoding context is in failure state.
|
||||
*/
|
||||
int nghttp3_qpack_huffman_decode_failure_state(
|
||||
nghttp3_qpack_huffman_decode_context *ctx);
|
||||
nghttp3_qpack_huffman_decode_context *ctx);
|
||||
|
||||
#endif /* NGHTTP3_QPACK_HUFFMAN_H */
|
||||
#endif /* !defined(NGHTTP3_QPACK_HUFFMAN_H) */
|
||||
+4948
-4948
File diff suppressed because it is too large.
Load diff
+4
-2
@@ -34,11 +34,13 @@ void nghttp3_range_init(nghttp3_range *r, uint64_t begin, uint64_t end) {
|
||||
nghttp3_range nghttp3_range_intersect(const nghttp3_range *a,
|
||||
const nghttp3_range *b) {
|
||||
nghttp3_range r = {0, 0};
|
||||
uint64_t begin = nghttp3_max(a->begin, b->begin);
|
||||
uint64_t end = nghttp3_min(a->end, b->end);
|
||||
uint64_t begin = nghttp3_max_uint64(a->begin, b->begin);
|
||||
uint64_t end = nghttp3_min_uint64(a->end, b->end);
|
||||
|
||||
if (begin < end) {
|
||||
nghttp3_range_init(&r, begin, end);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -28,7 +28,7 @@
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#endif /* defined(HAVE_CONFIG_H) */
|
||||
|
||||
#include <nghttp3/nghttp3.h>
|
||||
|
||||
@@ -59,7 +59,7 @@ uint64_t nghttp3_range_len(const nghttp3_range *r);
|
||||
|
||||
/*
|
||||
* nghttp3_range_eq returns nonzero if |a| equals |b|, such that
|
||||
* a->begin == b->begin, and a->end == b->end hold.
|
||||
* a->begin == b->begin and a->end == b->end hold.
|
||||
*/
|
||||
int nghttp3_range_eq(const nghttp3_range *a, const nghttp3_range *b);
|
||||
|
||||
@@ -78,4 +78,4 @@ void nghttp3_range_cut(nghttp3_range *left, nghttp3_range *right,
|
||||
*/
|
||||
int nghttp3_range_not_after(const nghttp3_range *a, const nghttp3_range *b);
|
||||
|
||||
#endif /* NGHTTP3_RANGE_H */
|
||||
#endif /* !defined(NGHTTP3_RANGE_H) */
|
||||
+2
-2
@@ -28,7 +28,7 @@
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#endif /* defined(HAVE_CONFIG_H) */
|
||||
|
||||
#include <nghttp3/nghttp3.h>
|
||||
|
||||
@@ -78,4 +78,4 @@ int nghttp3_rcbuf_new2(nghttp3_rcbuf **rcbuf_ptr, const uint8_t *src,
|
||||
*/
|
||||
void nghttp3_rcbuf_del(nghttp3_rcbuf *rcbuf);
|
||||
|
||||
#endif /* NGHTTP3_RCBUF_H */
|
||||
#endif /* !defined(NGHTTP3_RCBUF_H) */
|
||||
+15
-21
@@ -29,29 +29,27 @@
|
||||
#include <string.h>
|
||||
#ifdef WIN32
|
||||
# include <intrin.h>
|
||||
#endif
|
||||
#endif /* defined(WIN32) */
|
||||
|
||||
#include "nghttp3_macro.h"
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1941 && !defined(__clang__) && \
|
||||
(defined(_M_ARM) || defined(_M_ARM64))
|
||||
unsigned int __popcnt(unsigned int x) {
|
||||
unsigned int c = 0;
|
||||
for (; x; ++c) {
|
||||
x &= x - 1;
|
||||
}
|
||||
return c;
|
||||
static int ispow2(size_t n) {
|
||||
#if defined(_MSC_VER) && !defined(__clang__) && \
|
||||
(defined(_M_ARM) || (defined(_M_ARM64) && _MSC_VER < 1941))
|
||||
return n && !(n & (n - 1));
|
||||
#elif defined(WIN32)
|
||||
return 1 == __popcnt((unsigned int)n);
|
||||
#else /* !((defined(_MSC_VER) && !defined(__clang__) && (defined(_M_ARM) || \
|
||||
(defined(_M_ARM64) && _MSC_VER < 1941))) || defined(WIN32)) */
|
||||
return 1 == __builtin_popcount((unsigned int)n);
|
||||
#endif /* !((defined(_MSC_VER) && !defined(__clang__) && (defined(_M_ARM) || \
|
||||
(defined(_M_ARM64) && _MSC_VER < 1941))) || defined(WIN32)) */
|
||||
}
|
||||
#endif
|
||||
|
||||
int nghttp3_ringbuf_init(nghttp3_ringbuf *rb, size_t nmemb, size_t size,
|
||||
const nghttp3_mem *mem) {
|
||||
if (nmemb) {
|
||||
#ifdef WIN32
|
||||
assert(1 == __popcnt((unsigned int)nmemb));
|
||||
#else
|
||||
assert(1 == __builtin_popcount((unsigned int)nmemb));
|
||||
#endif
|
||||
assert(ispow2(nmemb));
|
||||
|
||||
rb->buf = nghttp3_mem_malloc(mem, nmemb * size);
|
||||
if (rb->buf == NULL) {
|
||||
@@ -80,7 +78,7 @@ void nghttp3_ringbuf_free(nghttp3_ringbuf *rb) {
|
||||
|
||||
void *nghttp3_ringbuf_push_front(nghttp3_ringbuf *rb) {
|
||||
rb->first = (rb->first - 1) & (rb->nmemb - 1);
|
||||
rb->len = nghttp3_min(rb->nmemb, rb->len + 1);
|
||||
rb->len = nghttp3_min_size(rb->nmemb, rb->len + 1);
|
||||
|
||||
return (void *)&rb->buf[rb->first * rb->size];
|
||||
}
|
||||
@@ -127,11 +125,7 @@ int nghttp3_ringbuf_reserve(nghttp3_ringbuf *rb, size_t nmemb) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
assert(1 == __popcnt((unsigned int)nmemb));
|
||||
#else
|
||||
assert(1 == __builtin_popcount((unsigned int)nmemb));
|
||||
#endif
|
||||
assert(ispow2(nmemb));
|
||||
|
||||
buf = nghttp3_mem_malloc(rb->mem, nmemb * rb->size);
|
||||
if (buf == NULL) {
|
||||
|
||||
+2
-2
@@ -28,7 +28,7 @@
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#endif /* defined(HAVE_CONFIG_H) */
|
||||
|
||||
#include <nghttp3/nghttp3.h>
|
||||
|
||||
@@ -110,4 +110,4 @@ int nghttp3_ringbuf_full(nghttp3_ringbuf *rb);
|
||||
|
||||
int nghttp3_ringbuf_reserve(nghttp3_ringbuf *rb, size_t nmemb);
|
||||
|
||||
#endif /* NGHTTP3_RINGBUF_H */
|
||||
#endif /* !defined(NGHTTP3_RINGBUF_H) */
|
||||
+64
-64
@@ -36,70 +36,70 @@ uint8_t *nghttp3_cpymem(uint8_t *dest, const uint8_t *src, size_t n) {
|
||||
|
||||
/* Generated by gendowncasetbl.py */
|
||||
static const uint8_t DOWNCASE_TBL[] = {
|
||||
0 /* NUL */, 1 /* SOH */, 2 /* STX */, 3 /* ETX */,
|
||||
4 /* EOT */, 5 /* ENQ */, 6 /* ACK */, 7 /* BEL */,
|
||||
8 /* BS */, 9 /* HT */, 10 /* LF */, 11 /* VT */,
|
||||
12 /* FF */, 13 /* CR */, 14 /* SO */, 15 /* SI */,
|
||||
16 /* DLE */, 17 /* DC1 */, 18 /* DC2 */, 19 /* DC3 */,
|
||||
20 /* DC4 */, 21 /* NAK */, 22 /* SYN */, 23 /* ETB */,
|
||||
24 /* CAN */, 25 /* EM */, 26 /* SUB */, 27 /* ESC */,
|
||||
28 /* FS */, 29 /* GS */, 30 /* RS */, 31 /* US */,
|
||||
32 /* SPC */, 33 /* ! */, 34 /* " */, 35 /* # */,
|
||||
36 /* $ */, 37 /* % */, 38 /* & */, 39 /* ' */,
|
||||
40 /* ( */, 41 /* ) */, 42 /* * */, 43 /* + */,
|
||||
44 /* , */, 45 /* - */, 46 /* . */, 47 /* / */,
|
||||
48 /* 0 */, 49 /* 1 */, 50 /* 2 */, 51 /* 3 */,
|
||||
52 /* 4 */, 53 /* 5 */, 54 /* 6 */, 55 /* 7 */,
|
||||
56 /* 8 */, 57 /* 9 */, 58 /* : */, 59 /* ; */,
|
||||
60 /* < */, 61 /* = */, 62 /* > */, 63 /* ? */,
|
||||
64 /* @ */, 97 /* A */, 98 /* B */, 99 /* C */,
|
||||
100 /* D */, 101 /* E */, 102 /* F */, 103 /* G */,
|
||||
104 /* H */, 105 /* I */, 106 /* J */, 107 /* K */,
|
||||
108 /* L */, 109 /* M */, 110 /* N */, 111 /* O */,
|
||||
112 /* P */, 113 /* Q */, 114 /* R */, 115 /* S */,
|
||||
116 /* T */, 117 /* U */, 118 /* V */, 119 /* W */,
|
||||
120 /* X */, 121 /* Y */, 122 /* Z */, 91 /* [ */,
|
||||
92 /* \ */, 93 /* ] */, 94 /* ^ */, 95 /* _ */,
|
||||
96 /* ` */, 97 /* a */, 98 /* b */, 99 /* c */,
|
||||
100 /* d */, 101 /* e */, 102 /* f */, 103 /* g */,
|
||||
104 /* h */, 105 /* i */, 106 /* j */, 107 /* k */,
|
||||
108 /* l */, 109 /* m */, 110 /* n */, 111 /* o */,
|
||||
112 /* p */, 113 /* q */, 114 /* r */, 115 /* s */,
|
||||
116 /* t */, 117 /* u */, 118 /* v */, 119 /* w */,
|
||||
120 /* x */, 121 /* y */, 122 /* z */, 123 /* { */,
|
||||
124 /* | */, 125 /* } */, 126 /* ~ */, 127 /* DEL */,
|
||||
128 /* 0x80 */, 129 /* 0x81 */, 130 /* 0x82 */, 131 /* 0x83 */,
|
||||
132 /* 0x84 */, 133 /* 0x85 */, 134 /* 0x86 */, 135 /* 0x87 */,
|
||||
136 /* 0x88 */, 137 /* 0x89 */, 138 /* 0x8a */, 139 /* 0x8b */,
|
||||
140 /* 0x8c */, 141 /* 0x8d */, 142 /* 0x8e */, 143 /* 0x8f */,
|
||||
144 /* 0x90 */, 145 /* 0x91 */, 146 /* 0x92 */, 147 /* 0x93 */,
|
||||
148 /* 0x94 */, 149 /* 0x95 */, 150 /* 0x96 */, 151 /* 0x97 */,
|
||||
152 /* 0x98 */, 153 /* 0x99 */, 154 /* 0x9a */, 155 /* 0x9b */,
|
||||
156 /* 0x9c */, 157 /* 0x9d */, 158 /* 0x9e */, 159 /* 0x9f */,
|
||||
160 /* 0xa0 */, 161 /* 0xa1 */, 162 /* 0xa2 */, 163 /* 0xa3 */,
|
||||
164 /* 0xa4 */, 165 /* 0xa5 */, 166 /* 0xa6 */, 167 /* 0xa7 */,
|
||||
168 /* 0xa8 */, 169 /* 0xa9 */, 170 /* 0xaa */, 171 /* 0xab */,
|
||||
172 /* 0xac */, 173 /* 0xad */, 174 /* 0xae */, 175 /* 0xaf */,
|
||||
176 /* 0xb0 */, 177 /* 0xb1 */, 178 /* 0xb2 */, 179 /* 0xb3 */,
|
||||
180 /* 0xb4 */, 181 /* 0xb5 */, 182 /* 0xb6 */, 183 /* 0xb7 */,
|
||||
184 /* 0xb8 */, 185 /* 0xb9 */, 186 /* 0xba */, 187 /* 0xbb */,
|
||||
188 /* 0xbc */, 189 /* 0xbd */, 190 /* 0xbe */, 191 /* 0xbf */,
|
||||
192 /* 0xc0 */, 193 /* 0xc1 */, 194 /* 0xc2 */, 195 /* 0xc3 */,
|
||||
196 /* 0xc4 */, 197 /* 0xc5 */, 198 /* 0xc6 */, 199 /* 0xc7 */,
|
||||
200 /* 0xc8 */, 201 /* 0xc9 */, 202 /* 0xca */, 203 /* 0xcb */,
|
||||
204 /* 0xcc */, 205 /* 0xcd */, 206 /* 0xce */, 207 /* 0xcf */,
|
||||
208 /* 0xd0 */, 209 /* 0xd1 */, 210 /* 0xd2 */, 211 /* 0xd3 */,
|
||||
212 /* 0xd4 */, 213 /* 0xd5 */, 214 /* 0xd6 */, 215 /* 0xd7 */,
|
||||
216 /* 0xd8 */, 217 /* 0xd9 */, 218 /* 0xda */, 219 /* 0xdb */,
|
||||
220 /* 0xdc */, 221 /* 0xdd */, 222 /* 0xde */, 223 /* 0xdf */,
|
||||
224 /* 0xe0 */, 225 /* 0xe1 */, 226 /* 0xe2 */, 227 /* 0xe3 */,
|
||||
228 /* 0xe4 */, 229 /* 0xe5 */, 230 /* 0xe6 */, 231 /* 0xe7 */,
|
||||
232 /* 0xe8 */, 233 /* 0xe9 */, 234 /* 0xea */, 235 /* 0xeb */,
|
||||
236 /* 0xec */, 237 /* 0xed */, 238 /* 0xee */, 239 /* 0xef */,
|
||||
240 /* 0xf0 */, 241 /* 0xf1 */, 242 /* 0xf2 */, 243 /* 0xf3 */,
|
||||
244 /* 0xf4 */, 245 /* 0xf5 */, 246 /* 0xf6 */, 247 /* 0xf7 */,
|
||||
248 /* 0xf8 */, 249 /* 0xf9 */, 250 /* 0xfa */, 251 /* 0xfb */,
|
||||
252 /* 0xfc */, 253 /* 0xfd */, 254 /* 0xfe */, 255 /* 0xff */,
|
||||
0 /* NUL */, 1 /* SOH */, 2 /* STX */, 3 /* ETX */,
|
||||
4 /* EOT */, 5 /* ENQ */, 6 /* ACK */, 7 /* BEL */,
|
||||
8 /* BS */, 9 /* HT */, 10 /* LF */, 11 /* VT */,
|
||||
12 /* FF */, 13 /* CR */, 14 /* SO */, 15 /* SI */,
|
||||
16 /* DLE */, 17 /* DC1 */, 18 /* DC2 */, 19 /* DC3 */,
|
||||
20 /* DC4 */, 21 /* NAK */, 22 /* SYN */, 23 /* ETB */,
|
||||
24 /* CAN */, 25 /* EM */, 26 /* SUB */, 27 /* ESC */,
|
||||
28 /* FS */, 29 /* GS */, 30 /* RS */, 31 /* US */,
|
||||
32 /* SPC */, 33 /* ! */, 34 /* " */, 35 /* # */,
|
||||
36 /* $ */, 37 /* % */, 38 /* & */, 39 /* ' */,
|
||||
40 /* ( */, 41 /* ) */, 42 /* * */, 43 /* + */,
|
||||
44 /* , */, 45 /* - */, 46 /* . */, 47 /* / */,
|
||||
48 /* 0 */, 49 /* 1 */, 50 /* 2 */, 51 /* 3 */,
|
||||
52 /* 4 */, 53 /* 5 */, 54 /* 6 */, 55 /* 7 */,
|
||||
56 /* 8 */, 57 /* 9 */, 58 /* : */, 59 /* ; */,
|
||||
60 /* < */, 61 /* = */, 62 /* > */, 63 /* ? */,
|
||||
64 /* @ */, 97 /* A */, 98 /* B */, 99 /* C */,
|
||||
100 /* D */, 101 /* E */, 102 /* F */, 103 /* G */,
|
||||
104 /* H */, 105 /* I */, 106 /* J */, 107 /* K */,
|
||||
108 /* L */, 109 /* M */, 110 /* N */, 111 /* O */,
|
||||
112 /* P */, 113 /* Q */, 114 /* R */, 115 /* S */,
|
||||
116 /* T */, 117 /* U */, 118 /* V */, 119 /* W */,
|
||||
120 /* X */, 121 /* Y */, 122 /* Z */, 91 /* [ */,
|
||||
92 /* \ */, 93 /* ] */, 94 /* ^ */, 95 /* _ */,
|
||||
96 /* ` */, 97 /* a */, 98 /* b */, 99 /* c */,
|
||||
100 /* d */, 101 /* e */, 102 /* f */, 103 /* g */,
|
||||
104 /* h */, 105 /* i */, 106 /* j */, 107 /* k */,
|
||||
108 /* l */, 109 /* m */, 110 /* n */, 111 /* o */,
|
||||
112 /* p */, 113 /* q */, 114 /* r */, 115 /* s */,
|
||||
116 /* t */, 117 /* u */, 118 /* v */, 119 /* w */,
|
||||
120 /* x */, 121 /* y */, 122 /* z */, 123 /* { */,
|
||||
124 /* | */, 125 /* } */, 126 /* ~ */, 127 /* DEL */,
|
||||
128 /* 0x80 */, 129 /* 0x81 */, 130 /* 0x82 */, 131 /* 0x83 */,
|
||||
132 /* 0x84 */, 133 /* 0x85 */, 134 /* 0x86 */, 135 /* 0x87 */,
|
||||
136 /* 0x88 */, 137 /* 0x89 */, 138 /* 0x8a */, 139 /* 0x8b */,
|
||||
140 /* 0x8c */, 141 /* 0x8d */, 142 /* 0x8e */, 143 /* 0x8f */,
|
||||
144 /* 0x90 */, 145 /* 0x91 */, 146 /* 0x92 */, 147 /* 0x93 */,
|
||||
148 /* 0x94 */, 149 /* 0x95 */, 150 /* 0x96 */, 151 /* 0x97 */,
|
||||
152 /* 0x98 */, 153 /* 0x99 */, 154 /* 0x9a */, 155 /* 0x9b */,
|
||||
156 /* 0x9c */, 157 /* 0x9d */, 158 /* 0x9e */, 159 /* 0x9f */,
|
||||
160 /* 0xa0 */, 161 /* 0xa1 */, 162 /* 0xa2 */, 163 /* 0xa3 */,
|
||||
164 /* 0xa4 */, 165 /* 0xa5 */, 166 /* 0xa6 */, 167 /* 0xa7 */,
|
||||
168 /* 0xa8 */, 169 /* 0xa9 */, 170 /* 0xaa */, 171 /* 0xab */,
|
||||
172 /* 0xac */, 173 /* 0xad */, 174 /* 0xae */, 175 /* 0xaf */,
|
||||
176 /* 0xb0 */, 177 /* 0xb1 */, 178 /* 0xb2 */, 179 /* 0xb3 */,
|
||||
180 /* 0xb4 */, 181 /* 0xb5 */, 182 /* 0xb6 */, 183 /* 0xb7 */,
|
||||
184 /* 0xb8 */, 185 /* 0xb9 */, 186 /* 0xba */, 187 /* 0xbb */,
|
||||
188 /* 0xbc */, 189 /* 0xbd */, 190 /* 0xbe */, 191 /* 0xbf */,
|
||||
192 /* 0xc0 */, 193 /* 0xc1 */, 194 /* 0xc2 */, 195 /* 0xc3 */,
|
||||
196 /* 0xc4 */, 197 /* 0xc5 */, 198 /* 0xc6 */, 199 /* 0xc7 */,
|
||||
200 /* 0xc8 */, 201 /* 0xc9 */, 202 /* 0xca */, 203 /* 0xcb */,
|
||||
204 /* 0xcc */, 205 /* 0xcd */, 206 /* 0xce */, 207 /* 0xcf */,
|
||||
208 /* 0xd0 */, 209 /* 0xd1 */, 210 /* 0xd2 */, 211 /* 0xd3 */,
|
||||
212 /* 0xd4 */, 213 /* 0xd5 */, 214 /* 0xd6 */, 215 /* 0xd7 */,
|
||||
216 /* 0xd8 */, 217 /* 0xd9 */, 218 /* 0xda */, 219 /* 0xdb */,
|
||||
220 /* 0xdc */, 221 /* 0xdd */, 222 /* 0xde */, 223 /* 0xdf */,
|
||||
224 /* 0xe0 */, 225 /* 0xe1 */, 226 /* 0xe2 */, 227 /* 0xe3 */,
|
||||
228 /* 0xe4 */, 229 /* 0xe5 */, 230 /* 0xe6 */, 231 /* 0xe7 */,
|
||||
232 /* 0xe8 */, 233 /* 0xe9 */, 234 /* 0xea */, 235 /* 0xeb */,
|
||||
236 /* 0xec */, 237 /* 0xed */, 238 /* 0xee */, 239 /* 0xef */,
|
||||
240 /* 0xf0 */, 241 /* 0xf1 */, 242 /* 0xf2 */, 243 /* 0xf3 */,
|
||||
244 /* 0xf4 */, 245 /* 0xf5 */, 246 /* 0xf6 */, 247 /* 0xf7 */,
|
||||
248 /* 0xf8 */, 249 /* 0xf9 */, 250 /* 0xfa */, 251 /* 0xfb */,
|
||||
252 /* 0xfc */, 253 /* 0xfd */, 254 /* 0xfe */, 255 /* 0xff */,
|
||||
};
|
||||
|
||||
void nghttp3_downcase(uint8_t *s, size_t len) {
|
||||
|
||||
+2
-2
@@ -29,7 +29,7 @@
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#endif /* defined(HAVE_CONFIG_H) */
|
||||
|
||||
#include <nghttp3/nghttp3.h>
|
||||
|
||||
@@ -37,4 +37,4 @@ uint8_t *nghttp3_cpymem(uint8_t *dest, const uint8_t *src, size_t n);
|
||||
|
||||
void nghttp3_downcase(uint8_t *s, size_t len);
|
||||
|
||||
#endif /* NGHTTP3_STR_H */
|
||||
#endif /* !defined(NGHTTP3_STR_H) */
|
||||
+42
-46
@@ -73,7 +73,6 @@ int nghttp3_stream_new(nghttp3_stream **pstream, int64_t stream_id,
|
||||
|
||||
stream->qpack_blocked_pe.index = NGHTTP3_PQ_BAD_INDEX;
|
||||
stream->mem = mem;
|
||||
stream->tx.offset = 0;
|
||||
stream->rx.http.status_code = -1;
|
||||
stream->rx.http.content_length = -1;
|
||||
stream->rx.http.pri.urgency = NGHTTP3_DEFAULT_URGENCY;
|
||||
@@ -180,48 +179,44 @@ void nghttp3_stream_read_state_reset(nghttp3_stream_read_state *rstate) {
|
||||
}
|
||||
|
||||
nghttp3_ssize nghttp3_read_varint(nghttp3_varint_read_state *rvint,
|
||||
const uint8_t *src, size_t srclen, int fin) {
|
||||
size_t nread = 0;
|
||||
size_t n;
|
||||
size_t i;
|
||||
const uint8_t *begin, const uint8_t *end,
|
||||
int fin) {
|
||||
const uint8_t *orig_begin = begin;
|
||||
size_t len;
|
||||
|
||||
assert(srclen > 0);
|
||||
assert(begin != end);
|
||||
|
||||
if (rvint->left == 0) {
|
||||
assert(rvint->acc == 0);
|
||||
|
||||
rvint->left = nghttp3_get_varintlen(src);
|
||||
if (rvint->left <= srclen) {
|
||||
rvint->acc = nghttp3_get_varint(&nread, src);
|
||||
rvint->left = 0;
|
||||
return (nghttp3_ssize)nread;
|
||||
len = nghttp3_get_varintlen(begin);
|
||||
if (len <= (size_t)(end - begin)) {
|
||||
nghttp3_get_varint(&rvint->acc, begin);
|
||||
return (nghttp3_ssize)len;
|
||||
}
|
||||
|
||||
if (fin) {
|
||||
return NGHTTP3_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
rvint->acc = nghttp3_get_varint_fb(src);
|
||||
nread = 1;
|
||||
++src;
|
||||
--srclen;
|
||||
--rvint->left;
|
||||
rvint->acc = nghttp3_get_varint_fb(begin++);
|
||||
rvint->left = len - 1;
|
||||
}
|
||||
|
||||
n = nghttp3_min(rvint->left, srclen);
|
||||
len = nghttp3_min_size(rvint->left, (size_t)(end - begin));
|
||||
end = begin + len;
|
||||
|
||||
for (i = 0; i < n; ++i) {
|
||||
rvint->acc = (rvint->acc << 8) + src[i];
|
||||
for (; begin != end;) {
|
||||
rvint->acc = (rvint->acc << 8) + *begin++;
|
||||
}
|
||||
|
||||
rvint->left -= n;
|
||||
nread += n;
|
||||
rvint->left -= len;
|
||||
|
||||
if (fin && rvint->left) {
|
||||
return NGHTTP3_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
return (nghttp3_ssize)nread;
|
||||
return (nghttp3_ssize)(begin - orig_begin);
|
||||
}
|
||||
|
||||
int nghttp3_stream_frq_add(nghttp3_stream *stream,
|
||||
@@ -231,7 +226,8 @@ int nghttp3_stream_frq_add(nghttp3_stream *stream,
|
||||
int rv;
|
||||
|
||||
if (nghttp3_ringbuf_full(frq)) {
|
||||
size_t nlen = nghttp3_max(NGHTTP3_MIN_RBLEN, nghttp3_ringbuf_len(frq) * 2);
|
||||
size_t nlen =
|
||||
nghttp3_max_size(NGHTTP3_MIN_RBLEN, nghttp3_ringbuf_len(frq) * 2);
|
||||
rv = nghttp3_ringbuf_reserve(frq, nlen);
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
@@ -444,8 +440,8 @@ int nghttp3_stream_write_headers(nghttp3_stream *stream,
|
||||
assert(conn);
|
||||
|
||||
return nghttp3_stream_write_header_block(
|
||||
stream, &conn->qenc, conn->tx.qenc, &conn->tx.qpack.rbuf,
|
||||
&conn->tx.qpack.ebuf, NGHTTP3_FRAME_HEADERS, fr->nva, fr->nvlen);
|
||||
stream, &conn->qenc, conn->tx.qenc, &conn->tx.qpack.rbuf,
|
||||
&conn->tx.qpack.ebuf, NGHTTP3_FRAME_HEADERS, fr->nva, fr->nvlen);
|
||||
}
|
||||
|
||||
int nghttp3_stream_write_header_block(nghttp3_stream *stream,
|
||||
@@ -738,7 +734,7 @@ int nghttp3_stream_outq_add(nghttp3_stream *stream,
|
||||
}
|
||||
|
||||
if (nghttp3_ringbuf_full(outq)) {
|
||||
size_t nlen = nghttp3_max(NGHTTP3_MIN_RBLEN, len * 2);
|
||||
size_t nlen = nghttp3_max_size(NGHTTP3_MIN_RBLEN, len * 2);
|
||||
rv = nghttp3_ringbuf_reserve(outq, nlen);
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
@@ -770,8 +766,8 @@ int nghttp3_stream_ensure_chunk(nghttp3_stream *stream, size_t need) {
|
||||
;
|
||||
|
||||
if (n == NGHTTP3_STREAM_MIN_CHUNK_SIZE) {
|
||||
p = (uint8_t *)nghttp3_objalloc_chunk_len_get(stream->out_chunk_objalloc,
|
||||
n);
|
||||
p =
|
||||
(uint8_t *)nghttp3_objalloc_chunk_len_get(stream->out_chunk_objalloc, n);
|
||||
} else {
|
||||
p = nghttp3_mem_malloc(stream->mem, n);
|
||||
}
|
||||
@@ -780,7 +776,7 @@ int nghttp3_stream_ensure_chunk(nghttp3_stream *stream, size_t need) {
|
||||
}
|
||||
|
||||
if (nghttp3_ringbuf_full(chunks)) {
|
||||
size_t nlen = nghttp3_max(NGHTTP3_MIN_RBLEN, len * 2);
|
||||
size_t nlen = nghttp3_max_size(NGHTTP3_MIN_RBLEN, len * 2);
|
||||
rv = nghttp3_ringbuf_reserve(chunks, nlen);
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
@@ -928,9 +924,8 @@ static void stream_pop_outq_entry(nghttp3_stream *stream,
|
||||
nghttp3_ringbuf_pop_front(&stream->outq);
|
||||
}
|
||||
|
||||
int nghttp3_stream_add_ack_offset(nghttp3_stream *stream, uint64_t n) {
|
||||
int nghttp3_stream_update_ack_offset(nghttp3_stream *stream, uint64_t offset) {
|
||||
nghttp3_ringbuf *outq = &stream->outq;
|
||||
uint64_t offset = stream->ack_offset + n;
|
||||
size_t buflen;
|
||||
size_t npopped = 0;
|
||||
uint64_t nack;
|
||||
@@ -941,24 +936,25 @@ int nghttp3_stream_add_ack_offset(nghttp3_stream *stream, uint64_t n) {
|
||||
tbuf = nghttp3_ringbuf_get(outq, 0);
|
||||
buflen = nghttp3_buf_len(&tbuf->buf);
|
||||
|
||||
if (tbuf->type == NGHTTP3_BUF_TYPE_ALIEN) {
|
||||
nack = nghttp3_min(offset, (uint64_t)buflen) - stream->ack_done;
|
||||
if (stream->callbacks.acked_data) {
|
||||
rv = stream->callbacks.acked_data(stream, stream->node.id, nack,
|
||||
stream->user_data);
|
||||
if (rv != 0) {
|
||||
return NGHTTP3_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
/* For NGHTTP3_BUF_TYPE_ALIEN, we never add 0 length buffer. */
|
||||
if (tbuf->type == NGHTTP3_BUF_TYPE_ALIEN && stream->ack_offset < offset &&
|
||||
stream->callbacks.acked_data) {
|
||||
nack = nghttp3_min_uint64(offset, stream->ack_base + buflen) -
|
||||
stream->ack_offset;
|
||||
|
||||
rv = stream->callbacks.acked_data(stream, stream->node.id, nack,
|
||||
stream->user_data);
|
||||
if (rv != 0) {
|
||||
return NGHTTP3_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
stream->ack_done += nack;
|
||||
}
|
||||
|
||||
if (offset >= buflen) {
|
||||
if (offset >= stream->ack_base + buflen) {
|
||||
stream_pop_outq_entry(stream, tbuf);
|
||||
|
||||
offset -= buflen;
|
||||
stream->ack_base += buflen;
|
||||
stream->ack_offset = stream->ack_base;
|
||||
++npopped;
|
||||
stream->ack_done = 0;
|
||||
|
||||
if (stream->outq_idx + 1 == npopped) {
|
||||
stream->outq_offset = 0;
|
||||
@@ -996,7 +992,7 @@ int nghttp3_stream_buffer_data(nghttp3_stream *stream, const uint8_t *data,
|
||||
if (len) {
|
||||
buf = nghttp3_ringbuf_get(inq, len - 1);
|
||||
bufleft = nghttp3_buf_left(buf);
|
||||
nwrite = nghttp3_min(datalen, bufleft);
|
||||
nwrite = nghttp3_min_size(datalen, bufleft);
|
||||
buf->last = nghttp3_cpymem(buf->last, data, nwrite);
|
||||
data += nwrite;
|
||||
datalen -= nwrite;
|
||||
@@ -1005,7 +1001,7 @@ int nghttp3_stream_buffer_data(nghttp3_stream *stream, const uint8_t *data,
|
||||
for (; datalen;) {
|
||||
if (nghttp3_ringbuf_full(inq)) {
|
||||
size_t nlen =
|
||||
nghttp3_max(NGHTTP3_MIN_RBLEN, nghttp3_ringbuf_len(inq) * 2);
|
||||
nghttp3_max_size(NGHTTP3_MIN_RBLEN, nghttp3_ringbuf_len(inq) * 2);
|
||||
rv = nghttp3_ringbuf_reserve(inq, nlen);
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
@@ -1020,7 +1016,7 @@ int nghttp3_stream_buffer_data(nghttp3_stream *stream, const uint8_t *data,
|
||||
buf = nghttp3_ringbuf_push_back(inq);
|
||||
nghttp3_buf_wrap_init(buf, rawbuf, 16384);
|
||||
bufleft = nghttp3_buf_left(buf);
|
||||
nwrite = nghttp3_min(datalen, bufleft);
|
||||
nwrite = nghttp3_min_size(datalen, bufleft);
|
||||
buf->last = nghttp3_cpymem(buf->last, data, nwrite);
|
||||
data += nwrite;
|
||||
datalen -= nwrite;
|
||||
|
||||
+18
-14
@@ -27,7 +27,7 @@
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#endif /* defined(HAVE_CONFIG_H) */
|
||||
|
||||
#include <nghttp3/nghttp3.h>
|
||||
|
||||
@@ -88,8 +88,8 @@ typedef struct nghttp3_varint_read_state {
|
||||
typedef struct nghttp3_stream_read_state {
|
||||
nghttp3_varint_read_state rvint;
|
||||
nghttp3_frame fr;
|
||||
int state;
|
||||
int64_t left;
|
||||
int state;
|
||||
} nghttp3_stream_read_state;
|
||||
|
||||
/* NGHTTP3_STREAM_FLAG_NONE indicates that no flag is set. */
|
||||
@@ -186,9 +186,6 @@ typedef struct nghttp3_stream_callbacks {
|
||||
} nghttp3_stream_callbacks;
|
||||
|
||||
typedef struct nghttp3_http_state {
|
||||
/* status_code is HTTP status code received. This field is used
|
||||
if connection is initialized as client. */
|
||||
int32_t status_code;
|
||||
/* content_length is the value of received content-length header
|
||||
field. */
|
||||
int64_t content_length;
|
||||
@@ -196,6 +193,9 @@ typedef struct nghttp3_http_state {
|
||||
far. */
|
||||
int64_t recv_content_length;
|
||||
nghttp3_pri pri;
|
||||
/* status_code is HTTP status code received. This field is used
|
||||
if connection is initialized as client. */
|
||||
int32_t status_code;
|
||||
uint32_t flags;
|
||||
} nghttp3_http_state;
|
||||
|
||||
@@ -226,13 +226,12 @@ struct nghttp3_stream {
|
||||
/* outq_offset is write offset relative to the element at outq_idx
|
||||
in outq. */
|
||||
uint64_t outq_offset;
|
||||
/* ack_offset is offset acknowledged by peer relative to the first
|
||||
element in outq. */
|
||||
/* ack_base is the number of bytes acknowledged by a remote
|
||||
endpoint where the first element in outq is positioned at. */
|
||||
uint64_t ack_base;
|
||||
/* ack_offset is the number of bytes acknowledged by a remote
|
||||
endpoint so far. */
|
||||
uint64_t ack_offset;
|
||||
/* ack_done is the number of bytes notified to an application that
|
||||
they are acknowledged inside the first outq element if it is of
|
||||
type NGHTTP3_BUF_TYPE_ALIEN. */
|
||||
uint64_t ack_done;
|
||||
uint64_t unscheduled_nwrite;
|
||||
nghttp3_stream_type type;
|
||||
nghttp3_stream_read_state rstate;
|
||||
@@ -283,7 +282,8 @@ void nghttp3_varint_read_state_reset(nghttp3_varint_read_state *rvint);
|
||||
void nghttp3_stream_read_state_reset(nghttp3_stream_read_state *rstate);
|
||||
|
||||
nghttp3_ssize nghttp3_read_varint(nghttp3_varint_read_state *rvint,
|
||||
const uint8_t *src, size_t srclen, int fin);
|
||||
const uint8_t *begin, const uint8_t *end,
|
||||
int fin);
|
||||
|
||||
int nghttp3_stream_frq_add(nghttp3_stream *stream,
|
||||
const nghttp3_frame_entry *frent);
|
||||
@@ -336,7 +336,11 @@ void nghttp3_stream_add_outq_offset(nghttp3_stream *stream, size_t n);
|
||||
*/
|
||||
int nghttp3_stream_outq_write_done(nghttp3_stream *stream);
|
||||
|
||||
int nghttp3_stream_add_ack_offset(nghttp3_stream *stream, uint64_t n);
|
||||
/*
|
||||
* nghttp2_stream_update_ack_offset updates the last acknowledged
|
||||
* offset to |offset|.
|
||||
*/
|
||||
int nghttp3_stream_update_ack_offset(nghttp3_stream *stream, uint64_t offset);
|
||||
|
||||
/*
|
||||
* nghttp3_stream_is_active returns nonzero if |stream| is active. In
|
||||
@@ -390,4 +394,4 @@ int nghttp3_client_stream_uni(int64_t stream_id);
|
||||
*/
|
||||
int nghttp3_server_stream_uni(int64_t stream_id);
|
||||
|
||||
#endif /* NGHTTP3_STREAM_H */
|
||||
#endif /* !defined(NGHTTP3_STREAM_H) */
|
||||
+3
-3
@@ -73,8 +73,8 @@ int nghttp3_tnode_schedule(nghttp3_tnode *tnode, nghttp3_pq *pq,
|
||||
|
||||
if (tnode->pe.index == NGHTTP3_PQ_BAD_INDEX) {
|
||||
tnode->cycle =
|
||||
pq_get_first_cycle(pq) +
|
||||
((nwrite == 0 || !tnode->pri.inc) ? 0 : nghttp3_max(1, penalty));
|
||||
pq_get_first_cycle(pq) +
|
||||
((nwrite == 0 || !tnode->pri.inc) ? 0 : nghttp3_max_uint64(1, penalty));
|
||||
} else if (nwrite > 0) {
|
||||
if (!tnode->pri.inc || nghttp3_pq_size(pq) == 1) {
|
||||
return 0;
|
||||
@@ -82,7 +82,7 @@ int nghttp3_tnode_schedule(nghttp3_tnode *tnode, nghttp3_pq *pq,
|
||||
|
||||
nghttp3_pq_remove(pq, &tnode->pe);
|
||||
tnode->pe.index = NGHTTP3_PQ_BAD_INDEX;
|
||||
tnode->cycle += nghttp3_max(1, penalty);
|
||||
tnode->cycle += nghttp3_max_uint64(1, penalty);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
+2
-2
@@ -27,7 +27,7 @@
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#endif /* defined(HAVE_CONFIG_H) */
|
||||
|
||||
#include <nghttp3/nghttp3.h>
|
||||
|
||||
@@ -63,4 +63,4 @@ int nghttp3_tnode_schedule(nghttp3_tnode *tnode, nghttp3_pq *pq,
|
||||
*/
|
||||
int nghttp3_tnode_is_scheduled(nghttp3_tnode *tnode);
|
||||
|
||||
#endif /* NGHTTP3_TNODE_H */
|
||||
#endif /* !defined(NGHTTP3_TNODE_H) */
|
||||
+4
-4
@@ -29,11 +29,11 @@
|
||||
#include <errno.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif /* HAVE_UNISTD_H */
|
||||
#endif /* defined(HAVE_UNISTD_H) */
|
||||
#include <stdlib.h>
|
||||
#ifdef WIN32
|
||||
# include <io.h>
|
||||
#endif /* WIN32 */
|
||||
#endif /* defined(WIN32) */
|
||||
|
||||
void nghttp3_unreachable_fail(const char *file, int line, const char *func) {
|
||||
char *buf;
|
||||
@@ -62,9 +62,9 @@ void nghttp3_unreachable_fail(const char *file, int line, const char *func) {
|
||||
#ifndef WIN32
|
||||
while (write(STDERR_FILENO, buf, (size_t)rv) == -1 && errno == EINTR)
|
||||
;
|
||||
#else /* WIN32 */
|
||||
#else /* defined(WIN32) */
|
||||
_write(_fileno(stderr), buf, (unsigned int)rv);
|
||||
#endif /* WIN32 */
|
||||
#endif /* defined(WIN32) */
|
||||
|
||||
free(buf);
|
||||
|
||||
|
||||
+6
-6
@@ -28,26 +28,26 @@
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#endif /* defined(HAVE_CONFIG_H) */
|
||||
|
||||
#include <nghttp3/nghttp3.h>
|
||||
|
||||
#ifdef __FILE_NAME__
|
||||
# define NGHTTP3_FILE_NAME __FILE_NAME__
|
||||
#else /* !__FILE_NAME__ */
|
||||
#else /* !defined(__FILE_NAME__) */
|
||||
# define NGHTTP3_FILE_NAME "(file)"
|
||||
#endif /* !__FILE_NAME__ */
|
||||
#endif /* !defined(__FILE_NAME__) */
|
||||
|
||||
#define nghttp3_unreachable() \
|
||||
nghttp3_unreachable_fail(NGHTTP3_FILE_NAME, __LINE__, __func__)
|
||||
|
||||
#ifdef _MSC_VER
|
||||
__declspec(noreturn)
|
||||
#endif /* _MSC_VER */
|
||||
#endif /* defined(_MSC_VER) */
|
||||
void nghttp3_unreachable_fail(const char *file, int line, const char *func)
|
||||
#ifndef _MSC_VER
|
||||
__attribute__((noreturn))
|
||||
#endif /* !_MSC_VER */
|
||||
#endif /* !defined(_MSC_VER) */
|
||||
;
|
||||
|
||||
#endif /* NGHTTP3_UNREACHABLE_H */
|
||||
#endif /* !defined(NGHTTP3_UNREACHABLE_H) */
|
||||
+2
-2
@@ -28,7 +28,7 @@
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#endif /* defined(HAVE_CONFIG_H) */
|
||||
|
||||
#include <nghttp3/nghttp3.h>
|
||||
|
||||
@@ -38,4 +38,4 @@
|
||||
*/
|
||||
int64_t nghttp3_vec_len_varint(const nghttp3_vec *vec, size_t n);
|
||||
|
||||
#endif /* NGHTTP3_VEC_H */
|
||||
#endif /* !defined(NGHTTP3_VEC_H) */
|
||||
+1
-1
@@ -24,7 +24,7 @@
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#endif /* defined(HAVE_CONFIG_H) */
|
||||
|
||||
#include <nghttp3/nghttp3.h>
|
||||
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2023 sfparse contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
+458
-87
@@ -135,6 +135,70 @@
|
||||
UCALPHA_CASES: \
|
||||
LCALPHA_CASES
|
||||
|
||||
#define TOKEN_CASES \
|
||||
case '!': \
|
||||
case '#': \
|
||||
case '$': \
|
||||
case '%': \
|
||||
case '&': \
|
||||
case '\'': \
|
||||
case '*': \
|
||||
case '+': \
|
||||
case '-': \
|
||||
case '.': \
|
||||
case '/': \
|
||||
DIGIT_CASES: \
|
||||
case ':': \
|
||||
UCALPHA_CASES: \
|
||||
case '^': \
|
||||
case '_': \
|
||||
case '`': \
|
||||
LCALPHA_CASES: \
|
||||
case '|': \
|
||||
case '~'
|
||||
|
||||
#define LCHEXALPHA_CASES \
|
||||
case 'a': \
|
||||
case 'b': \
|
||||
case 'c': \
|
||||
case 'd': \
|
||||
case 'e': \
|
||||
case 'f'
|
||||
|
||||
#define X00_1F_CASES \
|
||||
case 0x00: \
|
||||
case 0x01: \
|
||||
case 0x02: \
|
||||
case 0x03: \
|
||||
case 0x04: \
|
||||
case 0x05: \
|
||||
case 0x06: \
|
||||
case 0x07: \
|
||||
case 0x08: \
|
||||
case 0x09: \
|
||||
case 0x0a: \
|
||||
case 0x0b: \
|
||||
case 0x0c: \
|
||||
case 0x0d: \
|
||||
case 0x0e: \
|
||||
case 0x0f: \
|
||||
case 0x10: \
|
||||
case 0x11: \
|
||||
case 0x12: \
|
||||
case 0x13: \
|
||||
case 0x14: \
|
||||
case 0x15: \
|
||||
case 0x16: \
|
||||
case 0x17: \
|
||||
case 0x18: \
|
||||
case 0x19: \
|
||||
case 0x1a: \
|
||||
case 0x1b: \
|
||||
case 0x1c: \
|
||||
case 0x1d: \
|
||||
case 0x1e: \
|
||||
case 0x1f
|
||||
|
||||
#define X20_21_CASES \
|
||||
case ' ': \
|
||||
case '!'
|
||||
@@ -175,6 +239,137 @@
|
||||
case '}': \
|
||||
case '~'
|
||||
|
||||
#define X7F_FF_CASES \
|
||||
case 0x7f: \
|
||||
case 0x80: \
|
||||
case 0x81: \
|
||||
case 0x82: \
|
||||
case 0x83: \
|
||||
case 0x84: \
|
||||
case 0x85: \
|
||||
case 0x86: \
|
||||
case 0x87: \
|
||||
case 0x88: \
|
||||
case 0x89: \
|
||||
case 0x8a: \
|
||||
case 0x8b: \
|
||||
case 0x8c: \
|
||||
case 0x8d: \
|
||||
case 0x8e: \
|
||||
case 0x8f: \
|
||||
case 0x90: \
|
||||
case 0x91: \
|
||||
case 0x92: \
|
||||
case 0x93: \
|
||||
case 0x94: \
|
||||
case 0x95: \
|
||||
case 0x96: \
|
||||
case 0x97: \
|
||||
case 0x98: \
|
||||
case 0x99: \
|
||||
case 0x9a: \
|
||||
case 0x9b: \
|
||||
case 0x9c: \
|
||||
case 0x9d: \
|
||||
case 0x9e: \
|
||||
case 0x9f: \
|
||||
case 0xa0: \
|
||||
case 0xa1: \
|
||||
case 0xa2: \
|
||||
case 0xa3: \
|
||||
case 0xa4: \
|
||||
case 0xa5: \
|
||||
case 0xa6: \
|
||||
case 0xa7: \
|
||||
case 0xa8: \
|
||||
case 0xa9: \
|
||||
case 0xaa: \
|
||||
case 0xab: \
|
||||
case 0xac: \
|
||||
case 0xad: \
|
||||
case 0xae: \
|
||||
case 0xaf: \
|
||||
case 0xb0: \
|
||||
case 0xb1: \
|
||||
case 0xb2: \
|
||||
case 0xb3: \
|
||||
case 0xb4: \
|
||||
case 0xb5: \
|
||||
case 0xb6: \
|
||||
case 0xb7: \
|
||||
case 0xb8: \
|
||||
case 0xb9: \
|
||||
case 0xba: \
|
||||
case 0xbb: \
|
||||
case 0xbc: \
|
||||
case 0xbd: \
|
||||
case 0xbe: \
|
||||
case 0xbf: \
|
||||
case 0xc0: \
|
||||
case 0xc1: \
|
||||
case 0xc2: \
|
||||
case 0xc3: \
|
||||
case 0xc4: \
|
||||
case 0xc5: \
|
||||
case 0xc6: \
|
||||
case 0xc7: \
|
||||
case 0xc8: \
|
||||
case 0xc9: \
|
||||
case 0xca: \
|
||||
case 0xcb: \
|
||||
case 0xcc: \
|
||||
case 0xcd: \
|
||||
case 0xce: \
|
||||
case 0xcf: \
|
||||
case 0xd0: \
|
||||
case 0xd1: \
|
||||
case 0xd2: \
|
||||
case 0xd3: \
|
||||
case 0xd4: \
|
||||
case 0xd5: \
|
||||
case 0xd6: \
|
||||
case 0xd7: \
|
||||
case 0xd8: \
|
||||
case 0xd9: \
|
||||
case 0xda: \
|
||||
case 0xdb: \
|
||||
case 0xdc: \
|
||||
case 0xdd: \
|
||||
case 0xde: \
|
||||
case 0xdf: \
|
||||
case 0xe0: \
|
||||
case 0xe1: \
|
||||
case 0xe2: \
|
||||
case 0xe3: \
|
||||
case 0xe4: \
|
||||
case 0xe5: \
|
||||
case 0xe6: \
|
||||
case 0xe7: \
|
||||
case 0xe8: \
|
||||
case 0xe9: \
|
||||
case 0xea: \
|
||||
case 0xeb: \
|
||||
case 0xec: \
|
||||
case 0xed: \
|
||||
case 0xee: \
|
||||
case 0xef: \
|
||||
case 0xf0: \
|
||||
case 0xf1: \
|
||||
case 0xf2: \
|
||||
case 0xf3: \
|
||||
case 0xf4: \
|
||||
case 0xf5: \
|
||||
case 0xf6: \
|
||||
case 0xf7: \
|
||||
case 0xf8: \
|
||||
case 0xf9: \
|
||||
case 0xfa: \
|
||||
case 0xfb: \
|
||||
case 0xfc: \
|
||||
case 0xfd: \
|
||||
case 0xfe: \
|
||||
case 0xff
|
||||
|
||||
static int is_ws(uint8_t c) {
|
||||
switch (c) {
|
||||
case ' ':
|
||||
@@ -431,25 +626,7 @@ static int parser_token(sf_parser *sfp, sf_value *dest) {
|
||||
|
||||
for (; !parser_eof(sfp); ++sfp->pos) {
|
||||
switch (*sfp->pos) {
|
||||
case '!':
|
||||
case '#':
|
||||
case '$':
|
||||
case '%':
|
||||
case '&':
|
||||
case '\'':
|
||||
case '*':
|
||||
case '+':
|
||||
case '-':
|
||||
case '.':
|
||||
case '^':
|
||||
case '_':
|
||||
case '`':
|
||||
case '|':
|
||||
case '~':
|
||||
case ':':
|
||||
case '/':
|
||||
DIGIT_CASES:
|
||||
ALPHA_CASES:
|
||||
TOKEN_CASES:
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -487,58 +664,30 @@ static int parser_byteseq(sf_parser *sfp, sf_value *dest) {
|
||||
case 1:
|
||||
return SF_ERR_PARSE_ERROR;
|
||||
case 2:
|
||||
switch (*(sfp->pos - 1)) {
|
||||
case 'A':
|
||||
case 'Q':
|
||||
case 'g':
|
||||
case 'w':
|
||||
break;
|
||||
default:
|
||||
++sfp->pos;
|
||||
|
||||
if (parser_eof(sfp)) {
|
||||
return SF_ERR_PARSE_ERROR;
|
||||
}
|
||||
|
||||
++sfp->pos;
|
||||
|
||||
if (parser_eof(sfp) || *sfp->pos != '=') {
|
||||
return SF_ERR_PARSE_ERROR;
|
||||
if (*sfp->pos == '=') {
|
||||
++sfp->pos;
|
||||
}
|
||||
|
||||
break;
|
||||
case 3:
|
||||
switch (*(sfp->pos - 1)) {
|
||||
case 'A':
|
||||
case 'E':
|
||||
case 'I':
|
||||
case 'M':
|
||||
case 'Q':
|
||||
case 'U':
|
||||
case 'Y':
|
||||
case 'c':
|
||||
case 'g':
|
||||
case 'k':
|
||||
case 'o':
|
||||
case 's':
|
||||
case 'w':
|
||||
case '0':
|
||||
case '4':
|
||||
case '8':
|
||||
break;
|
||||
default:
|
||||
return SF_ERR_PARSE_ERROR;
|
||||
}
|
||||
++sfp->pos;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
++sfp->pos;
|
||||
|
||||
if (parser_eof(sfp) || *sfp->pos != ':') {
|
||||
return SF_ERR_PARSE_ERROR;
|
||||
}
|
||||
|
||||
goto fin;
|
||||
case ':':
|
||||
if ((sfp->pos - base) & 0x3) {
|
||||
if (((sfp->pos - base) & 0x3) == 1) {
|
||||
return SF_ERR_PARSE_ERROR;
|
||||
}
|
||||
|
||||
@@ -599,6 +748,169 @@ static int parser_boolean(sf_parser *sfp, sf_value *dest) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pctdecode(uint8_t *pc, const uint8_t **ppos) {
|
||||
uint8_t c, b = **ppos;
|
||||
|
||||
switch (b) {
|
||||
DIGIT_CASES:
|
||||
c = (uint8_t)((b - '0') << 4);
|
||||
|
||||
break;
|
||||
LCHEXALPHA_CASES:
|
||||
c = (uint8_t)((b - 'a' + 10) << 4);
|
||||
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
b = *++*ppos;
|
||||
|
||||
switch (b) {
|
||||
DIGIT_CASES:
|
||||
c |= (uint8_t)(b - '0');
|
||||
|
||||
break;
|
||||
LCHEXALPHA_CASES:
|
||||
c |= (uint8_t)(b - 'a' + 10);
|
||||
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
*pc = c;
|
||||
++*ppos;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Start of utf8 dfa */
|
||||
/* Copyright (c) 2008-2010 Bjoern Hoehrmann <bjoern@hoehrmann.de>
|
||||
* See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details.
|
||||
*
|
||||
* Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#define UTF8_ACCEPT 0
|
||||
#define UTF8_REJECT 12
|
||||
|
||||
/* clang-format off */
|
||||
static const uint8_t utf8d[] = {
|
||||
/*
|
||||
* The first part of the table maps bytes to character classes that
|
||||
* to reduce the size of the transition table and create bitmasks.
|
||||
*/
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
|
||||
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
||||
8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
|
||||
10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8,
|
||||
|
||||
/*
|
||||
* The second part is a transition table that maps a combination
|
||||
* of a state of the automaton and a character class to a state.
|
||||
*/
|
||||
0,12,24,36,60,96,84,12,12,12,48,72, 12,12,12,12,12,12,12,12,12,12,12,12,
|
||||
12, 0,12,12,12,12,12, 0,12, 0,12,12, 12,24,12,12,12,12,12,24,12,24,12,12,
|
||||
12,12,12,12,12,12,12,24,12,12,12,12, 12,24,12,12,12,12,12,12,12,24,12,12,
|
||||
12,12,12,12,12,12,12,36,12,36,12,12, 12,36,12,12,12,12,12,36,12,36,12,12,
|
||||
12,36,12,12,12,12,12,12,12,12,12,12,
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
static void utf8_decode(uint32_t *state, uint8_t byte) {
|
||||
*state = utf8d[256 + *state + utf8d[byte]];
|
||||
}
|
||||
|
||||
/* End of utf8 dfa */
|
||||
|
||||
static int parser_dispstring(sf_parser *sfp, sf_value *dest) {
|
||||
const uint8_t *base;
|
||||
uint8_t c;
|
||||
uint32_t utf8state = UTF8_ACCEPT;
|
||||
|
||||
assert('%' == *sfp->pos);
|
||||
|
||||
++sfp->pos;
|
||||
|
||||
if (parser_eof(sfp) || *sfp->pos != '"') {
|
||||
return SF_ERR_PARSE_ERROR;
|
||||
}
|
||||
|
||||
base = ++sfp->pos;
|
||||
|
||||
for (; !parser_eof(sfp);) {
|
||||
switch (*sfp->pos) {
|
||||
X00_1F_CASES:
|
||||
X7F_FF_CASES:
|
||||
return SF_ERR_PARSE_ERROR;
|
||||
case '%':
|
||||
++sfp->pos;
|
||||
|
||||
if (sfp->pos + 2 > sfp->end) {
|
||||
return SF_ERR_PARSE_ERROR;
|
||||
}
|
||||
|
||||
if (pctdecode(&c, &sfp->pos) != 0) {
|
||||
return SF_ERR_PARSE_ERROR;
|
||||
}
|
||||
|
||||
utf8_decode(&utf8state, c);
|
||||
if (utf8state == UTF8_REJECT) {
|
||||
return SF_ERR_PARSE_ERROR;
|
||||
}
|
||||
|
||||
break;
|
||||
case '"':
|
||||
if (utf8state != UTF8_ACCEPT) {
|
||||
return SF_ERR_PARSE_ERROR;
|
||||
}
|
||||
|
||||
if (dest) {
|
||||
dest->type = SF_TYPE_DISPSTRING;
|
||||
dest->flags = SF_VALUE_FLAG_NONE;
|
||||
dest->vec.len = (size_t)(sfp->pos - base);
|
||||
dest->vec.base = dest->vec.len == 0 ? NULL : (uint8_t *)base;
|
||||
}
|
||||
|
||||
++sfp->pos;
|
||||
|
||||
return 0;
|
||||
default:
|
||||
if (utf8state != UTF8_ACCEPT) {
|
||||
return SF_ERR_PARSE_ERROR;
|
||||
}
|
||||
|
||||
++sfp->pos;
|
||||
}
|
||||
}
|
||||
|
||||
return SF_ERR_PARSE_ERROR;
|
||||
}
|
||||
|
||||
static int parser_bare_item(sf_parser *sfp, sf_value *dest) {
|
||||
switch (*sfp->pos) {
|
||||
case '"':
|
||||
@@ -615,6 +927,8 @@ static int parser_bare_item(sf_parser *sfp, sf_value *dest) {
|
||||
case '*':
|
||||
ALPHA_CASES:
|
||||
return parser_token(sfp, dest);
|
||||
case '%':
|
||||
return parser_dispstring(sfp, dest);
|
||||
default:
|
||||
return SF_ERR_PARSE_ERROR;
|
||||
}
|
||||
@@ -1037,7 +1351,7 @@ void sf_unescape(sf_vec *dest, const sf_vec *src) {
|
||||
size_t len, slen;
|
||||
|
||||
if (src->len == 0) {
|
||||
*dest = *src;
|
||||
dest->len = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -1049,16 +1363,12 @@ void sf_unescape(sf_vec *dest, const sf_vec *src) {
|
||||
for (;;) {
|
||||
q = memchr(p, '\\', len);
|
||||
if (q == NULL) {
|
||||
if (len == src->len) {
|
||||
*dest = *src;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(o, p, len);
|
||||
o += len;
|
||||
|
||||
break;
|
||||
dest->len = (size_t)(o - dest->base);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
slen = (size_t)(q - p);
|
||||
@@ -1069,8 +1379,6 @@ void sf_unescape(sf_vec *dest, const sf_vec *src) {
|
||||
*o++ = *p++;
|
||||
len -= slen + 2;
|
||||
}
|
||||
|
||||
dest->len = (size_t)(o - dest->base);
|
||||
}
|
||||
|
||||
void sf_base64decode(sf_vec *dest, const sf_vec *src) {
|
||||
@@ -1093,20 +1401,22 @@ void sf_base64decode(sf_vec *dest, const sf_vec *src) {
|
||||
uint8_t *o;
|
||||
const uint8_t *p, *end;
|
||||
uint32_t n;
|
||||
size_t i;
|
||||
size_t i, left;
|
||||
int idx;
|
||||
|
||||
assert((src->len & 0x3) == 0);
|
||||
|
||||
if (src->len == 0) {
|
||||
*dest = *src;
|
||||
dest->len = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
o = dest->base;
|
||||
p = src->base;
|
||||
end = src->base + src->len;
|
||||
left = src->len & 0x3;
|
||||
if (left == 0 && src->base[src->len - 1] == '=') {
|
||||
left = 4;
|
||||
}
|
||||
end = src->base + src->len - left;
|
||||
|
||||
for (; p != end;) {
|
||||
n = 0;
|
||||
@@ -1114,24 +1424,7 @@ void sf_base64decode(sf_vec *dest, const sf_vec *src) {
|
||||
for (i = 1; i <= 4; ++i, ++p) {
|
||||
idx = index_tbl[*p];
|
||||
|
||||
if (idx == -1) {
|
||||
assert(i > 2);
|
||||
|
||||
if (i == 3) {
|
||||
assert(*p == '=' && *(p + 1) == '=' && p + 2 == end);
|
||||
|
||||
*o++ = (uint8_t)(n >> 16);
|
||||
|
||||
goto fin;
|
||||
}
|
||||
|
||||
assert(*p == '=' && p + 1 == end);
|
||||
|
||||
*o++ = (uint8_t)(n >> 16);
|
||||
*o++ = (n >> 8) & 0xffu;
|
||||
|
||||
goto fin;
|
||||
}
|
||||
assert(idx != -1);
|
||||
|
||||
n += (uint32_t)(idx << (24 - i * 6));
|
||||
}
|
||||
@@ -1141,6 +1434,84 @@ void sf_base64decode(sf_vec *dest, const sf_vec *src) {
|
||||
*o++ = n & 0xffu;
|
||||
}
|
||||
|
||||
switch (left) {
|
||||
case 0:
|
||||
goto fin;
|
||||
case 1:
|
||||
assert(0);
|
||||
abort();
|
||||
case 3:
|
||||
if (src->base[src->len - 1] == '=') {
|
||||
left = 2;
|
||||
}
|
||||
|
||||
break;
|
||||
case 4:
|
||||
assert('=' == src->base[src->len - 1]);
|
||||
|
||||
if (src->base[src->len - 2] == '=') {
|
||||
left = 2;
|
||||
} else {
|
||||
left = 3;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
switch (left) {
|
||||
case 2:
|
||||
*o = (uint8_t)(index_tbl[*p++] << 2);
|
||||
*o++ |= (uint8_t)(index_tbl[*p++] >> 4);
|
||||
|
||||
break;
|
||||
case 3:
|
||||
n = (uint32_t)(index_tbl[*p++] << 10);
|
||||
n += (uint32_t)(index_tbl[*p++] << 4);
|
||||
n += (uint32_t)(index_tbl[*p++] >> 2);
|
||||
*o++ = (n >> 8) & 0xffu;
|
||||
*o++ = n & 0xffu;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
fin:
|
||||
dest->len = (size_t)(o - dest->base);
|
||||
}
|
||||
|
||||
void sf_pctdecode(sf_vec *dest, const sf_vec *src) {
|
||||
const uint8_t *p, *q;
|
||||
uint8_t *o;
|
||||
size_t len, slen;
|
||||
|
||||
if (src->len == 0) {
|
||||
dest->len = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
o = dest->base;
|
||||
p = src->base;
|
||||
len = src->len;
|
||||
|
||||
for (;;) {
|
||||
q = memchr(p, '%', len);
|
||||
if (q == NULL) {
|
||||
memcpy(o, p, len);
|
||||
o += len;
|
||||
|
||||
dest->len = (size_t)(o - dest->base);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
slen = (size_t)(q - p);
|
||||
memcpy(o, p, slen);
|
||||
o += slen;
|
||||
|
||||
p = q + 1;
|
||||
|
||||
pctdecode(o++, &p);
|
||||
|
||||
len -= slen + 3;
|
||||
}
|
||||
}
|
||||
+29
-10
@@ -85,7 +85,11 @@ typedef enum sf_type {
|
||||
/**
|
||||
* :enum:`SF_TYPE_DATE` indicates date type.
|
||||
*/
|
||||
SF_TYPE_DATE
|
||||
SF_TYPE_DATE,
|
||||
/**
|
||||
* :enum:`SF_TYPE_DISPSTRING` indicates display string type.
|
||||
*/
|
||||
SF_TYPE_DISPSTRING
|
||||
} sf_type;
|
||||
|
||||
/**
|
||||
@@ -197,8 +201,8 @@ typedef struct sf_value {
|
||||
/**
|
||||
* :member:`vec` contains sequence of bytes if :member:`type` is
|
||||
* either :enum:`sf_type.SF_TYPE_STRING`,
|
||||
* :enum:`sf_type.SF_TYPE_TOKEN`, or
|
||||
* :enum:`sf_type.SF_TYPE_BYTESEQ`.
|
||||
* :enum:`sf_type.SF_TYPE_TOKEN`, :enum:`sf_type.SF_TYPE_BYTESEQ`,
|
||||
* or :enum:`sf_type.SF_TYPE_DISPSTRING`.
|
||||
*
|
||||
* For :enum:`sf_type.SF_TYPE_STRING`, this field contains one or
|
||||
* more escaped characters if :member:`flags` has
|
||||
@@ -209,6 +213,10 @@ typedef struct sf_value {
|
||||
* encoded string. To decode this byte string, use
|
||||
* `sf_base64decode`.
|
||||
*
|
||||
* For :enum:`sf_type.SF_TYPE_DISPSTRING`, this field may contain
|
||||
* percent-encoded UTF-8 byte sequences. To decode it, use
|
||||
* `sf_pctdecode`.
|
||||
*
|
||||
* If :member:`vec.len <sf_vec.len>` == 0, :member:`vec.base
|
||||
* <sf_vec.base>` is guaranteed to be NULL.
|
||||
*/
|
||||
@@ -372,10 +380,6 @@ int sf_parser_inner_list(sf_parser *sfp, sf_value *dest);
|
||||
* :member:`dest->base <sf_vec.base>` must point to the buffer that
|
||||
* has sufficient space to store the unescaped string.
|
||||
*
|
||||
* If there is no escape character in |src|, |*src| is assigned to
|
||||
* |*dest|. This includes the case that :member:`src->len
|
||||
* <sf_vec.len>` == 0.
|
||||
*
|
||||
* This function sets the length of unescaped string to
|
||||
* :member:`dest->len <sf_vec.len>`.
|
||||
*/
|
||||
@@ -394,14 +398,29 @@ void sf_unescape(sf_vec *dest, const sf_vec *src);
|
||||
* :member:`dest->base <sf_vec.base>` must point to the buffer that
|
||||
* has sufficient space to store the decoded byte string.
|
||||
*
|
||||
* If :member:`src->len <sf_vec.len>` == 0, |*src| is assigned to
|
||||
* |*dest|.
|
||||
*
|
||||
* This function sets the length of decoded byte string to
|
||||
* :member:`dest->len <sf_vec.len>`.
|
||||
*/
|
||||
void sf_base64decode(sf_vec *dest, const sf_vec *src);
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
* `sf_pctdecode` decodes percent-encoded string |src| and writes the
|
||||
* result into |dest|. |src| should be the pointer to
|
||||
* :member:`sf_value.vec` of type :enum:`sf_type.SF_TYPE_DISPSTRING`
|
||||
* produced by either `sf_parser_dict`, `sf_parser_list`,
|
||||
* `sf_parser_inner_list`, `sf_parser_item`, or `sf_parser_param`,
|
||||
* otherwise the behavior is undefined.
|
||||
*
|
||||
* :member:`dest->base <sf_vec.base>` must point to the buffer that
|
||||
* has sufficient space to store the decoded byte string.
|
||||
*
|
||||
* This function sets the length of decoded byte string to
|
||||
* :member:`dest->len <sf_vec.len>`.
|
||||
*/
|
||||
void sf_pctdecode(sf_vec *dest, const sf_vec *src);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
Reference in new issue
Block a user