diff options
author | dartraiden <wowemuh@gmail.com> | 2024-09-11 21:49:43 +0300 |
---|---|---|
committer | dartraiden <wowemuh@gmail.com> | 2024-09-11 21:52:35 +0300 |
commit | c36db68a5f58ec6c9135eff778b6e77c30e58088 (patch) | |
tree | 22eea126db82c50388c9f94cd683d6ec6f04e6cb /libs/libcurl/src/bufq.c | |
parent | 02bb82c1c0a4031e7b2f5578370fa5acd620f8e1 (diff) |
libcurl: update to 8.10.0
Diffstat (limited to 'libs/libcurl/src/bufq.c')
-rw-r--r-- | libs/libcurl/src/bufq.c | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/libs/libcurl/src/bufq.c b/libs/libcurl/src/bufq.c index 2bcad8a57f..5db25a3666 100644 --- a/libs/libcurl/src/bufq.c +++ b/libs/libcurl/src/bufq.c @@ -91,6 +91,23 @@ static size_t chunk_read(struct buf_chunk *chunk, }
}
+static size_t chunk_unwrite(struct buf_chunk *chunk, size_t len)
+{
+ size_t n = chunk->w_offset - chunk->r_offset;
+ DEBUGASSERT(chunk->w_offset >= chunk->r_offset);
+ if(!n) {
+ return 0;
+ }
+ else if(n <= len) {
+ chunk->r_offset = chunk->w_offset = 0;
+ return n;
+ }
+ else {
+ chunk->w_offset -= len;
+ return len;
+ }
+}
+
static ssize_t chunk_slurpn(struct buf_chunk *chunk, size_t max_len,
Curl_bufq_reader *reader,
void *reader_ctx, CURLcode *err)
@@ -363,6 +380,49 @@ static void prune_head(struct bufq *q) }
}
+static struct buf_chunk *chunk_prev(struct buf_chunk *head,
+ struct buf_chunk *chunk)
+{
+ while(head) {
+ if(head == chunk)
+ return NULL;
+ if(head->next == chunk)
+ return head;
+ head = head->next;
+ }
+ return NULL;
+}
+
+static void prune_tail(struct bufq *q)
+{
+ struct buf_chunk *chunk;
+
+ while(q->tail && chunk_is_empty(q->tail)) {
+ chunk = q->tail;
+ q->tail = chunk_prev(q->head, chunk);
+ if(q->tail)
+ q->tail->next = NULL;
+ if(q->head == chunk)
+ q->head = q->tail;
+ if(q->pool) {
+ bufcp_put(q->pool, chunk);
+ --q->chunk_count;
+ }
+ else if((q->chunk_count > q->max_chunks) ||
+ (q->opts & BUFQ_OPT_NO_SPARES)) {
+ /* SOFT_LIMIT allowed us more than max. free spares until
+ * we are at max again. Or free them if we are configured
+ * to not use spares. */
+ free(chunk);
+ --q->chunk_count;
+ }
+ else {
+ chunk->next = q->spare;
+ q->spare = chunk;
+ }
+ }
+}
+
static struct buf_chunk *get_non_full_tail(struct bufq *q)
{
struct buf_chunk *chunk;
@@ -428,6 +488,15 @@ CURLcode Curl_bufq_cwrite(struct bufq *q, return result;
}
+CURLcode Curl_bufq_unwrite(struct bufq *q, size_t len)
+{
+ while(len && q->tail) {
+ len -= chunk_unwrite(q->head, len);
+ prune_tail(q);
+ }
+ return len? CURLE_AGAIN : CURLE_OK;
+}
+
ssize_t Curl_bufq_read(struct bufq *q, unsigned char *buf, size_t len,
CURLcode *err)
{
|