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