MySQL 9.1.0
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 = nullptr; \
56 x->name##_array_len = 0; \
57 }
58
59/**
60 Resize an array
61 */
62#define expand_xdr_array(name) \
63 u_int old_length = x->name##_array_len; \
64 if (n + 1 > (x->name##_array_len)) { \
65 if (x->name##_array_len == 0) x->name##_array_len = 1; \
66 do { \
67 x->name##_array_len *= 2; \
68 } while (n + 1 > (x->name##_array_len)); \
69 x->name##_array_val = (name *)realloc(x->name##_array_val, \
70 x->name##_array_len * sizeof(name)); \
71 memset(&x->name##_array_val[old_length], 0, \
72 (x->name##_array_len - old_length) * sizeof(name)); \
73 }
74
75/**
76 Define a set function for an array
77 */
78#define def_set_xdr_array(name) \
79 static inline void set_##name(name##_array *x, name a, u_int n)
80#define set_xdr_array(name) \
81 def_set_xdr_array(name) { \
82 expand_xdr_array(name); \
83 assert(n < x->name##_array_len); \
84 x->name##_array_val[n] = a; \
85 }
86
87/**
88 Define a get function for an array
89 */
90#define def_get_xdr_array(name) \
91 static inline name get_##name(name##_array *x, u_int n)
92#define get_xdr_array(name) \
93 def_get_xdr_array(name) { \
94 expand_xdr_array(name); \
95 assert(n < x->name##_array_len); \
96 return x->name##_array_val[n]; \
97 }
98
99/**
100 Define a function to clone an array
101 */
102#define def_clone_xdr_array(name) \
103 static inline name##_array clone_##name##_array(name##_array x)
104#define clone_xdr_array(name) \
105 def_clone_xdr_array(name) { \
106 name##_array retval = x; \
107 u_int i; \
108 retval.name##_array_len = x.name##_array_len; \
109 IFDBG(D_XDR, FN; NDBG(retval.name##_array_len, u)); \
110 if (retval.name##_array_len > 0) { \
111 retval.name##_array_val = \
112 (name *)xcom_calloc((size_t)x.name##_array_len, sizeof(name)); \
113 for (i = 0; i < retval.name##_array_len; i++) { \
114 retval.name##_array_val[i] = x.name##_array_val[i]; \
115 IFDBG(D_XDR, FN; STRLIT("clone_xdr_array"); NDBG(i, u)); \
116 } \
117 } else { \
118 retval.name##_array_val = 0; \
119 } \
120 return retval; \
121 }
122
123/**
124 Declare all functions for an array
125 */
126#define d_xdr_funcs(name) \
127 def_init_xdr_array(name); \
128 def_free_xdr_array(name); \
129 def_set_xdr_array(name); \
130 def_get_xdr_array(name); \
131 def_clone_xdr_array(name);
132
133/**
134 Define all functions for an array
135 */
136#define define_xdr_funcs(name) \
137 init_xdr_array(name) free_xdr_array(name) set_xdr_array(name) \
138 get_xdr_array(name) clone_xdr_array(name)
139
140/**
141 Macro to do insertion sort
142 */
143#define insert_sort(type, x, n) \
144 { \
145 int i, j; \
146 for (i = 1; i < n; i++) { /* x[0..i-1] is sorted */ \
147 type tmp; \
148 j = i; \
149 tmp = x[j]; \
150 while (j > 0 && insert_sort_gt(x[j - 1], tmp)) { \
151 x[j] = x[j - 1]; \
152 j--; \
153 } \
154 x[j] = tmp; \
155 } \
156 }
157
158/**
159 Macro to do binary search for first occurrence
160
161 Invariant: x[l] < key and x[u] >= key and l < u
162*/
163#define bin_search_first_body(x, first, last, key, p) \
164 int l = first - 1; \
165 int u = last + 1; \
166 int m = 0; \
167 while (l + 1 != u) { \
168 m = (l + u) / 2; \
169 if (bin_search_lt((x)[m], (key))) { \
170 l = m; \
171 } else { \
172 u = m; \
173 } \
174 }
175
176/**
177 Macro to do binary search for last occurrence.
178
179 Invariant: x[l] <= key and x[u] > key and l < u
180*/
181#define bin_search_last_body(x, first, last, key, p) \
182 int l = first - 1; \
183 int u = last + 1; \
184 int m = 0; \
185 while (l + 1 != u) { \
186 m = (l + u) / 2; \
187 if (bin_search_gt((x)[m], (key))) { \
188 u = m; \
189 } else { \
190 l = m; \
191 } \
192 }
193
194/**
195 Find first element which matches key
196*/
197#define bin_search_first(x, first, last, key, p) \
198 { \
199 bin_search_first_body(x, first, last, key, p); \
200 p = u; \
201 if (p > last || (!bin_search_eq((x)[p], (key)))) p = -1; \
202 }
203
204/**
205 Find first element which is greater than key
206*/
207#define bin_search_first_gt(x, first, last, key, p) \
208 { \
209 bin_search_last_body(x, first, last, key, p); \
210 p = u; \
211 if (p > last || (!bin_search_gt((x)[p], (key)))) p = -1; \
212 }
213
214/**
215 Find last element which matches key
216*/
217#define bin_search_last(x, first, last, key, p) \
218 { \
219 bin_search_last_body(x, first, last, key, p); \
220 p = l; \
221 if (p < first || (!bin_search_eq((x)[p], (key)))) p = -1; \
222 }
223
224/**
225 Find first element which is less than key
226*/
227#define bin_search_last_lt(x, first, last, key, p) \
228 { \
229 bin_search_first_body(x, first, last, key, p); \
230 p = l; \
231 if (p < first || (!bin_search_lt((x)[p], (key)))) p = -1; \
232 }
233
234#define diff_get(type, a, i) get_##type##_array(a, i)
235#define diff_output(type, x) set_##type##_array(&retval, x, retval_i++)
236#define diff_gt(x, y) insert_sort_gt(x, y)
237
238/**
239 Macro to compute diff of two arrays, which as a side effect will
240 be sorted after the operation has completed.
241 */
242#define diff_xdr_array(type, x, y) \
243 type##_array diff_##type##_array(type##_array x, type##_array y) { \
244 int x_i = 0; \
245 int y_i = 0; \
246 type retval; \
247 int retval_i = 0; \
248 init_##type##_array(&retval); \
249 insert_sort(type, x.type##_val, x.type##_len); \
250 insert_sort(type, y.type##_val, y.type##_len); \
251 while (x_i < x.type##_len && y < y.type##_len) { \
252 if (diff_eq(diff_get(type, x, x_i), diff_get(type, y, y_i))) { \
253 x_i++; \
254 y_i++; \
255 } else if (diff_lt(diff_get(type, x, x_i), diff_get(type, y, y_i))) { \
256 diff_output(type, diff_get(type, x, x_i++)); \
257 } else { \
258 diff_output(type, diff_get(type, y, y_i++)); \
259 } \
260 } \
261 while (x_i < x.type##_len) { \
262 diff_output(type, diff_get(type, x, x_i++)); \
263 } \
264 while (y_i < y.type##_len) { \
265 diff_output(type, diff_get(type, y, y_i++)); \
266 } \
267 retval.type##_len = retval_i; \
268 return retval; \
269 }
270
271/* Reverse elements n1..n2 */
272
273#define x_reverse(type, x, in_n1, in_n2) \
274 { \
275 int n1 = in_n1; \
276 int n2 = in_n2; \
277 while ((n1) < (n2)) { \
278 type tmp = (x)[n1]; \
279 (x)[n1] = (x)[n2]; \
280 (x)[n2] = tmp; \
281 (n1)++; \
282 (n2)--; \
283 } \
284 }
285
286/* Move elements n1..n2 to after n3 */
287
288#define x_blkmove(type, x, n1, n2, n3) \
289 { \
290 if ((n3) < (n1)-1) { \
291 x_reverse(type, (x), (n3) + 1, (n1)-1); \
292 x_reverse(type, (x), (n1), (n2)); \
293 x_reverse(type, (x), (n3) + 1, (n2)); \
294 } else if ((n3) > (n2)) { \
295 x_reverse(type, (x), (n1), (n2)); \
296 x_reverse(type, (x), (n2) + 1, (n3)); \
297 x_reverse(type, (x), (n1), (n3)); \
298 } \
299 }
300
301#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