rdataset.h 5.97 KB
Newer Older
1
/*  Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
2 3 4 5 6 7 8 9 10 11 12 13 14 15

    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 <http://www.gnu.org/licenses/>.
 */
16 17 18 19 20
/*!
 * \file
 *
 * \brief API for manipulating RR arrays.
 *
21
 * \addtogroup rr
22 23
 * @{
 */
24

25 26
#pragma once

27
#include <assert.h>
28
#include <stddef.h>
29
#include <stdint.h>
30
#include <stdbool.h>
31

32
#include "libknot/mm_ctx.h"
33
#include "libknot/rdata.h"
34

35
/*!< \brief Set of RRs. */
36
typedef struct {
37 38
	uint16_t count;      /*!< \brief Count of RRs stored in the structure. */
	knot_rdata_t *rdata; /*!< \brief Serialized rdata, canonically sorted. */
39
} knot_rdataset_t;
40 41 42

/*!
 * \brief Initializes RRS structure.
43
 *
44 45
 * \param rrs  Structure to be initialized.
 */
46 47 48
inline static void knot_rdataset_init(knot_rdataset_t *rrs)
{
	if (rrs != NULL) {
49 50
		rrs->count = 0;
		rrs->rdata = NULL;
51 52
	}
}
53

54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
/*!
 * \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_rdata_next(knot_rdata_t *rr)
{
	assert(rr);
	return (knot_rdata_t *)((uint8_t *)rr + knot_rdata_size(rr->len));
}

71 72
/*!
 * \brief Frees data initialized by RRS structure, but not the structure itself.
73
 *
74 75 76
 * \param rrs  Structure to be cleared.
 * \param mm   Memory context used to create allocations.
 */
77
void knot_rdataset_clear(knot_rdataset_t *rrs, knot_mm_t *mm);
78 79 80

/*!
 * \brief Deep copies RRS structure. All data are duplicated.
81
 *
82 83 84
 * \param dst  Copy destination.
 * \param src  Copy source.
 * \param mm   Memory context.
85
 *
86 87
 * \return KNOT_E*
 */
88
int knot_rdataset_copy(knot_rdataset_t *dst, const knot_rdataset_t *src, knot_mm_t *mm);
89 90 91

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

100
/*!
101
 * \brief Returns size of the structures holding the RR set.
102
 *
103
 * \param rrs  RR array.
104
 *
105 106
 * \return Array size.
 */
107
size_t knot_rdataset_size(const knot_rdataset_t *rrs);
108

109 110
/*!
 * \brief Adds single RR into RRS structure. All data are copied.
111
 *
112 113 114
 * \param rrs  RRS structure to add RR into.
 * \param rr   RR to add.
 * \param mm   Memory context.
115
 *
116 117
 * \return KNOT_E*
 */
118
int knot_rdataset_add(knot_rdataset_t *rrs, const knot_rdata_t *rr, knot_mm_t *mm);
119

120 121
/*!
 * \brief Reserves space at the end of the RRS structure.
122
 *
123 124 125
 * \param rrs   RRS structure to reserve space at.
 * \param size  How much space to reserve.
 * \param mm    Memory context.
126
 *
127 128
 * \return KNOT_E*
 */
129
int knot_rdataset_reserve(knot_rdataset_t *rrs, uint16_t size, knot_mm_t *mm);
130

131 132
/*!
 * \brief Removes the last RR from RRS structure, i.e. does the opposite of _reserve.
133
 *
134 135
 * \param rrs  RRS structure to remove RR from.
 * \param mm   Memory context.
136
 *
137 138
 * \return KNOT_E*
 */
139
int knot_rdataset_unreserve(knot_rdataset_t *rrs, knot_mm_t *mm);
140

141 142
/*!
 * \brief RRS equality check.
143
 *
144 145
 * \param rrs1  First RRS to be compared.
 * \param rrs2  Second RRS to be compared.
146
 *
147 148 149
 * \retval true if rrs1 == rrs2.
 * \retval false if rrs1 != rrs2.
 */
150
bool knot_rdataset_eq(const knot_rdataset_t *rrs1, const knot_rdataset_t *rrs2);
151

152 153
/*!
 * \brief Returns true if \a rr is present in \a rrs, false otherwise.
154 155 156 157
 *
 * \param rrs  RRS to search in.
 * \param rr   RR to compare with.
 *
158 159 160
 * \retval true if \a rr is present in \a rrs.
 * \retval false if \a rr is not present in \a rrs.
 */
161
bool knot_rdataset_member(const knot_rdataset_t *rrs, const knot_rdata_t *rr);
162

163 164 165
/*!
 * \brief Merges two RRS into the first one. Second RRS is left intact.
 *        Canonical order is preserved.
166
 *
167 168 169
 * \param rrs1  Destination RRS (merge here).
 * \param rrs2  RRS to be merged (merge from).
 * \param mm    Memory context.
170
 *
171 172
 * \return KNOT_E*
 */
173
int knot_rdataset_merge(knot_rdataset_t *rrs1, const knot_rdataset_t *rrs2,
174
                        knot_mm_t *mm);
175 176 177

/*!
 * \brief RRS set-like intersection. Full compare is done.
178 179 180 181 182 183
 *
 * \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.
 *
184 185
 * \return KNOT_E*
 */
186
int knot_rdataset_intersect(const knot_rdataset_t *rrs1, const knot_rdataset_t *rrs2,
187
                            knot_rdataset_t *out, knot_mm_t *mm);
188 189

/*!
190
 * \brief Does set-like RRS subtraction. \a from RRS is changed.
191
 *
192 193 194
 * \param from  RRS to subtract from.
 * \param what  RRS to subtract.
 * \param mm    Memory context use to reallocated \a from data.
195
 *
196 197
 * \return KNOT_E*
 */
198
int knot_rdataset_subtract(knot_rdataset_t *from, const knot_rdataset_t *what,
199
                           knot_mm_t *mm);
200

201 202
/*!
 * \brief Sorts the dataset. Removes the element if found to be duplicate.
203 204 205 206 207
 *
 * \param rrs  RRS to sort.
 * \param pos  Position of the element to sort (counted from 0).
 * \param mm   Memory context used to remove the element if duplicate.
 *
208 209
 * \return KNOT_E*
 */
210
int knot_rdataset_sort_at(knot_rdataset_t *rrs, uint16_t pos, knot_mm_t *mm);
211

212
/*! \brief Check helper. */
213
#define KNOT_RDATASET_CHECK(rrs, pos) \
214
	assert(rrs && rrs->rdata && rrs->count > 0 && pos < rrs->count);
215

216
/*! \brief Access helper. */
217
static inline
218 219
uint8_t *knot_rdata_offset(const knot_rdataset_t *rrs, uint16_t pos, uint16_t offset)
{
220
	knot_rdata_t *rr = knot_rdataset_at(rrs, pos);
221
	assert(rr);
222
	return rr->data + offset;
223
}
224 225

/*! @} */