5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2008 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
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.
23 /************************** Types and definitions ***************************/
25 /* Check that buffer has enough room to format data in it, if not
27 #define FORMAT_HAS_SPACE(s, b, req) \
29 if (silc_unlikely(!silc_buffer_senlarge(s, b, req))) \
34 /* Check that there is data to be unformatted */
35 #define UNFORMAT_HAS_SPACE(b, req) \
37 if (silc_unlikely(req > silc_buffer_len(b))) { \
38 silc_set_errno(SILC_ERR_OVERFLOW); \
41 if (silc_unlikely((req + 1) <= 0)) { \
42 silc_set_errno(SILC_ERR_UNDERFLOW); \
48 /******************************* Formatting *********************************/
50 int silc_buffer_sformat_vp_i(SilcStack stack, SilcBuffer dst, va_list ap,
55 SilcBool advance = FALSE;
57 /* Parse the arguments by formatting type. */
59 fmt = va_arg(ap, SilcParam);
61 SILC_LOG_DEBUG(("Buffer format type %d", fmt));
66 SilcBufferFormatFunc func;
71 func = va_arg(ap, SilcBufferFormatFunc);
72 val = va_arg(ap, void *);
73 context = va_arg(ap, void *);
78 tmp_len = func(stack, dst, val, context);
82 silc_buffer_pull(dst, tmp_len);
88 case SILC_PARAM_REGEX:
90 const char *regex = va_arg(ap, char *);
91 SilcBufferRegexFlags rflags = va_arg(ap, SilcUInt32);
92 SilcBufferStruct match, saved;
93 SilcBool match_all = (rflags & SILC_STR_REGEX_ALL) != 0;
94 SilcBool match_nl = (rflags & SILC_STR_REGEX_NL) != 0;
96 unsigned char *saved_incl = NULL;
97 int matched = 0, ret_len;
106 memset(&saved, 0, sizeof(saved));
110 /* Match for '\n' in the buffer. If not found, treat as line
111 without '\n' (buffer has only one line, or this is last line). */
113 if (silc_regex_buffer(dst, "\n", &match, NULL))
114 dst->tail = match.tail;
119 ret = silc_regex_buffer(dst, regex, &match, NULL);
120 ret ^= (rflags & SILC_STR_REGEX_NOT) != 0;
122 if (!matched && rflags & SILC_STR_REGEX_MISMATCH) {
123 silc_set_errno(SILC_ERR_NOT_FOUND);
130 if (rflags & SILC_STR_REGEX_NOT)
133 if (!(rflags & SILC_STR_REGEX_NO_ADVANCE)) {
134 /* Advance buffer after match */
135 flen += (match.data - dst->data);
136 if (!silc_buffer_pull(dst, (match.data - dst->data)))
140 if (rflags & SILC_STR_REGEX_INCLUSIVE) {
141 saved_incl = dst->tail;
142 dst->tail = match.tail;
145 /* Recursively format */
146 silc_va_copy(cp, ap);
147 ret_len = silc_buffer_sformat_vp_i(stack, dst, cp, TRUE);
152 if (rflags & SILC_STR_REGEX_INCLUSIVE)
153 dst->tail = saved_incl;
155 /* Advance buffer after formatting */
157 if (!silc_buffer_pull(dst, ret_len))
160 if (match_all && (!match_nl || silc_buffer_len(dst) > 1))
165 /* Go to next line, it is at the end of the data area. Adjust
166 the tail area of the target buffer to show rest of the buffer. */
167 flen += (dst->tail - dst->data);
168 if (!silc_buffer_pull(dst, (dst->tail - dst->data)))
170 if (!silc_buffer_pull_tail(dst, (saved.tail - dst->tail)))
173 if (silc_buffer_len(dst) > 0)
177 /* Skip to the next SILC_PARAM_END */
178 silc_buffer_sformat_vp_i(NULL, NULL, ap, FALSE);
182 case SILC_PARAM_UI8_STRING:
183 case SILC_PARAM_UI16_STRING:
184 case SILC_PARAM_UI32_STRING:
185 case SILC_PARAM_UI8_STRING | SILC_PARAM_ALLOC:
186 case SILC_PARAM_UI16_STRING | SILC_PARAM_ALLOC:
187 case SILC_PARAM_UI32_STRING | SILC_PARAM_ALLOC:
189 char *x = va_arg(ap, char *);
190 SilcUInt32 tmp_len = x ? strlen(x) : 0;
196 FORMAT_HAS_SPACE(stack, dst, tmp_len);
197 silc_buffer_put(dst, (unsigned char *)x, tmp_len);
198 silc_buffer_pull(dst, tmp_len);
203 case SILC_PARAM_UI8_NSTRING:
204 case SILC_PARAM_UI16_NSTRING:
205 case SILC_PARAM_UI32_NSTRING:
206 case SILC_PARAM_UICHAR:
207 case SILC_PARAM_UI8_NSTRING | SILC_PARAM_ALLOC:
208 case SILC_PARAM_UI16_NSTRING | SILC_PARAM_ALLOC:
209 case SILC_PARAM_UI32_NSTRING | SILC_PARAM_ALLOC:
210 case SILC_PARAM_UICHAR | SILC_PARAM_ALLOC:
212 unsigned char *x = va_arg(ap, unsigned char *);
213 SilcUInt32 tmp_len = va_arg(ap, SilcUInt32);
219 FORMAT_HAS_SPACE(stack, dst, tmp_len);
220 silc_buffer_put(dst, x, tmp_len);
221 silc_buffer_pull(dst, tmp_len);
226 case SILC_PARAM_UINT8:
228 unsigned char x = (unsigned char)va_arg(ap, int);
233 FORMAT_HAS_SPACE(stack, dst, 1);
234 silc_buffer_put(dst, &x, 1);
235 silc_buffer_pull(dst, 1);
239 case SILC_PARAM_UINT16:
242 SilcUInt16 x = (SilcUInt16)va_arg(ap, int);
247 FORMAT_HAS_SPACE(stack, dst, 2);
248 SILC_PUT16_MSB(x, xf);
249 silc_buffer_put(dst, xf, 2);
250 silc_buffer_pull(dst, 2);
254 case SILC_PARAM_UINT32:
257 SilcUInt32 x = va_arg(ap, SilcUInt32);
262 FORMAT_HAS_SPACE(stack, dst, 4);
263 SILC_PUT32_MSB(x, xf);
264 silc_buffer_put(dst, xf, 4);
265 silc_buffer_pull(dst, 4);
269 case SILC_PARAM_UINT64:
272 SilcUInt64 x = va_arg(ap, SilcUInt64);
277 FORMAT_HAS_SPACE(stack, dst, sizeof(SilcUInt64));
278 SILC_PUT64_MSB(x, xf);
279 silc_buffer_put(dst, xf, sizeof(SilcUInt64));
280 silc_buffer_pull(dst, sizeof(SilcUInt64));
284 case SILC_PARAM_SINT8:
286 char x = (char)va_arg(ap, int);
291 FORMAT_HAS_SPACE(stack, dst, 1);
292 silc_buffer_put(dst, (unsigned char *)&x, 1);
293 silc_buffer_pull(dst, 1);
297 case SILC_PARAM_SINT16:
300 SilcInt16 x = (SilcInt16)va_arg(ap, int);
305 FORMAT_HAS_SPACE(stack, dst, 2);
306 SILC_PUT16_MSB(x, xf);
307 silc_buffer_put(dst, xf, 2);
308 silc_buffer_pull(dst, 2);
312 case SILC_PARAM_SINT32:
315 SilcInt32 x = va_arg(ap, SilcInt32);
320 FORMAT_HAS_SPACE(stack, dst, 4);
321 SILC_PUT32_MSB(x, xf);
322 silc_buffer_put(dst, xf, 4);
323 silc_buffer_pull(dst, 4);
327 case SILC_PARAM_SINT64:
330 SilcInt64 x = va_arg(ap, SilcInt64);
335 FORMAT_HAS_SPACE(stack, dst, sizeof(SilcInt64));
336 SILC_PUT64_MSB(x, xf);
337 silc_buffer_put(dst, xf, sizeof(SilcInt64));
338 silc_buffer_pull(dst, sizeof(SilcInt64));
342 case SILC_PARAM_BUFFER:
343 case SILC_PARAM_BUFFER | SILC_PARAM_ALLOC:
345 SilcBuffer x = va_arg(ap, SilcBuffer);
351 if (x && silc_buffer_len(x)) {
352 FORMAT_HAS_SPACE(stack, dst, silc_buffer_len(x) + 4);
353 SILC_PUT32_MSB(silc_buffer_len(x), xf);
354 silc_buffer_put(dst, xf, 4);
355 silc_buffer_pull(dst, 4);
356 silc_buffer_put(dst, silc_buffer_data(x), silc_buffer_len(x));
357 silc_buffer_pull(dst, silc_buffer_len(x));
362 case SILC_PARAM_OFFSET:
364 int offst = va_arg(ap, int);
373 if (offst > silc_buffer_len(dst)) {
374 silc_set_errno(SILC_ERR_OVERFLOW);
377 silc_buffer_pull(dst, offst);
380 silc_buffer_push(dst, -(offst));
386 case SILC_PARAM_OFFSET_START:
389 if (!silc_buffer_push(dst, flen))
394 case SILC_PARAM_OFFSET_END:
397 flen += silc_buffer_len(dst);
398 silc_buffer_pull(dst, silc_buffer_len(dst));
401 case SILC_PARAM_ADVANCE:
412 SILC_LOG_DEBUG(("Bad buffer formatting type `%d'. Could not "
413 "format the data.", fmt));
414 silc_set_errno_reason(SILC_ERR_INVALID_ARGUMENT,
415 "Bad buffer formatting type %d", fmt);
422 SILC_LOG_DEBUG(("Error occured while formatting data"));
423 if (process && !advance)
424 silc_buffer_push(dst, flen);
428 /* Push the buffer back to where it belongs. */
429 if (process && !advance)
430 silc_buffer_push(dst, flen);
434 int silc_buffer_format(SilcBuffer dst, ...)
440 ret = silc_buffer_sformat_vp(NULL, dst, ap);
446 int silc_buffer_format_vp(SilcBuffer dst, va_list ap)
448 return silc_buffer_sformat_vp(NULL, dst, ap);
451 int silc_buffer_sformat(SilcStack stack, SilcBuffer dst, ...)
457 ret = silc_buffer_sformat_vp(stack, dst, ap);
463 int silc_buffer_sformat_vp(SilcStack stack, SilcBuffer dst, va_list ap)
465 return silc_buffer_sformat_vp_i(stack, dst, ap, TRUE);
468 /****************************** Unformatting ********************************/
470 int silc_buffer_sunformat_vp_i(SilcStack stack, SilcBuffer src, va_list ap,
474 unsigned char *start_ptr = src->data;
476 SilcBool advance = FALSE;
478 /* Parse the arguments by formatting type. */
480 fmt = va_arg(ap, SilcParam);
482 SILC_LOG_DEBUG(("Buffer unformat type %d", fmt));
485 case SILC_PARAM_FUNC:
487 SilcBufferUnformatFunc func;
491 func = va_arg(ap, SilcBufferUnformatFunc);
492 val = va_arg(ap, void **);
493 context = va_arg(ap, void *);
498 tmp_len = func(stack, src, val, context);
502 UNFORMAT_HAS_SPACE(src, tmp_len);
503 silc_buffer_pull(src, tmp_len);
508 case SILC_PARAM_REGEX:
510 const char *regex = va_arg(ap, char *);
511 SilcBufferRegexFlags rflags = va_arg(ap, SilcUInt32);
512 SilcBufferStruct match, saved;
513 SilcBool match_all = (rflags & SILC_STR_REGEX_ALL) != 0;
514 SilcBool match_nl = (rflags & SILC_STR_REGEX_NL) != 0;
516 unsigned char *saved_incl = NULL;
517 int matched = 0, ret_len;
526 memset(&saved, 0, sizeof(saved));
530 /* Match for '\n' in the buffer. If not found, treat as line
531 without '\n' (buffer has only one line, or this is last line). */
533 if (silc_regex_buffer(src, "\n", &match, NULL))
534 src->tail = match.tail;
539 ret = silc_regex_buffer(src, regex, &match, NULL);
540 ret ^= (rflags & SILC_STR_REGEX_NOT) != 0;
542 if (!matched && rflags & SILC_STR_REGEX_MISMATCH) {
543 silc_set_errno(SILC_ERR_NOT_FOUND);
550 if (rflags & SILC_STR_REGEX_NOT)
553 if (!(rflags & SILC_STR_REGEX_NO_ADVANCE)) {
554 /* Advance buffer after match */
555 UNFORMAT_HAS_SPACE(src, (match.data - src->data));
556 if (!silc_buffer_pull(src, (match.data - src->data)))
560 if (rflags & SILC_STR_REGEX_INCLUSIVE) {
561 saved_incl = src->tail;
562 src->tail = match.tail;
565 /* Recursively format */
566 silc_va_copy(cp, ap);
567 ret_len = silc_buffer_sunformat_vp_i(stack, src, cp, TRUE);
572 if (rflags & SILC_STR_REGEX_INCLUSIVE)
573 src->tail = saved_incl;
575 /* Advance buffer after formatting */
576 UNFORMAT_HAS_SPACE(src, ret_len);
577 if (!silc_buffer_pull(src, ret_len))
580 if (match_all && (!match_nl || silc_buffer_len(src) > 1))
585 /* Go to next line, it is at the end of the data area. Adjust
586 the tail area of the target buffer to show rest of the buffer. */
587 UNFORMAT_HAS_SPACE(src, src->tail - src->data);
588 if (!silc_buffer_pull(src, (src->tail - src->data)))
590 if (!silc_buffer_pull_tail(src, (saved.tail - src->tail)))
593 if (silc_buffer_len(src) > 0)
597 /* Skip to the next SILC_PARAM_END */
598 silc_buffer_sunformat_vp_i(NULL, src, ap, FALSE);
602 case SILC_PARAM_UICHAR:
604 unsigned char **x = va_arg(ap, unsigned char **);
605 SilcUInt32 len2 = va_arg(ap, SilcUInt32);
610 UNFORMAT_HAS_SPACE(src, len2);
611 if (silc_likely(len2 && x))
613 silc_buffer_pull(src, len2);
617 case SILC_PARAM_UICHAR | SILC_PARAM_ALLOC:
619 unsigned char **x = va_arg(ap, unsigned char **);
620 SilcUInt32 len2 = va_arg(ap, SilcUInt32);
625 UNFORMAT_HAS_SPACE(src, len2);
626 if (silc_likely(len2 && x)) {
627 *x = silc_scalloc(stack, len2 + 1, sizeof(unsigned char));
628 memcpy(*x, src->data, len2);
630 silc_buffer_pull(src, len2);
634 case SILC_PARAM_UINT8:
636 unsigned char *x = va_arg(ap, unsigned char *);
641 UNFORMAT_HAS_SPACE(src, 1);
644 silc_buffer_pull(src, 1);
648 case SILC_PARAM_UINT16:
650 SilcUInt16 *x = va_arg(ap, SilcUInt16 *);
655 UNFORMAT_HAS_SPACE(src, 2);
657 SILC_GET16_MSB(*x, src->data);
658 silc_buffer_pull(src, 2);
662 case SILC_PARAM_UINT32:
664 SilcUInt32 *x = va_arg(ap, SilcUInt32 *);
669 UNFORMAT_HAS_SPACE(src, 4);
671 SILC_GET32_MSB(*x, src->data);
672 silc_buffer_pull(src, 4);
676 case SILC_PARAM_UINT64:
678 SilcUInt64 *x = va_arg(ap, SilcUInt64 *);
683 UNFORMAT_HAS_SPACE(src, sizeof(SilcUInt64));
685 SILC_GET64_MSB(*x, src->data);
686 silc_buffer_pull(src, sizeof(SilcUInt64));
690 case SILC_PARAM_SINT8:
692 char *x = va_arg(ap, char *);
697 UNFORMAT_HAS_SPACE(src, 1);
700 silc_buffer_pull(src, 1);
704 case SILC_PARAM_SINT16:
706 SilcInt16 *x = va_arg(ap, SilcInt16 *);
711 UNFORMAT_HAS_SPACE(src, 2);
713 SILC_GET16_MSB(*x, src->data);
714 silc_buffer_pull(src, 2);
718 case SILC_PARAM_SINT32:
720 SilcInt32 *x = va_arg(ap, SilcInt32 *);
725 UNFORMAT_HAS_SPACE(src, 4);
727 SILC_GET32_MSB(*x, src->data);
728 silc_buffer_pull(src, 4);
732 case SILC_PARAM_SINT64:
734 SilcInt64 *x = va_arg(ap, SilcInt64 *);
739 UNFORMAT_HAS_SPACE(src, sizeof(SilcInt64));
741 SILC_GET64_MSB(*x, src->data);
742 silc_buffer_pull(src, sizeof(SilcInt64));
746 case SILC_PARAM_UI8_STRING:
749 unsigned char **x = va_arg(ap, unsigned char **);
754 UNFORMAT_HAS_SPACE(src, 1);
755 len2 = (SilcUInt8)src->data[0];
756 silc_buffer_pull(src, 1);
757 UNFORMAT_HAS_SPACE(src, len2);
760 silc_buffer_pull(src, len2);
764 case SILC_PARAM_UI8_STRING | SILC_PARAM_ALLOC:
767 unsigned char **x = va_arg(ap, unsigned char **);
772 UNFORMAT_HAS_SPACE(src, 1);
773 len2 = (SilcUInt8)src->data[0];
774 silc_buffer_pull(src, 1);
775 UNFORMAT_HAS_SPACE(src, len2);
776 if (silc_likely(x && len2)) {
777 *x = silc_scalloc(stack, len2 + 1, sizeof(unsigned char));
778 memcpy(*x, src->data, len2);
780 silc_buffer_pull(src, len2);
784 case SILC_PARAM_UI16_STRING:
787 unsigned char **x = va_arg(ap, unsigned char **);
792 UNFORMAT_HAS_SPACE(src, 2);
793 SILC_GET16_MSB(len2, src->data);
794 silc_buffer_pull(src, 2);
795 UNFORMAT_HAS_SPACE(src, len2);
798 silc_buffer_pull(src, len2);
802 case SILC_PARAM_UI16_STRING | SILC_PARAM_ALLOC:
805 unsigned char **x = va_arg(ap, unsigned char **);
810 UNFORMAT_HAS_SPACE(src, 2);
811 SILC_GET16_MSB(len2, src->data);
812 silc_buffer_pull(src, 2);
813 UNFORMAT_HAS_SPACE(src, len2);
814 if (silc_likely(x && len2)) {
815 *x = silc_scalloc(stack, len2 + 1, sizeof(unsigned char));
816 memcpy(*x, src->data, len2);
818 silc_buffer_pull(src, len2);
822 case SILC_PARAM_UI32_STRING:
825 unsigned char **x = va_arg(ap, unsigned char **);
830 UNFORMAT_HAS_SPACE(src, 4);
831 SILC_GET32_MSB(len2, src->data);
832 silc_buffer_pull(src, 4);
833 UNFORMAT_HAS_SPACE(src, len2);
836 silc_buffer_pull(src, len2);
840 case SILC_PARAM_UI32_STRING | SILC_PARAM_ALLOC:
843 unsigned char **x = va_arg(ap, unsigned char **);
848 UNFORMAT_HAS_SPACE(src, 4);
849 SILC_GET32_MSB(len2, src->data);
850 silc_buffer_pull(src, 4);
851 UNFORMAT_HAS_SPACE(src, len2);
852 if (silc_likely(x && len2)) {
853 *x = silc_scalloc(stack, len2 + 1, sizeof(unsigned char));
854 memcpy(*x, src->data, len2);
856 silc_buffer_pull(src, len2);
860 case SILC_PARAM_UI8_NSTRING:
863 unsigned char **x = va_arg(ap, unsigned char **);
864 SilcUInt8 *len3 = va_arg(ap, SilcUInt8 *);
869 UNFORMAT_HAS_SPACE(src, 1);
870 len2 = (SilcUInt8)src->data[0];
871 silc_buffer_pull(src, 1);
872 UNFORMAT_HAS_SPACE(src, len2);
877 silc_buffer_pull(src, len2);
881 case SILC_PARAM_UI8_NSTRING | SILC_PARAM_ALLOC:
884 unsigned char **x = va_arg(ap, unsigned char **);
885 SilcUInt8 *len3 = va_arg(ap, SilcUInt8 *);
890 UNFORMAT_HAS_SPACE(src, 1);
891 len2 = (SilcUInt8)src->data[0];
892 silc_buffer_pull(src, 1);
893 UNFORMAT_HAS_SPACE(src, len2);
897 *x = silc_scalloc(stack, len2 + 1, sizeof(unsigned char));
898 memcpy(*x, src->data, len2);
900 silc_buffer_pull(src, len2);
904 case SILC_PARAM_UI16_NSTRING:
907 unsigned char **x = va_arg(ap, unsigned char **);
908 SilcUInt16 *len3 = va_arg(ap, SilcUInt16 *);
913 UNFORMAT_HAS_SPACE(src, 2);
914 SILC_GET16_MSB(len2, src->data);
915 silc_buffer_pull(src, 2);
916 UNFORMAT_HAS_SPACE(src, len2);
921 silc_buffer_pull(src, len2);
925 case SILC_PARAM_UI16_NSTRING | SILC_PARAM_ALLOC:
928 unsigned char **x = va_arg(ap, unsigned char **);
929 SilcUInt16 *len3 = va_arg(ap, SilcUInt16 *);
934 UNFORMAT_HAS_SPACE(src, 2);
935 SILC_GET16_MSB(len2, src->data);
936 silc_buffer_pull(src, 2);
937 UNFORMAT_HAS_SPACE(src, len2);
941 *x = silc_scalloc(stack, len2 + 1, sizeof(unsigned char));
942 memcpy(*x, src->data, len2);
944 silc_buffer_pull(src, len2);
948 case SILC_PARAM_UI32_NSTRING:
951 unsigned char **x = va_arg(ap, unsigned char **);
952 SilcUInt32 *len3 = va_arg(ap, SilcUInt32 *);
957 UNFORMAT_HAS_SPACE(src, 4);
958 SILC_GET32_MSB(len2, src->data);
959 silc_buffer_pull(src, 4);
960 UNFORMAT_HAS_SPACE(src, len2);
965 silc_buffer_pull(src, len2);
969 case SILC_PARAM_UI32_NSTRING | SILC_PARAM_ALLOC:
972 unsigned char **x = va_arg(ap, unsigned char **);
973 SilcUInt32 *len3 = va_arg(ap, SilcUInt32 *);
978 UNFORMAT_HAS_SPACE(src, 4);
979 SILC_GET32_MSB(len2, src->data);
980 silc_buffer_pull(src, 4);
981 UNFORMAT_HAS_SPACE(src, len2);
984 if (silc_likely(x && len2)) {
985 *x = silc_scalloc(stack, len2 + 1, sizeof(unsigned char));
986 memcpy(*x, src->data, len2);
988 silc_buffer_pull(src, len2);
992 case SILC_PARAM_BUFFER:
994 SilcBuffer x = va_arg(ap, SilcBuffer);
1000 UNFORMAT_HAS_SPACE(src, 4);
1001 SILC_GET32_MSB(len2, src->data);
1002 silc_buffer_pull(src, 4);
1003 UNFORMAT_HAS_SPACE(src, len2);
1004 silc_buffer_set(x, src->data, len2);
1005 silc_buffer_pull(src, len2);
1009 case SILC_PARAM_BUFFER | SILC_PARAM_ALLOC:
1011 SilcBuffer x = va_arg(ap, SilcBuffer);
1017 UNFORMAT_HAS_SPACE(src, 4);
1018 SILC_GET32_MSB(len2, src->data);
1019 silc_buffer_pull(src, 4);
1020 UNFORMAT_HAS_SPACE(src, len2);
1021 silc_buffer_sformat(stack, x,
1022 SILC_STR_DATA(src->data, len2),
1024 silc_buffer_pull(src, len2);
1028 case SILC_PARAM_OFFSET:
1030 int offst = va_arg(ap, int);
1039 UNFORMAT_HAS_SPACE(src, offst);
1040 silc_buffer_pull(src, offst);
1042 silc_buffer_push(src, -(offst));
1047 case SILC_PARAM_OFFSET_START:
1050 silc_buffer_push(src, (src->data - start_ptr));
1053 case SILC_PARAM_OFFSET_END:
1056 silc_buffer_pull(src, silc_buffer_len(src));
1059 case SILC_PARAM_ADVANCE:
1065 case SILC_PARAM_END:
1070 SILC_LOG_DEBUG(("Bad buffer formatting type `%d'. Could not "
1071 "format the data.", fmt));
1072 silc_set_errno_reason(SILC_ERR_INVALID_ARGUMENT,
1073 "Bad buffer formatting type %d", fmt);
1080 SILC_LOG_DEBUG(("Error occured while unformatting buffer, type %d", fmt));
1081 if (process && !advance) {
1082 len = src->data - start_ptr;
1083 silc_buffer_push(src, len);
1088 /* Push the buffer back to the start. */
1089 if (process && !advance) {
1090 len = src->data - start_ptr;
1091 silc_buffer_push(src, len);
1096 int silc_buffer_unformat(SilcBuffer src, ...)
1102 ret = silc_buffer_sunformat_vp(NULL, src, ap);
1108 int silc_buffer_unformat_vp(SilcBuffer src, va_list ap)
1110 return silc_buffer_sunformat_vp(NULL, src, ap);
1113 int silc_buffer_sunformat(SilcStack stack, SilcBuffer src, ...)
1119 ret = silc_buffer_sunformat_vp(stack, src, ap);
1125 int silc_buffer_sunformat_vp(SilcStack stack, SilcBuffer src, va_list ap)
1127 return silc_buffer_sunformat_vp_i(stack, src, ap, TRUE);
1130 /**************************** Utility functions *****************************/
1132 /* Formats strings into a buffer */
1134 int silc_buffer_strformat(SilcBuffer dst, ...)
1136 int len = silc_buffer_truelen(dst);
1137 int hlen = silc_buffer_headlen(dst);
1142 /* Parse the arguments by formatting type. */
1144 char *string = va_arg(va, char *);
1150 if (string == (char *)SILC_PARAM_END)
1153 slen = strlen(string);
1154 d = silc_realloc(dst->head, sizeof(*dst->head) * (slen + len + 1));
1155 if (silc_unlikely(!d))
1158 memcpy(dst->head + len, string, slen);
1160 dst->head[len] = '\0';
1163 SILC_LOG_DEBUG(("Error occured while formatting buffer"));
1168 dst->end = dst->head + len;
1169 dst->data = dst->head + hlen;
1170 dst->tail = dst->end;
1176 /* Formats strings into a buffer. Allocates memory from SilcStack. */
1178 int silc_buffer_sstrformat(SilcStack stack, SilcBuffer dst, ...)
1180 int len = silc_buffer_truelen(dst);
1181 int hlen = silc_buffer_headlen(dst);
1186 /* Parse the arguments by formatting type. */
1188 char *string = va_arg(va, char *);
1194 if (string == (char *)SILC_PARAM_END)
1197 slen = strlen(string);
1198 d = silc_srealloc(stack, len + 1, dst->head,
1199 sizeof(*dst->head) * (slen + len + 1));
1200 if (silc_unlikely(!d))
1203 memcpy(dst->head + len, string, slen);
1205 dst->head[len] = '\0';
1208 SILC_LOG_DEBUG(("Error occured while formatting buffer"));
1213 dst->end = dst->head + len;
1214 dst->data = dst->head + hlen;
1215 dst->tail = dst->end;