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