#include #include #include #include "buf.h" int min(int a, int b) { return ((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; } static 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. } static void shortenbuf(buf* buffer){ buf_node* tmp = buffer->tail; buffer->tail = buffer->tail->next; free(tmp->text); free(tmp); } char popchrbuf(buf* buffer){ if (buffer->pop == buffer->cap){ shortenbuf(buffer); buffer->pop = 0; } 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; memcpy(str, buffer->tail->text+buffer->pop, min(ct, buffer->cap-buffer->pop)); size_t loc; for (loc = buffer->cap - buffer->pop; loc < ct; loc += buffer->cap){ shortenbuf(buffer); memcpy(str+loc, buffer->tail->text, min(ct-loc, buffer->cap)); } buffer->pop = ct - loc + buffer->cap; return str; } void inschrbuf(buf* buffer, char chr){ if (buffer->ins == buffer->cap){ extendbuf(buffer); buffer->ins = 0; } 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); for (;tgtcap){ extendbuf(buffer); memcpy(buffer->head->text, str+tgt, min(len-tgt, buffer->cap)); } buffer->ins = 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 size_t bytect; for (size_t tgt = 0; len > 0; len -= bytect, tgt += bytect){ bytect = min(buffer->cap - loc, len); memcpy(str+tgt, start->text+loc, bytect); start = start->next; loc = 0; } return str; } char peekchrbuf(buf* buffer, size_t loc){ buf_node* start; loc += buffer->pop; for (start = buffer->tail; loc>buffer->cap; loc -= buffer->cap) start = start->next; return start->text[loc]; }