#include #include #include #include "buf.h" #define min(a,b) (atext = malloc(sizeof(char)*cap); return bufnode; } buf* newbuf(size_t cap){ buf* buffer = malloc(sizeof(buf)); buffer->tail = buffer->head = newbufnode(cap); buffer->cap = cap; buffer->ins = buffer->pop = 0; return buffer; } size_t buflen(buf* buffer){ buf_node* cur = buffer->tail; size_t size = buffer->ins-buffer->pop; while (cur != buffer->head) { cur = cur->next; size += buffer->cap; }; return size; } void extendbuf(buf* buffer){ buffer->head->next = newbufnode(buffer->cap); buffer->head = buffer->head->next; // buffer->ins = 0 is taken care of in the function that uses this. } void shortenbuf(buf* buffer){ buf_node* tmp = buffer->tail; buffer->tail = buffer->tail->next; free(tmp); buffer->pop = 0; } char popchrbuf(buf* buffer){ if (buffer->pop == buffer->cap) shortenbuf(buffer); buffer->pop++; return buffer->tail->text[buffer->pop-1]; } char* popstrbuf(buf* buffer, size_t ct){ char* str = malloc((ct+1)*sizeof(char)); str[ct] = 0; size_t rem; for (size_t loc = 0; ct>loc; loc += rem){ if (buffer->pop == buffer->cap) shortenbuf(buffer); rem = min(buffer->cap, ct-loc); memcpy(str+loc, buffer->tail->text+buffer->pop, rem); buffer->pop += rem; } /* probably some inefficiencies here*/ return str; } void inschrbuf(buf* buffer, char chr){ if (buffer->ins == buffer->cap) extendbuf(buffer); buffer->ins++; buffer->head->text[buffer->ins-1] = chr; } void insstrbuf(buf* buffer, char* str){ size_t len = strlen(str); size_t tgt = min(len, buffer->cap - buffer->ins); memcpy(buffer->head->text+buffer->ins, str, tgt); buffer->ins += len; buffer->ins %= buffer->cap; for (;tgtcap){ extendbuf(buffer); memcpy(buffer->head->text, str+tgt, min(len-tgt, buffer->cap)); } } char* peekstrbuf(buf* buffer, size_t loc, size_t len){ char* str = malloc(sizeof(char)*(len+1)); str[len] = 0; buf_node* start; loc += buffer->pop; for (start = buffer->tail; loc>buffer->cap; loc -= buffer->cap) start = start->next; // start,loc is where one starts streaming while (len > 0){ memcpy(str, start->text+loc, min(buffer->cap-loc, len)); len -= min(buffer->cap - loc, len); loc = 0; } return str; }