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