2 Unix SMB/CIFS implementation.
4 routines for marshalling/unmarshalling string types
6 Copyright (C) Andrew Tridgell 2003
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "librpc/ndr/libndr.h"
26 pull a general string from the wire
28 _PUBLIC_
enum ndr_err_code
ndr_pull_string(struct ndr_pull
*ndr
, int ndr_flags
, const char **s
)
31 uint32_t len1
, ofs
, len2
;
34 charset_t chset
= CH_UTF16
;
35 unsigned byte_mul
= 2;
36 unsigned flags
= ndr
->flags
;
37 unsigned c_len_term
= 0;
39 if (!(ndr_flags
& NDR_SCALARS
)) {
40 return NDR_ERR_SUCCESS
;
47 if (flags
& LIBNDR_FLAG_STR_ASCII
) {
50 flags
&= ~LIBNDR_FLAG_STR_ASCII
;
53 if (flags
& LIBNDR_FLAG_STR_UTF8
) {
56 flags
&= ~LIBNDR_FLAG_STR_UTF8
;
59 flags
&= ~LIBNDR_FLAG_STR_CONFORMANT
;
60 if (flags
& LIBNDR_FLAG_STR_CHARLEN
) {
62 flags
&= ~LIBNDR_FLAG_STR_CHARLEN
;
65 switch (flags
& LIBNDR_STRING_FLAGS
) {
66 case LIBNDR_FLAG_STR_LEN4
|LIBNDR_FLAG_STR_SIZE4
:
67 case LIBNDR_FLAG_STR_LEN4
|LIBNDR_FLAG_STR_SIZE4
|LIBNDR_FLAG_STR_NOTERM
:
68 NDR_CHECK(ndr_pull_uint32(ndr
, NDR_SCALARS
, &len1
));
69 NDR_CHECK(ndr_pull_uint32(ndr
, NDR_SCALARS
, &ofs
));
71 return ndr_pull_error(ndr
, NDR_ERR_STRING
, "non-zero array offset with string flags 0x%x\n",
72 ndr
->flags
& LIBNDR_STRING_FLAGS
);
74 NDR_CHECK(ndr_pull_uint32(ndr
, NDR_SCALARS
, &len2
));
76 return ndr_pull_error(ndr
, NDR_ERR_STRING
,
77 "Bad string lengths len1=%u ofs=%u len2=%u\n",
80 NDR_PULL_NEED_BYTES(ndr
, (len2
+ c_len_term
)*byte_mul
);
82 as
= talloc_strdup(ndr
->current_mem_ctx
, "");
84 ret
= convert_string_talloc_convenience(ndr
->current_mem_ctx
,
85 ndr
->iconv_convenience
, chset
, CH_UNIX
,
86 ndr
->data
+ndr
->offset
,
87 (len2
+ c_len_term
)*byte_mul
,
90 return ndr_pull_error(ndr
, NDR_ERR_CHARCNV
,
91 "Bad character conversion");
94 NDR_CHECK(ndr_pull_advance(ndr
, (len2
+ c_len_term
)*byte_mul
));
97 DEBUG(6,("len1[%u] != len2[%u] '%s'\n", len1
, len2
, as
));
100 /* this is a way of detecting if a string is sent with the wrong
102 if (ndr
->flags
& LIBNDR_FLAG_STR_NOTERM
) {
103 if (strlen(as
) < (len2
+ c_len_term
)) {
104 DEBUG(6,("short string '%s'\n", as
));
107 if (strlen(as
) == (len2
+ c_len_term
)) {
108 DEBUG(6,("long string '%s'\n", as
));
114 case LIBNDR_FLAG_STR_SIZE4
:
115 case LIBNDR_FLAG_STR_SIZE4
|LIBNDR_FLAG_STR_NOTERM
:
116 NDR_CHECK(ndr_pull_uint32(ndr
, NDR_SCALARS
, &len1
));
117 NDR_PULL_NEED_BYTES(ndr
, (len1
+ c_len_term
)*byte_mul
);
119 as
= talloc_strdup(ndr
->current_mem_ctx
, "");
121 ret
= convert_string_talloc_convenience(ndr
->current_mem_ctx
,
122 ndr
->iconv_convenience
,
124 ndr
->data
+ndr
->offset
,
125 (len1
+ c_len_term
)*byte_mul
,
126 (void **)&as
, false);
128 return ndr_pull_error(ndr
, NDR_ERR_CHARCNV
,
129 "Bad character conversion");
132 NDR_CHECK(ndr_pull_advance(ndr
, (len1
+ c_len_term
)*byte_mul
));
134 /* this is a way of detecting if a string is sent with the wrong
136 if (ndr
->flags
& LIBNDR_FLAG_STR_NOTERM
) {
137 if (strlen(as
) < (len1
+ c_len_term
)) {
138 DEBUG(6,("short string '%s'\n", as
));
141 if (strlen(as
) == (len1
+ c_len_term
)) {
142 DEBUG(6,("long string '%s'\n", as
));
148 case LIBNDR_FLAG_STR_LEN4
:
149 case LIBNDR_FLAG_STR_LEN4
|LIBNDR_FLAG_STR_NOTERM
:
150 NDR_CHECK(ndr_pull_uint32(ndr
, NDR_SCALARS
, &ofs
));
152 return ndr_pull_error(ndr
, NDR_ERR_STRING
, "non-zero array offset with string flags 0x%x\n",
153 ndr
->flags
& LIBNDR_STRING_FLAGS
);
155 NDR_CHECK(ndr_pull_uint32(ndr
, NDR_SCALARS
, &len1
));
156 NDR_PULL_NEED_BYTES(ndr
, (len1
+ c_len_term
)*byte_mul
);
158 as
= talloc_strdup(ndr
->current_mem_ctx
, "");
160 ret
= convert_string_talloc_convenience(ndr
->current_mem_ctx
,
161 ndr
->iconv_convenience
,
163 ndr
->data
+ndr
->offset
,
164 (len1
+ c_len_term
)*byte_mul
,
165 (void **)&as
, false);
167 return ndr_pull_error(ndr
, NDR_ERR_CHARCNV
,
168 "Bad character conversion");
171 NDR_CHECK(ndr_pull_advance(ndr
, (len1
+ c_len_term
)*byte_mul
));
173 /* this is a way of detecting if a string is sent with the wrong
175 if (ndr
->flags
& LIBNDR_FLAG_STR_NOTERM
) {
176 if (strlen(as
) < (len1
+ c_len_term
)) {
177 DEBUG(6,("short string '%s'\n", as
));
180 if (strlen(as
) == (len1
+ c_len_term
)) {
181 DEBUG(6,("long string '%s'\n", as
));
188 case LIBNDR_FLAG_STR_SIZE2
:
189 case LIBNDR_FLAG_STR_SIZE2
|LIBNDR_FLAG_STR_NOTERM
:
190 NDR_CHECK(ndr_pull_uint16(ndr
, NDR_SCALARS
, &len3
));
191 NDR_PULL_NEED_BYTES(ndr
, (len3
+ c_len_term
)*byte_mul
);
193 as
= talloc_strdup(ndr
->current_mem_ctx
, "");
195 ret
= convert_string_talloc_convenience(ndr
->current_mem_ctx
,
196 ndr
->iconv_convenience
,
198 ndr
->data
+ndr
->offset
,
199 (len3
+ c_len_term
)*byte_mul
,
200 (void **)&as
, false);
202 return ndr_pull_error(ndr
, NDR_ERR_CHARCNV
,
203 "Bad character conversion");
206 NDR_CHECK(ndr_pull_advance(ndr
, (len3
+ c_len_term
)*byte_mul
));
208 /* this is a way of detecting if a string is sent with the wrong
210 if (ndr
->flags
& LIBNDR_FLAG_STR_NOTERM
) {
211 if (strlen(as
) < (len3
+ c_len_term
)) {
212 DEBUG(6,("short string '%s'\n", as
));
215 if (strlen(as
) == (len3
+ c_len_term
)) {
216 DEBUG(6,("long string '%s'\n", as
));
222 case LIBNDR_FLAG_STR_SIZE2
|LIBNDR_FLAG_STR_NOTERM
|LIBNDR_FLAG_STR_BYTESIZE
:
223 NDR_CHECK(ndr_pull_uint16(ndr
, NDR_SCALARS
, &len3
));
224 NDR_PULL_NEED_BYTES(ndr
, len3
);
226 as
= talloc_strdup(ndr
->current_mem_ctx
, "");
228 ret
= convert_string_talloc_convenience(ndr
->current_mem_ctx
,
229 ndr
->iconv_convenience
,
231 ndr
->data
+ndr
->offset
,
233 (void **)&as
, false);
235 return ndr_pull_error(ndr
, NDR_ERR_CHARCNV
,
236 "Bad character conversion");
239 NDR_CHECK(ndr_pull_advance(ndr
, len3
));
243 case LIBNDR_FLAG_STR_NULLTERM
:
245 len1
= ascii_len_n((const char *)(ndr
->data
+ndr
->offset
), ndr
->data_size
- ndr
->offset
);
247 len1
= utf16_len_n(ndr
->data
+ndr
->offset
, ndr
->data_size
- ndr
->offset
);
249 ret
= convert_string_talloc_convenience(ndr
->current_mem_ctx
,
250 ndr
->iconv_convenience
, chset
, CH_UNIX
,
251 ndr
->data
+ndr
->offset
,
253 (void **)&as
, false);
255 return ndr_pull_error(ndr
, NDR_ERR_CHARCNV
,
256 "Bad character conversion");
258 NDR_CHECK(ndr_pull_advance(ndr
, len1
));
262 case LIBNDR_FLAG_STR_NOTERM
:
263 if (!(ndr
->flags
& LIBNDR_FLAG_REMAINING
)) {
264 return ndr_pull_error(ndr
, NDR_ERR_STRING
, "Bad string flags 0x%x (missing NDR_REMAINING)\n",
265 ndr
->flags
& LIBNDR_STRING_FLAGS
);
268 len1
= ndr
->data_size
- ndr
->offset
;
270 NDR_PULL_NEED_BYTES(ndr
, len1
);
272 as
= talloc_strdup(ndr
->current_mem_ctx
, "");
274 ret
= convert_string_talloc_convenience(ndr
->current_mem_ctx
,
275 ndr
->iconv_convenience
,
277 ndr
->data
+ndr
->offset
,
279 (void **)&as
, false);
281 return ndr_pull_error(ndr
, NDR_ERR_CHARCNV
,
282 "Bad character conversion");
285 NDR_CHECK(ndr_pull_advance(ndr
, len1
));
291 return ndr_pull_error(ndr
, NDR_ERR_STRING
, "Bad string flags 0x%x\n",
292 ndr
->flags
& LIBNDR_STRING_FLAGS
);
295 return NDR_ERR_SUCCESS
;
300 push a general string onto the wire
302 _PUBLIC_
enum ndr_err_code
ndr_push_string(struct ndr_push
*ndr
, int ndr_flags
, const char *s
)
304 ssize_t s_len
, c_len
, d_len
;
305 int chset
= CH_UTF16
;
306 unsigned flags
= ndr
->flags
;
307 unsigned byte_mul
= 2;
308 uint8_t *dest
= NULL
;
310 if (!(ndr_flags
& NDR_SCALARS
)) {
311 return NDR_ERR_SUCCESS
;
318 s_len
= s
?strlen(s
):0;
320 if (flags
& LIBNDR_FLAG_STR_ASCII
) {
323 flags
&= ~LIBNDR_FLAG_STR_ASCII
;
326 if (flags
& LIBNDR_FLAG_STR_UTF8
) {
329 flags
&= ~LIBNDR_FLAG_STR_UTF8
;
332 flags
&= ~LIBNDR_FLAG_STR_CONFORMANT
;
334 if (!(flags
& LIBNDR_FLAG_STR_NOTERM
)) {
337 d_len
= convert_string_talloc_convenience(ndr
, ndr
->iconv_convenience
, CH_UNIX
, chset
, s
, s_len
, (void **)&dest
, false);
339 return ndr_push_error(ndr
, NDR_ERR_CHARCNV
,
340 "Bad character conversion");
343 if (flags
& LIBNDR_FLAG_STR_BYTESIZE
) {
345 flags
&= ~LIBNDR_FLAG_STR_BYTESIZE
;
346 } else if (flags
& LIBNDR_FLAG_STR_CHARLEN
) {
347 c_len
= (d_len
/ byte_mul
)-1;
348 flags
&= ~LIBNDR_FLAG_STR_CHARLEN
;
350 c_len
= d_len
/ byte_mul
;
353 switch ((flags
& LIBNDR_STRING_FLAGS
) & ~LIBNDR_FLAG_STR_NOTERM
) {
354 case LIBNDR_FLAG_STR_LEN4
|LIBNDR_FLAG_STR_SIZE4
:
355 NDR_CHECK(ndr_push_uint32(ndr
, NDR_SCALARS
, c_len
));
356 NDR_CHECK(ndr_push_uint32(ndr
, NDR_SCALARS
, 0));
357 NDR_CHECK(ndr_push_uint32(ndr
, NDR_SCALARS
, c_len
));
358 NDR_CHECK(ndr_push_bytes(ndr
, dest
, d_len
));
361 case LIBNDR_FLAG_STR_LEN4
:
362 NDR_CHECK(ndr_push_uint32(ndr
, NDR_SCALARS
, 0));
363 NDR_CHECK(ndr_push_uint32(ndr
, NDR_SCALARS
, c_len
));
364 NDR_CHECK(ndr_push_bytes(ndr
, dest
, d_len
));
367 case LIBNDR_FLAG_STR_SIZE4
:
368 NDR_CHECK(ndr_push_uint32(ndr
, NDR_SCALARS
, c_len
));
369 NDR_CHECK(ndr_push_bytes(ndr
, dest
, d_len
));
372 case LIBNDR_FLAG_STR_SIZE2
:
373 NDR_CHECK(ndr_push_uint16(ndr
, NDR_SCALARS
, c_len
));
374 NDR_CHECK(ndr_push_bytes(ndr
, dest
, d_len
));
377 case LIBNDR_FLAG_STR_NULLTERM
:
378 NDR_CHECK(ndr_push_bytes(ndr
, dest
, d_len
));
382 if (ndr
->flags
& LIBNDR_FLAG_REMAINING
) {
383 NDR_CHECK(ndr_push_bytes(ndr
, dest
, d_len
));
387 return ndr_push_error(ndr
, NDR_ERR_STRING
, "Bad string flags 0x%x\n",
388 ndr
->flags
& LIBNDR_STRING_FLAGS
);
393 return NDR_ERR_SUCCESS
;
397 push a general string onto the wire
399 _PUBLIC_
size_t ndr_string_array_size(struct ndr_push
*ndr
, const char *s
)
402 unsigned flags
= ndr
->flags
;
403 unsigned byte_mul
= 2;
404 unsigned c_len_term
= 1;
406 c_len
= s
?strlen_m(s
):0;
408 if (flags
& (LIBNDR_FLAG_STR_ASCII
|LIBNDR_FLAG_STR_UTF8
)) {
412 if (flags
& LIBNDR_FLAG_STR_NOTERM
) {
416 c_len
= c_len
+ c_len_term
;
418 if (flags
& LIBNDR_FLAG_STR_BYTESIZE
) {
419 c_len
= c_len
* byte_mul
;
425 _PUBLIC_
void ndr_print_string(struct ndr_print
*ndr
, const char *name
, const char *s
)
428 ndr
->print(ndr
, "%-25s: '%s'", name
, s
);
430 ndr
->print(ndr
, "%-25s: NULL", name
);
434 _PUBLIC_
uint32_t ndr_size_string(int ret
, const char * const* string
, int flags
)
436 /* FIXME: Is this correct for all strings ? */
437 if(!(*string
)) return ret
;
438 return ret
+strlen(*string
)+1;
442 pull a general string array from the wire
444 _PUBLIC_
enum ndr_err_code
ndr_pull_string_array(struct ndr_pull
*ndr
, int ndr_flags
, const char ***_a
)
446 const char **a
= NULL
;
448 unsigned flags
= ndr
->flags
;
449 unsigned saved_flags
= ndr
->flags
;
451 if (!(ndr_flags
& NDR_SCALARS
)) {
452 return NDR_ERR_SUCCESS
;
455 switch (flags
& LIBNDR_STRING_FLAGS
) {
456 case LIBNDR_FLAG_STR_NULLTERM
:
458 * here the strings are null terminated
459 * but also the array is null terminated
461 for (count
= 0;; count
++) {
463 const char *s
= NULL
;
464 a
= talloc_realloc(ndr
->current_mem_ctx
, a
, const char *, count
+ 2);
465 NDR_ERR_HAVE_NO_MEMORY(a
);
469 tmp_ctx
= ndr
->current_mem_ctx
;
470 ndr
->current_mem_ctx
= a
;
471 NDR_CHECK(ndr_pull_string(ndr
, ndr_flags
, &s
));
472 ndr
->current_mem_ctx
= tmp_ctx
;
473 if (strcmp("", s
)==0) {
484 case LIBNDR_FLAG_STR_NOTERM
:
485 if (!(ndr
->flags
& LIBNDR_FLAG_REMAINING
)) {
486 return ndr_pull_error(ndr
, NDR_ERR_STRING
, "Bad string flags 0x%x (missing NDR_REMAINING)\n",
487 ndr
->flags
& LIBNDR_STRING_FLAGS
);
490 * here the strings are not null terminated
491 * but serarated by a null terminator
493 * which means the same as:
494 * very string is null terminated exept the last
495 * string is terminated by the end of the buffer
497 * as LIBNDR_FLAG_STR_NULLTERM also end at the end
498 * of the buffer, we can pull each string with this flag
500 ndr
->flags
&= ~(LIBNDR_FLAG_STR_NOTERM
|LIBNDR_FLAG_REMAINING
);
501 ndr
->flags
|= LIBNDR_FLAG_STR_NULLTERM
;
503 for (count
= 0; ((ndr
->data_size
- ndr
->offset
) > 0); count
++) {
505 const char *s
= NULL
;
506 a
= talloc_realloc(ndr
->current_mem_ctx
, a
, const char *, count
+ 2);
507 NDR_ERR_HAVE_NO_MEMORY(a
);
511 tmp_ctx
= ndr
->current_mem_ctx
;
512 ndr
->current_mem_ctx
= a
;
513 NDR_CHECK(ndr_pull_string(ndr
, ndr_flags
, &s
));
514 ndr
->current_mem_ctx
= tmp_ctx
;
522 return ndr_pull_error(ndr
, NDR_ERR_STRING
, "Bad string flags 0x%x\n",
523 ndr
->flags
& LIBNDR_STRING_FLAGS
);
526 ndr
->flags
= saved_flags
;
527 return NDR_ERR_SUCCESS
;
531 push a general string array onto the wire
533 _PUBLIC_
enum ndr_err_code
ndr_push_string_array(struct ndr_push
*ndr
, int ndr_flags
, const char **a
)
536 unsigned flags
= ndr
->flags
;
537 unsigned saved_flags
= ndr
->flags
;
539 if (!(ndr_flags
& NDR_SCALARS
)) {
540 return NDR_ERR_SUCCESS
;
543 switch (flags
& LIBNDR_STRING_FLAGS
) {
544 case LIBNDR_FLAG_STR_NULLTERM
:
545 for (count
= 0; a
&& a
[count
]; count
++) {
546 NDR_CHECK(ndr_push_string(ndr
, ndr_flags
, a
[count
]));
549 NDR_CHECK(ndr_push_string(ndr
, ndr_flags
, ""));
552 case LIBNDR_FLAG_STR_NOTERM
:
553 if (!(ndr
->flags
& LIBNDR_FLAG_REMAINING
)) {
554 return ndr_push_error(ndr
, NDR_ERR_STRING
, "Bad string flags 0x%x (missing NDR_REMAINING)\n",
555 ndr
->flags
& LIBNDR_STRING_FLAGS
);
558 for (count
= 0; a
&& a
[count
]; count
++) {
560 ndr
->flags
&= ~(LIBNDR_FLAG_STR_NOTERM
|LIBNDR_FLAG_REMAINING
);
561 ndr
->flags
|= LIBNDR_FLAG_STR_NULLTERM
;
562 NDR_CHECK(ndr_push_string(ndr
, ndr_flags
, ""));
563 ndr
->flags
= saved_flags
;
565 NDR_CHECK(ndr_push_string(ndr
, ndr_flags
, a
[count
]));
571 return ndr_push_error(ndr
, NDR_ERR_STRING
, "Bad string flags 0x%x\n",
572 ndr
->flags
& LIBNDR_STRING_FLAGS
);
575 ndr
->flags
= saved_flags
;
576 return NDR_ERR_SUCCESS
;
579 _PUBLIC_
void ndr_print_string_array(struct ndr_print
*ndr
, const char *name
, const char **a
)
584 for (count
= 0; a
&& a
[count
]; count
++) {}
586 ndr
->print(ndr
, "%s: ARRAY(%d)", name
, count
);
588 for (i
=0;i
<count
;i
++) {
590 if (asprintf(&idx
, "[%d]", i
) != -1) {
591 ndr_print_string(ndr
, idx
, a
[i
]);
598 _PUBLIC_
size_t ndr_size_string_array(const char **a
, uint32_t count
, int flags
)
603 switch (flags
& LIBNDR_STRING_FLAGS
) {
604 case LIBNDR_FLAG_STR_NULLTERM
:
605 for (i
= 0; i
< count
; i
++) {
606 size
+= strlen_m_term(a
[i
]);
609 case LIBNDR_FLAG_STR_NOTERM
:
610 for (i
= 0; i
< count
; i
++) {
611 size
+= strlen_m(a
[i
]);
622 * Return number of elements in a string including the last (zeroed) element
624 _PUBLIC_
uint32_t ndr_string_length(const void *_var
, uint32_t element_size
)
627 uint8_t zero
[4] = {0,0,0,0};
628 const char *var
= (const char *)_var
;
630 for (i
= 0; memcmp(var
+i
*element_size
,zero
,element_size
) != 0; i
++);
635 _PUBLIC_
enum ndr_err_code
ndr_check_string_terminator(struct ndr_pull
*ndr
, uint32_t count
, uint32_t element_size
)
638 uint32_t save_offset
;
640 save_offset
= ndr
->offset
;
641 ndr_pull_advance(ndr
, (count
- 1) * element_size
);
642 NDR_PULL_NEED_BYTES(ndr
, element_size
);
644 for (i
= 0; i
< element_size
; i
++) {
645 if (ndr
->data
[ndr
->offset
+i
] != 0) {
646 ndr
->offset
= save_offset
;
648 return ndr_pull_error(ndr
, NDR_ERR_ARRAY_SIZE
, "String terminator not present or outside string boundaries");
652 ndr
->offset
= save_offset
;
654 return NDR_ERR_SUCCESS
;
657 _PUBLIC_
enum ndr_err_code
ndr_pull_charset(struct ndr_pull
*ndr
, int ndr_flags
, const char **var
, uint32_t length
, uint8_t byte_mul
, charset_t chset
)
661 *var
= talloc_strdup(ndr
->current_mem_ctx
, "");
662 return NDR_ERR_SUCCESS
;
665 if (NDR_BE(ndr
) && chset
== CH_UTF16
) {
669 NDR_PULL_NEED_BYTES(ndr
, length
*byte_mul
);
671 ret
= convert_string_talloc_convenience(ndr
->current_mem_ctx
,
672 ndr
->iconv_convenience
,
674 ndr
->data
+ndr
->offset
,
676 discard_const_p(void *, var
), false);
678 return ndr_pull_error(ndr
, NDR_ERR_CHARCNV
,
679 "Bad character conversion");
681 NDR_CHECK(ndr_pull_advance(ndr
, length
*byte_mul
));
683 return NDR_ERR_SUCCESS
;
686 _PUBLIC_
enum ndr_err_code
ndr_push_charset(struct ndr_push
*ndr
, int ndr_flags
, const char *var
, uint32_t length
, uint8_t byte_mul
, charset_t chset
)
688 ssize_t ret
, required
;
690 if (NDR_BE(ndr
) && chset
== CH_UTF16
) {
694 required
= byte_mul
* length
;
696 NDR_PUSH_NEED_BYTES(ndr
, required
);
697 ret
= convert_string_convenience(ndr
->iconv_convenience
, CH_UNIX
, chset
,
699 ndr
->data
+ndr
->offset
, required
, false);
701 return ndr_push_error(ndr
, NDR_ERR_CHARCNV
,
702 "Bad character conversion");
705 /* Make sure the remaining part of the string is filled with zeroes */
706 if (ret
< required
) {
707 memset(ndr
->data
+ndr
->offset
+ret
, 0, required
-ret
);
710 ndr
->offset
+= required
;
712 return NDR_ERR_SUCCESS
;
715 /* Return number of elements in a string in the specified charset */
716 _PUBLIC_
uint32_t ndr_charset_length(const void *var
, charset_t chset
)
718 /* FIXME: Treat special chars special here, taking chset into account */
719 /* Also include 0 byte */
720 return strlen((const char *)var
)+1;