X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilcutil%2Fsilcbuffmt.h;h=4334dc571793470dd77dae602cdb3810c5b64cda;hb=f2462c5dd7e885e3daa00066fbf53e166fd361e0;hp=fc213001030a9de89db0b5c6c8a605126fe87f4f;hpb=5c0580bfaa956973c2e292d98cb3df490c0a2fde;p=silc.git diff --git a/lib/silcutil/silcbuffmt.h b/lib/silcutil/silcbuffmt.h index fc213001..4334dc57 100644 --- a/lib/silcutil/silcbuffmt.h +++ b/lib/silcutil/silcbuffmt.h @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 1997 - 2007 Pekka Riikonen + Copyright (C) 1997 - 2008 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -23,9 +23,19 @@ * * SILC Buffer Format API provides functions for formatting different data * types into a buffer and retrieving different data types from a buffer - * into specified data types. It is especially useful to format packets, + * into specified data types. It is especially useful to encode packets, * protocol payloads and such. * + * It also provides many advanced features like calling user specified + * encoder and decoder functions that are free to do anything to the buffer. + * The API also provides powerful regular expression matching capabilities + * within the buffer, enabling caller to not only match regular expressions + * but to make the API behave like Stream Editor (Sed) and Awk. The buffer + * can be matched against regular expression and then edited. Caller can + * do anything they want to the buffer after a match. The SILC_STR_REGEX + * macro provides many different flags that can change the behavior of the + * matching, with capabilities to also mimic Sed behavior. + * * As the SilcBuffer API is not thread-safe these routines may not be used * in multithreaded environment with a same SilcBuffer context without * concurrency control. @@ -36,15 +46,21 @@ * * memset(&buffer, 0, sizeof(buffer)); * ret = silc_buffer_format(&buffer, - * SILC_STR_UI_INT(intval), - * SILC_STR_CHAR(charval), - * SILC_STR_UI_INT(intval), - * SILC_STR_SHORT(str_len), + * SILC_STR_UINT32(intval), + * SILC_STR_UINT8(charval), + * SILC_STR_UINT64(longintval), + * SILC_STR_UINT16(str_len), * SILC_STR_DATA(str, str_len), * SILC_STR_END); * if (ret < 0) * error; * + * // sed 's/foo/bar/', replace first foo with bar + * silc_buffer_format(buffer, + * SILC_STR_REGEX("foo", 0), + * SILC_STR_STRING("bar"), + * SILC_STR_END, SILC_STR_END); + * ***/ #ifndef SILCBUFFMT_H @@ -120,10 +136,10 @@ typedef int (*SilcBufferUnformatFunc)(SilcStack stack, SilcBuffer buffer, * * DESCRIPTION * - * Formats a buffer from a variable argument list. Returns -1 on error - * and the length of the formatted buffer otherwise. The buffer is - * enlarged automatically during formatting, if it doesn't already have - * enough space. + * Formats a buffer from a variable argument list. Returns -1 if the + * system is out of memory and the length of the formatted buffer otherwise. + * The buffer is enlarged automatically during formatting, if it doesn't + * already have enough space. Sets silc_errno in case of error. * * EXAMPLE * @@ -134,10 +150,10 @@ typedef int (*SilcBufferUnformatFunc)(SilcStack stack, SilcBuffer buffer, * * memset(&buffer, 0, sizeof(buffer)); * ret = silc_buffer_format(&buffer, - * SILC_STR_UI_INT(intval), - * SILC_STR_CHAR(charval), - * SILC_STR_UI_INT(intval), - * SILC_STR_SHORT(str_len), + * SILC_STR_UINT32(intval), + * SILC_STR_UINT8(charval), + * SILC_STR_UINT32(intval), + * SILC_STR_UINT16(str_len), * SILC_STR_DATA(str, str_len), * SILC_STR_END); * if (ret < 0) @@ -150,8 +166,8 @@ typedef int (*SilcBufferUnformatFunc)(SilcStack stack, SilcBuffer buffer, * SilcBuffer buf; * buf = silc_buffer_alloc(0); * ret = silc_buffer_format(buf, - * SILC_STR_UI_INT(intval), - * SILC_STR_CHAR(charval), + * SILC_STR_UINT32(intval), + * SILC_STR_UINT8(charval), * SILC_STR_END); * if (ret < 0) * error; @@ -163,7 +179,7 @@ typedef int (*SilcBufferUnformatFunc)(SilcStack stack, SilcBuffer buffer, * SilcBuffer buf; * buf = silc_buffer_alloc(2 + str_len); * ret = silc_buffer_format(buf, - * SILC_STR_UI_SHORT(str_len), + * SILC_STR_UINT16(str_len), * SILC_STR_DATA(str, str_len), * SILC_STR_END); * if (ret < 0) @@ -181,7 +197,8 @@ int silc_buffer_format(SilcBuffer dst, ...); * DESCRIPTION * * Same as silc_buffer_format but uses `stack' to allocate the memory. - * if `stack' is NULL reverts back to silc_buffer_format call. + * if `stack' is NULL reverts back to silc_buffer_format call. Returns + * -1 if system is out of memory. Sets silc_errno in case of error. * * Note that this call consumes the `stack'. The caller should push the * stack before calling the function and pop it later. @@ -198,7 +215,8 @@ int silc_buffer_sformat(SilcStack stack, SilcBuffer dst, ...); * DESCRIPTION * * Formats a buffer from a variable argument list indicated by the `ap'. - * Returns -1 on error and the length of the formatted buffer otherwise. + * Returns -1 if system is out of memory and the length of the formatted + * buffer otherwise. * ***/ int silc_buffer_format_vp(SilcBuffer dst, va_list ap); @@ -212,7 +230,8 @@ int silc_buffer_format_vp(SilcBuffer dst, va_list ap); * DESCRIPTION * * Same as silc_buffer_format_vp but uses `stack' to allocate the memory. - * if `stack' is NULL reverts back to silc_buffer_format_vp call. + * if `stack' is NULL reverts back to silc_buffer_format_vp call. Returns + * -1 if system is out of memory. Sets silc_errno in case of error. * * Note that this call consumes the `stack'. The caller should push the * stack before calling the function and pop it later. @@ -229,13 +248,14 @@ int silc_buffer_sformat_vp(SilcStack stack, SilcBuffer dst, va_list ap); * DESCRIPTION * * Unformats a buffer from a variable argument list. Returns -1 on error - * and the length of the unformatted buffer otherwise. + * and the length of the unformatted buffer otherwise. Sets silc_errno + * in case of error. * * EXAMPLE * * ret = silc_buffer_unformat(buffer, - * SILC_STR_UI_INT(&intval), - * SILC_STR_CHAR(&charval), + * SILC_STR_UINT32(&intval), + * SILC_STR_UINT8(&charval), * SILC_STR_OFFSET(4), * SILC_STR_UI16_NSTRING_ALLOC(&str, &str_len), * SILC_STR_END); @@ -306,7 +326,8 @@ int silc_buffer_sunformat_vp(SilcStack stack, SilcBuffer src, va_list ap); * be end with SILC_STRFMT_END argument. This allows that a string in * the list can be NULL, in which case it is skipped. This automatically * allocates the space for the buffer data but `dst' must be already - * allocated by the caller. + * allocated by the caller. Returns -1 if system is out of memory and + * sets silc_errno. * * EXAMPLE * @@ -331,7 +352,8 @@ int silc_buffer_strformat(SilcBuffer dst, ...); * the list can be NULL, in which case it is skipped. This automatically * allocates the space for the buffer data but `dst' must be already * allocated by the caller. This function is equivalent to - * silc_buffer_strformat but allocates memory from `stack'. + * silc_buffer_strformat but allocates memory from `stack'. Returns -1 + * if system is out of memory and sets silc_errno. * * Note that this call consumes the `stack'. The caller should push the * stack before calling the function and pop it later. @@ -339,139 +361,175 @@ int silc_buffer_strformat(SilcBuffer dst, ...); ***/ int silc_buffer_sstrformat(SilcStack stack, SilcBuffer dst, ...); -/****d* silcutil/SilcBufferFormatAPI/SilcBufferParamType +/****d* silcutil/SilcBufferFormatAPI/SILC_STR_SINT8 * * NAME * - * typedef enum { ... } SilcBufferParamType; + * #define SILC_STR_SINT8() ... * * DESCRIPTION * - * Buffer parameter types. These are not needed when formatting or - * unformatting buffers. Use the macros such as SILC_STR_UI_CHAR and - * others instead. These types may be used when describing what a - * buffer looks like, and how it may be formatted and unformatted. + * One 8-bit signed integer. * - * SOURCE - */ -typedef enum { - SILC_PARAM_SI8_CHAR, /* Signed 8-bit char */ - SILC_PARAM_UI8_CHAR, /* Unsigned 8-bit char */ - SILC_PARAM_SI16_SHORT, /* Signed 16-bit int */ - SILC_PARAM_UI16_SHORT, /* Unsigned 16-bit int */ - SILC_PARAM_SI32_INT, /* Signed 32-bit int */ - SILC_PARAM_UI32_INT, /* Unsigned 32-bit int */ - SILC_PARAM_SI64_INT, /* Signed 64-bit int */ - SILC_PARAM_UI64_INT, /* Unsigned 64-bit int */ - SILC_PARAM_UI8_STRING, /* String (max len 8-bits)*/ - SILC_PARAM_UI16_STRING, /* String (max len 16-bits) */ - SILC_PARAM_UI32_STRING, /* String (max len 32-bits) */ - SILC_PARAM_BUFFER, /* SilcBuffer */ - - /* Internal types */ - SILC_PARAM_DATA, /* Binary data */ - SILC_PARAM_UI8_NSTRING, /* String (max len 8-bits) */ - SILC_PARAM_UI16_NSTRING, /* String (max len 16-bits) */ - SILC_PARAM_UI32_NSTRING, /* String (max len 32-bits) */ - SILC_PARAM_UI8_STRING_ALLOC, /* Alloc + memcpy */ - SILC_PARAM_UI16_STRING_ALLOC, /* Alloc + memcpy */ - SILC_PARAM_UI32_STRING_ALLOC, /* Alloc + memcpy */ - SILC_PARAM_UI8_NSTRING_ALLOC, /* Alloc + memcpy */ - SILC_PARAM_UI16_NSTRING_ALLOC, /* Alloc + memcpy */ - SILC_PARAM_UI32_NSTRING_ALLOC, /* Alloc + memcpy */ - SILC_PARAM_DATA_ALLOC, /* Alloc + memcpy */ - SILC_PARAM_BUFFER_ALLOC, /* Alloc + memcpy */ - - SILC_PARAM_OFFSET, - SILC_PARAM_ADVANCE, - SILC_PARAM_FUNC, - - SILC_PARAM_UI_XNSTRING, - SILC_PARAM_UI_XNSTRING_ALLOC, - - SILC_PARAM_END -} SilcBufferParamType; -/***/ + * Formatting: SILC_STR_SINT8(SilcInt8) + * Unformatting: SILC_STR_SINT8(SilcInt8 *) + * + ***/ +#define SILC_STR_SINT8(x) SILC_PARAM_SINT8, (x) + +/****d* silcutil/SilcBufferFormatAPI/SILC_STR_UINT8 + * + * NAME + * + * #define SILC_STR_UINT8() ... + * + * DESCRIPTION + * + * One 8-bit unsigned integer. + * + * Formatting: SILC_STR_UINT8(SilcUInt8) + * Unformatting: SILC_STR_UINT8(SilcUInt8 *) + * + ***/ +#define SILC_STR_UINT8(x) SILC_PARAM_UINT8, (x) -/****d* silcutil/SilcBufferFormatAPI/SILC_STR_*_CHAR +/* Deprecated */ +#define SILC_STR_SI_CHAR(x) SILC_PARAM_SINT8, (x) +#define SILC_STR_UI_CHAR(x) SILC_PARAM_UINT8, (x) + +/****d* silcutil/SilcBufferFormatAPI/SILC_STR_SINT16 * * NAME * - * #define SILC_STR_UI_CHAR() ... - * #define SILC_STR_SI_CHAR() ... + * #define SILC_STR_SINT16() ... * * DESCRIPTION * - * One signed/unsigned character. + * SilcInt16. * - * Formatting: SILC_STR_SI_CHAR(char) - * SILC_STR_UI_CHAR(unsigned char) - * Unformatting: SILC_STR_SI_CHAR(char *) - * SILC_STR_UI_CHAR(unsigned char *) + * Formatting: SILC_STR_SINT16(SilcInt16) + * Unformatting: SILC_STR_SINT16(SilcInt16 *) * ***/ -#define SILC_STR_SI_CHAR(x) SILC_PARAM_SI8_CHAR, (x) -#define SILC_STR_UI_CHAR(x) SILC_PARAM_UI8_CHAR, (x) +#define SILC_STR_SINT16(x) SILC_PARAM_SINT16, (x) -/****d* silcutil/SilcBufferFormatAPI/SILC_STR_*_SHORT +/****d* silcutil/SilcBufferFormatAPI/SILC_STR_UINT16 * * NAME * - * #define SILC_STR_UI_SHORT() ... - * #define SILC_STR_SI_SHORT() ... + * #define SILC_STR_UINT16() ... * * DESCRIPTION * - * SilcInt16/SilcUInt16. + * SilcUInt16. * - * Formatting: SILC_STR_SI_SHORT(SilcInt16) - * SILC_STR_UI_SHORT(SilcUInt16) - * Unformatting: SILC_STR_SI_SHORT(SilcInt16 *) - * SILC_STR_UI_SHORT(SilcUInt16 *) + * Formatting: SILC_STR_UINT16(SilcUInt16) + * Unformatting: SILC_STR_UINT16(SilcUInt16 *) * ***/ -#define SILC_STR_SI_SHORT(x) SILC_PARAM_SI16_SHORT, (x) -#define SILC_STR_UI_SHORT(x) SILC_PARAM_UI16_SHORT, (x) +#define SILC_STR_UINT16(x) SILC_PARAM_UINT16, (x) + +/* Deprecated */ +#define SILC_STR_SI_SHORT(x) SILC_PARAM_SINT16, (x) +#define SILC_STR_UI_SHORT(x) SILC_PARAM_UINT16, (x) -/****d* silcutil/SilcBufferFormatAPI/SILC_STR_*_INT +/****d* silcutil/SilcBufferFormatAPI/SILC_STR_SINT32 * * NAME * - * #define SILC_STR_UI_INT() ... - * #define SILC_STR_SI_INT() ... + * #define SILC_STR_SINT32() ... * * DESCRIPTION * - * SilcInt32/SilcUInt32. + * SilcInt32. * - * Formatting: SILC_STR_SI_INT(SilcInt32) - * SILC_STR_UI_INT(SilcUInt32) - * Unformatting: SILC_STR_SI_INT(SilcInt32 *) - * SILC_STR_UI_INT(SilcUInt32 *) + * Formatting: SILC_STR_SINT32(SilcInt32) + * Unformatting: SILC_STR_SINT32(SilcInt32 *) * ***/ -#define SILC_STR_SI_INT(x) SILC_PARAM_SI32_INT, (x) -#define SILC_STR_UI_INT(x) SILC_PARAM_UI32_INT, (x) +#define SILC_STR_SINT32(x) SILC_PARAM_SINT32, (x) -/****d* silcutil/SilcBufferFormatAPI/SILC_STR_*_INT64 +/****d* silcutil/SilcBufferFormatAPI/SILC_STR_UINT32 * * NAME * - * #define SILC_STR_UI_INT64() ... - * #define SILC_STR_SI_INT64() ... + * #define SILC_STR_UINT32() ... * * DESCRIPTION * - * SilcInt64/SilcUInt64. + * SilcUInt32. + * + * Formatting: SILC_STR_UINT32(SilcUInt32) + * Unformatting: SILC_STR_UINT32(SilcUInt32 *) + * + ***/ +#define SILC_STR_UINT32(x) SILC_PARAM_UINT32, (x) + +/* Deprecated */ +#define SILC_STR_SI_INT(x) SILC_PARAM_SINT32, (x) +#define SILC_STR_UI_INT(x) SILC_PARAM_UINT32, (x) + +/****d* silcutil/SilcBufferFormatAPI/SILC_STR_SINT64 + * + * NAME + * + * #define SILC_STR_SINT64() ... + * + * DESCRIPTION + * + * SilcInt64. + * + * Formatting: SILC_STR_SINT64(SilcInt64) + * Unformatting: SILC_STR_SINT64(SilcInt64 *) + * + ***/ +#define SILC_STR_SI_INT64(x) SILC_PARAM_SINT64, (x) + +/****d* silcutil/SilcBufferFormatAPI/SILC_STR_UINT64 + * + * NAME + * + * #define SILC_STR_UINT64() ... + * + * DESCRIPTION + * + * SilcUInt64. + * + * Formatting: SILC_STR_UINT64(SilcUInt64) + * Unformatting: SILC_STR_UINT64(SilcUInt64 *) + * + ***/ +#define SILC_STR_UI_INT64(x) SILC_PARAM_UINT64, (x) + +/* Deprecated */ +#define SILC_STR_SI_INT64(x) SILC_PARAM_SINT64, (x) +#define SILC_STR_UI_INT64(x) SILC_PARAM_UINT64, (x) + +/****d* silcutil/SilcBufferFormatAPI/SILC_STR_STRING + * + * NAME + * + * #define SILC_STR_STRING() ... + * + * DESCRIPTION + * + * Encode NULL terminated string. Use this only for formatting. + * + * Formatting: SILC_STR_STRING(char *) + * + * For unformatting use one of the SILC_STR_*_STRING macros, which + * automatically gets the length of the string from the buffer. Note + * SILC_STR_STRING does not save the length of the string into the buffer. + * The caller must do that in order for the unformatting macros to work. * - * Formatting: SILC_STR_SI_INT64(SilcInt64) - * SILC_STR_UI_INT64(SilcUInt64) - * Unformatting: SILC_STR_SI_INT64(SilcInt64 *) - * SILC_STR_UI_INT64(SilcUInt64 *) + * Example: + * + * Formatting: ..., SILC_STR_UINT32(strlen(string)), + * SILC_STR_STRING(string), ... + * Unformatting: ..., SILC_STR_UI32_STRING(&string), ... * ***/ -#define SILC_STR_SI_INT64(x) SILC_PARAM_SI64_INT, (x) -#define SILC_STR_UI_INT64(x) SILC_PARAM_UI64_INT, (x) +#define SILC_STR_STRING(x) SILC_PARAM_UI8_STRING, (x) /****d* silcutil/SilcBufferFormatAPI/SILC_STR_*_STRING * @@ -495,33 +553,32 @@ typedef enum { * * Unformatting procedure will check for length of the string from the * buffer before trying to get the string out. Thus, one *must* format the - * length as UI_INT or UI_SHORT into the buffer *before* formatting the - * actual string to the buffer, and, in unformatting one must ignore the + * length as UINT32 or UINT16 or UINT8 into the buffer *before* formatting + * the actual string to the buffer, and, in unformatting one ignores the * length of the string because unformatting procedure will take it * automatically. * * Example: * - * Formatting: ..., SILC_STR_UI_INT(strlen(string)), + * Formatting: ..., SILC_STR_UINT32(strlen(string)), * SILC_STR_UI32_STRING(string), ... * Unformatting: ..., SILC_STR_UI32_STRING(&string), ... * * I.e., you can ignore the formatted length field in unformatting. * * UI8, UI16 and UI32 means that the length is considered to be - * either char (8 bits), short (16 bits) or int (32 bits) in - * unformatting. + * either UINT8, UINT16 or UINT32 in unformatting. * * _ALLOC routines automatically allocates memory for the variable sent * as argument in unformatting. * ***/ #define SILC_STR_UI8_STRING(x) SILC_PARAM_UI8_STRING, (x) -#define SILC_STR_UI8_STRING_ALLOC(x) SILC_PARAM_UI8_STRING_ALLOC, (x) +#define SILC_STR_UI8_STRING_ALLOC(x) SILC_PARAM_UI8_STRING | SILC_PARAM_ALLOC, (x) #define SILC_STR_UI16_STRING(x) SILC_PARAM_UI16_STRING, (x) -#define SILC_STR_UI16_STRING_ALLOC(x) SILC_PARAM_UI16_STRING_ALLOC, (x) +#define SILC_STR_UI16_STRING_ALLOC(x) SILC_PARAM_UI16_STRING | SILC_PARAM_ALLOC, (x) #define SILC_STR_UI32_STRING(x) SILC_PARAM_UI32_STRING, (x) -#define SILC_STR_UI32_STRING_ALLOC(x) SILC_PARAM_UI32_STRING_ALLOC, (x) +#define SILC_STR_UI32_STRING_ALLOC(x) SILC_PARAM_UI32_STRING | SILC_PARAM_ALLOC, (x) /****d* silcutil/SilcBufferFormatAPI/SILC_STR_*_NSTRING * @@ -543,14 +600,14 @@ typedef enum { * * Unformatting procedure will check for length of the string from the * buffer before trying to get the string out. Thus, one *must* format the - * length as UI_INT or UI_SHORT into the buffer *before* formatting the - * actual string to the buffer, and, in unformatting one must ignore the + * length as UINT32 or UINT16 or UINT8 into the buffer *before* formatting + * the actual string to the buffer, and, in unformatting one ignores the * length of the string because unformatting procedure will take it * automatically. * * Example: * - * Formatting: ..., SILC_STR_UI_INT(strlen(string)), + * Formatting: ..., SILC_STR_UINT32(strlen(string)), * SILC_STR_UI32_NSTRING(string, strlen(string)), ... * Unformatting: ..., SILC_STR_UI32_NSTRING(&string, &len), ... * @@ -559,8 +616,7 @@ typedef enum { * argument (&len in above example). * * UI8, UI16 and UI32 means that the length is considered to be - * either char (8 bits), short (16 bits) or int (32 bits) in - * unformatting. + * either UINT8, UINT16 or UINT32 in unformatting. * * _ALLOC routines automatically allocates memory for the variable sent * as argument in unformatting. @@ -568,13 +624,13 @@ typedef enum { ***/ #define SILC_STR_UI8_NSTRING(x, l) SILC_PARAM_UI8_NSTRING, (x), (l) #define SILC_STR_UI8_NSTRING_ALLOC(x, l) \ - SILC_PARAM_UI8_NSTRING_ALLOC, (x), (l) + SILC_PARAM_UI8_NSTRING | SILC_PARAM_ALLOC, (x), (l) #define SILC_STR_UI16_NSTRING(x, l) SILC_PARAM_UI16_NSTRING, (x), (l) #define SILC_STR_UI16_NSTRING_ALLOC(x, l) \ - SILC_PARAM_UI16_NSTRING_ALLOC, (x), (l) + SILC_PARAM_UI16_NSTRING | SILC_PARAM_ALLOC, (x), (l) #define SILC_STR_UI32_NSTRING(x, l) SILC_PARAM_UI32_NSTRING, (x), (l) #define SILC_STR_UI32_NSTRING_ALLOC(x, l) \ - SILC_PARAM_UI32_NSTRING_ALLOC, (x), (l) + SILC_PARAM_UI32_NSTRING | SILC_PARAM_ALLOC, (x), (l) /****d* silcutil/SilcBufferFormatAPI/SILC_STR_DATA * @@ -597,12 +653,12 @@ typedef enum { * as argument in unformatting. * ***/ -#define SILC_STR_DATA(x, l) SILC_PARAM_DATA, (x), (l) -#define SILC_STR_DATA_ALLOC(x, l) SILC_PARAM_DATA_ALLOC, (x), (l) +#define SILC_STR_DATA(x, l) SILC_PARAM_UICHAR, (x), (l) +#define SILC_STR_DATA_ALLOC(x, l) SILC_PARAM_UICHAR | SILC_PARAM_ALLOC, (x), (l) /* Deprecated */ -#define SILC_STR_UI_XNSTRING(x, l) SILC_PARAM_UI_XNSTRING, (x), (l) -#define SILC_STR_UI_XNSTRING_ALLOC(x, l) SILC_PARAM_UI_XNSTRING_ALLOC, (x), (l) +#define SILC_STR_UI_XNSTRING(x, l) SILC_PARAM_UICHAR, (x), (l) +#define SILC_STR_UI_XNSTRING_ALLOC(x, l) SILC_PARAM_UICHAR | SILC_PARAM_ALLOC, (x), (l) /****d* silcutil/SilcBufferFormatAPI/SILC_STR_BUFFER * @@ -628,7 +684,7 @@ typedef enum { * ***/ #define SILC_STR_BUFFER(x) SILC_PARAM_BUFFER, (x) -#define SILC_STR_BUFFER_ALLOC(x) SILC_PARAM_BUFFER_ALLOC, (x) +#define SILC_STR_BUFFER_ALLOC(x) SILC_PARAM_BUFFER | SILC_PARAM_ALLOC, (x) /****d* silcutil/SilcBufferFormatAPI/SILC_STR_FUNC * @@ -638,7 +694,7 @@ typedef enum { * * DESCRIPTION * - * SilcBuffer formatting. + * Formatting and unformatting of arbitrary data. * * Formatting: SILC_STR_FUNC(function, void *value, void *context) * Unformatting: SILC_STR_FUNC(function, void **value, void *context) @@ -664,7 +720,7 @@ typedef enum { * // Encode payload, encrypt and compute MAC. * silc_buffer_format(buf, * SILC_STR_FUNC(foo_encode_id, id, ctx), - * SILC_STR_UI_SHORT(len), + * SILC_STR_UINT16(len), * SILC_STR_DATA(data, len), * SILC_STR_FUNC(foo_buf_encrypt, NULL, key), * SILC_STR_FUNC(foo_buf_hmac, NULL, hmac), @@ -676,13 +732,141 @@ typedef enum { * SILC_STR_FUNC(foo_buf_hmac, NULL, hmac), * SILC_STR_FUNC(foo_buf_decrypt, NULL, key), * SILC_STR_FUNC(foo_decode_id, &id, ctx), - * SILC_STR_UI_SHORT(&len), + * SILC_STR_UINT16(&len), * SILC_STR_END); * ***/ #define SILC_STR_FUNC(func, val, context) SILC_PARAM_FUNC, \ func, (val), (context) +/****d* silcutil/SilcBufferFormatAPI/SilcBufferRegexFlags + * + * NAME + * + * typedef enum { ... } SilcBufferRegexFlags; + * + * DESCRIPTION + * + * Regular expression flags for SILC_STR_REGEX macro. The flags can be + * used to manipulate the behavior of the SILC_STR_REGEX. All flags + * may be combined unless otherwise stated. + * + * SOURCE + */ +typedef enum { + SILC_STR_REGEX_NONE = 0x00000000, + + /* By default mismatch will be skipped. Set this flag if mismatch should + cause error and stopping of the formatting/unformatting. */ + SILC_STR_REGEX_MISMATCH = 0x00000001, + + /* By default only the first match is found. Set this flag to find + all matches. */ + SILC_STR_REGEX_ALL = 0x00000002, + + /* By default the buffer position is advanced to the position of the + first match. Set this flag if the buffer should not be advanced to + the match. */ + SILC_STR_REGEX_NO_ADVANCE = 0x00000004, + + /* By default SILC_STR_REGEX performs the match on the whole buffer. Set + this flag to make it behave like sed and match line by line. Each line + must end with '\n'. If buffer doesn't have '\n' it is considered to be + one line. Note that, any formatting done immediately after SILC_STR_REGEX + block with this flag will be formatted to the end of the buffer (after + last line). Use SILC_STR_OFFSET* macros to change the position if + needed. Also note that, any encoding macro inside the SILC_STR_REGEX + block will see only the matched line (including '\n'), instead of whole + buffer after the match. */ + SILC_STR_REGEX_NL = 0x00000008, + + /* Set this flag to not match the regular expression, but to match everything + else. When combined with SILC_STR_REGEX_NL this flag matches all other + lines except the ones with matching regular expression. */ + SILC_STR_REGEX_NOT = 0x00000010, + + /* By default the buffer is advanced to the first match and the rest of the + buffer remains as is. Set this flag to pass the exact match to the + SILC_STR_* macros in the SILC_STR_REGEX block; macros see the start of + the match and the end of the match, but not rest of the buffer (ie. with + match 'foo' the size of the buffer is 3 bytes). */ + SILC_STR_REGEX_INCLUSIVE = 0x00000020, +} SilcBufferRegexFlags; +/***/ + +/****d* silcutil/SilcBufferFormatAPI/SILC_STR_REGEX + * + * NAME + * + * #define SILC_STR_REGEX() ... + * + * DESCRIPTION + * + * Regular expression matching within the buffer. + * + * Formatting: SILC_STR_REGEX(char *regex, SilcBufferRegexFlags flags) + * Unformatting: SILC_STR_REGEX(char *regex, SilcBufferRegexFlags flags) + * + * SILC_STR_REGEX can be used to do regular expression matching within + * the SilcBuffer. When the string in the buffer matches the regular + * expression the position of the buffer is advanced to the position of + * the first match (rest of the buffer remains intact). If the regular + * expression does not match it is skipped, unless the flags specify + * otherwise. If flags are not needed they can be set to 0. + * + * In addition of matching regular expressions it can be used in a + * Stream Editor (sed) and Awk like fashion. The regular expression can be + * matched and then edited by any of the SILC_STR_* macros. The flags + * can be used to perform complex operations on the data. Some sed + * features that cannot be directly done with the flags can be done with + * SILC_STR_FUNC and other macros (the SILC_STR_FUNC could do anything + * after the match). + * + * The SILC_STR_REGEX itself is used as an opening of a block of encoding + * macros and must be closed with SILC_STR_END. This means that for + * each SILC_STR_REGEX there must be one SILC_STR_END. See examples for + * more information. + * + * The SILC_STR_REGEX can be used in buffer unformatting also to do + * string matching and parsing, but not editing, except with SILC_STR_FUNC + * macro, which can do anything caller wants. + * + * EXAMPLE + * + * // sed 's/foo/bar/', replace first foo with bar + * silc_buffer_format(buffer, + * SILC_STR_REGEX("foo", 0), + * SILC_STR_STRING("bar"), + * SILC_STR_END, SILC_STR_END); + * + * // sed 's/foo/bar/g', replace all foo's with bar + * silc_buffer_format(buffer, + * SILC_STR_REGEX("foo", SILC_STR_REGEX_ALL), + * SILC_STR_STRING("bar"), + * SILC_STR_END, SILC_STR_END); + * + * // sed '/baz/s/foo/bar/g, replace all foo's with bar on lines with baz + * silc_buffer_format(buffer, + * SILC_STR_REGEX("baz", SILC_STR_REGEX_NL), + * SILC_STR_REGEX("foo", SILC_STR_REGEX_ALL), + * SILC_STR_STRING("bar"), + * SILC_STR_END, + * SILC_STR_END, SILC_STR_END); + * + * // Print all lines that start with 'R' + * int print(SilcStack stack, SilcBuffer buf, void *value, void *context) + * { + * return fwrite(silc_buffer_data(buf), 1, silc_buffer_len(buf), stdout); + * } + * + * silc_buffer_unformat(buffer, + * SILC_STR_REGEX("^R", SILC_STR_REGEX_NL), + * SILC_STR_FUNC(print, NULL, NULL), + * SILC_STR_END, SILC_STR_END); + * + ***/ +#define SILC_STR_REGEX(regex, flags) SILC_PARAM_REGEX, (regex), (flags) + /****d* silcutil/SilcBufferFormatAPI/SILC_STR_OFFSET * * NAME @@ -708,6 +892,40 @@ typedef enum { ***/ #define SILC_STR_OFFSET(x) SILC_PARAM_OFFSET, (x) +/****d* silcutil/SilcBufferFormatAPI/SILC_STR_OFFSET_START + * + * NAME + * + * #define SILC_STR_OFFSET_START ... + * + * DESCRIPTION + * + * Moves the buffer position to the start of the data area. + * + * Example: + * + * ..., SILC_STR_OFFSET_START, ... + * + ***/ +#define SILC_STR_OFFSET_START SILC_PARAM_OFFSET_START + +/****d* silcutil/SilcBufferFormatAPI/SILC_STR_OFFSET_END + * + * NAME + * + * #define SILC_STR_OFFSET_END ... + * + * DESCRIPTION + * + * Moves the buffer position to the end of the data area. + * + * Example: + * + * ..., SILC_STR_OFFSET_END, ... + * + ***/ +#define SILC_STR_OFFSET_END SILC_PARAM_OFFSET_END + /****d* silcutil/SilcBufferFormatAPI/SILC_STR_ADVANCE * * NAME @@ -718,8 +936,8 @@ typedef enum { * * 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 + * buffer is positioned at the start of the data. With SILC_STR_ADVANCE + * the buffer will be positioned at the end of the data. This makes it * easy to add new data immediately after the previously added data. * The SILC_STR_ADVANCE may also be used in unformatting. *