1a74702c6SGeorge Wang/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc.  See LICENSE. */
250aadb33SDmitri Tikhonov/*
350aadb33SDmitri Tikhonov * lsquic_data_in_if.h -- DATA in interface
450aadb33SDmitri Tikhonov */
550aadb33SDmitri Tikhonov
650aadb33SDmitri Tikhonov#ifndef LSQUIC_DATA_IN_IF_H
750aadb33SDmitri Tikhonov#define LSQUIC_DATA_IN_IF_H 1
850aadb33SDmitri Tikhonov
95392f7a3SLiteSpeed Tech
1050aadb33SDmitri Tikhonovstruct data_frame;
1150aadb33SDmitri Tikhonovstruct data_in;
1250aadb33SDmitri Tikhonovstruct lsquic_conn_public;
1350aadb33SDmitri Tikhonovstruct stream_frame;
1450aadb33SDmitri Tikhonov
155392f7a3SLiteSpeed Tech
1650aadb33SDmitri Tikhonovenum ins_frame
1750aadb33SDmitri Tikhonov{
1850aadb33SDmitri Tikhonov    INS_FRAME_OK,
1950aadb33SDmitri Tikhonov    INS_FRAME_ERR,
2050aadb33SDmitri Tikhonov    INS_FRAME_DUP,
21be4cfad0SDmitri Tikhonov    INS_FRAME_OVERLAP,
2250aadb33SDmitri Tikhonov};
2350aadb33SDmitri Tikhonov
245392f7a3SLiteSpeed Tech
2550aadb33SDmitri Tikhonovstruct data_in_iface
2650aadb33SDmitri Tikhonov{
2750aadb33SDmitri Tikhonov    void
2850aadb33SDmitri Tikhonov    (*di_destroy) (struct data_in *);
2950aadb33SDmitri Tikhonov
3050aadb33SDmitri Tikhonov    int
3150aadb33SDmitri Tikhonov    (*di_empty) (struct data_in *);
3250aadb33SDmitri Tikhonov
33be4cfad0SDmitri Tikhonov    /* When INS_FRAME_OK, INS_FRAME_ERR, or INS_FRAME_DUP is returned, the
34be4cfad0SDmitri Tikhonov     * caller releases control of stream frame.  Do not reference it after
35be4cfad0SDmitri Tikhonov     * the call.
36be4cfad0SDmitri Tikhonov     *
37be4cfad0SDmitri Tikhonov     * When INS_FRAME_OVERLAP is returned the caller has a choice to switch
38be4cfad0SDmitri Tikhonov     * to implementation that supports overlaps and try to insert the frame
39be4cfad0SDmitri Tikhonov     * again or to treat this as an error.  Either way, the caller retains
40be4cfad0SDmitri Tikhonov     * control of the frame.
4150aadb33SDmitri Tikhonov     */
4250aadb33SDmitri Tikhonov    enum ins_frame
4350aadb33SDmitri Tikhonov    (*di_insert_frame) (struct data_in *, struct stream_frame *,
4450aadb33SDmitri Tikhonov                                                        uint64_t read_offset);
4550aadb33SDmitri Tikhonov
4650aadb33SDmitri Tikhonov    struct data_frame *
4750aadb33SDmitri Tikhonov    (*di_get_frame) (struct data_in *, uint64_t read_offset);
4850aadb33SDmitri Tikhonov
4950aadb33SDmitri Tikhonov    void
5050aadb33SDmitri Tikhonov    (*di_frame_done) (struct data_in *, struct data_frame *);
5150aadb33SDmitri Tikhonov
5250aadb33SDmitri Tikhonov    /* Creates a new data_in object, feeds its stream frames to it, deletes
5350aadb33SDmitri Tikhonov     * itself and returns the new object.
5450aadb33SDmitri Tikhonov     */
5550aadb33SDmitri Tikhonov    struct data_in *
5650aadb33SDmitri Tikhonov    (*di_switch_impl) (struct data_in *, uint64_t read_offset);
57c51ce338SDmitri Tikhonov
58c51ce338SDmitri Tikhonov    size_t
59c51ce338SDmitri Tikhonov    (*di_mem_used) (struct data_in *);
6050aadb33SDmitri Tikhonov
615392f7a3SLiteSpeed Tech    void
625392f7a3SLiteSpeed Tech    (*di_dump_state) (struct data_in *);
635392f7a3SLiteSpeed Tech
645392f7a3SLiteSpeed Tech    /* Return number of bytes readable starting at offset `read_offset' */
655392f7a3SLiteSpeed Tech    uint64_t
665392f7a3SLiteSpeed Tech    (*di_readable_bytes) (struct data_in *, uint64_t read_offset);
67cca25415SDmitri Tikhonov
68cca25415SDmitri Tikhonov    /* If set, this means that when di_insert_frame() returns INS_FRAME_OK,
69cca25415SDmitri Tikhonov     * the data_in handler has taken ownership of the frame.  Otherwise, it
70cca25415SDmitri Tikhonov     * is up to the caller to free it.
71cca25415SDmitri Tikhonov     */
72cca25415SDmitri Tikhonov    const int
73cca25415SDmitri Tikhonov    di_own_on_ok;
74355db7c6SDmitri Tikhonov};
7550aadb33SDmitri Tikhonov
765392f7a3SLiteSpeed Tech
7750aadb33SDmitri Tikhonovstruct data_in
7850aadb33SDmitri Tikhonov{
7950aadb33SDmitri Tikhonov    const struct data_in_iface  *di_if;
8050aadb33SDmitri Tikhonov    enum {
8150aadb33SDmitri Tikhonov        /* If DI_SWITCH_IMPL is set, switching data_in implementation is
8250aadb33SDmitri Tikhonov         * recommended in order to get better performance for current
8350aadb33SDmitri Tikhonov         * incoming stream frame scenario.  Check the value of this flag
8450aadb33SDmitri Tikhonov         * after calls to di_insert_frame() and di_frame_done().
8550aadb33SDmitri Tikhonov         */
8650aadb33SDmitri Tikhonov        DI_SWITCH_IMPL = (1 << 0),
8750aadb33SDmitri Tikhonov    }                            di_flags;
8850aadb33SDmitri Tikhonov};
8950aadb33SDmitri Tikhonov
905392f7a3SLiteSpeed Tech
91be4cfad0SDmitri Tikhonov/* This implementation does not support overlapping frame and may return
92be4cfad0SDmitri Tikhonov * INS_FRAME_OVERLAP.
93be4cfad0SDmitri Tikhonov */
9450aadb33SDmitri Tikhonovstruct data_in *
95a5fa05f9SDmitri Tikhonovlsquic_data_in_nocopy_new (struct lsquic_conn_public *, lsquic_stream_id_t);
9650aadb33SDmitri Tikhonov
97be4cfad0SDmitri Tikhonov/* This implementation supports overlapping frames and will never return
98be4cfad0SDmitri Tikhonov * INS_FRAME_OVERLAP.
99be4cfad0SDmitri Tikhonov */
10050aadb33SDmitri Tikhonovstruct data_in *
101a5fa05f9SDmitri Tikhonovlsquic_data_in_hash_new (struct lsquic_conn_public *, lsquic_stream_id_t,
10250aadb33SDmitri Tikhonov                  uint64_t byteage);
10350aadb33SDmitri Tikhonov
10450aadb33SDmitri Tikhonovenum ins_frame
105a5fa05f9SDmitri Tikhonovlsquic_data_in_hash_insert_data_frame (struct data_in *data_in,
10650aadb33SDmitri Tikhonov                const struct data_frame *data_frame, uint64_t read_offset);
10750aadb33SDmitri Tikhonov
10850aadb33SDmitri Tikhonovstruct data_in *
109a5fa05f9SDmitri Tikhonovlsquic_data_in_error_new ();
11050aadb33SDmitri Tikhonov
11150aadb33SDmitri Tikhonov#endif
112