2016-11-25 17:18:40 +01:00
|
|
|
/*
|
|
|
|
* 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>
|
2017-04-19 23:33:14 +02:00
|
|
|
#include <lib9.h>
|
2016-11-25 17:18:40 +01:00
|
|
|
|
|
|
|
#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;
|
|
|
|
}
|