gdi32: Use NtGdiPolyPolyDraw for PolylineTo implementation.
[wine.git] / dlls / wldap32 / ber.c
blobca5bbc305c50bbf325c6686343c11f789e6148bc
1 /*
2 * WLDAP32 - LDAP support for Wine
4 * Copyright 2005 Hans Leidekker
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <stdarg.h>
22 #include <stdlib.h>
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winnls.h"
26 #include "winldap.h"
27 #include "winber.h"
29 #include "wine/debug.h"
30 #include "winldap_private.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(wldap32);
34 /***********************************************************************
35 * ber_alloc_t (WLDAP32.@)
37 * Allocate a berelement structure.
39 * PARAMS
40 * options [I] Must be LBER_USE_DER.
42 * RETURNS
43 * Success: Pointer to an allocated berelement structure.
44 * Failure: NULL
46 * NOTES
47 * Free the berelement structure with ber_free.
49 BerElement * CDECL ber_alloc_t( int options )
51 BerElement *ret;
53 if (!(ret = malloc( sizeof(*ret) ))) return NULL;
54 if (!(BER(ret) = ldap_funcs->fn_ber_alloc_t( options )))
56 free( ret );
57 return NULL;
59 return ret;
63 /***********************************************************************
64 * ber_bvdup (WLDAP32.@)
66 * Copy a berval structure.
68 * PARAMS
69 * berval [I] Pointer to the berval structure to be copied.
71 * RETURNS
72 * Success: Pointer to a copy of the berval structure.
73 * Failure: NULL
75 * NOTES
76 * Free the copy with ber_bvfree.
78 BERVAL * CDECL ber_bvdup( BERVAL *berval )
80 return bervalWtoW( berval );
84 /***********************************************************************
85 * ber_bvecfree (WLDAP32.@)
87 * Free an array of berval structures.
89 * PARAMS
90 * berval [I] Pointer to an array of berval structures.
92 * RETURNS
93 * Nothing.
95 * NOTES
96 * Use this function only to free an array of berval structures
97 * returned by a call to ber_scanf with a 'V' in the format string.
99 void CDECL ber_bvecfree( BERVAL **berval )
101 bvarrayfreeW( berval );
105 /***********************************************************************
106 * ber_bvfree (WLDAP32.@)
108 * Free a berval structure.
110 * PARAMS
111 * berval [I] Pointer to a berval structure.
113 * RETURNS
114 * Nothing.
116 * NOTES
117 * Use this function only to free berval structures allocated by
118 * an LDAP API.
120 void CDECL ber_bvfree( BERVAL *berval )
122 free( berval );
126 /***********************************************************************
127 * ber_first_element (WLDAP32.@)
129 * Return the tag of the first element in a set or sequence.
131 * PARAMS
132 * berelement [I] Pointer to a berelement structure.
133 * len [O] Receives the length of the first element.
134 * opaque [O] Receives a pointer to a cookie.
136 * RETURNS
137 * Success: Tag of the first element.
138 * Failure: LBER_DEFAULT (no more data).
140 * NOTES
141 * len and cookie should be passed to ber_next_element.
143 ULONG CDECL ber_first_element( BerElement *ber, ULONG *len, char **opaque )
145 return ldap_funcs->fn_ber_first_element( BER(ber), len, opaque );
149 /***********************************************************************
150 * ber_flatten (WLDAP32.@)
152 * Flatten a berelement structure into a berval structure.
154 * PARAMS
155 * berelement [I] Pointer to a berelement structure.
156 * berval [O] Pointer to a berval structure.
158 * RETURNS
159 * Success: 0
160 * Failure: LBER_ERROR
162 * NOTES
163 * Free the berval structure with ber_bvfree.
165 int CDECL ber_flatten( BerElement *ber, BERVAL **berval )
167 struct bervalU *bervalU;
168 struct berval *bervalW;
170 if (ldap_funcs->fn_ber_flatten( BER(ber), &bervalU )) return LBER_ERROR;
172 if (!(bervalW = bervalUtoW( bervalU ))) return LBER_ERROR;
173 ldap_funcs->fn_ber_bvfree( bervalU );
174 if (!bervalW) return LBER_ERROR;
175 *berval = bervalW;
176 return 0;
180 /***********************************************************************
181 * ber_free (WLDAP32.@)
183 * Free a berelement structure.
185 * PARAMS
186 * berelement [I] Pointer to the berelement structure to be freed.
187 * buf [I] Flag.
189 * RETURNS
190 * Nothing.
192 * NOTES
193 * Set buf to 0 if the berelement was allocated with ldap_first_attribute
194 * or ldap_next_attribute, otherwise set it to 1.
196 void CDECL ber_free( BerElement *ber, int freebuf )
198 ldap_funcs->fn_ber_free( BER(ber), freebuf );
199 free( ber );
203 /***********************************************************************
204 * ber_init (WLDAP32.@)
206 * Initialise a berelement structure from a berval structure.
208 * PARAMS
209 * berval [I] Pointer to a berval structure.
211 * RETURNS
212 * Success: Pointer to a berelement structure.
213 * Failure: NULL
215 * NOTES
216 * Call ber_free to free the returned berelement structure.
218 BerElement * CDECL ber_init( BERVAL *berval )
220 struct bervalU *bervalU;
221 BerElement *ret;
223 if (!(ret = malloc( sizeof(*ret) ))) return NULL;
224 if (!(bervalU = bervalWtoU( berval )))
226 free( ret );
227 return NULL;
229 if (!(BER(ret) = ldap_funcs->fn_ber_init( bervalU )))
231 free( ret );
232 ret = NULL;
234 free( bervalU );
235 return ret;
239 /***********************************************************************
240 * ber_next_element (WLDAP32.@)
242 * Return the tag of the next element in a set or sequence.
244 * PARAMS
245 * berelement [I] Pointer to a berelement structure.
246 * len [I/O] Receives the length of the next element.
247 * opaque [I/O] Pointer to a cookie.
249 * RETURNS
250 * Success: Tag of the next element.
251 * Failure: LBER_DEFAULT (no more data).
253 * NOTES
254 * len and cookie are initialized by ber_first_element and should
255 * be passed on in subsequent calls to ber_next_element.
257 ULONG CDECL ber_next_element( BerElement *ber, ULONG *len, char *opaque )
259 return ldap_funcs->fn_ber_next_element( BER(ber), len, opaque );
263 /***********************************************************************
264 * ber_peek_tag (WLDAP32.@)
266 * Return the tag of the next element.
268 * PARAMS
269 * berelement [I] Pointer to a berelement structure.
270 * len [O] Receives the length of the next element.
272 * RETURNS
273 * Success: Tag of the next element.
274 * Failure: LBER_DEFAULT (no more data).
276 ULONG CDECL ber_peek_tag( BerElement *ber, ULONG *len )
278 return ldap_funcs->fn_ber_peek_tag( BER(ber), len );
282 /***********************************************************************
283 * ber_skip_tag (WLDAP32.@)
285 * Skip the current tag and return the tag of the next element.
287 * PARAMS
288 * berelement [I] Pointer to a berelement structure.
289 * len [O] Receives the length of the skipped element.
291 * RETURNS
292 * Success: Tag of the next element.
293 * Failure: LBER_DEFAULT (no more data).
295 ULONG CDECL ber_skip_tag( BerElement *ber, ULONG *len )
297 return ldap_funcs->fn_ber_skip_tag( BER(ber), len );
301 /***********************************************************************
302 * ber_printf (WLDAP32.@)
304 * Encode a berelement structure.
306 * PARAMS
307 * berelement [I/O] Pointer to a berelement structure.
308 * fmt [I] Format string.
309 * ... [I] Values to encode.
311 * RETURNS
312 * Success: Non-negative number.
313 * Failure: LBER_ERROR
315 * NOTES
316 * berelement must have been allocated with ber_alloc_t. This function
317 * can be called multiple times to append data.
319 int WINAPIV ber_printf( BerElement *ber, char *fmt, ... )
321 __ms_va_list list;
322 int ret = 0;
323 char new_fmt[2];
325 new_fmt[1] = 0;
326 __ms_va_start( list, fmt );
327 while (*fmt)
329 new_fmt[0] = *fmt++;
330 switch (new_fmt[0])
332 case 'b':
333 case 'e':
334 case 'i':
336 int i = va_arg( list, int );
337 ret = ldap_funcs->fn_ber_printf( BER(ber), new_fmt, i );
338 break;
340 case 'o':
341 case 's':
343 char *str = va_arg( list, char * );
344 ret = ldap_funcs->fn_ber_printf( BER(ber), new_fmt, str );
345 break;
347 case 't':
349 unsigned int tag = va_arg( list, unsigned int );
350 ret = ldap_funcs->fn_ber_printf( BER(ber), new_fmt, tag );
351 break;
353 case 'v':
355 char **array = va_arg( list, char ** );
356 ret = ldap_funcs->fn_ber_printf( BER(ber), new_fmt, array );
357 break;
359 case 'V':
361 struct berval **array = va_arg( list, struct berval ** );
362 struct bervalU **arrayU;
363 if (!(arrayU = bvarrayWtoU( array )))
365 ret = -1;
366 break;
368 ret = ldap_funcs->fn_ber_printf( BER(ber), new_fmt, arrayU );
369 bvarrayfreeU( arrayU );
370 break;
372 case 'X':
374 char *str = va_arg( list, char * );
375 int len = va_arg( list, int );
376 new_fmt[0] = 'B'; /* 'X' is deprecated */
377 ret = ldap_funcs->fn_ber_printf( BER(ber), new_fmt, str, len );
378 break;
380 case 'n':
381 case '{':
382 case '}':
383 case '[':
384 case ']':
385 ret = ldap_funcs->fn_ber_printf( BER(ber), new_fmt );
386 break;
388 default:
389 FIXME( "Unknown format '%c'\n", new_fmt[0] );
390 ret = -1;
391 break;
393 if (ret == -1) break;
395 __ms_va_end( list );
396 return ret;
400 /***********************************************************************
401 * ber_scanf (WLDAP32.@)
403 * Decode a berelement structure.
405 * PARAMS
406 * berelement [I/O] Pointer to a berelement structure.
407 * fmt [I] Format string.
408 * ... [I] Pointers to values to be decoded.
410 * RETURNS
411 * Success: Non-negative number.
412 * Failure: LBER_ERROR
414 * NOTES
415 * berelement must have been allocated with ber_init. This function
416 * can be called multiple times to decode data.
418 ULONG WINAPIV ber_scanf( BerElement *ber, char *fmt, ... )
420 __ms_va_list list;
421 int ret = 0;
422 char new_fmt[2];
424 new_fmt[1] = 0;
425 __ms_va_start( list, fmt );
426 while (*fmt)
428 new_fmt[0] = *fmt++;
429 switch (new_fmt[0])
431 case 'a':
433 char *str, **ptr = va_arg( list, char ** );
434 if ((ret = ldap_funcs->fn_ber_scanf( BER(ber), new_fmt, &str )) == -1) break;
435 *ptr = strdupU( str );
436 ldap_funcs->fn_ldap_memfree( str );
437 break;
439 case 'b':
440 case 'e':
441 case 'i':
443 int *i = va_arg( list, int * );
444 ret = ldap_funcs->fn_ber_scanf( BER(ber), new_fmt, i );
445 break;
447 case 't':
449 unsigned int *tag = va_arg( list, unsigned int * );
450 ret = ldap_funcs->fn_ber_scanf( BER(ber), new_fmt, tag );
451 break;
453 case 'v':
455 char *str, **arrayU, **ptr, ***array = va_arg( list, char *** );
456 if ((ret = ldap_funcs->fn_ber_scanf( BER(ber), new_fmt, &arrayU )) == -1) break;
457 *array = strarrayUtoU( arrayU );
458 ptr = arrayU;
459 while ((str = *ptr))
461 ldap_funcs->fn_ldap_memfree( str );
462 ptr++;
464 ldap_funcs->fn_ldap_memfree( arrayU );
465 break;
467 case 'B':
469 char *strU, **str = va_arg( list, char ** );
470 int *len = va_arg( list, int * );
471 if ((ret = ldap_funcs->fn_ber_scanf( BER(ber), new_fmt, &strU, len )) == -1) break;
472 *str = malloc( *len );
473 memcpy( *str, strU, *len );
474 ldap_funcs->fn_ldap_memfree( strU );
475 break;
477 case 'O':
479 struct berval **berval = va_arg( list, struct berval ** );
480 struct bervalU *bervalU;
481 if ((ret = ldap_funcs->fn_ber_scanf( BER(ber), new_fmt, &bervalU )) == -1) break;
482 *berval = bervalUtoW( bervalU );
483 ldap_funcs->fn_ber_bvfree( bervalU );
484 break;
486 case 'V':
488 struct berval ***array = va_arg( list, struct berval *** );
489 struct bervalU **arrayU;
490 if ((ret = ldap_funcs->fn_ber_scanf( BER(ber), new_fmt, &arrayU )) == -1) break;
491 *array = bvarrayUtoW( arrayU );
492 ldap_funcs->fn_ber_bvecfree( arrayU );
493 break;
495 case 'n':
496 case 'x':
497 case '{':
498 case '}':
499 case '[':
500 case ']':
501 ret = ldap_funcs->fn_ber_scanf( BER(ber), new_fmt );
502 break;
504 default:
505 FIXME( "Unknown format '%c'\n", new_fmt[0] );
506 ret = -1;
507 break;
509 if (ret == -1) break;
511 __ms_va_end( list );
512 return ret;