a40b4298a42d3b397d812a5d2b85181de1a9a962
[kai/samba.git] / lib / util / charset / util_unistr.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Samba utility functions
4    Copyright (C) Andrew Tridgell 1992-2001
5    Copyright (C) Simo Sorce 2001
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "includes.h"
22 #include "system/locale.h"
23
24 struct smb_iconv_convenience *global_iconv_convenience = NULL;
25
26 static inline struct smb_iconv_convenience *get_iconv_convenience(void)
27 {
28         if (global_iconv_convenience == NULL)
29                 global_iconv_convenience = smb_iconv_convenience_init(talloc_autofree_context(), "ASCII", "UTF-8", true);
30         return global_iconv_convenience;
31 }
32
33 /**
34  Case insensitive string compararison
35 **/
36 _PUBLIC_ int strcasecmp_m(const char *s1, const char *s2)
37 {
38         codepoint_t c1=0, c2=0;
39         size_t size1, size2;
40         struct smb_iconv_convenience *iconv_convenience = get_iconv_convenience();
41
42         /* handle null ptr comparisons to simplify the use in qsort */
43         if (s1 == s2) return 0;
44         if (s1 == NULL) return -1;
45         if (s2 == NULL) return 1;
46
47         while (*s1 && *s2) {
48                 c1 = next_codepoint(iconv_convenience, s1, &size1);
49                 c2 = next_codepoint(iconv_convenience, s2, &size2);
50
51                 s1 += size1;
52                 s2 += size2;
53
54                 if (c1 == c2) {
55                         continue;
56                 }
57
58                 if (c1 == INVALID_CODEPOINT ||
59                     c2 == INVALID_CODEPOINT) {
60                         /* what else can we do?? */
61                         return strcasecmp(s1, s2);
62                 }
63
64                 if (toupper_m(c1) != toupper_m(c2)) {
65                         return c1 - c2;
66                 }
67         }
68
69         return *s1 - *s2;
70 }
71
72 /**
73  * Get the next token from a string, return False if none found.
74  * Handles double-quotes.
75  * 
76  * Based on a routine by GJC@VILLAGE.COM. 
77  * Extensively modified by Andrew.Tridgell@anu.edu.au
78  **/
79 _PUBLIC_ bool next_token(const char **ptr,char *buff, const char *sep, size_t bufsize)
80 {
81         const char *s;
82         bool quoted;
83         size_t len=1;
84
85         if (!ptr)
86                 return false;
87
88         s = *ptr;
89
90         /* default to simple separators */
91         if (!sep)
92                 sep = " \t\n\r";
93
94         /* find the first non sep char */
95         while (*s && strchr_m(sep,*s))
96                 s++;
97         
98         /* nothing left? */
99         if (!*s)
100                 return false;
101         
102         /* copy over the token */
103         for (quoted = false; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) {
104                 if (*s == '\"') {
105                         quoted = !quoted;
106                 } else {
107                         len++;
108                         *buff++ = *s;
109                 }
110         }
111         
112         *ptr = (*s) ? s+1 : s;  
113         *buff = 0;
114         
115         return true;
116 }
117
118 /**
119  Case insensitive string compararison, length limited
120 **/
121 _PUBLIC_ int strncasecmp_m(const char *s1, const char *s2, size_t n)
122 {
123         codepoint_t c1=0, c2=0;
124         size_t size1, size2;
125         struct smb_iconv_convenience *iconv_convenience = get_iconv_convenience();
126
127         /* handle null ptr comparisons to simplify the use in qsort */
128         if (s1 == s2) return 0;
129         if (s1 == NULL) return -1;
130         if (s2 == NULL) return 1;
131
132         while (*s1 && *s2 && n) {
133                 n--;
134
135                 c1 = next_codepoint(iconv_convenience, s1, &size1);
136                 c2 = next_codepoint(iconv_convenience, s2, &size2);
137
138                 s1 += size1;
139                 s2 += size2;
140
141                 if (c1 == c2) {
142                         continue;
143                 }
144
145                 if (c1 == INVALID_CODEPOINT ||
146                     c2 == INVALID_CODEPOINT) {
147                         /* what else can we do?? */
148                         return strcasecmp(s1, s2);
149                 }
150
151                 if (toupper_m(c1) != toupper_m(c2)) {
152                         return c1 - c2;
153                 }
154         }
155
156         if (n == 0) {
157                 return 0;
158         }
159
160         return *s1 - *s2;
161 }
162
163 /**
164  * Compare 2 strings.
165  *
166  * @note The comparison is case-insensitive.
167  **/
168 _PUBLIC_ bool strequal_m(const char *s1, const char *s2)
169 {
170         return strcasecmp_m(s1,s2) == 0;
171 }
172
173 /**
174  Compare 2 strings (case sensitive).
175 **/
176 _PUBLIC_ bool strcsequal_m(const char *s1,const char *s2)
177 {
178         if (s1 == s2)
179                 return true;
180         if (!s1 || !s2)
181                 return false;
182         
183         return strcmp(s1,s2) == 0;
184 }
185
186
187 /**
188  String replace.
189  NOTE: oldc and newc must be 7 bit characters
190 **/
191 _PUBLIC_ void string_replace_m(char *s, char oldc, char newc)
192 {
193         struct smb_iconv_convenience *ic = get_iconv_convenience();
194         while (s && *s) {
195                 size_t size;
196                 codepoint_t c = next_codepoint(ic, s, &size);
197                 if (c == oldc) {
198                         *s = newc;
199                 }
200                 s += size;
201         }
202 }
203
204 /**
205  Paranoid strcpy into a buffer of given length (includes terminating
206  zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
207  and replaces with '_'. Deliberately does *NOT* check for multibyte
208  characters. Don't change it !
209 **/
210
211 _PUBLIC_ char *alpha_strcpy(char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
212 {
213         size_t len, i;
214
215         if (maxlength == 0) {
216                 /* can't fit any bytes at all! */
217                 return NULL;
218         }
219
220         if (!dest) {
221                 DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n"));
222                 return NULL;
223         }
224
225         if (!src) {
226                 *dest = 0;
227                 return dest;
228         }  
229
230         len = strlen(src);
231         if (len >= maxlength)
232                 len = maxlength - 1;
233
234         if (!other_safe_chars)
235                 other_safe_chars = "";
236
237         for(i = 0; i < len; i++) {
238                 int val = (src[i] & 0xff);
239                 if (isupper(val) || islower(val) || isdigit(val) || strchr_m(other_safe_chars, val))
240                         dest[i] = src[i];
241                 else
242                         dest[i] = '_';
243         }
244
245         dest[i] = '\0';
246
247         return dest;
248 }
249
250 /**
251  Count the number of UCS2 characters in a string. Normally this will
252  be the same as the number of bytes in a string for single byte strings,
253  but will be different for multibyte.
254 **/
255 _PUBLIC_ size_t strlen_m(const char *s)
256 {
257         size_t count = 0;
258         struct smb_iconv_convenience *ic = get_iconv_convenience();
259
260         if (!s) {
261                 return 0;
262         }
263
264         while (*s && !(((uint8_t)*s) & 0x80)) {
265                 s++;
266                 count++;
267         }
268
269         if (!*s) {
270                 return count;
271         }
272
273         while (*s) {
274                 size_t c_size;
275                 codepoint_t c = next_codepoint(ic, s, &c_size);
276                 if (c < 0x10000) {
277                         count += 1;
278                 } else {
279                         count += 2;
280                 }
281                 s += c_size;
282         }
283
284         return count;
285 }
286
287 /**
288    Work out the number of multibyte chars in a string, including the NULL
289    terminator.
290 **/
291 _PUBLIC_ size_t strlen_m_term(const char *s)
292 {
293         if (!s) {
294                 return 0;
295         }
296
297         return strlen_m(s) + 1;
298 }
299
300 /**
301  Strchr and strrchr_m are a bit complex on general multi-byte strings. 
302 **/
303 _PUBLIC_ char *strchr_m(const char *s, char c)
304 {
305         struct smb_iconv_convenience *ic = get_iconv_convenience();
306         if (s == NULL) {
307                 return NULL;
308         }
309         /* characters below 0x3F are guaranteed to not appear in
310            non-initial position in multi-byte charsets */
311         if ((c & 0xC0) == 0) {
312                 return strchr(s, c);
313         }
314
315         while (*s) {
316                 size_t size;
317                 codepoint_t c2 = next_codepoint(ic, s, &size);
318                 if (c2 == c) {
319                         return discard_const_p(char, s);
320                 }
321                 s += size;
322         }
323
324         return NULL;
325 }
326
327 /**
328  * Multibyte-character version of strrchr
329  */
330 _PUBLIC_ char *strrchr_m(const char *s, char c)
331 {
332         struct smb_iconv_convenience *ic = get_iconv_convenience();
333         char *ret = NULL;
334
335         if (s == NULL) {
336                 return NULL;
337         }
338
339         /* characters below 0x3F are guaranteed to not appear in
340            non-initial position in multi-byte charsets */
341         if ((c & 0xC0) == 0) {
342                 return strrchr(s, c);
343         }
344
345         while (*s) {
346                 size_t size;
347                 codepoint_t c2 = next_codepoint(ic, s, &size);
348                 if (c2 == c) {
349                         ret = discard_const_p(char, s);
350                 }
351                 s += size;
352         }
353
354         return ret;
355 }
356
357 /**
358   return True if any (multi-byte) character is lower case
359 */
360 _PUBLIC_ bool strhaslower(const char *string)
361 {
362         struct smb_iconv_convenience *ic = get_iconv_convenience();
363         while (*string) {
364                 size_t c_size;
365                 codepoint_t s;
366                 codepoint_t t;
367
368                 s = next_codepoint(ic, string, &c_size);
369                 string += c_size;
370
371                 t = toupper_m(s);
372
373                 if (s != t) {
374                         return true; /* that means it has lower case chars */
375                 }
376         }
377
378         return false;
379
380
381 /**
382   return True if any (multi-byte) character is upper case
383 */
384 _PUBLIC_ bool strhasupper(const char *string)
385 {
386         struct smb_iconv_convenience *ic = get_iconv_convenience();
387         while (*string) {
388                 size_t c_size;
389                 codepoint_t s;
390                 codepoint_t t;
391
392                 s = next_codepoint(ic, string, &c_size);
393                 string += c_size;
394
395                 t = tolower_m(s);
396
397                 if (s != t) {
398                         return true; /* that means it has upper case chars */
399                 }
400         }
401
402         return false;
403
404
405 /**
406  Convert a string to lower case, allocated with talloc
407 **/
408 _PUBLIC_ char *strlower_talloc(TALLOC_CTX *ctx, const char *src)
409 {
410         size_t size=0;
411         char *dest;
412         struct smb_iconv_convenience *iconv_convenience = get_iconv_convenience();
413
414         /* this takes advantage of the fact that upper/lower can't
415            change the length of a character by more than 1 byte */
416         dest = talloc_array(ctx, char, 2*(strlen(src))+1);
417         if (dest == NULL) {
418                 return NULL;
419         }
420
421         while (*src) {
422                 size_t c_size;
423                 codepoint_t c = next_codepoint(iconv_convenience, src, &c_size);
424                 src += c_size;
425
426                 c = tolower_m(c);
427
428                 c_size = push_codepoint(iconv_convenience, dest+size, c);
429                 if (c_size == -1) {
430                         talloc_free(dest);
431                         return NULL;
432                 }
433                 size += c_size;
434         }
435
436         dest[size] = 0;
437
438         /* trim it so talloc_append_string() works */
439         dest = talloc_realloc(ctx, dest, char, size+1);
440
441         talloc_set_name_const(dest, dest);
442
443         return dest;
444 }
445
446 /**
447  Convert a string to UPPER case, allocated with talloc
448  source length limited to n bytes
449 **/
450 _PUBLIC_ char *strupper_talloc_n(TALLOC_CTX *ctx, const char *src, size_t n)
451 {
452         size_t size=0;
453         char *dest;
454         struct smb_iconv_convenience *iconv_convenience = get_iconv_convenience();
455         
456         if (!src) {
457                 return NULL;
458         }
459
460         /* this takes advantage of the fact that upper/lower can't
461            change the length of a character by more than 1 byte */
462         dest = talloc_array(ctx, char, 2*(n+1));
463         if (dest == NULL) {
464                 return NULL;
465         }
466
467         while (*src && n--) {
468                 size_t c_size;
469                 codepoint_t c = next_codepoint(iconv_convenience, src, &c_size);
470                 src += c_size;
471
472                 c = toupper_m(c);
473
474                 c_size = push_codepoint(iconv_convenience, dest+size, c);
475                 if (c_size == -1) {
476                         talloc_free(dest);
477                         return NULL;
478                 }
479                 size += c_size;
480         }
481
482         dest[size] = 0;
483
484         /* trim it so talloc_append_string() works */
485         dest = talloc_realloc(ctx, dest, char, size+1);
486
487         talloc_set_name_const(dest, dest);
488
489         return dest;
490 }
491
492 /**
493  Convert a string to UPPER case, allocated with talloc
494 **/
495 _PUBLIC_ char *strupper_talloc(TALLOC_CTX *ctx, const char *src)
496 {
497         return strupper_talloc_n(ctx, src, src?strlen(src):0);
498 }
499
500 /**
501  talloc_strdup() a unix string to upper case.
502 **/
503 _PUBLIC_ char *talloc_strdup_upper(TALLOC_CTX *ctx, const char *src)
504 {
505         return strupper_talloc(ctx, src);
506 }
507
508 /**
509  Convert a string to lower case.
510 **/
511 _PUBLIC_ void strlower_m(char *s)
512 {
513         char *d;
514         struct smb_iconv_convenience *iconv_convenience;
515
516         /* this is quite a common operation, so we want it to be
517            fast. We optimise for the ascii case, knowing that all our
518            supported multi-byte character sets are ascii-compatible
519            (ie. they match for the first 128 chars) */
520         while (*s && !(((uint8_t)*s) & 0x80)) {
521                 *s = tolower((uint8_t)*s);
522                 s++;
523         }
524
525         if (!*s)
526                 return;
527
528         iconv_convenience = get_iconv_convenience();
529
530         d = s;
531
532         while (*s) {
533                 size_t c_size, c_size2;
534                 codepoint_t c = next_codepoint(iconv_convenience, s, &c_size);
535                 c_size2 = push_codepoint(iconv_convenience, d, tolower_m(c));
536                 if (c_size2 > c_size) {
537                         DEBUG(0,("FATAL: codepoint 0x%x (0x%x) expanded from %d to %d bytes in strlower_m\n",
538                                  c, tolower_m(c), (int)c_size, (int)c_size2));
539                         smb_panic("codepoint expansion in strlower_m\n");
540                 }
541                 s += c_size;
542                 d += c_size2;
543         }
544         *d = 0;
545 }
546
547 /**
548  Convert a string to UPPER case.
549 **/
550 _PUBLIC_ void strupper_m(char *s)
551 {
552         char *d;
553         struct smb_iconv_convenience *iconv_convenience;
554
555         /* this is quite a common operation, so we want it to be
556            fast. We optimise for the ascii case, knowing that all our
557            supported multi-byte character sets are ascii-compatible
558            (ie. they match for the first 128 chars) */
559         while (*s && !(((uint8_t)*s) & 0x80)) {
560                 *s = toupper((uint8_t)*s);
561                 s++;
562         }
563
564         if (!*s)
565                 return;
566
567         iconv_convenience = get_iconv_convenience();
568
569         d = s;
570
571         while (*s) {
572                 size_t c_size, c_size2;
573                 codepoint_t c = next_codepoint(iconv_convenience, s, &c_size);
574                 c_size2 = push_codepoint(iconv_convenience, d, toupper_m(c));
575                 if (c_size2 > c_size) {
576                         DEBUG(0,("FATAL: codepoint 0x%x (0x%x) expanded from %d to %d bytes in strupper_m\n",
577                                  c, toupper_m(c), (int)c_size, (int)c_size2));
578                         smb_panic("codepoint expansion in strupper_m\n");
579                 }
580                 s += c_size;
581                 d += c_size2;
582         }
583         *d = 0;
584 }
585
586
587 /**
588  Find the number of 'c' chars in a string
589 **/
590 _PUBLIC_ size_t count_chars_m(const char *s, char c)
591 {
592         struct smb_iconv_convenience *ic = get_iconv_convenience();
593         size_t count = 0;
594
595         while (*s) {
596                 size_t size;
597                 codepoint_t c2 = next_codepoint(ic, s, &size);
598                 if (c2 == c) count++;
599                 s += size;
600         }
601
602         return count;
603 }
604
605
606 /**
607  * Copy a string from a char* unix src to a dos codepage string destination.
608  *
609  * @return the number of bytes occupied by the string in the destination.
610  *
611  * @param flags can include
612  * <dl>
613  * <dt>STR_TERMINATE</dt> <dd>means include the null termination</dd>
614  * <dt>STR_UPPER</dt> <dd>means uppercase in the destination</dd>
615  * </dl>
616  *
617  * @param dest_len the maximum length in bytes allowed in the
618  * destination.  If @p dest_len is -1 then no maximum is used.
619  **/
620 static ssize_t push_ascii(void *dest, const char *src, size_t dest_len, int flags)
621 {
622         size_t src_len;
623         ssize_t ret;
624
625         if (flags & STR_UPPER) {
626                 char *tmpbuf = strupper_talloc(NULL, src);
627                 if (tmpbuf == NULL) {
628                         return -1;
629                 }
630                 ret = push_ascii(dest, tmpbuf, dest_len, flags & ~STR_UPPER);
631                 talloc_free(tmpbuf);
632                 return ret;
633         }
634
635         src_len = strlen(src);
636
637         if (flags & (STR_TERMINATE | STR_TERMINATE_ASCII))
638                 src_len++;
639
640         return convert_string(CH_UNIX, CH_DOS, src, src_len, dest, dest_len);
641 }
642
643 /**
644  * Copy a string from a unix char* src to an ASCII destination,
645  * allocating a buffer using talloc().
646  *
647  * @param dest always set at least to NULL 
648  *
649  * @returns The number of bytes occupied by the string in the destination
650  *         or -1 in case of error.
651  **/
652 _PUBLIC_ ssize_t push_ascii_talloc(TALLOC_CTX *ctx, char **dest, const char *src)
653 {
654         size_t src_len = strlen(src)+1;
655         *dest = NULL;
656         return convert_string_talloc(ctx, CH_UNIX, CH_DOS, src, src_len, (void **)dest);
657 }
658
659
660 /**
661  * Copy a string from a dos codepage source to a unix char* destination.
662  *
663  * The resulting string in "dest" is always null terminated.
664  *
665  * @param flags can have:
666  * <dl>
667  * <dt>STR_TERMINATE</dt>
668  * <dd>STR_TERMINATE means the string in @p src
669  * is null terminated, and src_len is ignored.</dd>
670  * </dl>
671  *
672  * @param src_len is the length of the source area in bytes.
673  * @returns the number of bytes occupied by the string in @p src.
674  **/
675 static ssize_t pull_ascii(char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
676 {
677         size_t ret;
678
679         if (flags & (STR_TERMINATE | STR_TERMINATE_ASCII)) {
680                 if (src_len == (size_t)-1) {
681                         src_len = strlen((const char *)src) + 1;
682                 } else {
683                         size_t len = strnlen((const char *)src, src_len);
684                         if (len < src_len)
685                                 len++;
686                         src_len = len;
687                 }
688         }
689
690         ret = convert_string(CH_DOS, CH_UNIX, src, src_len, dest, dest_len);
691
692         if (dest_len)
693                 dest[MIN(ret, dest_len-1)] = 0;
694
695         return src_len;
696 }
697
698 /**
699  * Copy a string from a char* src to a unicode destination.
700  *
701  * @returns the number of bytes occupied by the string in the destination.
702  *
703  * @param flags can have:
704  *
705  * <dl>
706  * <dt>STR_TERMINATE <dd>means include the null termination.
707  * <dt>STR_UPPER     <dd>means uppercase in the destination.
708  * <dt>STR_NOALIGN   <dd>means don't do alignment.
709  * </dl>
710  *
711  * @param dest_len is the maximum length allowed in the
712  * destination. If dest_len is -1 then no maxiumum is used.
713  **/
714 static ssize_t push_ucs2(void *dest, const char *src, size_t dest_len, int flags)
715 {
716         size_t len=0;
717         size_t src_len = strlen(src);
718         size_t ret;
719
720         if (flags & STR_UPPER) {
721                 char *tmpbuf = strupper_talloc(NULL, src);
722                 if (tmpbuf == NULL) {
723                         return -1;
724                 }
725                 ret = push_ucs2(dest, tmpbuf, dest_len, flags & ~STR_UPPER);
726                 talloc_free(tmpbuf);
727                 return ret;
728         }
729
730         if (flags & STR_TERMINATE)
731                 src_len++;
732
733         if (ucs2_align(NULL, dest, flags)) {
734                 *(char *)dest = 0;
735                 dest = (void *)((char *)dest + 1);
736                 if (dest_len) dest_len--;
737                 len++;
738         }
739
740         /* ucs2 is always a multiple of 2 bytes */
741         dest_len &= ~1;
742
743         ret = convert_string(CH_UNIX, CH_UTF16, src, src_len, dest, dest_len);
744         if (ret == (size_t)-1) {
745                 return 0;
746         }
747
748         len += ret;
749
750         return len;
751 }
752
753
754 /**
755  * Copy a string from a unix char* src to a UCS2 destination,
756  * allocating a buffer using talloc().
757  *
758  * @param dest always set at least to NULL 
759  *
760  * @returns The number of bytes occupied by the string in the destination
761  *         or -1 in case of error.
762  **/
763 _PUBLIC_ ssize_t push_ucs2_talloc(TALLOC_CTX *ctx, void **dest, const char *src)
764 {
765         size_t src_len = strlen(src)+1;
766         *dest = NULL;
767         return convert_string_talloc(ctx, CH_UNIX, CH_UTF16, src, src_len, dest);
768 }
769
770
771 /**
772  * Copy a string from a unix char* src to a UTF-8 destination, allocating a buffer using talloc
773  *
774  * @param dest always set at least to NULL 
775  *
776  * @returns The number of bytes occupied by the string in the destination
777  **/
778
779 _PUBLIC_ ssize_t push_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src)
780 {
781         size_t src_len = strlen(src)+1;
782         *dest = NULL;
783         return convert_string_talloc(ctx, CH_UNIX, CH_UTF8, src, src_len, (void **)dest);
784 }
785
786 /**
787  Copy a string from a ucs2 source to a unix char* destination.
788  Flags can have:
789   STR_TERMINATE means the string in src is null terminated.
790   STR_NOALIGN   means don't try to align.
791  if STR_TERMINATE is set then src_len is ignored if it is -1.
792  src_len is the length of the source area in bytes
793  Return the number of bytes occupied by the string in src.
794  The resulting string in "dest" is always null terminated.
795 **/
796
797 static size_t pull_ucs2(char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
798 {
799         size_t ret;
800
801         if (ucs2_align(NULL, src, flags)) {
802                 src = (const void *)((const char *)src + 1);
803                 if (src_len > 0)
804                         src_len--;
805         }
806
807         if (flags & STR_TERMINATE) {
808                 if (src_len == (size_t)-1) {
809                         src_len = utf16_len(src);
810                 } else {
811                         src_len = utf16_len_n(src, src_len);
812                 }
813         }
814
815         /* ucs2 is always a multiple of 2 bytes */
816         if (src_len != (size_t)-1)
817                 src_len &= ~1;
818         
819         ret = convert_string(CH_UTF16, CH_UNIX, src, src_len, dest, dest_len);
820         if (dest_len)
821                 dest[MIN(ret, dest_len-1)] = 0;
822
823         return src_len;
824 }
825
826 /**
827  * Copy a string from a ASCII src to a unix char * destination, allocating a buffer using talloc
828  *
829  * @param dest always set at least to NULL 
830  *
831  * @returns The number of bytes occupied by the string in the destination
832  **/
833
834 _PUBLIC_ ssize_t pull_ascii_talloc(TALLOC_CTX *ctx, char **dest, const char *src)
835 {
836         size_t src_len = strlen(src)+1;
837         *dest = NULL;
838         return convert_string_talloc(ctx, CH_DOS, CH_UNIX, src, src_len, (void **)dest);
839 }
840
841 /**
842  * Copy a string from a UCS2 src to a unix char * destination, allocating a buffer using talloc
843  *
844  * @param dest always set at least to NULL 
845  *
846  * @returns The number of bytes occupied by the string in the destination
847  **/
848
849 _PUBLIC_ ssize_t pull_ucs2_talloc(TALLOC_CTX *ctx, char **dest, const void *src)
850 {
851         size_t src_len = utf16_len(src);
852         *dest = NULL;
853         return convert_string_talloc(ctx, CH_UTF16, CH_UNIX, src, src_len, (void **)dest);
854 }
855
856 /**
857  * Copy a string from a UTF-8 src to a unix char * destination, allocating a buffer using talloc
858  *
859  * @param dest always set at least to NULL 
860  *
861  * @returns The number of bytes occupied by the string in the destination
862  **/
863
864 _PUBLIC_ ssize_t pull_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src)
865 {
866         size_t src_len = strlen(src)+1;
867         *dest = NULL;
868         return convert_string_talloc(ctx, CH_UTF8, CH_UNIX, src, src_len, (void **)dest);
869 }
870
871 /**
872  Copy a string from a char* src to a unicode or ascii
873  dos codepage destination choosing unicode or ascii based on the 
874  flags in the SMB buffer starting at base_ptr.
875  Return the number of bytes occupied by the string in the destination.
876  flags can have:
877   STR_TERMINATE means include the null termination.
878   STR_UPPER     means uppercase in the destination.
879   STR_ASCII     use ascii even with unicode packet.
880   STR_NOALIGN   means don't do alignment.
881  dest_len is the maximum length allowed in the destination. If dest_len
882  is -1 then no maxiumum is used.
883 **/
884
885 _PUBLIC_ ssize_t push_string(void *dest, const char *src, size_t dest_len, int flags)
886 {
887         if (flags & STR_ASCII) {
888                 return push_ascii(dest, src, dest_len, flags);
889         } else if (flags & STR_UNICODE) {
890                 return push_ucs2(dest, src, dest_len, flags);
891         } else {
892                 smb_panic("push_string requires either STR_ASCII or STR_UNICODE flag to be set");
893                 return -1;
894         }
895 }
896
897
898 /**
899  Copy a string from a unicode or ascii source (depending on
900  the packet flags) to a char* destination.
901  Flags can have:
902   STR_TERMINATE means the string in src is null terminated.
903   STR_UNICODE   means to force as unicode.
904   STR_ASCII     use ascii even with unicode packet.
905   STR_NOALIGN   means don't do alignment.
906  if STR_TERMINATE is set then src_len is ignored is it is -1
907  src_len is the length of the source area in bytes.
908  Return the number of bytes occupied by the string in src.
909  The resulting string in "dest" is always null terminated.
910 **/
911
912 _PUBLIC_ ssize_t pull_string(char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
913 {
914         if (flags & STR_ASCII) {
915                 return pull_ascii(dest, src, dest_len, src_len, flags);
916         } else if (flags & STR_UNICODE) {
917                 return pull_ucs2(dest, src, dest_len, src_len, flags);
918         } else {
919                 smb_panic("pull_string requires either STR_ASCII or STR_UNICODE flag to be set");
920                 return -1;
921         }
922 }
923
924
925 /**
926  * Convert string from one encoding to another, making error checking etc
927  *
928  * @param src pointer to source string (multibyte or singlebyte)
929  * @param srclen length of the source string in bytes
930  * @param dest pointer to destination string (multibyte or singlebyte)
931  * @param destlen maximal length allowed for string
932  * @returns the number of bytes occupied in the destination
933  **/
934 _PUBLIC_ ssize_t convert_string(charset_t from, charset_t to,
935                                 void const *src, size_t srclen, 
936                                 void *dest, size_t destlen)
937 {
938         return convert_string_convenience(get_iconv_convenience(), from, to, 
939                                                                           src, srclen,
940                                                                           dest, destlen);
941 }
942
943 /**
944  * Convert between character sets, allocating a new buffer using talloc for the result.
945  *
946  * @param srclen length of source buffer.
947  * @param dest always set at least to NULL
948  * @note -1 is not accepted for srclen.
949  *
950  * @returns Size in bytes of the converted string; or -1 in case of error.
951  **/
952
953 _PUBLIC_ ssize_t convert_string_talloc(TALLOC_CTX *ctx, 
954                                        charset_t from, charset_t to, 
955                                        void const *src, size_t srclen, 
956                                        void **dest)
957 {
958         return convert_string_talloc_convenience(ctx, get_iconv_convenience(),
959                                                                                          from, to, src, srclen, dest);
960 }