source: trunk/server/lib/util/charset/util_unistr.c

Last change on this file was 745, checked in by Silvan Scherrer, 13 years ago

Samba Server: updated trunk to 3.6.0

File size: 24.3 KB
Line 
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/**
25 Case insensitive string compararison
26**/
27_PUBLIC_ int strcasecmp_m(const char *s1, const char *s2)
28{
29 codepoint_t c1=0, c2=0;
30 size_t size1, size2;
31 struct smb_iconv_convenience *iconv_convenience = get_iconv_convenience();
32
33 /* handle null ptr comparisons to simplify the use in qsort */
34 if (s1 == s2) return 0;
35 if (s1 == NULL) return -1;
36 if (s2 == NULL) return 1;
37
38 while (*s1 && *s2) {
39 c1 = next_codepoint_convenience(iconv_convenience, s1, &size1);
40 c2 = next_codepoint_convenience(iconv_convenience, s2, &size2);
41
42 s1 += size1;
43 s2 += size2;
44
45 if (c1 == c2) {
46 continue;
47 }
48
49 if (c1 == INVALID_CODEPOINT ||
50 c2 == INVALID_CODEPOINT) {
51 /* what else can we do?? */
52 return strcasecmp(s1, s2);
53 }
54
55 if (toupper_m(c1) != toupper_m(c2)) {
56 return c1 - c2;
57 }
58 }
59
60 return *s1 - *s2;
61}
62
63/**
64 Case insensitive string compararison, length limited
65**/
66_PUBLIC_ int strncasecmp_m(const char *s1, const char *s2, size_t n)
67{
68 codepoint_t c1=0, c2=0;
69 size_t size1, size2;
70 struct smb_iconv_convenience *iconv_convenience = get_iconv_convenience();
71
72 /* handle null ptr comparisons to simplify the use in qsort */
73 if (s1 == s2) return 0;
74 if (s1 == NULL) return -1;
75 if (s2 == NULL) return 1;
76
77 while (*s1 && *s2 && n) {
78 n--;
79
80 c1 = next_codepoint_convenience(iconv_convenience, s1, &size1);
81 c2 = next_codepoint_convenience(iconv_convenience, s2, &size2);
82
83 s1 += size1;
84 s2 += size2;
85
86 if (c1 == c2) {
87 continue;
88 }
89
90 if (c1 == INVALID_CODEPOINT ||
91 c2 == INVALID_CODEPOINT) {
92 /* what else can we do?? */
93 return strcasecmp(s1, s2);
94 }
95
96 if (toupper_m(c1) != toupper_m(c2)) {
97 return c1 - c2;
98 }
99 }
100
101 if (n == 0) {
102 return 0;
103 }
104
105 return *s1 - *s2;
106}
107
108/**
109 * Compare 2 strings.
110 *
111 * @note The comparison is case-insensitive.
112 **/
113_PUBLIC_ bool strequal_m(const char *s1, const char *s2)
114{
115 return strcasecmp_m(s1,s2) == 0;
116}
117
118/**
119 Compare 2 strings (case sensitive).
120**/
121_PUBLIC_ bool strcsequal_m(const char *s1,const char *s2)
122{
123 if (s1 == s2)
124 return true;
125 if (!s1 || !s2)
126 return false;
127
128 return strcmp(s1,s2) == 0;
129}
130
131
132/**
133 String replace.
134 NOTE: oldc and newc must be 7 bit characters
135**/
136_PUBLIC_ void string_replace_m(char *s, char oldc, char newc)
137{
138 struct smb_iconv_convenience *ic = get_iconv_convenience();
139 while (s && *s) {
140 size_t size;
141 codepoint_t c = next_codepoint_convenience(ic, s, &size);
142 if (c == oldc) {
143 *s = newc;
144 }
145 s += size;
146 }
147}
148
149/**
150 Paranoid strcpy into a buffer of given length (includes terminating
151 zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
152 and replaces with '_'. Deliberately does *NOT* check for multibyte
153 characters. Don't change it !
154**/
155
156_PUBLIC_ char *alpha_strcpy(char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
157{
158 size_t len, i;
159
160 if (maxlength == 0) {
161 /* can't fit any bytes at all! */
162 return NULL;
163 }
164
165 if (!dest) {
166 DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n"));
167 return NULL;
168 }
169
170 if (!src) {
171 *dest = 0;
172 return dest;
173 }
174
175 len = strlen(src);
176 if (len >= maxlength)
177 len = maxlength - 1;
178
179 if (!other_safe_chars)
180 other_safe_chars = "";
181
182 for(i = 0; i < len; i++) {
183 int val = (src[i] & 0xff);
184 if (isupper(val) || islower(val) || isdigit(val) || strchr_m(other_safe_chars, val))
185 dest[i] = src[i];
186 else
187 dest[i] = '_';
188 }
189
190 dest[i] = '\0';
191
192 return dest;
193}
194
195/**
196 * Calculate the number of units (8 or 16-bit, depending on the
197 * destination charset), that would be needed to convert the input
198 * string which is expected to be in in src_charset encoding to the
199 * destination charset (which should be a unicode charset).
200 */
201_PUBLIC_ size_t strlen_m_ext(const char *s, charset_t src_charset, charset_t dst_charset)
202{
203 size_t count = 0;
204 struct smb_iconv_convenience *ic = get_iconv_convenience();
205
206 if (!s) {
207 return 0;
208 }
209
210 while (*s && !(((uint8_t)*s) & 0x80)) {
211 s++;
212 count++;
213 }
214
215 if (!*s) {
216 return count;
217 }
218
219 while (*s) {
220 size_t c_size;
221 codepoint_t c = next_codepoint_convenience_ext(ic, s, src_charset, &c_size);
222 s += c_size;
223
224 switch (dst_charset) {
225 case CH_UTF16LE:
226 case CH_UTF16BE:
227 case CH_UTF16MUNGED:
228 if (c < 0x10000) {
229 count += 1;
230 } else {
231 count += 2;
232 }
233 break;
234 case CH_UTF8:
235 /*
236 * this only checks ranges, and does not
237 * check for invalid codepoints
238 */
239 if (c < 0x80) {
240 count += 1;
241 } else if (c < 0x800) {
242 count += 2;
243 } else if (c < 0x1000) {
244 count += 3;
245 } else {
246 count += 4;
247 }
248 break;
249 default:
250 /*
251 * non-unicode encoding:
252 * assume that each codepoint fits into
253 * one unit in the destination encoding.
254 */
255 count += 1;
256 }
257 }
258
259 return count;
260}
261
262_PUBLIC_ size_t strlen_m_ext_term(const char *s, const charset_t src_charset,
263 const charset_t dst_charset)
264{
265 if (!s) {
266 return 0;
267 }
268 return strlen_m_ext(s, src_charset, dst_charset) + 1;
269}
270
271/**
272 * Calculate the number of 16-bit units that would be needed to convert
273 * the input string which is expected to be in CH_UNIX encoding to UTF16.
274 *
275 * This will be the same as the number of bytes in a string for single
276 * byte strings, but will be different for multibyte.
277 */
278_PUBLIC_ size_t strlen_m(const char *s)
279{
280 return strlen_m_ext(s, CH_UNIX, CH_UTF16LE);
281}
282
283/**
284 Work out the number of multibyte chars in a string, including the NULL
285 terminator.
286**/
287_PUBLIC_ size_t strlen_m_term(const char *s)
288{
289 if (!s) {
290 return 0;
291 }
292
293 return strlen_m(s) + 1;
294}
295
296/*
297 * Weird helper routine for the winreg pipe: If nothing is around, return 0,
298 * if a string is there, include the terminator.
299 */
300
301_PUBLIC_ size_t strlen_m_term_null(const char *s)
302{
303 size_t len;
304 if (!s) {
305 return 0;
306 }
307 len = strlen_m(s);
308 if (len == 0) {
309 return 0;
310 }
311
312 return len+1;
313}
314
315/**
316 Strchr and strrchr_m are a bit complex on general multi-byte strings.
317**/
318_PUBLIC_ char *strchr_m(const char *s, char c)
319{
320 struct smb_iconv_convenience *ic = get_iconv_convenience();
321 if (s == NULL) {
322 return NULL;
323 }
324 /* characters below 0x3F are guaranteed to not appear in
325 non-initial position in multi-byte charsets */
326 if ((c & 0xC0) == 0) {
327 return strchr(s, c);
328 }
329
330 while (*s) {
331 size_t size;
332 codepoint_t c2 = next_codepoint_convenience(ic, s, &size);
333 if (c2 == c) {
334 return discard_const_p(char, s);
335 }
336 s += size;
337 }
338
339 return NULL;
340}
341
342/**
343 * Multibyte-character version of strrchr
344 */
345_PUBLIC_ char *strrchr_m(const char *s, char c)
346{
347 struct smb_iconv_convenience *ic = get_iconv_convenience();
348 char *ret = NULL;
349
350 if (s == NULL) {
351 return NULL;
352 }
353
354 /* characters below 0x3F are guaranteed to not appear in
355 non-initial position in multi-byte charsets */
356 if ((c & 0xC0) == 0) {
357 return strrchr(s, c);
358 }
359
360 while (*s) {
361 size_t size;
362 codepoint_t c2 = next_codepoint_convenience(ic, s, &size);
363 if (c2 == c) {
364 ret = discard_const_p(char, s);
365 }
366 s += size;
367 }
368
369 return ret;
370}
371
372/**
373 return True if any (multi-byte) character is lower case
374*/
375_PUBLIC_ bool strhaslower(const char *string)
376{
377 struct smb_iconv_convenience *ic = get_iconv_convenience();
378 while (*string) {
379 size_t c_size;
380 codepoint_t s;
381 codepoint_t t;
382
383 s = next_codepoint_convenience(ic, string, &c_size);
384 string += c_size;
385
386 t = toupper_m(s);
387
388 if (s != t) {
389 return true; /* that means it has lower case chars */
390 }
391 }
392
393 return false;
394}
395
396/**
397 return True if any (multi-byte) character is upper case
398*/
399_PUBLIC_ bool strhasupper(const char *string)
400{
401 struct smb_iconv_convenience *ic = get_iconv_convenience();
402 while (*string) {
403 size_t c_size;
404 codepoint_t s;
405 codepoint_t t;
406
407 s = next_codepoint_convenience(ic, string, &c_size);
408 string += c_size;
409
410 t = tolower_m(s);
411
412 if (s != t) {
413 return true; /* that means it has upper case chars */
414 }
415 }
416
417 return false;
418}
419
420/**
421 Convert a string to lower case, allocated with talloc
422**/
423_PUBLIC_ char *strlower_talloc(TALLOC_CTX *ctx, const char *src)
424{
425 size_t size=0;
426 char *dest;
427 struct smb_iconv_convenience *iconv_convenience = get_iconv_convenience();
428
429 if(src == NULL) {
430 return NULL;
431 }
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
Note: See TracBrowser for help on using the repository browser.