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;
*
* 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.
*
***/
}
}
+/****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
*
* 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.
*
***/
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
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
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.
***/
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;
}
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
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
*
* 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.
***/
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 */