#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+buffer->cap; while (cur != buffer->head) { cur = cur->next; // skips one iter ^^^ 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->cap++; buffer->head->text[buffer->cap-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* strpeekbuf(buf* buffer, size_t loc, size_t len){ char* str = malloc(sizeof(char)*(len+1)); str[len] = 0; buf_node* start; loc += buffer->ins; for (start = buffer->tail; loc>0; loc -= buffer->cap) start = start->next; // start,loc is where one starts streaming if (len > buffer->cap){ memcpy(str, start->text+loc, buffer->cap-loc); len -= buffer->cap - loc; } for (; len > buffer->cap; len -= buffer->cap ){ memcpy(str, start->text, buffer->cap); } memcpy(str, start->text, len); return str; }