• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/router/samba-3.5.8/lib/util/charset/
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
24struct smb_iconv_convenience *global_iconv_convenience = NULL;
25
26static 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_convenience(iconv_convenience, s1, &size1);
49		c2 = next_codepoint_convenience(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_convenience(iconv_convenience, s1, &size1);
136		c2 = next_codepoint_convenience(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_convenience(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_convenience(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 * Weird helper routine for the winreg pipe: If nothing is around, return 0,
302 * if a string is there, include the terminator.
303 */
304
305_PUBLIC_ size_t strlen_m_term_null(const char *s)
306{
307	size_t len;
308	if (!s) {
309		return 0;
310	}
311	len = strlen_m(s);
312	if (len == 0) {
313		return 0;
314	}
315
316	return len+1;
317}
318
319/**
320 Strchr and strrchr_m are a bit complex on general multi-byte strings.
321**/
322_PUBLIC_ char *strchr_m(const char *s, char c)
323{
324	struct smb_iconv_convenience *ic = get_iconv_convenience();
325	if (s == NULL) {
326		return NULL;
327	}
328	/* characters below 0x3F are guaranteed to not appear in
329	   non-initial position in multi-byte charsets */
330	if ((c & 0xC0) == 0) {
331		return strchr(s, c);
332	}
333
334	while (*s) {
335		size_t size;
336		codepoint_t c2 = next_codepoint_convenience(ic, s, &size);
337		if (c2 == c) {
338			return discard_const_p(char, s);
339		}
340		s += size;
341	}
342
343	return NULL;
344}
345
346/**
347 * Multibyte-character version of strrchr
348 */
349_PUBLIC_ char *strrchr_m(const char *s, char c)
350{
351	struct smb_iconv_convenience *ic = get_iconv_convenience();
352	char *ret = NULL;
353
354	if (s == NULL) {
355		return NULL;
356	}
357
358	/* characters below 0x3F are guaranteed to not appear in
359	   non-initial position in multi-byte charsets */
360	if ((c & 0xC0) == 0) {
361		return strrchr(s, c);
362	}
363
364	while (*s) {
365		size_t size;
366		codepoint_t c2 = next_codepoint_convenience(ic, s, &size);
367		if (c2 == c) {
368			ret = discard_const_p(char, s);
369		}
370		s += size;
371	}
372
373	return ret;
374}
375
376/**
377  return True if any (multi-byte) character is lower case
378*/
379_PUBLIC_ bool strhaslower(const char *string)
380{
381	struct smb_iconv_convenience *ic = get_iconv_convenience();
382	while (*string) {
383		size_t c_size;
384		codepoint_t s;
385		codepoint_t t;
386
387		s = next_codepoint_convenience(ic, string, &c_size);
388		string += c_size;
389
390		t = toupper_m(s);
391
392		if (s != t) {
393			return true; /* that means it has lower case chars */
394		}
395	}
396
397	return false;
398}
399
400/**
401  return True if any (multi-byte) character is upper case
402*/
403_PUBLIC_ bool strhasupper(const char *string)
404{
405	struct smb_iconv_convenience *ic = get_iconv_convenience();
406	while (*string) {
407		size_t c_size;
408		codepoint_t s;
409		codepoint_t t;
410
411		s = next_codepoint_convenience(ic, string, &c_size);
412		string += c_size;
413
414		t = tolower_m(s);
415
416		if (s != t) {
417			return true; /* that means it has upper case chars */
418		}
419	}
420
421	return false;
422}
423
424/**
425 Convert a string to lower case, allocated with talloc
426**/
427_PUBLIC_ char *strlower_talloc(TALLOC_CTX *ctx, const char *src)
428{
429	size_t size=0;
430	char *dest;
431	struct smb_iconv_convenience *iconv_convenience = get_iconv_convenience();
432
433	/* this takes advantage of the fact that upper/lower can't
434	   change the length of a character by more than 1 byte */
435	dest = talloc_array(ctx, char, 2*(strlen(src))+1);
436	if (dest == NULL) {
437		return NULL;
438	}
439
440	while (*src) {
441		size_t c_size;
442		codepoint_t c = next_codepoint_convenience(iconv_convenience, src, &c_size);
443		src += c_size;
444
445		c = tolower_m(c);
446
447		c_size = push_codepoint_convenience(iconv_convenience, dest+size, c);
448		if (c_size == -1) {
449			talloc_free(dest);
450			return NULL;
451		}
452		size += c_size;
453	}
454
455	dest[size] = 0;
456
457	/* trim it so talloc_append_string() works */
458	dest = talloc_realloc(ctx, dest, char, size+1);
459
460	talloc_set_name_const(dest, dest);
461
462	return dest;
463}
464
465/**
466 Convert a string to UPPER case, allocated with talloc
467 source length limited to n bytes
468**/
469_PUBLIC_ char *strupper_talloc_n(TALLOC_CTX *ctx, const char *src, size_t n)
470{
471	size_t size=0;
472	char *dest;
473	struct smb_iconv_convenience *iconv_convenience = get_iconv_convenience();
474
475	if (!src) {
476		return NULL;
477	}
478
479	/* this takes advantage of the fact that upper/lower can't
480	   change the length of a character by more than 1 byte */
481	dest = talloc_array(ctx, char, 2*(n+1));
482	if (dest == NULL) {
483		return NULL;
484	}
485
486	while (n-- && *src) {
487		size_t c_size;
488		codepoint_t c = next_codepoint_convenience(iconv_convenience, src, &c_size);
489		src += c_size;
490
491		c = toupper_m(c);
492
493		c_size = push_codepoint_convenience(iconv_convenience, dest+size, c);
494		if (c_size == -1) {
495			talloc_free(dest);
496			return NULL;
497		}
498		size += c_size;
499	}
500
501	dest[size] = 0;
502
503	/* trim it so talloc_append_string() works */
504	dest = talloc_realloc(ctx, dest, char, size+1);
505
506	talloc_set_name_const(dest, dest);
507
508	return dest;
509}
510
511/**
512 Convert a string to UPPER case, allocated with talloc
513**/
514_PUBLIC_ char *strupper_talloc(TALLOC_CTX *ctx, const char *src)
515{
516	return strupper_talloc_n(ctx, src, src?strlen(src):0);
517}
518
519/**
520 talloc_strdup() a unix string to upper case.
521**/
522_PUBLIC_ char *talloc_strdup_upper(TALLOC_CTX *ctx, const char *src)
523{
524	return strupper_talloc(ctx, src);
525}
526
527/**
528 Convert a string to lower case.
529**/
530_PUBLIC_ void strlower_m(char *s)
531{
532	char *d;
533	struct smb_iconv_convenience *iconv_convenience;
534
535	/* this is quite a common operation, so we want it to be
536	   fast. We optimise for the ascii case, knowing that all our
537	   supported multi-byte character sets are ascii-compatible
538	   (ie. they match for the first 128 chars) */
539	while (*s && !(((uint8_t)*s) & 0x80)) {
540		*s = tolower((uint8_t)*s);
541		s++;
542	}
543
544	if (!*s)
545		return;
546
547	iconv_convenience = get_iconv_convenience();
548
549	d = s;
550
551	while (*s) {
552		size_t c_size, c_size2;
553		codepoint_t c = next_codepoint_convenience(iconv_convenience, s, &c_size);
554		c_size2 = push_codepoint_convenience(iconv_convenience, d, tolower_m(c));
555		if (c_size2 > c_size) {
556			DEBUG(0,("FATAL: codepoint 0x%x (0x%x) expanded from %d to %d bytes in strlower_m\n",
557				 c, tolower_m(c), (int)c_size, (int)c_size2));
558			smb_panic("codepoint expansion in strlower_m\n");
559		}
560		s += c_size;
561		d += c_size2;
562	}
563	*d = 0;
564}
565
566/**
567 Convert a string to UPPER case.
568**/
569_PUBLIC_ void strupper_m(char *s)
570{
571	char *d;
572	struct smb_iconv_convenience *iconv_convenience;
573
574	/* this is quite a common operation, so we want it to be
575	   fast. We optimise for the ascii case, knowing that all our
576	   supported multi-byte character sets are ascii-compatible
577	   (ie. they match for the first 128 chars) */
578	while (*s && !(((uint8_t)*s) & 0x80)) {
579		*s = toupper((uint8_t)*s);
580		s++;
581	}
582
583	if (!*s)
584		return;
585
586	iconv_convenience = get_iconv_convenience();
587
588	d = s;
589
590	while (*s) {
591		size_t c_size, c_size2;
592		codepoint_t c = next_codepoint_convenience(iconv_convenience, s, &c_size);
593		c_size2 = push_codepoint_convenience(iconv_convenience, d, toupper_m(c));
594		if (c_size2 > c_size) {
595			DEBUG(0,("FATAL: codepoint 0x%x (0x%x) expanded from %d to %d bytes in strupper_m\n",
596				 c, toupper_m(c), (int)c_size, (int)c_size2));
597			smb_panic("codepoint expansion in strupper_m\n");
598		}
599		s += c_size;
600		d += c_size2;
601	}
602	*d = 0;
603}
604
605
606/**
607 Find the number of 'c' chars in a string
608**/
609_PUBLIC_ size_t count_chars_m(const char *s, char c)
610{
611	struct smb_iconv_convenience *ic = get_iconv_convenience();
612	size_t count = 0;
613
614	while (*s) {
615		size_t size;
616		codepoint_t c2 = next_codepoint_convenience(ic, s, &size);
617		if (c2 == c) count++;
618		s += size;
619	}
620
621	return count;
622}
623
624
625/**
626 * Copy a string from a char* unix src to a dos codepage string destination.
627 *
628 * @return the number of bytes occupied by the string in the destination.
629 *
630 * @param flags can include
631 * <dl>
632 * <dt>STR_TERMINATE</dt> <dd>means include the null termination</dd>
633 * <dt>STR_UPPER</dt> <dd>means uppercase in the destination</dd>
634 * </dl>
635 *
636 * @param dest_len the maximum length in bytes allowed in the
637 * destination.  If @p dest_len is -1 then no maximum is used.
638 **/
639static ssize_t push_ascii(void *dest, const char *src, size_t dest_len, int flags)
640{
641	size_t src_len;
642	ssize_t ret;
643
644	if (flags & STR_UPPER) {
645		char *tmpbuf = strupper_talloc(NULL, src);
646		if (tmpbuf == NULL) {
647			return -1;
648		}
649		ret = push_ascii(dest, tmpbuf, dest_len, flags & ~STR_UPPER);
650		talloc_free(tmpbuf);
651		return ret;
652	}
653
654	src_len = strlen(src);
655
656	if (flags & (STR_TERMINATE | STR_TERMINATE_ASCII))
657		src_len++;
658
659	return convert_string(CH_UNIX, CH_DOS, src, src_len, dest, dest_len, false);
660}
661
662/**
663 * Copy a string from a unix char* src to an ASCII destination,
664 * allocating a buffer using talloc().
665 *
666 * @param dest always set at least to NULL
667 *
668 * @returns The number of bytes occupied by the string in the destination
669 *         or -1 in case of error.
670 **/
671_PUBLIC_ bool push_ascii_talloc(TALLOC_CTX *ctx, char **dest, const char *src, size_t *converted_size)
672{
673	size_t src_len = strlen(src)+1;
674	*dest = NULL;
675	return convert_string_talloc(ctx, CH_UNIX, CH_DOS, src, src_len, (void **)dest, converted_size, false);
676}
677
678
679/**
680 * Copy a string from a dos codepage source to a unix char* destination.
681 *
682 * The resulting string in "dest" is always null terminated.
683 *
684 * @param flags can have:
685 * <dl>
686 * <dt>STR_TERMINATE</dt>
687 * <dd>STR_TERMINATE means the string in @p src
688 * is null terminated, and src_len is ignored.</dd>
689 * </dl>
690 *
691 * @param src_len is the length of the source area in bytes.
692 * @returns the number of bytes occupied by the string in @p src.
693 **/
694static ssize_t pull_ascii(char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
695{
696	size_t ret;
697
698	if (flags & (STR_TERMINATE | STR_TERMINATE_ASCII)) {
699		if (src_len == (size_t)-1) {
700			src_len = strlen((const char *)src) + 1;
701		} else {
702			size_t len = strnlen((const char *)src, src_len);
703			if (len < src_len)
704				len++;
705			src_len = len;
706		}
707	}
708
709	ret = convert_string(CH_DOS, CH_UNIX, src, src_len, dest, dest_len, false);
710
711	if (dest_len)
712		dest[MIN(ret, dest_len-1)] = 0;
713
714	return src_len;
715}
716
717/**
718 * Copy a string from a char* src to a unicode destination.
719 *
720 * @returns the number of bytes occupied by the string in the destination.
721 *
722 * @param flags can have:
723 *
724 * <dl>
725 * <dt>STR_TERMINATE <dd>means include the null termination.
726 * <dt>STR_UPPER     <dd>means uppercase in the destination.
727 * <dt>STR_NOALIGN   <dd>means don't do alignment.
728 * </dl>
729 *
730 * @param dest_len is the maximum length allowed in the
731 * destination. If dest_len is -1 then no maxiumum is used.
732 **/
733static ssize_t push_ucs2(void *dest, const char *src, size_t dest_len, int flags)
734{
735	size_t len=0;
736	size_t src_len = strlen(src);
737	size_t ret;
738
739	if (flags & STR_UPPER) {
740		char *tmpbuf = strupper_talloc(NULL, src);
741		if (tmpbuf == NULL) {
742			return -1;
743		}
744		ret = push_ucs2(dest, tmpbuf, dest_len, flags & ~STR_UPPER);
745		talloc_free(tmpbuf);
746		return ret;
747	}
748
749	if (flags & STR_TERMINATE)
750		src_len++;
751
752	if (ucs2_align(NULL, dest, flags)) {
753		*(char *)dest = 0;
754		dest = (void *)((char *)dest + 1);
755		if (dest_len) dest_len--;
756		len++;
757	}
758
759	/* ucs2 is always a multiple of 2 bytes */
760	dest_len &= ~1;
761
762	ret = convert_string(CH_UNIX, CH_UTF16, src, src_len, dest, dest_len, false);
763	if (ret == (size_t)-1) {
764		return 0;
765	}
766
767	len += ret;
768
769	return len;
770}
771
772
773/**
774 * Copy a string from a unix char* src to a UCS2 destination,
775 * allocating a buffer using talloc().
776 *
777 * @param dest always set at least to NULL
778 *
779 * @returns The number of bytes occupied by the string in the destination
780 *         or -1 in case of error.
781 **/
782_PUBLIC_ bool push_ucs2_talloc(TALLOC_CTX *ctx, smb_ucs2_t **dest, const char *src, size_t *converted_size)
783{
784	size_t src_len = strlen(src)+1;
785	*dest = NULL;
786	return convert_string_talloc(ctx, CH_UNIX, CH_UTF16, src, src_len, (void **)dest, converted_size, false);
787}
788
789
790/**
791 * Copy a string from a unix char* src to a UTF-8 destination, allocating a buffer using talloc
792 *
793 * @param dest always set at least to NULL
794 *
795 * @returns The number of bytes occupied by the string in the destination
796 **/
797
798_PUBLIC_ bool push_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src, size_t *converted_size)
799{
800	size_t src_len = strlen(src)+1;
801	*dest = NULL;
802	return convert_string_talloc(ctx, CH_UNIX, CH_UTF8, src, src_len, (void **)dest, converted_size, false);
803}
804
805/**
806 Copy a string from a ucs2 source to a unix char* destination.
807 Flags can have:
808  STR_TERMINATE means the string in src is null terminated.
809  STR_NOALIGN   means don't try to align.
810 if STR_TERMINATE is set then src_len is ignored if it is -1.
811 src_len is the length of the source area in bytes
812 Return the number of bytes occupied by the string in src.
813 The resulting string in "dest" is always null terminated.
814**/
815
816static size_t pull_ucs2(char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
817{
818	size_t ret;
819
820	if (ucs2_align(NULL, src, flags)) {
821		src = (const void *)((const char *)src + 1);
822		if (src_len > 0)
823			src_len--;
824	}
825
826	if (flags & STR_TERMINATE) {
827		if (src_len == (size_t)-1) {
828			src_len = utf16_len(src);
829		} else {
830			src_len = utf16_len_n(src, src_len);
831		}
832	}
833
834	/* ucs2 is always a multiple of 2 bytes */
835	if (src_len != (size_t)-1)
836		src_len &= ~1;
837
838	ret = convert_string(CH_UTF16, CH_UNIX, src, src_len, dest, dest_len, false);
839	if (dest_len)
840		dest[MIN(ret, dest_len-1)] = 0;
841
842	return src_len;
843}
844
845/**
846 * Copy a string from a ASCII src to a unix char * destination, allocating a buffer using talloc
847 *
848 * @param dest always set at least to NULL
849 *
850 * @returns The number of bytes occupied by the string in the destination
851 **/
852
853_PUBLIC_ bool pull_ascii_talloc(TALLOC_CTX *ctx, char **dest, const char *src, size_t *converted_size)
854{
855	size_t src_len = strlen(src)+1;
856	*dest = NULL;
857	return convert_string_talloc(ctx, CH_DOS, CH_UNIX, src, src_len, (void **)dest, converted_size, false);
858}
859
860/**
861 * Copy a string from a UCS2 src to a unix char * destination, allocating a buffer using talloc
862 *
863 * @param dest always set at least to NULL
864 *
865 * @returns The number of bytes occupied by the string in the destination
866 **/
867
868_PUBLIC_ bool pull_ucs2_talloc(TALLOC_CTX *ctx, char **dest, const smb_ucs2_t *src, size_t *converted_size)
869{
870	size_t src_len = utf16_len(src);
871	*dest = NULL;
872	return convert_string_talloc(ctx, CH_UTF16, CH_UNIX, src, src_len, (void **)dest, converted_size, false);
873}
874
875/**
876 * Copy a string from a UTF-8 src to a unix char * destination, allocating a buffer using talloc
877 *
878 * @param dest always set at least to NULL
879 *
880 * @returns The number of bytes occupied by the string in the destination
881 **/
882
883_PUBLIC_ bool pull_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src, size_t *converted_size)
884{
885	size_t src_len = strlen(src)+1;
886	*dest = NULL;
887	return convert_string_talloc(ctx, CH_UTF8, CH_UNIX, src, src_len, (void **)dest, converted_size, false);
888}
889
890/**
891 Copy a string from a char* src to a unicode or ascii
892 dos codepage destination choosing unicode or ascii based on the
893 flags in the SMB buffer starting at base_ptr.
894 Return the number of bytes occupied by the string in the destination.
895 flags can have:
896  STR_TERMINATE means include the null termination.
897  STR_UPPER     means uppercase in the destination.
898  STR_ASCII     use ascii even with unicode packet.
899  STR_NOALIGN   means don't do alignment.
900 dest_len is the maximum length allowed in the destination. If dest_len
901 is -1 then no maxiumum is used.
902**/
903
904_PUBLIC_ ssize_t push_string(void *dest, const char *src, size_t dest_len, int flags)
905{
906	if (flags & STR_ASCII) {
907		return push_ascii(dest, src, dest_len, flags);
908	} else if (flags & STR_UNICODE) {
909		return push_ucs2(dest, src, dest_len, flags);
910	} else {
911		smb_panic("push_string requires either STR_ASCII or STR_UNICODE flag to be set");
912		return -1;
913	}
914}
915
916
917/**
918 Copy a string from a unicode or ascii source (depending on
919 the packet flags) to a char* destination.
920 Flags can have:
921  STR_TERMINATE means the string in src is null terminated.
922  STR_UNICODE   means to force as unicode.
923  STR_ASCII     use ascii even with unicode packet.
924  STR_NOALIGN   means don't do alignment.
925 if STR_TERMINATE is set then src_len is ignored is it is -1
926 src_len is the length of the source area in bytes.
927 Return the number of bytes occupied by the string in src.
928 The resulting string in "dest" is always null terminated.
929**/
930
931_PUBLIC_ ssize_t pull_string(char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
932{
933	if (flags & STR_ASCII) {
934		return pull_ascii(dest, src, dest_len, src_len, flags);
935	} else if (flags & STR_UNICODE) {
936		return pull_ucs2(dest, src, dest_len, src_len, flags);
937	} else {
938		smb_panic("pull_string requires either STR_ASCII or STR_UNICODE flag to be set");
939		return -1;
940	}
941}
942
943
944/**
945 * Convert string from one encoding to another, making error checking etc
946 *
947 * @param src pointer to source string (multibyte or singlebyte)
948 * @param srclen length of the source string in bytes
949 * @param dest pointer to destination string (multibyte or singlebyte)
950 * @param destlen maximal length allowed for string
951 * @returns the number of bytes occupied in the destination
952 **/
953_PUBLIC_ size_t convert_string(charset_t from, charset_t to,
954				void const *src, size_t srclen,
955				void *dest, size_t destlen,
956				bool allow_badcharcnv)
957{
958	size_t ret;
959	if (!convert_string_convenience(get_iconv_convenience(), from, to,
960									  src, srclen,
961									  dest, destlen, &ret,
962									  allow_badcharcnv))
963		return -1;
964	return ret;
965}
966
967/**
968 * Convert between character sets, allocating a new buffer using talloc for the result.
969 *
970 * @param srclen length of source buffer.
971 * @param dest always set at least to NULL
972 * @param converted_size Size in bytes of the converted string
973 * @note -1 is not accepted for srclen.
974 *
975 * @returns boolean indication whether the conversion succeeded
976 **/
977
978_PUBLIC_ bool convert_string_talloc(TALLOC_CTX *ctx,
979				       charset_t from, charset_t to,
980				       void const *src, size_t srclen,
981				       void *dest, size_t *converted_size,
982					   bool allow_badcharcnv)
983{
984	return convert_string_talloc_convenience(ctx, get_iconv_convenience(),
985											 from, to, src, srclen, dest,
986											 converted_size,
987											 allow_badcharcnv);
988}
989
990
991_PUBLIC_ codepoint_t next_codepoint(const char *str, size_t *size)
992{
993	return next_codepoint_convenience(get_iconv_convenience(), str, size);
994}
995
996_PUBLIC_ ssize_t push_codepoint(char *str, codepoint_t c)
997{
998	return push_codepoint_convenience(get_iconv_convenience(), str, c);
999}
1000