Sat, 03 Dec 2022 16:31:08 +0100
use separate buffer for chunked transfer encoding, not inbuf
/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 2018 Olaf Wintermann. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "writer.h" void writer_init(Writer *w, SYS_NETFD fd, char *buf, size_t len) { w->fd = fd; w->write = (wr_writefunc)net_write; w->buffer = buf; w->size = len; w->pos = 0; w->error = 0; } void writer_init_with_stream(Writer *w, void *stream, wr_writefunc writefunc, char *buf, size_t len) { w->fd = stream; w->write = writefunc; w->buffer = buf; w->size = len; w->pos = 0; w->error = 0; } int writer_flush(Writer *w) { if(w->error) { return w->error; } size_t pos = 0; size_t len = w->pos; while(len > 0) { //fwrite(w->buffer+pos, 1, len, stdout); //fflush(stdout); ssize_t r = w->write(w->fd, w->buffer + pos, len); if(r <= 0) { break; } len -= r; pos += r; } if(pos != w->pos) { w->error = 1; return 1; } w->pos = 0; return 0; } int writer_put(Writer *w, const char *s, size_t len) { if(w->error) { return w->error; } // available bytes size_t a = w->size - w->pos; if(a == 0) { if(writer_flush(w)) { return 1; } } size_t cplen = len > a ? a : len; // number of bytes we can copy memcpy(w->buffer+w->pos, s, cplen); w->pos += cplen; if(cplen < len) { // not all bytes copied -> call writer_put again // the number of available bytes is 0 then, therefore flush is called return writer_put(w, s + cplen, len - cplen); } else { return 0; } } int writer_puts(Writer *w, cxstring s) { return writer_put(w, s.ptr, s.length); } int writer_putc(Writer *w, char c) { if(w->pos == w->size) { if(writer_flush(w)) { return 1; } } w->buffer[w->pos++] = c; return 0; } int writer_fwrite(const void *s, size_t size, size_t nelem, Writer *out) { int w = writer_put(out, s, size*nelem); return w/size; }