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 buffer has enough room to format data in it, if not
35 allocate more. This will append, thus not replacing any existing data. */
36 #define FORMAT_HAS_SPACE_APPEND(s, b, req) \
38 if (silc_buffer_len(b) < req) \
39 if (silc_unlikely(!silc_buffer_sappend(s, b, req - silc_buffer_len(b)))) \
44 /* Check that there is data to be unformatted */
45 #define UNFORMAT_HAS_SPACE(b, req) \
47 if (silc_unlikely(req > silc_buffer_len(b))) { \
48 silc_set_errno(SILC_ERR_OVERFLOW); \
51 if (silc_unlikely((req + 1) <= 0)) { \
52 silc_set_errno(SILC_ERR_UNDERFLOW); \
58 /******************************* Formatting *********************************/
60 int silc_buffer_sformat_vp_i(SilcStack stack, SilcBuffer dst, va_list ap,
65 SilcBool advance = FALSE;
67 /* Parse the arguments by formatting type. */
69 fmt = va_arg(ap, SilcParam);
71 SILC_LOG_DEBUG(("Buffer format type %d", fmt));
76 SilcBufferFormatFunc func;
81 func = va_arg(ap, SilcBufferFormatFunc);
82 val = va_arg(ap, void *);
83 context = va_arg(ap, void *);
88 tmp_len = func(stack, dst, val, context);
92 silc_buffer_pull(dst, tmp_len);
98 case SILC_PARAM_REGEX:
100 const char *regex = va_arg(ap, char *);
101 SilcBufferRegexFlags rflags = va_arg(ap, SilcUInt32);
102 SilcBufferStruct match, saved;
103 SilcBool match_all = (rflags & SILC_STR_REGEX_ALL) != 0;
104 SilcBool match_nl = (rflags & SILC_STR_REGEX_NL) != 0;
106 SilcUInt32 inclusive_pos = 0;
107 int matched = 0, ret_len;
116 memset(&saved, 0, sizeof(saved));
120 /* Match for '\n' in the buffer. If not found, treat as line
121 without '\n' (buffer has only one line, or this is last line). */
123 if (silc_regex_buffer(dst, "\n", &match, NULL))
124 dst->tail = match.tail;
129 ret = silc_regex_buffer(dst, regex, &match, NULL);
130 ret ^= (rflags & SILC_STR_REGEX_NOT) != 0;
132 if (!matched && rflags & SILC_STR_REGEX_MISMATCH) {
133 silc_set_errno(SILC_ERR_NOT_FOUND);
140 if (rflags & SILC_STR_REGEX_NOT)
143 if (!(rflags & SILC_STR_REGEX_NO_ADVANCE)) {
144 /* Advance buffer after match */
145 flen += (match.data - dst->data);
146 if (!silc_buffer_pull(dst, (match.data - dst->data)))
150 if (rflags & SILC_STR_REGEX_INCLUSIVE) {
151 inclusive_pos = dst->tail - match.tail;
152 dst->tail = match.tail;
155 /* Recursively format */
156 silc_va_copy(cp, ap);
157 ret_len = silc_buffer_sformat_vp_i(stack, dst, cp, TRUE);
162 if (rflags & SILC_STR_REGEX_INCLUSIVE)
163 if (!silc_buffer_pull_tail(dst, inclusive_pos))
166 /* Advance buffer after formatting */
168 if (!silc_buffer_pull(dst, ret_len))
171 if (match_all && (!match_nl || silc_buffer_len(dst) > 1))
176 /* Go to next line, it is at the end of the data area. Adjust
177 the tail area of the target buffer to show rest of the buffer. */
178 flen += (dst->tail - dst->data);
179 if (!silc_buffer_pull(dst, (dst->tail - dst->data)))
181 if (!silc_buffer_pull_tail(dst, (saved.tail - dst->tail)))
184 if (silc_buffer_len(dst) > 0)
188 /* Skip to the next SILC_PARAM_END */
189 silc_buffer_sformat_vp_i(NULL, NULL, ap, FALSE);
193 case SILC_PARAM_UI8_STRING:
194 case SILC_PARAM_UI16_STRING:
195 case SILC_PARAM_UI32_STRING:
196 case SILC_PARAM_UI8_STRING | SILC_PARAM_ALLOC:
197 case SILC_PARAM_UI16_STRING | SILC_PARAM_ALLOC:
198 case SILC_PARAM_UI32_STRING | SILC_PARAM_ALLOC:
200 char *x = va_arg(ap, char *);
201 SilcUInt32 tmp_len = x ? strlen(x) : 0;
207 FORMAT_HAS_SPACE(stack, dst, tmp_len);
208 silc_buffer_put(dst, x, tmp_len);
209 silc_buffer_pull(dst, tmp_len);
214 case SILC_PARAM_UI8_STRING | SILC_PARAM_APPEND:
215 case SILC_PARAM_UI16_STRING | SILC_PARAM_APPEND:
216 case SILC_PARAM_UI32_STRING | SILC_PARAM_APPEND:
218 char *x = va_arg(ap, char *);
219 SilcUInt32 tmp_len = x ? strlen(x) : 0;
225 FORMAT_HAS_SPACE_APPEND(stack, dst, tmp_len);
226 silc_buffer_put(dst, x, tmp_len);
227 silc_buffer_pull(dst, tmp_len);
232 case SILC_PARAM_UI8_NSTRING:
233 case SILC_PARAM_UI16_NSTRING:
234 case SILC_PARAM_UI32_NSTRING:
235 case SILC_PARAM_UICHAR:
236 case SILC_PARAM_UI8_NSTRING | SILC_PARAM_ALLOC:
237 case SILC_PARAM_UI16_NSTRING | SILC_PARAM_ALLOC:
238 case SILC_PARAM_UI32_NSTRING | SILC_PARAM_ALLOC:
239 case SILC_PARAM_UICHAR | SILC_PARAM_ALLOC:
241 unsigned char *x = va_arg(ap, unsigned char *);
242 SilcUInt32 tmp_len = va_arg(ap, SilcUInt32);
248 FORMAT_HAS_SPACE(stack, dst, tmp_len);
249 silc_buffer_put(dst, x, tmp_len);
250 silc_buffer_pull(dst, tmp_len);
255 case SILC_PARAM_UINT8:
257 unsigned char x = (unsigned char)va_arg(ap, int);
262 FORMAT_HAS_SPACE(stack, dst, 1);
263 silc_buffer_put(dst, &x, 1);
264 silc_buffer_pull(dst, 1);
268 case SILC_PARAM_UINT16:
271 SilcUInt16 x = (SilcUInt16)va_arg(ap, int);
276 FORMAT_HAS_SPACE(stack, dst, 2);
277 SILC_PUT16_MSB(x, xf);
278 silc_buffer_put(dst, xf, 2);
279 silc_buffer_pull(dst, 2);
283 case SILC_PARAM_UINT32:
286 SilcUInt32 x = va_arg(ap, SilcUInt32);
291 FORMAT_HAS_SPACE(stack, dst, 4);
292 SILC_PUT32_MSB(x, xf);
293 silc_buffer_put(dst, xf, 4);
294 silc_buffer_pull(dst, 4);
298 case SILC_PARAM_UINT64:
301 SilcUInt64 x = va_arg(ap, SilcUInt64);
306 FORMAT_HAS_SPACE(stack, dst, sizeof(SilcUInt64));
307 SILC_PUT64_MSB(x, xf);
308 silc_buffer_put(dst, xf, sizeof(SilcUInt64));
309 silc_buffer_pull(dst, sizeof(SilcUInt64));
313 case SILC_PARAM_SINT8:
315 char x = (char)va_arg(ap, int);
320 FORMAT_HAS_SPACE(stack, dst, 1);
321 silc_buffer_put(dst, (unsigned char *)&x, 1);
322 silc_buffer_pull(dst, 1);
326 case SILC_PARAM_SINT16:
329 SilcInt16 x = (SilcInt16)va_arg(ap, int);
334 FORMAT_HAS_SPACE(stack, dst, 2);
335 SILC_PUT16_MSB(x, xf);
336 silc_buffer_put(dst, xf, 2);
337 silc_buffer_pull(dst, 2);
341 case SILC_PARAM_SINT32:
344 SilcInt32 x = va_arg(ap, SilcInt32);
349 FORMAT_HAS_SPACE(stack, dst, 4);
350 SILC_PUT32_MSB(x, xf);
351 silc_buffer_put(dst, xf, 4);
352 silc_buffer_pull(dst, 4);
356 case SILC_PARAM_SINT64:
359 SilcInt64 x = va_arg(ap, SilcInt64);
364 FORMAT_HAS_SPACE(stack, dst, sizeof(SilcInt64));
365 SILC_PUT64_MSB(x, xf);
366 silc_buffer_put(dst, xf, sizeof(SilcInt64));
367 silc_buffer_pull(dst, sizeof(SilcInt64));
371 case SILC_PARAM_BUFFER:
372 case SILC_PARAM_BUFFER | SILC_PARAM_ALLOC:
374 SilcBuffer x = va_arg(ap, SilcBuffer);
380 if (x && silc_buffer_len(x)) {
381 FORMAT_HAS_SPACE(stack, dst, silc_buffer_len(x) + 4);
382 SILC_PUT32_MSB(silc_buffer_len(x), xf);
383 silc_buffer_put(dst, xf, 4);
384 silc_buffer_pull(dst, 4);
385 silc_buffer_put(dst, silc_buffer_data(x), silc_buffer_len(x));
386 silc_buffer_pull(dst, silc_buffer_len(x));
391 case SILC_PARAM_OFFSET:
393 int offst = va_arg(ap, int);
402 if (offst > silc_buffer_len(dst)) {
403 silc_set_errno(SILC_ERR_OVERFLOW);
406 silc_buffer_pull(dst, offst);
409 silc_buffer_push(dst, -(offst));
415 case SILC_PARAM_OFFSET_START:
418 if (!silc_buffer_push(dst, flen))
423 case SILC_PARAM_OFFSET_END:
426 flen += silc_buffer_len(dst);
427 silc_buffer_pull(dst, silc_buffer_len(dst));
430 case SILC_PARAM_ADVANCE:
441 SILC_LOG_DEBUG(("Bad buffer formatting type `%d'. Could not "
442 "format the data.", fmt));
443 silc_set_errno_reason(SILC_ERR_INVALID_ARGUMENT,
444 "Bad buffer formatting type %d", fmt);
451 SILC_LOG_DEBUG(("Error occured while formatting data"));
452 if (process && !advance)
453 silc_buffer_push(dst, flen);
457 /* Push the buffer back to where it belongs. */
458 if (process && !advance)
459 silc_buffer_push(dst, flen);
463 int silc_buffer_format(SilcBuffer dst, ...)
469 ret = silc_buffer_sformat_vp(NULL, dst, ap);
475 int silc_buffer_format_vp(SilcBuffer dst, va_list ap)
477 return silc_buffer_sformat_vp(NULL, dst, ap);
480 int silc_buffer_sformat(SilcStack stack, SilcBuffer dst, ...)
486 ret = silc_buffer_sformat_vp(stack, dst, ap);
492 int silc_buffer_sformat_vp(SilcStack stack, SilcBuffer dst, va_list ap)
494 return silc_buffer_sformat_vp_i(stack, dst, ap, TRUE);
497 /****************************** Unformatting ********************************/
499 int silc_buffer_sunformat_vp_i(SilcStack stack, SilcBuffer src, va_list ap,
503 unsigned char *start_ptr = src->data;
505 SilcBool advance = FALSE;
507 /* Parse the arguments by formatting type. */
509 fmt = va_arg(ap, SilcParam);
511 SILC_LOG_DEBUG(("Buffer unformat type %d", fmt));
514 case SILC_PARAM_FUNC:
516 SilcBufferUnformatFunc func;
520 func = va_arg(ap, SilcBufferUnformatFunc);
521 val = va_arg(ap, void **);
522 context = va_arg(ap, void *);
527 tmp_len = func(stack, src, val, context);
531 UNFORMAT_HAS_SPACE(src, tmp_len);
532 silc_buffer_pull(src, tmp_len);
537 case SILC_PARAM_REGEX:
539 const char *regex = va_arg(ap, char *);
540 SilcBufferRegexFlags rflags = va_arg(ap, SilcUInt32);
541 SilcBufferStruct match, saved;
542 SilcBool match_all = (rflags & SILC_STR_REGEX_ALL) != 0;
543 SilcBool match_nl = (rflags & SILC_STR_REGEX_NL) != 0;
545 SilcUInt32 inclusive_pos = 0;
546 int matched = 0, ret_len;
555 memset(&saved, 0, sizeof(saved));
559 /* Match for '\n' in the buffer. If not found, treat as line
560 without '\n' (buffer has only one line, or this is last line). */
562 if (silc_regex_buffer(src, "\n", &match, NULL))
563 src->tail = match.tail;
568 ret = silc_regex_buffer(src, regex, &match, NULL);
569 ret ^= (rflags & SILC_STR_REGEX_NOT) != 0;
571 if (!matched && rflags & SILC_STR_REGEX_MISMATCH) {
572 silc_set_errno(SILC_ERR_NOT_FOUND);
579 if (rflags & SILC_STR_REGEX_NOT)
582 if (!(rflags & SILC_STR_REGEX_NO_ADVANCE)) {
583 /* Advance buffer after match */
584 UNFORMAT_HAS_SPACE(src, (match.data - src->data));
585 if (!silc_buffer_pull(src, (match.data - src->data)))
589 if (rflags & SILC_STR_REGEX_INCLUSIVE) {
590 inclusive_pos = src->tail - match.tail;
591 src->tail = match.tail;
594 /* Recursively format */
595 silc_va_copy(cp, ap);
596 ret_len = silc_buffer_sunformat_vp_i(stack, src, cp, TRUE);
601 if (rflags & SILC_STR_REGEX_INCLUSIVE)
602 if (!silc_buffer_pull_tail(src, inclusive_pos))
605 /* Advance buffer after formatting */
606 UNFORMAT_HAS_SPACE(src, ret_len);
607 if (!silc_buffer_pull(src, ret_len))
610 if (match_all && (!match_nl || silc_buffer_len(src) > 1))
615 /* Go to next line, it is at the end of the data area. Adjust
616 the tail area of the target buffer to show rest of the buffer. */
617 UNFORMAT_HAS_SPACE(src, src->tail - src->data);
618 if (!silc_buffer_pull(src, (src->tail - src->data)))
620 if (!silc_buffer_pull_tail(src, (saved.tail - src->tail)))
623 if (silc_buffer_len(src) > 0)
627 /* Skip to the next SILC_PARAM_END */
628 silc_buffer_sunformat_vp_i(NULL, src, ap, FALSE);
632 case SILC_PARAM_UICHAR:
634 unsigned char **x = va_arg(ap, unsigned char **);
635 SilcUInt32 len2 = va_arg(ap, SilcUInt32);
640 UNFORMAT_HAS_SPACE(src, len2);
641 if (silc_likely(len2 && x))
643 silc_buffer_pull(src, len2);
647 case SILC_PARAM_UICHAR | SILC_PARAM_ALLOC:
649 unsigned char **x = va_arg(ap, unsigned char **);
650 SilcUInt32 len2 = va_arg(ap, SilcUInt32);
655 UNFORMAT_HAS_SPACE(src, len2);
656 if (silc_likely(len2 && x)) {
657 *x = silc_scalloc(stack, len2 + 1, sizeof(unsigned char));
658 memcpy(*x, src->data, len2);
660 silc_buffer_pull(src, len2);
664 case SILC_PARAM_UINT8:
666 unsigned char *x = va_arg(ap, unsigned char *);
671 UNFORMAT_HAS_SPACE(src, 1);
674 silc_buffer_pull(src, 1);
678 case SILC_PARAM_UINT16:
680 SilcUInt16 *x = va_arg(ap, SilcUInt16 *);
685 UNFORMAT_HAS_SPACE(src, 2);
687 SILC_GET16_MSB(*x, src->data);
688 silc_buffer_pull(src, 2);
692 case SILC_PARAM_UINT32:
694 SilcUInt32 *x = va_arg(ap, SilcUInt32 *);
699 UNFORMAT_HAS_SPACE(src, 4);
701 SILC_GET32_MSB(*x, src->data);
702 silc_buffer_pull(src, 4);
706 case SILC_PARAM_UINT64:
708 SilcUInt64 *x = va_arg(ap, SilcUInt64 *);
713 UNFORMAT_HAS_SPACE(src, sizeof(SilcUInt64));
715 SILC_GET64_MSB(*x, src->data);
716 silc_buffer_pull(src, sizeof(SilcUInt64));
720 case SILC_PARAM_SINT8:
722 char *x = va_arg(ap, char *);
727 UNFORMAT_HAS_SPACE(src, 1);
730 silc_buffer_pull(src, 1);
734 case SILC_PARAM_SINT16:
736 SilcInt16 *x = va_arg(ap, SilcInt16 *);
741 UNFORMAT_HAS_SPACE(src, 2);
743 SILC_GET16_MSB(*x, src->data);
744 silc_buffer_pull(src, 2);
748 case SILC_PARAM_SINT32:
750 SilcInt32 *x = va_arg(ap, SilcInt32 *);
755 UNFORMAT_HAS_SPACE(src, 4);
757 SILC_GET32_MSB(*x, src->data);
758 silc_buffer_pull(src, 4);
762 case SILC_PARAM_SINT64:
764 SilcInt64 *x = va_arg(ap, SilcInt64 *);
769 UNFORMAT_HAS_SPACE(src, sizeof(SilcInt64));
771 SILC_GET64_MSB(*x, src->data);
772 silc_buffer_pull(src, sizeof(SilcInt64));
776 case SILC_PARAM_UI8_STRING:
779 unsigned char **x = va_arg(ap, unsigned char **);
784 UNFORMAT_HAS_SPACE(src, 1);
785 len2 = (SilcUInt8)src->data[0];
786 silc_buffer_pull(src, 1);
787 UNFORMAT_HAS_SPACE(src, len2);
790 silc_buffer_pull(src, len2);
794 case SILC_PARAM_UI8_STRING | SILC_PARAM_ALLOC:
797 unsigned char **x = va_arg(ap, unsigned char **);
802 UNFORMAT_HAS_SPACE(src, 1);
803 len2 = (SilcUInt8)src->data[0];
804 silc_buffer_pull(src, 1);
805 UNFORMAT_HAS_SPACE(src, len2);
806 if (silc_likely(x && len2)) {
807 *x = silc_scalloc(stack, len2 + 1, sizeof(unsigned char));
808 memcpy(*x, src->data, len2);
810 silc_buffer_pull(src, len2);
814 case SILC_PARAM_UI16_STRING:
817 unsigned char **x = va_arg(ap, unsigned char **);
822 UNFORMAT_HAS_SPACE(src, 2);
823 SILC_GET16_MSB(len2, src->data);
824 silc_buffer_pull(src, 2);
825 UNFORMAT_HAS_SPACE(src, len2);
828 silc_buffer_pull(src, len2);
832 case SILC_PARAM_UI16_STRING | SILC_PARAM_ALLOC:
835 unsigned char **x = va_arg(ap, unsigned char **);
840 UNFORMAT_HAS_SPACE(src, 2);
841 SILC_GET16_MSB(len2, src->data);
842 silc_buffer_pull(src, 2);
843 UNFORMAT_HAS_SPACE(src, len2);
844 if (silc_likely(x && len2)) {
845 *x = silc_scalloc(stack, len2 + 1, sizeof(unsigned char));
846 memcpy(*x, src->data, len2);
848 silc_buffer_pull(src, len2);
852 case SILC_PARAM_UI32_STRING:
855 unsigned char **x = va_arg(ap, unsigned char **);
860 UNFORMAT_HAS_SPACE(src, 4);
861 SILC_GET32_MSB(len2, src->data);
862 silc_buffer_pull(src, 4);
863 UNFORMAT_HAS_SPACE(src, len2);
866 silc_buffer_pull(src, len2);
870 case SILC_PARAM_UI32_STRING | SILC_PARAM_ALLOC:
873 unsigned char **x = va_arg(ap, unsigned char **);
878 UNFORMAT_HAS_SPACE(src, 4);
879 SILC_GET32_MSB(len2, src->data);
880 silc_buffer_pull(src, 4);
881 UNFORMAT_HAS_SPACE(src, len2);
882 if (silc_likely(x && len2)) {
883 *x = silc_scalloc(stack, len2 + 1, sizeof(unsigned char));
884 memcpy(*x, src->data, len2);
886 silc_buffer_pull(src, len2);
890 case SILC_PARAM_UI8_NSTRING:
893 unsigned char **x = va_arg(ap, unsigned char **);
894 SilcUInt8 *len3 = va_arg(ap, SilcUInt8 *);
899 UNFORMAT_HAS_SPACE(src, 1);
900 len2 = (SilcUInt8)src->data[0];
901 silc_buffer_pull(src, 1);
902 UNFORMAT_HAS_SPACE(src, len2);
907 silc_buffer_pull(src, len2);
911 case SILC_PARAM_UI8_NSTRING | SILC_PARAM_ALLOC:
914 unsigned char **x = va_arg(ap, unsigned char **);
915 SilcUInt8 *len3 = va_arg(ap, SilcUInt8 *);
920 UNFORMAT_HAS_SPACE(src, 1);
921 len2 = (SilcUInt8)src->data[0];
922 silc_buffer_pull(src, 1);
923 UNFORMAT_HAS_SPACE(src, len2);
927 *x = silc_scalloc(stack, len2 + 1, sizeof(unsigned char));
928 memcpy(*x, src->data, len2);
930 silc_buffer_pull(src, len2);
934 case SILC_PARAM_UI16_NSTRING:
937 unsigned char **x = va_arg(ap, unsigned char **);
938 SilcUInt16 *len3 = va_arg(ap, SilcUInt16 *);
943 UNFORMAT_HAS_SPACE(src, 2);
944 SILC_GET16_MSB(len2, src->data);
945 silc_buffer_pull(src, 2);
946 UNFORMAT_HAS_SPACE(src, len2);
951 silc_buffer_pull(src, len2);
955 case SILC_PARAM_UI16_NSTRING | SILC_PARAM_ALLOC:
958 unsigned char **x = va_arg(ap, unsigned char **);
959 SilcUInt16 *len3 = va_arg(ap, SilcUInt16 *);
964 UNFORMAT_HAS_SPACE(src, 2);
965 SILC_GET16_MSB(len2, src->data);
966 silc_buffer_pull(src, 2);
967 UNFORMAT_HAS_SPACE(src, len2);
971 *x = silc_scalloc(stack, len2 + 1, sizeof(unsigned char));
972 memcpy(*x, src->data, len2);
974 silc_buffer_pull(src, len2);
978 case SILC_PARAM_UI32_NSTRING:
981 unsigned char **x = va_arg(ap, unsigned char **);
982 SilcUInt32 *len3 = va_arg(ap, SilcUInt32 *);
987 UNFORMAT_HAS_SPACE(src, 4);
988 SILC_GET32_MSB(len2, src->data);
989 silc_buffer_pull(src, 4);
990 UNFORMAT_HAS_SPACE(src, len2);
995 silc_buffer_pull(src, len2);
999 case SILC_PARAM_UI32_NSTRING | SILC_PARAM_ALLOC:
1002 unsigned char **x = va_arg(ap, unsigned char **);
1003 SilcUInt32 *len3 = va_arg(ap, SilcUInt32 *);
1008 UNFORMAT_HAS_SPACE(src, 4);
1009 SILC_GET32_MSB(len2, src->data);
1010 silc_buffer_pull(src, 4);
1011 UNFORMAT_HAS_SPACE(src, len2);
1014 if (silc_likely(x && len2)) {
1015 *x = silc_scalloc(stack, len2 + 1, sizeof(unsigned char));
1016 memcpy(*x, src->data, len2);
1018 silc_buffer_pull(src, len2);
1022 case SILC_PARAM_BUFFER:
1024 SilcBuffer x = va_arg(ap, SilcBuffer);
1030 UNFORMAT_HAS_SPACE(src, 4);
1031 SILC_GET32_MSB(len2, src->data);
1032 silc_buffer_pull(src, 4);
1033 UNFORMAT_HAS_SPACE(src, len2);
1034 silc_buffer_set(x, src->data, len2);
1035 silc_buffer_pull(src, len2);
1039 case SILC_PARAM_BUFFER | SILC_PARAM_ALLOC:
1041 SilcBuffer x = va_arg(ap, SilcBuffer);
1047 UNFORMAT_HAS_SPACE(src, 4);
1048 SILC_GET32_MSB(len2, src->data);
1049 silc_buffer_pull(src, 4);
1050 UNFORMAT_HAS_SPACE(src, len2);
1051 silc_buffer_sformat(stack, x,
1052 SILC_STR_DATA(src->data, len2),
1054 silc_buffer_pull(src, len2);
1058 case SILC_PARAM_OFFSET:
1060 int offst = va_arg(ap, int);
1069 UNFORMAT_HAS_SPACE(src, offst);
1070 silc_buffer_pull(src, offst);
1072 silc_buffer_push(src, -(offst));
1077 case SILC_PARAM_OFFSET_START:
1080 silc_buffer_push(src, (src->data - start_ptr));
1083 case SILC_PARAM_OFFSET_END:
1086 silc_buffer_pull(src, silc_buffer_len(src));
1089 case SILC_PARAM_ADVANCE:
1095 case SILC_PARAM_END:
1100 SILC_LOG_DEBUG(("Bad buffer formatting type `%d'. Could not "
1101 "format the data.", fmt));
1102 silc_set_errno_reason(SILC_ERR_INVALID_ARGUMENT,
1103 "Bad buffer formatting type %d", fmt);
1110 SILC_LOG_DEBUG(("Error occured while unformatting buffer, type %d", fmt));
1111 if (process && !advance) {
1112 len = src->data - start_ptr;
1113 silc_buffer_push(src, len);
1118 /* Push the buffer back to the start. */
1119 if (process && !advance) {
1120 len = src->data - start_ptr;
1121 silc_buffer_push(src, len);
1126 int silc_buffer_unformat(SilcBuffer src, ...)
1132 ret = silc_buffer_sunformat_vp(NULL, src, ap);
1138 int silc_buffer_unformat_vp(SilcBuffer src, va_list ap)
1140 return silc_buffer_sunformat_vp(NULL, src, ap);
1143 int silc_buffer_sunformat(SilcStack stack, SilcBuffer src, ...)
1149 ret = silc_buffer_sunformat_vp(stack, src, ap);
1155 int silc_buffer_sunformat_vp(SilcStack stack, SilcBuffer src, va_list ap)
1157 return silc_buffer_sunformat_vp_i(stack, src, ap, TRUE);
1160 /**************************** Utility functions *****************************/
1162 /* Formats strings into a buffer */
1164 int silc_buffer_strformat(SilcBuffer dst, ...)
1166 int len = silc_buffer_truelen(dst);
1167 int hlen = silc_buffer_headlen(dst);
1172 /* Parse the arguments by formatting type. */
1174 char *string = va_arg(va, char *);
1180 if (string == (char *)SILC_PARAM_END)
1183 slen = strlen(string);
1184 d = silc_realloc(dst->head, sizeof(*dst->head) * (slen + len + 1));
1185 if (silc_unlikely(!d))
1188 memcpy(dst->head + len, string, slen);
1190 dst->head[len] = '\0';
1193 SILC_LOG_DEBUG(("Error occured while formatting buffer"));
1198 dst->end = dst->head + len;
1199 dst->data = dst->head + hlen;
1200 dst->tail = dst->end;
1206 /* Formats strings into a buffer. Allocates memory from SilcStack. */
1208 int silc_buffer_sstrformat(SilcStack stack, SilcBuffer dst, ...)
1210 int len = silc_buffer_truelen(dst);
1211 int hlen = silc_buffer_headlen(dst);
1216 /* Parse the arguments by formatting type. */
1218 char *string = va_arg(va, char *);
1224 if (string == (char *)SILC_PARAM_END)
1227 slen = strlen(string);
1228 d = silc_srealloc(stack, len + 1, dst->head,
1229 sizeof(*dst->head) * (slen + len + 1));
1230 if (silc_unlikely(!d))
1233 memcpy(dst->head + len, string, slen);
1235 dst->head[len] = '\0';
1238 SILC_LOG_DEBUG(("Error occured while formatting buffer"));
1243 dst->end = dst->head + len;
1244 dst->data = dst->head + hlen;
1245 dst->tail = dst->end;