/* * This file is part of Jehanne. * * Copyright (C) 2015 Giacomo Tesio * * Jehanne is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3 of the License. * * Jehanne is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Jehanne. If not, see . */ #include #include #include "console.h" /* data buffers */ Buffer* balloc(uint32_t size) { Buffer* b; b = (Buffer*)malloc(sizeof(Buffer)); b->written = 0; b->read = 0; b->linewidth = 0; b->newlines = 0; b->ctrld = size; b->size = size; b->data = (char*)malloc(size); return b; } uint32_t bwrite(Buffer *b, char *source, uint32_t len) { uint32_t i; debug("bwrite(%#p, src, %d): b->written was %d, b->ctrld was %d, b->linewidth was %d; ", b, len, b->written, b->ctrld, b->linewidth); i = 0; if(b->read == b->written){ b->written = 0; b->read = 0; } while(i < len) { if(b->written < b->size){ b->add(source[i++], b); } else len = i; } debug("len = %d, b->written = %d, b->size = %d, b->read = %d, b->ctrld = %d, b->linewidth = %d\n", len, b->written, b->size, b->read, b->ctrld, b->linewidth); return len; } char * bread(Buffer *b, uint32_t *length) { uint32_t len; char *data; len = *length; data = nil; debug("bread(%#p, %#p): len = %d, b->written was %d, b->read was %d, b->ctrld was %d; ", b, length, len, b->written, b->read, b->ctrld); if(len > b->written - b->read) len = b->written - b->read; if(b->written > b->ctrld) len = b->ctrld - b->read; assert(len < b->size); /* check correctness by detecting overflows */ if(len > 0){ data = b->data + b->read; b->read += len; } if(b->read == b->ctrld) b->ctrld = b->size; debug("len = %d, b->written = %d, b->size = %d, b->read = %d, b->ctrld = %d\n", len, b->written, b->size, b->read, b->ctrld); *length = len; return data; } char * breadln(Buffer *b, uint32_t *length) { uint32_t len; char *data, *c; len = *length; data = nil; debug("breadln(%#p, %#p): len = %d, b->written was %d, b->read was %d, b->ctrld was %d; ", b, length, len, b->written, b->read, b->ctrld); if(len > b->written - b->read) len = b->written - b->read; if(b->written > b->ctrld) len = b->ctrld - b->read; assert(len < b->size); /* check correctness by detecting overflows */ if(len > 0){ data = b->data + b->read; /* take up to the first \n... */ c = data; do { if(*c++ == '\n') len = c - data; } while(c - data < len); b->read += len; if(b->data[b->read - 1] == '\n'){ --b->newlines; b->linewidth = 0; } } if(b->read == b->ctrld) b->ctrld = b->size; debug("len = %d, b->written = %d, b->size = %d, b->read = %d, b->ctrld = %d\n", len, b->written, b->size, b->read, b->ctrld); *length = len; return data; } int blineready(Buffer *b) { if(b && !bempty(b)){ if(b->ctrld < b->size) return 1; /* ctrl-d, see cons(3) */ if(b->newlines > 0) return 1; } return 0; }