X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=misc.c;fp=misc.c;h=f91e8a713f939c2e33b07ae27c71e8e55bb53a1c;hb=e7e92ac22ad1e9ef97bb0f06ceb55ead0e1ca524;hp=34e613efd5d782a566f6b93d51c9372eda0e11ea;hpb=d33c200de1737db6f94d8823936b01750b259e5e;p=PuTTY.git diff --git a/misc.c b/misc.c index 34e613ef..f91e8a71 100644 --- a/misc.c +++ b/misc.c @@ -88,6 +88,7 @@ void base64_encode_atom(unsigned char *data, int n, char *out) * - return a (pointer,length) pair giving some initial data in * the list, suitable for passing to a send or write system * call + * - retrieve a larger amount of initial data from the list * - return the current size of the buffer chain in bytes */ @@ -155,16 +156,23 @@ void bufchain_add(bufchain *ch, void *data, int len) void bufchain_consume(bufchain *ch, int len) { + struct bufchain_granule *tmp; + assert(ch->buffersize >= len); - assert(ch->head != NULL && ch->head->bufpos + len <= ch->head->buflen); - ch->head->bufpos += len; - ch->buffersize -= len; - if (ch->head->bufpos >= ch->head->buflen) { - struct bufchain_granule *tmp = ch->head; - ch->head = tmp->next; - sfree(tmp); - if (!ch->head) - ch->tail = NULL; + while (len > 0) { + int remlen = len; + assert(ch->head != NULL); + if (remlen >= ch->head->buflen - ch->head->bufpos) { + remlen = ch->head->buflen - ch->head->bufpos; + tmp = ch->head; + ch->head = tmp->next; + sfree(tmp); + if (!ch->head) + ch->tail = NULL; + } else + ch->head->bufpos += remlen; + ch->buffersize -= remlen; + len -= remlen; } } @@ -174,6 +182,28 @@ void bufchain_prefix(bufchain *ch, void **data, int *len) *data = ch->head->buf + ch->head->bufpos; } +void bufchain_fetch(bufchain *ch, void *data, int len) +{ + struct bufchain_granule *tmp; + char *data_c = (char *)data; + + tmp = ch->head; + + assert(ch->buffersize >= len); + while (len > 0) { + int remlen = len; + + assert(tmp != NULL); + if (remlen >= tmp->buflen - tmp->bufpos) + remlen = tmp->buflen - tmp->bufpos; + memcpy(data_c, tmp->buf + tmp->bufpos, remlen); + + tmp = tmp->next; + len -= remlen; + data_c += remlen; + } +} + /* ---------------------------------------------------------------------- * My own versions of malloc, realloc and free. Because I want * malloc and realloc to bomb out and exit the program if they run