MySQL 8.0.40
Source Code Documentation
xdr_utils.h
Go to the documentation of this file.
1/* Copyright (c) 2010, 2024, Oracle and/or its affiliates.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is designed to work with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have either included with
13 the program or referenced in the documentation.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
23
24#ifndef XDR_UTILS_H
25#define XDR_UTILS_H
26
27#include <assert.h>
28#include "xcom/xcom_memory.h"
29
30#ifdef __APPLE__
31/* OSX missing xdr_sizeof() */
32extern "C" u_long xdr_sizeof(xdrproc_t, void *);
33#endif
34
35/**
36 Initialize an array
37 */
38#define def_init_xdr_array(name) \
39 static inline void init_##name##_array(name##_array *x)
40#define init_xdr_array(name) \
41 def_init_xdr_array(name) { \
42 x->name##_array_len = 2; \
43 x->name##_array_val = \
44 (name *)xcom_calloc((size_t)x->name##_array_len, sizeof(name)); \
45 }
46
47/**
48 Free the contents of an array
49 */
50#define def_free_xdr_array(name) \
51 static inline void free_##name##_array(name##_array *x)
52#define free_xdr_array(name) \
53 def_free_xdr_array(name) { \
54 free(x->name##_array_val); \
55 x->name##_array_val = 0; \
56 x->name##_array_len = 0; \
57 }
58
59#define in_range(x, name, n) \
60 (((int)n) >= 0 && ((int)n) < ((int)(x).name##_array_len))
61
62/**
63 Resize an array
64 */
65#define expand_xdr_array(name) \
66 u_int old_length = x->name##_array_len; \
67 if (n + 1 > (x->name##_array_len)) { \
68 if (x->name##_array_len == 0) x->name##_array_len = 1; \
69 do { \
70 x->name##_array_len *= 2; \
71 } while (n + 1 > (x->name##_array_len)); \
72 x->name##_array_val = (name *)realloc(x->name##_array_val, \
73 x->name##_array_len * sizeof(name)); \
74 memset(&x->name##_array_val[old_length], 0, \
75 (x->name##_array_len - old_length) * sizeof(name)); \
76 }
77
78/**
79 Define a set function for an array
80 */
81#define def_set_xdr_array(name) \
82 static inline void set_##name(name##_array *x, name a, u_int n)
83#define set_xdr_array(name) \
84 def_set_xdr_array(name) { \
85 expand_xdr_array(name); \
86 assert(n < x->name##_array_len); \
87 x->name##_array_val[n] = a; \
88 }
89
90/**
91 Define a get function for an array
92 */
93#define def_get_xdr_array(name) \
94 static inline name get_##name(name##_array *x, u_int n)
95#define get_xdr_array(name) \
96 def_get_xdr_array(name) { \
97 expand_xdr_array(name); \
98 assert(n < x->name##_array_len); \
99 return x->name##_array_val[n]; \
100 }
101
102/**
103 Define a function to clone an array
104 */
105#define def_clone_xdr_array(name) \
106 static inline name##_array clone_##name##_array(name##_array x)
107#define clone_xdr_array(name) \
108 def_clone_xdr_array(name) { \
109 name##_array retval = x; \
110 u_int i; \
111 retval.name##_array_len = x.name##_array_len; \
112 IFDBG(D_XDR, FN; NDBG(retval.name##_array_len, u)); \
113 if (retval.name##_array_len > 0) { \
114 retval.name##_array_val = \
115 (name *)xcom_calloc((size_t)x.name##_array_len, sizeof(name)); \
116 for (i = 0; i < retval.name##_array_len; i++) { \
117 retval.name##_array_val[i] = x.name##_array_val[i]; \
118 IFDBG(D_XDR, FN; STRLIT("clone_xdr_array"); NDBG(i, u)); \
119 } \
120 } else { \
121 retval.name##_array_val = 0; \
122 } \
123 return retval; \
124 }
125
126/**
127 Declare all functions for an array
128 */
129#define d_xdr_funcs(name) \
130 def_init_xdr_array(name); \
131 def_free_xdr_array(name); \
132 def_set_xdr_array(name); \
133 def_get_xdr_array(name); \
134 def_clone_xdr_array(name);
135
136/**
137 Define all functions for an array
138 */
139#define define_xdr_funcs(name) \
140 init_xdr_array(name) free_xdr_array(name) set_xdr_array(name) \
141 get_xdr_array(name) clone_xdr_array(name)
142
143/**
144 Macro to do insertion sort
145 */
146#define insert_sort(type, x, n) \
147 { \
148 int i, j; \
149 for (i = 1; i < n; i++) { /* x[0..i-1] is sorted */ \
150 type tmp; \
151 j = i; \
152 tmp = x[j]; \
153 while (j > 0 && insert_sort_gt(x[j - 1], tmp)) { \
154 x[j] = x[j - 1]; \
155 j--; \
156 } \
157 x[j] = tmp; \
158 } \
159 }
160
161/**
162 Macro to do binary search for first occurrence
163
164 Invariant: x[l] < key and x[u] >= key and l < u
165*/
166#define bin_search_first_body(x, first, last, key, p) \
167 int l = first - 1; \
168 int u = last + 1; \
169 int m = 0; \
170 while (l + 1 != u) { \
171 m = (l + u) / 2; \
172 if (bin_search_lt((x)[m], (key))) { \
173 l = m; \
174 } else { \
175 u = m; \
176 } \
177 }
178
179/**
180 Macro to do binary search for last occurrence.
181
182 Invariant: x[l] <= key and x[u] > key and l < u
183*/
184#define bin_search_last_body(x, first, last, key, p) \
185 int l = first - 1; \
186 int u = last + 1; \
187 int m = 0; \
188 while (l + 1 != u) { \
189 m = (l + u) / 2; \
190 if (bin_search_gt((x)[m], (key))) { \
191 u = m; \
192 } else { \
193 l = m; \
194 } \
195 }
196
197/**
198 Find first element which matches key
199*/
200#define bin_search_first(x, first, last, key, p) \
201 { \
202 bin_search_first_body(x, first, last, key, p); \
203 p = u; \
204 if (p > last || (!bin_search_eq((x)[p], (key)))) p = -1; \
205 }
206
207/**
208 Find first element which is greater than key
209*/
210#define bin_search_first_gt(x, first, last, key, p) \
211 { \
212 bin_search_last_body(x, first, last, key, p); \
213 p = u; \
214 if (p > last || (!bin_search_gt((x)[p], (key)))) p = -1; \
215 }
216
217/**
218 Find last element which matches key
219*/
220#define bin_search_last(x, first, last, key, p) \
221 { \
222 bin_search_last_body(x, first, last, key, p); \
223 p = l; \
224 if (p < first || (!bin_search_eq((x)[p], (key)))) p = -1; \
225 }
226
227/**
228 Find first element which is less than key
229*/
230#define bin_search_last_lt(x, first, last, key, p) \
231 { \
232 bin_search_first_body(x, first, last, key, p); \
233 p = l; \
234 if (p < first || (!bin_search_lt((x)[p], (key)))) p = -1; \
235 }
236
237#define diff_get(type, a, i) get_##type##_array(a, i)
238#define diff_output(type, x) set_##type##_array(&retval, x, retval_i++)
239#define diff_gt(x, y) insert_sort_gt(x, y)
240
241/**
242 Macro to compute diff of two arrays, which as a side effect will
243 be sorted after the operation has completed.
244 */
245#define diff_xdr_array(type, x, y) \
246 type##_array diff_##type##_array(type##_array x, type##_array y) { \
247 int x_i = 0; \
248 int y_i = 0; \
249 type retval; \
250 int retval_i = 0; \
251 init_##type##_array(&retval); \
252 insert_sort(type, x.type##_val, x.type##_len); \
253 insert_sort(type, y.type##_val, y.type##_len); \
254 while (x_i < x.type##_len && y < y.type##_len) { \
255 if (diff_eq(diff_get(type, x, x_i), diff_get(type, y, y_i))) { \
256 x_i++; \
257 y_i++; \
258 } else if (diff_lt(diff_get(type, x, x_i), diff_get(type, y, y_i))) { \
259 diff_output(type, diff_get(type, x, x_i++)); \
260 } else { \
261 diff_output(type, diff_get(type, y, y_i++)); \
262 } \
263 } \
264 while (x_i < x.type##_len) { \
265 diff_output(type, diff_get(type, x, x_i++)); \
266 } \
267 while (y_i < y.type##_len) { \
268 diff_output(type, diff_get(type, y, y_i++)); \
269 } \
270 retval.type##_len = retval_i; \
271 return retval; \
272 }
273
274/* Reverse elements n1..n2 */
275
276#define x_reverse(type, x, in_n1, in_n2) \
277 { \
278 int n1 = in_n1; \
279 int n2 = in_n2; \
280 while ((n1) < (n2)) { \
281 type tmp = (x)[n1]; \
282 (x)[n1] = (x)[n2]; \
283 (x)[n2] = tmp; \
284 (n1)++; \
285 (n2)--; \
286 } \
287 }
288
289/* Move elements n1..n2 to after n3 */
290
291#define x_blkmove(type, x, n1, n2, n3) \
292 { \
293 if ((n3) < (n1)-1) { \
294 x_reverse(type, (x), (n3) + 1, (n1)-1); \
295 x_reverse(type, (x), (n1), (n2)); \
296 x_reverse(type, (x), (n3) + 1, (n2)); \
297 } else if ((n3) > (n2)) { \
298 x_reverse(type, (x), (n1), (n2)); \
299 x_reverse(type, (x), (n2) + 1, (n3)); \
300 x_reverse(type, (x), (n1), (n3)); \
301 } \
302 }
303
304#endif
__u_long u_long
Definition: types.h:74
bool_t(* xdrproc_t)(XDR *, void *,...)
Definition: xdr.h:143
u_long xdr_sizeof(xdrproc_t, void *) __THROW
Definition: xdr_sizeof.c:95