return buffer_max(buf);
}
+/*
+ * Return the maximum amount of bytes that can be written into the buffer in
+ * one call to buffer_feed*().
+ */
+static inline int buffer_free_space(struct buffer *buf)
+{
+ return buffer_max_len(buf) - buf->l;
+}
+
/*
* Return the max amount of bytes that can be stuffed into the buffer at once.
* Note that this may be lower than the actual buffer size when the free space
return ret;
}
+/*
+ * Same as above but the caller may pass the value of buffer_max_len(buf) if it
+ * knows it, thus avoiding some calculations.
+ */
+static inline int buffer_contig_space_with_len(struct buffer *buf, int maxlen)
+{
+ int ret;
+
+ if (buf->l == 0) {
+ buf->r = buf->w = buf->lr = buf->data;
+ ret = maxlen;
+ }
+ else if (buf->r > buf->w) {
+ ret = buf->data + maxlen - buf->r;
+ }
+ else {
+ ret = buf->w - buf->r;
+ if (ret > maxlen)
+ ret = maxlen;
+ }
+ return ret;
+}
+
/* Return 1 if the buffer has less than 1/4 of its capacity free, otherwise 0 */
static inline int buffer_almost_full(struct buffer *buf)
{
- if (buffer_contig_space(buf) < buf->size / 4)
+ if (buffer_free_space(buf) < buf->size / 4)
return 1;
return 0;
}
if (len == 0)
return -1;
- if (len > buffer_max_len(buf)) {
- /* we can't write this chunk and will never be able to, because
- * it is larger than the buffer's current max size.
+ max = buffer_max_len(buf);
+ if (len > max - buf->l) {
+ /* we can't write this chunk right now because the buffer is
+ * almost full or because the block is too large. Return the
+ * available space or -2 if impossible.
*/
- return -2;
- }
+ if (len > max)
+ return -2;
- max = buffer_contig_space(buf);
+ return max - buf->l;
+ }
+ /* OK so the data fits in the buffer in one or two blocks */
+ max = buffer_contig_space_with_len(buf, max);
+ memcpy(buf->r, str, MIN(len, max));
if (len > max)
- return max;
+ memcpy(buf->data, str + max, len - max);
- memcpy(buf->r, str, len);
buf->l += len;
buf->r += len;
buf->total += len;
buf->flags &= ~BF_OUT_EMPTY;
}
- if (buf->r == buf->data + buf->size)
- buf->r = buf->data;
+ if (buf->r >= buf->data + buf->size)
+ buf->r -= buf->size;
buf->flags &= ~BF_FULL;
if (buf->l >= buffer_max_len(buf))