X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilcutil%2Fsilcbuffmt.c;h=6534696384896110510b0844fa623379fb38f49b;hb=e7b6c157b80152bf9fb9266e6bdd93f9fb0db776;hp=559e7309d9cf700ce2cc9259dbe173ea7a4e60b4;hpb=38b10925eeea619c2b6fa646892df4416e6dd08f;p=silc.git diff --git a/lib/silcutil/silcbuffmt.c b/lib/silcutil/silcbuffmt.c index 559e7309..65346963 100644 --- a/lib/silcutil/silcbuffmt.c +++ b/lib/silcutil/silcbuffmt.c @@ -49,11 +49,89 @@ do { \ goto fail; \ } \ if (silc_unlikely((req + 1) <= 0)) { \ - silc_set_errno(SILC_ERR_UNDERFLOW); \ + silc_set_errno(SILC_ERR_OVERFLOW); \ goto fail; \ } \ } while(0) +#if defined(SILC_DEBUG) +static const char *silc_param_string(SilcParam fmt) +{ + if (fmt == SILC_PARAM_SINT8) + return "SINT8"; + if (fmt == SILC_PARAM_UINT8) + return "UINT8"; + if (fmt == SILC_PARAM_SINT16) + return "SINT16"; + if (fmt == SILC_PARAM_UINT16) + return "UINT16"; + if (fmt == SILC_PARAM_SINT32) + return "SINT32"; + if (fmt == SILC_PARAM_UINT32) + return "UINT32"; + if (fmt == SILC_PARAM_SINT64) + return "SINT64"; + if (fmt == SILC_PARAM_UINT64) + return "UINT64"; + if (fmt == SILC_PARAM_SICHAR) + return "SICHAR"; + if (fmt == (SILC_PARAM_SICHAR | SILC_PARAM_ALLOC)) + return "SICHAR ALLOC"; + if (fmt == SILC_PARAM_UICHAR) + return "UICHAR"; + if (fmt == (SILC_PARAM_UICHAR | SILC_PARAM_ALLOC)) + return "UICHAR ALLOC"; + if (fmt == (SILC_PARAM_UICHAR | SILC_PARAM_REPLACE)) + return "UICHAR REPLACE"; + if (fmt == SILC_PARAM_BUFFER) + return "BUFFER"; + if (fmt == (SILC_PARAM_BUFFER | SILC_PARAM_ALLOC)) + return "BUFFER ALLOC"; + if (fmt == SILC_PARAM_PTR) + return "PTR"; + if (fmt == SILC_PARAM_END) + return "END"; + if (fmt == SILC_PARAM_UI8_STRING) + return "UI8_STRING"; + if (fmt == SILC_PARAM_UI16_STRING) + return "UI16_STRING"; + if (fmt == SILC_PARAM_UI32_STRING) + return "UI32_STRING"; + if (fmt == SILC_PARAM_UI8_NSTRING) + return "UI8_STRING"; + if (fmt == SILC_PARAM_UI16_NSTRING) + return "UI16_STRING"; + if (fmt == SILC_PARAM_UI32_NSTRING) + return "UI32_STRING"; + if (fmt == (SILC_PARAM_UI8_STRING | SILC_PARAM_ALLOC)) + return "UI8_STRING ALLOC"; + if (fmt == (SILC_PARAM_UI16_STRING | SILC_PARAM_ALLOC)) + return "UI16_STRING ALLOC"; + if (fmt == (SILC_PARAM_UI32_STRING | SILC_PARAM_ALLOC)) + return "UI32_STRING ALLOC"; + if (fmt == (SILC_PARAM_UI8_NSTRING | SILC_PARAM_ALLOC)) + return "UI8_STRING ALLOC"; + if (fmt == (SILC_PARAM_UI16_NSTRING | SILC_PARAM_ALLOC)) + return "UI16_STRING ALLOC"; + if (fmt == (SILC_PARAM_UI32_NSTRING | SILC_PARAM_ALLOC)) + return "UI32_STRING"; + if (fmt == SILC_PARAM_OFFSET) + return "OFFSET"; + if (fmt == SILC_PARAM_ADVANCE) + return "ADDVANCE"; + if (fmt == SILC_PARAM_FUNC) + return "FUNC"; + if (fmt == SILC_PARAM_REGEX) + return "REGEX"; + if (fmt == SILC_PARAM_OFFSET_START) + return "OFFSET_START"; + if (fmt == SILC_PARAM_OFFSET_END) + return "OFFSET_END"; + if (fmt == SILC_PARAM_DELETE) + return "DELETE"; + return ""; +} +#endif /* SILC_DEBUG */ /******************************* Formatting *********************************/ @@ -68,7 +146,11 @@ int silc_buffer_sformat_vp_i(SilcStack stack, SilcBuffer dst, va_list ap, while (1) { fmt = va_arg(ap, SilcParam); - SILC_LOG_DEBUG(("Buffer format type %d", fmt)); +#if defined(SILC_DEBUG) + if (process) + SILC_LOG_DEBUG(("Buffer format type %s (%d)", + silc_param_string(fmt), fmt)); +#endif /* SILC_DEBUG */ switch (fmt) { case SILC_PARAM_FUNC: @@ -99,7 +181,7 @@ int silc_buffer_sformat_vp_i(SilcStack stack, SilcBuffer dst, va_list ap, { const char *regex = va_arg(ap, char *); SilcBufferRegexFlags rflags = va_arg(ap, SilcUInt32); - SilcBufferStruct match, saved; + SilcBufferStruct match; SilcBool match_all = (rflags & SILC_STR_REGEX_ALL) != 0; SilcBool match_nl = (rflags & SILC_STR_REGEX_NL) != 0; SilcBool ret; @@ -111,15 +193,12 @@ int silc_buffer_sformat_vp_i(SilcStack stack, SilcBuffer dst, va_list ap, break; if (!regex) - goto fail; - - memset(&saved, 0, sizeof(saved)); + break; if (match_nl) { start_nl_match: /* Match for '\n' in the buffer. If not found, treat as line without '\n' (buffer has only one line, or this is last line). */ - saved = *dst; if (silc_regex_buffer(dst, "\n", &match, NULL)) dst->tail = match.tail; } @@ -178,7 +257,7 @@ int silc_buffer_sformat_vp_i(SilcStack stack, SilcBuffer dst, va_list ap, flen += (dst->tail - dst->data); if (!silc_buffer_pull(dst, (dst->tail - dst->data))) goto fail; - if (!silc_buffer_pull_tail(dst, (saved.tail - dst->tail))) + if (!silc_buffer_pull_tail(dst, silc_buffer_taillen(dst))) goto fail; if (silc_buffer_len(dst) > 0) @@ -211,20 +290,39 @@ int silc_buffer_sformat_vp_i(SilcStack stack, SilcBuffer dst, va_list ap, break; } - case SILC_PARAM_UI8_STRING | SILC_PARAM_APPEND: - case SILC_PARAM_UI16_STRING | SILC_PARAM_APPEND: - case SILC_PARAM_UI32_STRING | SILC_PARAM_APPEND: + case SILC_PARAM_UICHAR | SILC_PARAM_REPLACE: { - char *x = va_arg(ap, char *); - SilcUInt32 tmp_len = x ? strlen(x) : 0; + unsigned char *x = va_arg(ap, unsigned char *); + SilcUInt32 x_len = va_arg(ap, SilcUInt32); if (!process) break; - if (x && tmp_len) { - FORMAT_HAS_SPACE_APPEND(stack, dst, tmp_len); - silc_buffer_put(dst, x, tmp_len); - silc_buffer_pull(dst, tmp_len); + if (!x) + break; + + if (silc_buffer_len(dst) == x_len) { + /* Replace */ + if (x_len) { + silc_buffer_put(dst, x, x_len); + silc_buffer_pull(dst, x_len); + flen += x_len; + } + } else if (silc_buffer_len(dst) < x_len) { + /* Append */ + if (x_len) { + FORMAT_HAS_SPACE_APPEND(stack, dst, x_len); + silc_buffer_put(dst, x, x_len); + silc_buffer_pull(dst, x_len); + } + } else { + /* Delete */ + if (x_len) { + silc_buffer_put(dst, x, x_len); + silc_buffer_pull(dst, x_len); + flen += x_len; + } + goto delete_rest; } break; } @@ -388,6 +486,39 @@ int silc_buffer_sformat_vp_i(SilcStack stack, SilcBuffer dst, va_list ap, } break; + case SILC_PARAM_DELETE: + { + int n = va_arg(ap, int); + + if (!process) + break; + + if (n == -1) { + /* Move all data from tail to data area */ + if (dst->data != dst->tail) { + delete_rest: + n = silc_buffer_len(dst); + memmove(dst->data, dst->tail, silc_buffer_taillen(dst)); + silc_buffer_push_tail(dst, n); + if (!silc_buffer_srealloc(stack, dst, + silc_buffer_truelen(dst) - n)) + goto fail; + } + break; + } + + if (n > silc_buffer_len(dst)) + goto fail; + + memmove(dst->data, dst->data + n, (silc_buffer_len(dst) - n) + + silc_buffer_taillen(dst)); + silc_buffer_push_tail(dst, silc_buffer_len(dst) - n); + if (!silc_buffer_srealloc(stack, dst, silc_buffer_truelen(dst) - n)) + goto fail; + + break; + } + case SILC_PARAM_OFFSET: { int offst = va_arg(ap, int); @@ -508,7 +639,8 @@ int silc_buffer_sunformat_vp_i(SilcStack stack, SilcBuffer src, va_list ap, while (1) { fmt = va_arg(ap, SilcParam); - SILC_LOG_DEBUG(("Buffer unformat type %d", fmt)); + SILC_LOG_DEBUG(("Buffer unformat type %s (%d)", + silc_param_string(fmt), fmt)); switch (fmt) { case SILC_PARAM_FUNC: @@ -538,7 +670,7 @@ int silc_buffer_sunformat_vp_i(SilcStack stack, SilcBuffer src, va_list ap, { const char *regex = va_arg(ap, char *); SilcBufferRegexFlags rflags = va_arg(ap, SilcUInt32); - SilcBufferStruct match, saved; + SilcBufferStruct match; SilcBool match_all = (rflags & SILC_STR_REGEX_ALL) != 0; SilcBool match_nl = (rflags & SILC_STR_REGEX_NL) != 0; SilcBool ret; @@ -550,15 +682,12 @@ int silc_buffer_sunformat_vp_i(SilcStack stack, SilcBuffer src, va_list ap, break; if (!regex) - goto fail; - - memset(&saved, 0, sizeof(saved)); + break; if (match_nl) { start_nl_match: /* Match for '\n' in the buffer. If not found, treat as line without '\n' (buffer has only one line, or this is last line). */ - saved = *src; if (silc_regex_buffer(src, "\n", &match, NULL)) src->tail = match.tail; } @@ -581,7 +710,6 @@ int silc_buffer_sunformat_vp_i(SilcStack stack, SilcBuffer src, va_list ap, if (!(rflags & SILC_STR_REGEX_NO_ADVANCE)) { /* Advance buffer after match */ - UNFORMAT_HAS_SPACE(src, (match.data - src->data)); if (!silc_buffer_pull(src, (match.data - src->data))) goto fail; } @@ -603,7 +731,6 @@ int silc_buffer_sunformat_vp_i(SilcStack stack, SilcBuffer src, va_list ap, goto fail; /* Advance buffer after formatting */ - UNFORMAT_HAS_SPACE(src, ret_len); if (!silc_buffer_pull(src, ret_len)) goto fail; @@ -614,10 +741,9 @@ int silc_buffer_sunformat_vp_i(SilcStack stack, SilcBuffer src, va_list ap, if (match_nl) { /* Go to next line, it is at the end of the data area. Adjust the tail area of the target buffer to show rest of the buffer. */ - UNFORMAT_HAS_SPACE(src, src->tail - src->data); if (!silc_buffer_pull(src, (src->tail - src->data))) goto fail; - if (!silc_buffer_pull_tail(src, (saved.tail - src->tail))) + if (!silc_buffer_pull_tail(src, silc_buffer_taillen(src))) goto fail; if (silc_buffer_len(src) > 0) @@ -626,6 +752,7 @@ int silc_buffer_sunformat_vp_i(SilcStack stack, SilcBuffer src, va_list ap, /* Skip to the next SILC_PARAM_END */ silc_buffer_sunformat_vp_i(NULL, src, ap, FALSE); + break; } break; @@ -1096,6 +1223,9 @@ int silc_buffer_sunformat_vp_i(SilcStack stack, SilcBuffer src, va_list ap, goto ok; break; + case SILC_PARAM_DELETE: + break; + default: SILC_LOG_DEBUG(("Bad buffer formatting type `%d'. Could not " "format the data.", fmt));