From: Pekka Riikonen Date: Sun, 8 Jul 2007 17:27:37 +0000 (+0000) Subject: Added silc_buffer_sfree and reorganized silcbuffer.h. X-Git-Tag: 1.2.beta1~198 X-Git-Url: http://git.silcnet.org/gitweb/?a=commitdiff_plain;h=d193b3700c5955f07de29336140e9f69961a938a;p=runtime.git Added silc_buffer_sfree and reorganized silcbuffer.h. --- diff --git a/lib/silcutil/Makefile.ad b/lib/silcutil/Makefile.ad index 5412a6c1..e7e540d8 100644 --- a/lib/silcutil/Makefile.ad +++ b/lib/silcutil/Makefile.ad @@ -71,7 +71,8 @@ libsilcutil_la_SOURCES = \ silcsnprintf.c \ silcthread.c \ silcdll.c \ - silcenv.c + silcenv.c \ + silcbase64.c #ifdef SILC_DIST_TOOLKIT include_HEADERS = \ @@ -114,7 +115,8 @@ include_HEADERS = \ silcstack_i.h \ silcsnprintf.h \ silcdll.h \ - silcenv.h + silcenv.h \ + silcbase64.h SILC_EXTRA_DIST = tests #endif SILC_DIST_TOOLKIT diff --git a/lib/silcutil/silcbuffer.h b/lib/silcutil/silcbuffer.h index 7dec1149..5fb70b84 100644 --- a/lib/silcutil/silcbuffer.h +++ b/lib/silcutil/silcbuffer.h @@ -254,7 +254,54 @@ SilcBuffer silc_buffer_alloc(SilcUInt32 len) if (silc_likely(len)) { /* Allocate the actual data area */ - sb->head = (unsigned char *)silc_calloc(len, sizeof(*sb->head)); + sb->head = (unsigned char *)silc_malloc(len * sizeof(*sb->head)); + if (silc_unlikely(!sb->head)) + return NULL; + + /* Set pointers to the new buffer */ + sb->data = sb->head; + sb->tail = sb->head; + sb->end = sb->head + len; + } + + return sb; +} + +/****f* silcutil/SilcBufferAPI/silc_buffer_salloc + * + * SYNOPSIS + * + * static inline + * SilcBuffer silc_buffer_salloc(SilcStack stack, SilcUInt32 len); + * + * DESCRIPTION + * + * Allocates new SilcBuffer and returns it. + * + * This routine use SilcStack are memory source. If `stack' is NULL + * reverts back to normal allocating routine. + * + * Note that this call consumes the `stack'. The caller should push the + * stack before calling the function and pop it later. + * + ***/ + +static inline +SilcBuffer silc_buffer_salloc(SilcStack stack, SilcUInt32 len) +{ + SilcBuffer sb; + + if (!stack) + return silc_buffer_alloc(len); + + /* Allocate new SilcBuffer */ + sb = (SilcBuffer)silc_scalloc(stack, 1, sizeof(*sb)); + if (silc_unlikely(!sb)) + return NULL; + + if (silc_likely(len)) { + /* Allocate the actual data area */ + sb->head = (unsigned char *)silc_smalloc(stack, len * sizeof(*sb->head)); if (silc_unlikely(!sb->head)) return NULL; @@ -282,6 +329,7 @@ SilcBuffer silc_buffer_alloc(SilcUInt32 len) * * Must not be called for buffers allocated with silc_buffer_salloc, * silc_buffer_salloc_size, silc_buffer_scopy and silc_buffer_sclone. + * Call silc_buffer_sfree instead. * ***/ @@ -298,6 +346,37 @@ void silc_buffer_free(SilcBuffer sb) } } +/****f* silcutil/SilcBufferAPI/silc_buffer_sfree + * + * SYNOPSIS + * + * static inline + * void silc_buffer_free(SilcStack stack, SilcBuffer sb); + * + * DESCRIPTION + * + * Frees SilcBuffer. If `stack' is NULL this calls silc_buffer_free. Can + * be called safely `sb' as NULL. + * + ***/ + +static inline +void silc_buffer_sfree(SilcStack stack, SilcBuffer sb) +{ + if (stack) { +#ifdef SILC_DEBUG + if (sb) { + if (sb->head) + memset(sb->head, 'F', silc_buffer_truelen(sb)); + memset(sb, 'F', sizeof(*sb)); + } +#endif /* SILC_DEBUG */ + return; + } + + silc_buffer_free(sb); +} + /****f* silcutil/SilcBufferAPI/silc_buffer_steal * * SYNOPSIS @@ -343,6 +422,7 @@ unsigned char *silc_buffer_steal(SilcBuffer sb, SilcUInt32 *data_len) * * Must not be called for buffers allocated with silc_buffer_salloc, * silc_buffer_salloc_size, silc_buffer_scopy and silc_buffer_sclone. + * Use silc_buffer_spurge instead. * ***/ @@ -352,6 +432,36 @@ void silc_buffer_purge(SilcBuffer sb) silc_free(silc_buffer_steal(sb, NULL)); } +/****f* silcutil/SilcBufferAPI/silc_buffer_spurge + * + * SYNOPSIS + * + * static inline + * void silc_buffer_spurge(SilcStack stack, SilcBuffer sb); + * + * DESCRIPTION + * + * Same as silc_buffer_free but free's only the contents of the buffer + * not the buffer itself. The `sb' remains intact, data is freed. Buffer + * is ready for re-use after calling this function. If `stack' is NULL + * this calls silc_buffer_purge. + * + ***/ + +static inline +void silc_buffer_spurge(SilcStack stack, SilcBuffer sb) +{ + if (stack) { +#ifdef SILC_DEBUG + if (sb && sb->head) + memset(silc_buffer_steal(sb, NULL), 'F', silc_buffer_truelen(sb)); +#endif /* SILC_DEBUG */ + return; + } + + silc_buffer_purge(sb); +} + /****f* silcutil/SilcBufferAPI/silc_buffer_set * * SYNOPSIS @@ -703,6 +813,37 @@ SilcBuffer silc_buffer_alloc_size(SilcUInt32 len) return sb; } +/****f* silcutil/SilcBufferAPI/silc_buffer_salloc_size + * + * SYNOPSIS + * + * static inline + * SilcBuffer silc_buffer_salloc_size(SilcStack stack, SilcUInt32 len); + * + * DESCRIPTION + * + * Allocates `len' bytes size buffer and moves the tail area automatically + * `len' bytes so that the buffer is ready to use without calling the + * silc_buffer_pull_tail. + * + * This routine use SilcStack are memory source. If `stack' is NULL + * reverts back to normal allocating routine. + * + * Note that this call consumes the `stack'. The caller should push the + * stack before calling the function and pop it later. + * + ***/ + +static inline +SilcBuffer silc_buffer_salloc_size(SilcStack stack, SilcUInt32 len) +{ + SilcBuffer sb = silc_buffer_salloc(stack, len); + if (silc_unlikely(!sb)) + return NULL; + silc_buffer_pull_tail(sb, len); + return sb; +} + /****f* silcutil/SilcBufferAPI/silc_buffer_reset * * SYNOPSIS @@ -815,148 +956,82 @@ SilcBuffer silc_buffer_copy(SilcBuffer sb) return sb_new; } -/****f* silcutil/SilcBufferAPI/silc_buffer_clone +/****f* silcutil/SilcBufferAPI/silc_buffer_scopy * * SYNOPSIS * * static inline - * SilcBuffer silc_buffer_clone(SilcBuffer sb); + * SilcBuffer silc_buffer_scopy(SilcStack stack, SilcBuffer sb); * * DESCRIPTION * - * Clones SilcBuffer. This generates new SilcBuffer and copies - * everything from the source buffer. The result is exact clone of - * the original buffer. Returns NULL on error. + * Generates copy of a SilcBuffer. This copies everything inside the + * currently valid data area, nothing more. Use silc_buffer_clone to + * copy entire buffer. + * + * This routine use SilcStack are memory source. If `stack' is NULL + * reverts back to normal allocating routine. + * + * Note that this call consumes the `stack'. The caller should push the + * stack before calling the function and pop it later. * ***/ static inline -SilcBuffer silc_buffer_clone(SilcBuffer sb) +SilcBuffer silc_buffer_scopy(SilcStack stack, SilcBuffer sb) { SilcBuffer sb_new; - sb_new = silc_buffer_alloc_size(silc_buffer_truelen(sb)); + sb_new = silc_buffer_salloc_size(stack, silc_buffer_len(sb)); if (silc_unlikely(!sb_new)) return NULL; - silc_buffer_put(sb_new, sb->head, silc_buffer_truelen(sb)); - sb_new->data = sb_new->head + silc_buffer_headlen(sb); - sb_new->tail = sb_new->data + silc_buffer_len(sb); + silc_buffer_put(sb_new, sb->data, silc_buffer_len(sb)); return sb_new; } -/****f* silcutil/SilcBufferAPI/silc_buffer_realloc +/****f* silcutil/SilcBufferAPI/silc_buffer_clone * * SYNOPSIS * * static inline - * SilcBuffer silc_buffer_realloc(SilcBuffer sb, SilcUInt32 newsize); + * SilcBuffer silc_buffer_clone(SilcBuffer sb); * * DESCRIPTION * - * Reallocates buffer. Old data is saved into the new buffer. The buffer - * is exact clone of the old one except that there is now more space - * at the end of buffer. This always returns the same `sb' unless `sb' - * was NULL. Returns NULL on error. + * Clones SilcBuffer. This generates new SilcBuffer and copies + * everything from the source buffer. The result is exact clone of + * the original buffer. Returns NULL on error. * ***/ static inline -SilcBuffer silc_buffer_realloc(SilcBuffer sb, SilcUInt32 newsize) +SilcBuffer silc_buffer_clone(SilcBuffer sb) { - SilcUInt32 hlen, dlen; - unsigned char *h; - - if (!sb) - return silc_buffer_alloc(newsize); - - if (silc_unlikely(newsize <= silc_buffer_truelen(sb))) - return sb; - - hlen = silc_buffer_headlen(sb); - dlen = silc_buffer_len(sb); - h = (unsigned char *)silc_realloc(sb->head, newsize); - if (silc_unlikely(!h)) - return NULL; - sb->head = h; - sb->data = sb->head + hlen; - sb->tail = sb->data + dlen; - sb->end = sb->head + newsize; - - return sb; -} - -/****f* silcutil/SilcBufferAPI/silc_buffer_realloc_size - * - * SYNOPSIS - * - * static inline - * SilcBuffer silc_buffer_realloc_size(SilcBuffer sb, SilcUInt32 newsize); - * - * DESCRIPTION - * - * Same as silc_buffer_realloc but moves moves the tail area - * automatically so that the buffer is ready to use without calling the - * silc_buffer_pull_tail. Returns NULL on error. - * - ***/ + SilcBuffer sb_new; -static inline -SilcBuffer silc_buffer_realloc_size(SilcBuffer sb, SilcUInt32 newsize) -{ - sb = silc_buffer_realloc(sb, newsize); - if (silc_unlikely(!sb)) + sb_new = silc_buffer_alloc_size(silc_buffer_truelen(sb)); + if (silc_unlikely(!sb_new)) return NULL; - silc_buffer_pull_tail(sb, silc_buffer_taillen(sb)); - return sb; -} - -/****f* silcutil/SilcBufferAPI/silc_buffer_enlarge - * - * SYNOPSIS - * - * static inline - * SilcBuffer silc_buffer_enlarge(SilcBuffer sb, SilcUInt32 size); - * - * DESCRIPTION - * - * Enlarges the buffer by the amount of `size' if it doesn't have that - * must space in the data area and in the tail area. Moves the tail - * area automatically after enlarging so that the current data area - * is at least the size of `size'. If there is more space than `size' - * in the data area this does not do anything. If there is enough - * space in the tail area this merely moves the tail area to reveal - * the extra space. Returns FALSE on error. - * - ***/ + silc_buffer_put(sb_new, sb->head, silc_buffer_truelen(sb)); + sb_new->data = sb_new->head + silc_buffer_headlen(sb); + sb_new->tail = sb_new->data + silc_buffer_len(sb); -static inline -SilcBool silc_buffer_enlarge(SilcBuffer sb, SilcUInt32 size) -{ - if (size > silc_buffer_len(sb)) { - if (size > silc_buffer_taillen(sb) + silc_buffer_len(sb)) - if (silc_unlikely(!silc_buffer_realloc(sb, silc_buffer_truelen(sb) + - (size - silc_buffer_taillen(sb) - - silc_buffer_len(sb))))) - return FALSE; - silc_buffer_pull_tail(sb, size - silc_buffer_len(sb)); - } - return TRUE; + return sb_new; } - -/* SilcStack aware SilcBuffer routines */ - -/****f* silcutil/SilcBufferAPI/silc_buffer_salloc +/****f* silcutil/SilcBufferAPI/silc_buffer_sclone * * SYNOPSIS * * static inline - * SilcBuffer silc_buffer_salloc(SilcStack stack, SilcUInt32 len); + * SilcBuffer silc_buffer_sclone(SilcStack stack, SilcBuffer sb); * * DESCRIPTION * - * Allocates new SilcBuffer and returns it. + * Clones SilcBuffer. This generates new SilcBuffer and copies + * everything from the source buffer. The result is exact clone of + * the original buffer. * * This routine use SilcStack are memory source. If `stack' is NULL * reverts back to normal allocating routine. @@ -967,59 +1042,58 @@ SilcBool silc_buffer_enlarge(SilcBuffer sb, SilcUInt32 size) ***/ static inline -SilcBuffer silc_buffer_salloc(SilcStack stack, SilcUInt32 len) +SilcBuffer silc_buffer_sclone(SilcStack stack, SilcBuffer sb) { - SilcBuffer sb; - - if (!stack) - return silc_buffer_alloc(len); - - /* Allocate new SilcBuffer */ - sb = (SilcBuffer)silc_scalloc(stack, 1, sizeof(*sb)); - if (silc_unlikely(!sb)) - return NULL; + SilcBuffer sb_new; - /* Allocate the actual data area */ - sb->head = (unsigned char *)silc_smalloc(stack, len); - if (silc_unlikely(!sb->head)) + sb_new = silc_buffer_salloc_size(stack, silc_buffer_truelen(sb)); + if (silc_unlikely(!sb_new)) return NULL; + silc_buffer_put(sb_new, sb->head, silc_buffer_truelen(sb)); + sb_new->data = sb_new->head + silc_buffer_headlen(sb); + sb_new->tail = sb_new->data + silc_buffer_len(sb); - /* Set pointers to the new buffer */ - sb->data = sb->head; - sb->tail = sb->head; - sb->end = sb->head + len; - - return sb; + return sb_new; } -/****f* silcutil/SilcBufferAPI/silc_buffer_salloc_size +/****f* silcutil/SilcBufferAPI/silc_buffer_realloc * * SYNOPSIS * * static inline - * SilcBuffer silc_buffer_salloc_size(SilcStack stack, SilcUInt32 len); + * SilcBuffer silc_buffer_realloc(SilcBuffer sb, SilcUInt32 newsize); * * DESCRIPTION * - * Allocates `len' bytes size buffer and moves the tail area automatically - * `len' bytes so that the buffer is ready to use without calling the - * silc_buffer_pull_tail. - * - * This routine use SilcStack are memory source. If `stack' is NULL - * reverts back to normal allocating routine. - * - * Note that this call consumes the `stack'. The caller should push the - * stack before calling the function and pop it later. + * Reallocates buffer. Old data is saved into the new buffer. The buffer + * is exact clone of the old one except that there is now more space + * at the end of buffer. This always returns the same `sb' unless `sb' + * was NULL. Returns NULL on error. * ***/ static inline -SilcBuffer silc_buffer_salloc_size(SilcStack stack, SilcUInt32 len) +SilcBuffer silc_buffer_realloc(SilcBuffer sb, SilcUInt32 newsize) { - SilcBuffer sb = silc_buffer_salloc(stack, len); - if (silc_unlikely(!sb)) + SilcUInt32 hlen, dlen; + unsigned char *h; + + if (!sb) + return silc_buffer_alloc(newsize); + + if (silc_unlikely(newsize <= silc_buffer_truelen(sb))) + return sb; + + hlen = silc_buffer_headlen(sb); + dlen = silc_buffer_len(sb); + h = (unsigned char *)silc_realloc(sb->head, newsize); + if (silc_unlikely(!h)) return NULL; - silc_buffer_pull_tail(sb, len); + sb->head = h; + sb->data = sb->head + hlen; + sb->tail = sb->data + dlen; + sb->end = sb->head + newsize; + return sb; } @@ -1082,6 +1156,31 @@ SilcBuffer silc_buffer_srealloc(SilcStack stack, return sb; } +/****f* silcutil/SilcBufferAPI/silc_buffer_realloc_size + * + * SYNOPSIS + * + * static inline + * SilcBuffer silc_buffer_realloc_size(SilcBuffer sb, SilcUInt32 newsize); + * + * DESCRIPTION + * + * Same as silc_buffer_realloc but moves moves the tail area + * automatically so that the buffer is ready to use without calling the + * silc_buffer_pull_tail. Returns NULL on error. + * + ***/ + +static inline +SilcBuffer silc_buffer_realloc_size(SilcBuffer sb, SilcUInt32 newsize) +{ + sb = silc_buffer_realloc(sb, newsize); + if (silc_unlikely(!sb)) + return NULL; + silc_buffer_pull_tail(sb, silc_buffer_taillen(sb)); + return sb; +} + /****f* silcutil/SilcBufferAPI/silc_buffer_srealloc_size * * SYNOPSIS @@ -1115,13 +1214,12 @@ SilcBuffer silc_buffer_srealloc_size(SilcStack stack, return sb; } -/****f* silcutil/SilcBufferAPI/silc_buffer_senlarge +/****f* silcutil/SilcBufferAPI/silc_buffer_enlarge * * SYNOPSIS * * static inline - * SilcBuffer silc_buffer_senlarge(SilcStack stack, SilcBuffer sb, - * SilcUInt32 size); + * SilcBuffer silc_buffer_enlarge(SilcBuffer sb, SilcUInt32 size); * * DESCRIPTION * @@ -1133,75 +1231,39 @@ SilcBuffer silc_buffer_srealloc_size(SilcStack stack, * space in the tail area this merely moves the tail area to reveal * the extra space. Returns FALSE on error. * - * This routine use SilcStack are memory source. If `stack' is NULL - * reverts back to normal allocating routine. - * - * Note that this call consumes the `stack'. The caller should push the - * stack before calling the function and pop it later. - * ***/ static inline -SilcBool silc_buffer_senlarge(SilcStack stack, SilcBuffer sb, SilcUInt32 size) +SilcBool silc_buffer_enlarge(SilcBuffer sb, SilcUInt32 size) { if (size > silc_buffer_len(sb)) { if (size > silc_buffer_taillen(sb) + silc_buffer_len(sb)) - if (silc_unlikely(!silc_buffer_srealloc(stack, sb, - silc_buffer_truelen(sb) + - (size - silc_buffer_taillen(sb) - - silc_buffer_len(sb))))) + if (silc_unlikely(!silc_buffer_realloc(sb, silc_buffer_truelen(sb) + + (size - silc_buffer_taillen(sb) - + silc_buffer_len(sb))))) return FALSE; silc_buffer_pull_tail(sb, size - silc_buffer_len(sb)); } return TRUE; } -/****f* silcutil/SilcBufferAPI/silc_buffer_scopy - * - * SYNOPSIS - * - * static inline - * SilcBuffer silc_buffer_scopy(SilcStack stack, SilcBuffer sb); - * - * DESCRIPTION - * - * Generates copy of a SilcBuffer. This copies everything inside the - * currently valid data area, nothing more. Use silc_buffer_clone to - * copy entire buffer. - * - * This routine use SilcStack are memory source. If `stack' is NULL - * reverts back to normal allocating routine. - * - * Note that this call consumes the `stack'. The caller should push the - * stack before calling the function and pop it later. - * - ***/ - -static inline -SilcBuffer silc_buffer_scopy(SilcStack stack, SilcBuffer sb) -{ - SilcBuffer sb_new; - - sb_new = silc_buffer_salloc_size(stack, silc_buffer_len(sb)); - if (silc_unlikely(!sb_new)) - return NULL; - silc_buffer_put(sb_new, sb->data, silc_buffer_len(sb)); - - return sb_new; -} - -/****f* silcutil/SilcBufferAPI/silc_buffer_sclone +/****f* silcutil/SilcBufferAPI/silc_buffer_senlarge * * SYNOPSIS * * static inline - * SilcBuffer silc_buffer_sclone(SilcStack stack, SilcBuffer sb); + * SilcBuffer silc_buffer_senlarge(SilcStack stack, SilcBuffer sb, + * SilcUInt32 size); * * DESCRIPTION * - * Clones SilcBuffer. This generates new SilcBuffer and copies - * everything from the source buffer. The result is exact clone of - * the original buffer. + * Enlarges the buffer by the amount of `size' if it doesn't have that + * must space in the data area and in the tail area. Moves the tail + * area automatically after enlarging so that the current data area + * is at least the size of `size'. If there is more space than `size' + * in the data area this does not do anything. If there is enough + * space in the tail area this merely moves the tail area to reveal + * the extra space. Returns FALSE on error. * * This routine use SilcStack are memory source. If `stack' is NULL * reverts back to normal allocating routine. @@ -1212,18 +1274,18 @@ SilcBuffer silc_buffer_scopy(SilcStack stack, SilcBuffer sb) ***/ static inline -SilcBuffer silc_buffer_sclone(SilcStack stack, SilcBuffer sb) +SilcBool silc_buffer_senlarge(SilcStack stack, SilcBuffer sb, SilcUInt32 size) { - SilcBuffer sb_new; - - sb_new = silc_buffer_salloc_size(stack, silc_buffer_truelen(sb)); - if (silc_unlikely(!sb_new)) - return NULL; - silc_buffer_put(sb_new, sb->head, silc_buffer_truelen(sb)); - sb_new->data = sb_new->head + silc_buffer_headlen(sb); - sb_new->tail = sb_new->data + silc_buffer_len(sb); - - return sb_new; + if (size > silc_buffer_len(sb)) { + if (size > silc_buffer_taillen(sb) + silc_buffer_len(sb)) + if (silc_unlikely(!silc_buffer_srealloc(stack, sb, + silc_buffer_truelen(sb) + + (size - silc_buffer_taillen(sb) - + silc_buffer_len(sb))))) + return FALSE; + silc_buffer_pull_tail(sb, size - silc_buffer_len(sb)); + } + return TRUE; } #endif /* SILCBUFFER_H */ diff --git a/lib/silcutil/silcmemory.c b/lib/silcutil/silcmemory.c index cd09a903..62a86165 100644 --- a/lib/silcutil/silcmemory.c +++ b/lib/silcutil/silcmemory.c @@ -92,8 +92,13 @@ void *silc_smalloc(SilcStack stack, SilcUInt32 size) void silc_sfree(SilcStack stack, void *ptr) { - if (stack) + if (stack) { +#ifdef SILC_DEBUG + if (ptr) + *(unsigned char *)ptr = 'F'; +#endif /* SILC_DEBUG */ return; + } silc_free(ptr); }