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