Coverage Report

Created: 2026-01-23 07:12

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/h2o/deps/quicly/include/quicly/streambuf.h
Line
Count
Source
1
/*
2
 * Copyright (c) 2018 Fastly, Kazuho Oku
3
 *
4
 * Permission is hereby granted, free of charge, to any person obtaining a copy
5
 * of this software and associated documentation files (the "Software"), to
6
 * deal in the Software without restriction, including without limitation the
7
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8
 * sell copies of the Software, and to permit persons to whom the Software is
9
 * furnished to do so, subject to the following conditions:
10
 *
11
 * The above copyright notice and this permission notice shall be included in
12
 * all copies or substantial portions of the Software.
13
 *
14
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20
 * IN THE SOFTWARE.
21
 */
22
#ifndef quicly_streambuf_h
23
#define quicly_streambuf_h
24
25
#ifdef __cplusplus
26
extern "C" {
27
#endif
28
29
#include <assert.h>
30
#include <stddef.h>
31
#include <stdint.h>
32
#include <string.h>
33
#include "picotls.h"
34
#include "quicly.h"
35
36
typedef struct st_quicly_sendbuf_vec_t quicly_sendbuf_vec_t;
37
38
/**
39
 * Callback that flattens the contents of an iovec.
40
 * @param dst the destination
41
 * @param off offset within the iovec from where serialization should happen
42
 * @param len number of bytes to serialize
43
 * @return 0 if successful, otherwise an error code
44
 */
45
typedef quicly_error_t (*quicly_sendbuf_flatten_vec_cb)(quicly_sendbuf_vec_t *vec, void *dst, size_t off, size_t len);
46
/**
47
 * An optional callback that is called when an iovec is discarded.
48
 */
49
typedef void (*quicly_sendbuf_discard_vec_cb)(quicly_sendbuf_vec_t *vec);
50
51
typedef struct st_quicly_streambuf_sendvec_callbacks_t {
52
    quicly_sendbuf_flatten_vec_cb flatten_vec;
53
    quicly_sendbuf_discard_vec_cb discard_vec;
54
} quicly_streambuf_sendvec_callbacks_t;
55
56
struct st_quicly_sendbuf_vec_t {
57
    const quicly_streambuf_sendvec_callbacks_t *cb;
58
    size_t len;
59
    void *cbdata;
60
};
61
62
/**
63
 * A simple stream-level send buffer that can be used to store data to be sent.
64
 */
65
typedef struct st_quicly_sendbuf_t {
66
    struct {
67
        quicly_sendbuf_vec_t *entries;
68
        size_t size, capacity;
69
    } vecs;
70
    size_t off_in_first_vec;
71
    uint64_t bytes_written;
72
} quicly_sendbuf_t;
73
74
/**
75
 * Initializes the send buffer.
76
 */
77
static void quicly_sendbuf_init(quicly_sendbuf_t *sb);
78
/**
79
 * Disposes of the send buffer.
80
 */
81
void quicly_sendbuf_dispose(quicly_sendbuf_t *sb);
82
/**
83
 * The concrete function to be used when `quicly_stream_callbacks_t::on_send_shift` is being invoked (i.e., applications using
84
 * `quicly_sendbuf_t` as the stream-level send buffer should call this function from it's `on_send_shift` callback).
85
 */
86
void quicly_sendbuf_shift(quicly_stream_t *stream, quicly_sendbuf_t *sb, size_t delta);
87
/**
88
 * The concrete function for `quicly_stream_callbacks_t::on_send_emit`.
89
 */
90
void quicly_sendbuf_emit(quicly_stream_t *stream, quicly_sendbuf_t *sb, size_t off, void *dst, size_t *len, int *wrote_all);
91
/**
92
 * Appends some bytes to the send buffer.  The data being appended is copied.
93
 */
94
int quicly_sendbuf_write(quicly_stream_t *stream, quicly_sendbuf_t *sb, const void *src, size_t len);
95
/**
96
 * Appends a vector to the send buffer.  Members of the `quicly_sendbuf_vec_t` are copied.
97
 */
98
int quicly_sendbuf_write_vec(quicly_stream_t *stream, quicly_sendbuf_t *sb, quicly_sendbuf_vec_t *vec);
99
100
/**
101
 * Pops the specified amount of bytes at the beginning of the simple stream-level receive buffer (which in fact is `ptls_buffer_t`).
102
 */
103
void quicly_recvbuf_shift(quicly_stream_t *stream, ptls_buffer_t *rb, size_t delta);
104
/**
105
 * Returns an iovec that refers to the data available in the receive buffer.  Applications are expected to call `quicly_recvbuf_get`
106
 * to first peek at the received data, process the bytes they can, then call `quicly_recvbuf_shift` to pop the bytes that have been
107
 * processed.
108
 */
109
ptls_iovec_t quicly_recvbuf_get(quicly_stream_t *stream, ptls_buffer_t *rb);
110
/**
111
 * The concrete function for `quicly_stream_callbacks_t::on_receive`.
112
 */
113
int quicly_recvbuf_receive(quicly_stream_t *stream, ptls_buffer_t *rb, size_t off, const void *src, size_t len);
114
115
/**
116
 * The simple stream buffer.  The API assumes that stream->data points to quicly_streambuf_t.  Applications can extend the structure
117
 * by passing arbitrary size to `quicly_streambuf_create`.
118
 */
119
typedef struct st_quicly_streambuf_t {
120
    quicly_sendbuf_t egress;
121
    ptls_buffer_t ingress;
122
} quicly_streambuf_t;
123
124
int quicly_streambuf_create(quicly_stream_t *stream, size_t sz);
125
void quicly_streambuf_destroy(quicly_stream_t *stream, quicly_error_t err);
126
static void quicly_streambuf_egress_shift(quicly_stream_t *stream, size_t delta);
127
void quicly_streambuf_egress_emit(quicly_stream_t *stream, size_t off, void *dst, size_t *len, int *wrote_all);
128
static int quicly_streambuf_egress_write(quicly_stream_t *stream, const void *src, size_t len);
129
static int quicly_streambuf_egress_write_vec(quicly_stream_t *stream, quicly_sendbuf_vec_t *vec);
130
int quicly_streambuf_egress_shutdown(quicly_stream_t *stream);
131
static void quicly_streambuf_ingress_shift(quicly_stream_t *stream, size_t delta);
132
static ptls_iovec_t quicly_streambuf_ingress_get(quicly_stream_t *stream);
133
/**
134
 * Writes given data into `quicly_stream_buf_t::ingress` and returns 0 if successful. Upon failure, `quicly_close` is called
135
 * automatically, and a non-zero value is returned. Applications can ignore the returned value, or use it to find out if it can use
136
 * the information stored in the ingress buffer.
137
 */
138
int quicly_streambuf_ingress_receive(quicly_stream_t *stream, size_t off, const void *src, size_t len);
139
140
/* inline definitions */
141
142
inline void quicly_sendbuf_init(quicly_sendbuf_t *sb)
143
0
{
144
0
    memset(sb, 0, sizeof(*sb));
145
0
}
Unexecuted instantiation: quicly.c:quicly_sendbuf_init
Unexecuted instantiation: streambuf.c:quicly_sendbuf_init
146
147
inline void quicly_streambuf_egress_shift(quicly_stream_t *stream, size_t delta)
148
0
{
149
0
    quicly_streambuf_t *sbuf = (quicly_streambuf_t *)stream->data;
150
0
    quicly_sendbuf_shift(stream, &sbuf->egress, delta);
151
0
}
Unexecuted instantiation: quicly.c:quicly_streambuf_egress_shift
Unexecuted instantiation: streambuf.c:quicly_streambuf_egress_shift
152
153
inline int quicly_streambuf_egress_write(quicly_stream_t *stream, const void *src, size_t len)
154
0
{
155
0
    quicly_streambuf_t *sbuf = (quicly_streambuf_t *)stream->data;
156
0
    return quicly_sendbuf_write(stream, &sbuf->egress, src, len);
157
0
}
Unexecuted instantiation: quicly.c:quicly_streambuf_egress_write
Unexecuted instantiation: streambuf.c:quicly_streambuf_egress_write
158
159
inline int quicly_streambuf_egress_write_vec(quicly_stream_t *stream, quicly_sendbuf_vec_t *vec)
160
0
{
161
0
    quicly_streambuf_t *sbuf = (quicly_streambuf_t *)stream->data;
162
0
    return quicly_sendbuf_write_vec(stream, &sbuf->egress, vec);
163
0
}
Unexecuted instantiation: quicly.c:quicly_streambuf_egress_write_vec
Unexecuted instantiation: streambuf.c:quicly_streambuf_egress_write_vec
164
165
inline void quicly_streambuf_ingress_shift(quicly_stream_t *stream, size_t delta)
166
0
{
167
0
    quicly_streambuf_t *sbuf = (quicly_streambuf_t *)stream->data;
168
0
    quicly_recvbuf_shift(stream, &sbuf->ingress, delta);
169
0
}
Unexecuted instantiation: quicly.c:quicly_streambuf_ingress_shift
Unexecuted instantiation: streambuf.c:quicly_streambuf_ingress_shift
170
171
inline ptls_iovec_t quicly_streambuf_ingress_get(quicly_stream_t *stream)
172
0
{
173
0
    quicly_streambuf_t *sbuf = (quicly_streambuf_t *)stream->data;
174
0
    return quicly_recvbuf_get(stream, &sbuf->ingress);
175
0
}
Unexecuted instantiation: quicly.c:quicly_streambuf_ingress_get
Unexecuted instantiation: streambuf.c:quicly_streambuf_ingress_get
176
177
#ifdef __cplusplus
178
}
179
#endif
180
181
#endif