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