jehanne/sys/src/cmd/hmi/console/buffer.c

133 lines
3.2 KiB
C

/*
* This file is part of Jehanne.
*
* Copyright (C) 2015 Giacomo Tesio <giacomo@tesio.it>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <u.h>
#include <lib9.h>
#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;
}