1 /*------------------------------------------------------------------------------
2 *
3 * Copyright (c) 2011-2021, EURid vzw. All rights reserved.
4 * The YADIFA TM software product is provided under the BSD 3-clause license:
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * * Neither the name of EURid nor the names of its contributors may be
16 * used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 *
31 *------------------------------------------------------------------------------
32 *
33 */
34
35 /** @defgroup streaming Streams
36 * @ingroup dnscore
37 * @brief
38 *
39 *
40 *
41 * @{
42 *
43 *----------------------------------------------------------------------------*/
44 #pragma once
45
46 #include <dnscore/sys_types.h>
47
48 #ifdef __cplusplus
49 extern "C" {
50 #endif
51
52 typedef struct input_stream input_stream;
53
54
55 typedef ya_result input_stream_read_method(input_stream *stream,void *in_buffer,u32 in_len);
56 typedef void input_stream_close_method(input_stream *stream);
57
58 typedef ya_result input_stream_skip_method(input_stream *stream,u32 byte_count);
59
60 typedef struct input_stream_vtbl input_stream_vtbl;
61
62
63 struct input_stream_vtbl
64 {
65 input_stream_read_method* read;
66 input_stream_skip_method* skip;
67 input_stream_close_method* close;
68 const char* __class__; /* MUST BE A UNIQUE POINTER, ie: One defined in the class's .c file */
69 /* The name should be unique in order to avoid compiler tricks */
70
71 /* Add your inheritable methods here */
72 };
73
74 struct input_stream
75 {
76 void* data;
77 const input_stream_vtbl* vtbl;
78 };
79
80 #define input_stream_class(is_) ((is_)->vtbl)
81 #define input_stream_class_name(is_) ((is_)->vtbl->__class__)
82 #define input_stream_read(is_,buffer_,len_) (is_)->vtbl->read(is_,buffer_,len_)
83 #define input_stream_close(is_) (is_)->vtbl->close(is_)
84 #define input_stream_skip(is_,len_) (is_)->vtbl->skip(is_,len_)
85 #define input_stream_valid(is_) ((is_)->vtbl != NULL)
86
87 ya_result input_stream_read_fully(input_stream *stream, void *buffer, u32 len);
88 ya_result input_stream_skip_fully(input_stream *stream, u32 len_start);
89
90 ya_result input_stream_read_nu32(input_stream *stream, u32 *output);
91 ya_result input_stream_read_nu16(input_stream *stream, u16 *output);
92 ya_result input_stream_read_u32(input_stream *stream, u32 *output);
93 ya_result input_stream_read_s32(input_stream *stream, s32 *output);
94 ya_result input_stream_read_u16(input_stream *stream, u16 *output);
95
input_stream_read_u8(input_stream * stream,u8 * output)96 static inline ya_result input_stream_read_u8(input_stream* stream, u8* output)
97 {
98 return input_stream_read_fully(stream, output, 1);
99 }
100
input_stream_read_s8(input_stream * stream,s8 * output)101 static inline ya_result input_stream_read_s8(input_stream* stream, s8* output)
102 {
103 return input_stream_read_fully(stream, output, 1);
104 }
105
106 ya_result input_stream_read_pu32(input_stream *stream, u32 *output);
107 ya_result input_stream_read_pu64(input_stream *stream, u64 *output);
108
109 ya_result input_stream_read_dnsname(input_stream *stream,u8 *output);
110
111 ya_result input_stream_read_rname(input_stream *stream, u8 *output_buffer);
112
113 ya_result input_stream_read_line(input_stream *stream, char *output, int max_len);
114
115 /**
116 * This tools allows a safer misuse (and detection) of closed streams
117 * It sets the stream to a sink that warns abouts its usage and for which every call that can fail fails.
118 *
119 * @param is the stream to set as a void. It needs to have been closed already.
120 */
121
122 void input_stream_set_void(input_stream *is);
123
124 /**
125 * Used to temporarily initialise a stream with a sink that can be closed safely.
126 * Typically used as pre-init so the stream can be closed even if the function
127 * setup failed before reaching stream initialisation.
128 *
129 * @param is
130 */
131
132 void input_stream_set_sink(input_stream* is);
133
134 #ifdef __cplusplus
135 }
136 #endif
137
138 /** @} */
139