/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 |