summaryrefslogtreecommitdiffstats
path: root/src/libknot/rdataset.h
blob: 6d9808663e93a85e84a492e4835e5a976c83523b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
/*  Copyright (C) 2022 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

/*!
 * \file
 *
 * \brief API for manipulating RR arrays.
 *
 * \addtogroup rr
 * @{
 */

#pragma once

#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>

#include "libknot/errcode.h"
#include "libknot/mm_ctx.h"
#include "libknot/rdata.h"

/*!< \brief Set of RRs. */
typedef struct {
	uint16_t count;      /*!< \brief Count of RRs stored in the structure. */
	uint32_t size;       /*!< \brief Size of the rdata array. */
	knot_rdata_t *rdata; /*!< \brief Serialized rdata, canonically sorted. */
} knot_rdataset_t;

/*!
 * \brief Initializes RRS structure.
 *
 * \param rrs  Structure to be initialized.
 */
inline static void knot_rdataset_init(knot_rdataset_t *rrs)
{
	if (rrs != NULL) {
		rrs->count = 0;
		rrs->size = 0;
		rrs->rdata = NULL;
	}
}

/*!
 * \brief Advance to the next rdata in a rdataset.
 *
 * Useful for iteration.
 *
 * \note Ensure that this operation makes sense!
 *
 * \param rr  Current RR.
 *
 * \return Next RR.
 */
static inline knot_rdata_t *knot_rdataset_next(knot_rdata_t *rr)
{
	assert(rr);
	return (knot_rdata_t *)((uint8_t *)rr + knot_rdata_size(rr->len));
}

/*!
 * \brief Frees data initialized by RRS structure, but not the structure itself.
 *
 * \param rrs  Structure to be cleared.
 * \param mm   Memory context used to create allocations.
 */
void knot_rdataset_clear(knot_rdataset_t *rrs, knot_mm_t *mm);

/*!
 * \brief Deep copies RRS structure. All data are duplicated.
 *
 * \param dst  Copy destination.
 * \param src  Copy source.
 * \param mm   Memory context.
 *
 * \return KNOT_E*
 */
int knot_rdataset_copy(knot_rdataset_t *dst, const knot_rdataset_t *src, knot_mm_t *mm);

/*!
 * \brief Gets RR from RRS structure, using given position.
 *
 * \param rrs  RRS structure to get RR from.
 * \param pos  Position to use (counted from 0).
 *
 * \return Pointer to RR at \a pos position.
 */
knot_rdata_t *knot_rdataset_at(const knot_rdataset_t *rrs, uint16_t pos);

/*!
 * \brief Adds single RR into RRS structure. All data are copied.
 *
 * \param rrs  RRS structure to add RR into.
 * \param rr   RR to add.
 * \param mm   Memory context.
 *
 * \return KNOT_E*
 */
int knot_rdataset_add(knot_rdataset_t *rrs, const knot_rdata_t *rr, knot_mm_t *mm);

/*!
 * \brief RRS equality check.
 *
 * \param rrs1  First RRS to be compared.
 * \param rrs2  Second RRS to be compared.
 *
 * \retval true if rrs1 == rrs2.
 * \retval false if rrs1 != rrs2.
 */
bool knot_rdataset_eq(const knot_rdataset_t *rrs1, const knot_rdataset_t *rrs2);

/*!
 * \brief Returns true if \a rr is present in \a rrs, false otherwise.
 *
 * \param rrs  RRS to search in.
 * \param rr   RR to compare with.
 *
 * \retval true if \a rr is present in \a rrs.
 * \retval false if \a rr is not present in \a rrs.
 */
bool knot_rdataset_member(const knot_rdataset_t *rrs, const knot_rdata_t *rr);

/*!
 * \brief Returns true if \a subset is a sub-set of \a of, false otherwise.
 *
 * \param subset  RRS to check.
 * \param of      RRS to search in.
 *
 * \retval true if \a subset is a sub-set of \a of.
 * \retval false if \a subset is not a sub-set of \a of.
 */
bool knot_rdataset_subset(const knot_rdataset_t *subset, const knot_rdataset_t *of);

/*!
 * \brief Merges two RRS into the first one. Second RRS is left intact.
 *        Canonical order is preserved.
 *
 * \param rrs1  Destination RRS (merge here).
 * \param rrs2  RRS to be merged (merge from).
 * \param mm    Memory context.
 *
 * \return KNOT_E*
 */
int knot_rdataset_merge(knot_rdataset_t *rrs1, const knot_rdataset_t *rrs2,
                        knot_mm_t *mm);

/*!
 * \brief RRS set-like intersection. Full compare is done.
 *
 * \param rrs1  First RRS to intersect.
 * \param rrs2  Second RRS to intersect.
 * \param out   Output RRS with intersection, RDATA are created anew.
 * \param mm    Memory context. Will be used to create new RDATA.
 *
 * \return KNOT_E*
 */
int knot_rdataset_intersect(const knot_rdataset_t *rrs1, const knot_rdataset_t *rrs2,
                            knot_rdataset_t *out, knot_mm_t *mm);

/*!
 * \brief Does set-like RRS intersection. \a from RRS is changed.
 *
 * \param from  RRS to be modified by intersection.
 * \param what  RRS to intersect.
 * \param mm    Memory context use to reallocated \a from data.
 *
 * \return KNOT_E*
 */
int knot_rdataset_intersect2(knot_rdataset_t *from, const knot_rdataset_t *what,
                             knot_mm_t *mm);

/*!
 * \brief Does set-like RRS subtraction. \a from RRS is changed.
 *
 * \param from  RRS to subtract from.
 * \param what  RRS to subtract.
 * \param mm    Memory context use to reallocated \a from data.
 *
 * \return KNOT_E*
 */
int knot_rdataset_subtract(knot_rdataset_t *from, const knot_rdataset_t *what,
                           knot_mm_t *mm);

/*!
 * \brief Removes single RR from RRS structure.
 *
 * \param rrs  RRS structure to remove RR from.
 * \param rr   RR to remove.
 * \param mm   Memory context.
 *
 * \return KNOT_E*
 */
inline static int knot_rdataset_remove(knot_rdataset_t *rrs, const knot_rdata_t *rr,
                                       knot_mm_t *mm)
{
	if (rr == NULL) {
		return KNOT_EINVAL;
	}

	knot_rdataset_t rrs_rm = { 1, knot_rdata_size(rr->len), (knot_rdata_t *)rr };
	return knot_rdataset_subtract(rrs, &rrs_rm, mm);
}

/*! @} */