From: Pekka Riikonen Date: Mon, 18 Sep 2006 21:09:36 +0000 (+0000) Subject: Added SILC_STR_ADVANCE. X-Git-Tag: 1.2.beta1~697 X-Git-Url: http://git.silcnet.org/gitweb/?a=commitdiff_plain;h=11b67294ca9e25f91c17950876fcf22b43f26ed0;p=runtime.git Added SILC_STR_ADVANCE. silc_buffer_strformat preserves buffer locations. --- diff --git a/lib/silcutil/silcbuffmt.c b/lib/silcutil/silcbuffmt.c index 6ba9ac96..4dd54965 100644 --- a/lib/silcutil/silcbuffmt.c +++ b/lib/silcutil/silcbuffmt.c @@ -78,6 +78,7 @@ int silc_buffer_sformat_vp(SilcStack stack, SilcBuffer dst, va_list ap) { SilcBufferParamType fmt; int flen = 0; + SilcBool advance = FALSE; /* Parse the arguments by formatting type. */ while (1) { @@ -194,10 +195,12 @@ int silc_buffer_sformat_vp(SilcStack stack, SilcBuffer dst, va_list ap) case SILC_BUFFER_PARAM_UI16_NSTRING: case SILC_BUFFER_PARAM_UI32_NSTRING: case SILC_BUFFER_PARAM_UI_XNSTRING: + case SILC_BUFFER_PARAM_DATA: case SILC_BUFFER_PARAM_UI8_NSTRING_ALLOC: case SILC_BUFFER_PARAM_UI16_NSTRING_ALLOC: case SILC_BUFFER_PARAM_UI32_NSTRING_ALLOC: case SILC_BUFFER_PARAM_UI_XNSTRING_ALLOC: + case SILC_BUFFER_PARAM_DATA_ALLOC: { unsigned char *x = va_arg(ap, unsigned char *); SilcUInt32 tmp_len = va_arg(ap, SilcUInt32); @@ -211,6 +214,9 @@ int silc_buffer_sformat_vp(SilcStack stack, SilcBuffer dst, va_list ap) case SILC_BUFFER_PARAM_END: goto ok; break; + case SILC_BUFFER_PARAM_ADVANCE: + advance = TRUE; + break; default: SILC_LOG_DEBUG(("Bad buffer formatting type `%d'. Could not " "format the data.", fmt)); @@ -221,12 +227,14 @@ int silc_buffer_sformat_vp(SilcStack stack, SilcBuffer dst, va_list ap) fail: SILC_LOG_DEBUG(("Error occured while formatting data")); - silc_buffer_push(dst, flen); + if (!advance) + silc_buffer_push(dst, flen); return -1; ok: /* Push the buffer back to where it belongs. */ - silc_buffer_push(dst, flen); + if (!advance) + silc_buffer_push(dst, flen); return flen; } @@ -510,6 +518,7 @@ int silc_buffer_unformat_vp(SilcBuffer src, va_list ap) break; } case SILC_BUFFER_PARAM_UI_XNSTRING: + case SILC_BUFFER_PARAM_DATA: { unsigned char **x = va_arg(ap, unsigned char **); SilcUInt32 len = va_arg(ap, SilcUInt32); @@ -520,6 +529,7 @@ int silc_buffer_unformat_vp(SilcBuffer src, va_list ap) break; } case SILC_BUFFER_PARAM_UI_XNSTRING_ALLOC: + case SILC_BUFFER_PARAM_DATA_ALLOC: { unsigned char **x = va_arg(ap, unsigned char **); SilcUInt32 len = va_arg(ap, SilcUInt32); @@ -534,6 +544,8 @@ int silc_buffer_unformat_vp(SilcBuffer src, va_list ap) case SILC_BUFFER_PARAM_END: goto ok; break; + case SILC_BUFFER_PARAM_ADVANCE: + break; default: SILC_LOG_DEBUG(("Bad buffer formatting type `%d'. Could not " "format the data.", fmt)); @@ -563,6 +575,7 @@ int silc_buffer_unformat_vp(SilcBuffer src, va_list ap) int silc_buffer_strformat(SilcBuffer dst, ...) { int len = silc_buffer_truelen(dst); + int hlen = silc_buffer_headlen(dst); va_list va; va_start(va, dst); @@ -594,7 +607,7 @@ int silc_buffer_strformat(SilcBuffer dst, ...) ok: dst->end = dst->head + len; - dst->data = dst->head; + dst->data = dst->head + hlen; dst->tail = dst->end; va_end(va); diff --git a/lib/silcutil/silcbuffmt.h b/lib/silcutil/silcbuffmt.h index 339459ce..cf0ed7b3 100644 --- a/lib/silcutil/silcbuffmt.h +++ b/lib/silcutil/silcbuffmt.h @@ -49,6 +49,7 @@ * EXAMPLE * * SilcBufferStruct buffer; + * SilcBuffer buf; * * memset(&buffer, 0, sizeof(buffer)); * ret = silc_buffer_format(&buffer, @@ -64,6 +65,16 @@ * // Free the allocated data * silc_buffer_purge(&buffer); * + * // Allocate zero size buffer + * buf = silc_buffer_alloc(); + * ret = silc_buffer_format(buf, + * SILC_STR_INT(intval), + * SILC_STR_CHAR(charval), + * SILC_STR_END); + * + * // Free the allocated buffer + * silc_buffer_free(buf); + * ***/ int silc_buffer_format(SilcBuffer dst, ...); @@ -235,8 +246,11 @@ typedef enum { SILC_BUFFER_PARAM_UI32_NSTRING_ALLOC, /* Alloc + memcpy */ SILC_BUFFER_PARAM_UI_XNSTRING, /* No copy */ SILC_BUFFER_PARAM_UI_XNSTRING_ALLOC, /* Alloc + memcpy */ + SILC_BUFFER_PARAM_DATA, /* No copy */ + SILC_BUFFER_PARAM_DATA_ALLOC, /* Alloc + memcpy */ SILC_BUFFER_PARAM_OFFSET, + SILC_BUFFER_PARAM_ADVANCE, SILC_BUFFER_PARAM_END } SilcBufferParamType; @@ -424,33 +438,32 @@ typedef enum { #define SILC_STR_UI32_NSTRING_ALLOC(x, l) \ SILC_BUFFER_PARAM_UI32_NSTRING_ALLOC, (x), (l) -/****d* silcutil/SilcBufferFormatAPI/SILC_STR_UI_XNSTRING +/****d* silcutil/SilcBufferFormatAPI/SILC_STR_DATA * * NAME * - * #define SILC_STR_UI_XNSTRING() ... - * #define SILC_STR_UI_XNSTRING_ALLOC() ... + * #define SILC_STR_DATA() ... + * #define SILC_STR_DATA_ALLOC() ... * * DESCRIPTION * - * Extended Unsigned string formatting. Second argument is the length of - * the string. + * Binary data formatting. Second argument is the lenght of the data. * - * Formatting: SILC_STR_UI_XNSTRING(unsigned char *, SilcUInt32) - * Unformatting: SILC_STR_UI_XNSTRING(unsigned char **, SilcUInt32) + * Formatting: SILC_STR_DATA(unsigned char *, SilcUInt32) + * Unformatting: SILC_STR_DATA(unsigned char **, SilcUInt32) * - * This type can be used to take arbitrary length string from the buffer - * by sending the requested amount of bytes as argument. This differs - * from *_STRING and *_NSTRING so that this doesn't try to find the - * length of the data from the buffer but the length of the data is - * sent as argument. This a handy way to unformat fixed length strings - * from the buffer without having the length of the string formatted - * in the buffer. + * This type can be used to take arbitrary size data block from the buffer + * by sending the requested amount of bytes as argument. * * _ALLOC routines automatically allocates memory for the variable sent * as argument in unformatting. * ***/ +#define SILC_STR_DATA(x, l) SILC_BUFFER_PARAM_DATA, (x), (l) +#define SILC_STR_DATA_ALLOC(x, l) \ + SILC_BUFFER_PARAM_DATA_ALLOC, (x), (l) + +/* Deprecated */ #define SILC_STR_UI_XNSTRING(x, l) SILC_BUFFER_PARAM_UI_XNSTRING, (x), (l) #define SILC_STR_UI_XNSTRING_ALLOC(x, l) \ SILC_BUFFER_PARAM_UI_XNSTRING_ALLOC, (x), (l) @@ -480,6 +493,38 @@ typedef enum { ***/ #define SILC_STR_OFFSET(x) SILC_BUFFER_PARAM_OFFSET, (x) +/****d* silcutil/SilcBufferFormatAPI/SILC_STR_ADVANCE + * + * NAME + * + * #define SILC_STR_ADVANCE ... + * + * DESCRIPTION + * + * Advance the buffer to the end of the data after the formatting is + * done. In normal operation when the formatted data is written the + * buffer is located at the start of the data. With SILC_STR_ADVANCE + * the buffer will be located at the end of the data. This makes it + * easy to add new data immediately after the previously added data. + * + * EXAMPLE + * + * do { + * len = read(fd, buf, sizeof(buf)); + * if (len > 0) + * // Add read data to the buffer + * silc_buffer_format(buffer, + * SILC_STR_ADVANCE, + * SILC_STR_UI_XNSTRING(buf, len), + * SILC_STR_END); + * } while (len > 0); + * + * // Move to beginning of buffer + * silc_buffer_push(buffer, silc_buffer_truelen(buffer)); + * + ***/ +#define SILC_STR_ADVANCE SILC_BUFFER_PARAM_ADVANCE + /****d* silcutil/SilcBufferFormatAPI/SILC_STR_END * * NAME