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:
Node.js GitHub Bot authored and GitHub committed 2024-12-17 13:08:00 +00:00
1 parent 12806e9697
commit 2a3fc98c4b
54 files changed
+7378 -6870

No files matched your search

+70 -40
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
File diff suppressed because it is too large. Load diff
+2 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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) */
+28 -13
View File
@@ -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;
}
+38 -30
View File
@@ -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
View File
File diff suppressed because it is too large. Load diff
+30 -16
View File
@@ -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
View File
@@ -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
View File
@@ -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) */
File diff suppressed because it is too large. Load diff
+4 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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.
@@ -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;
}
}
@@ -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