#include "vchdr.h"
#if __STD_C
Vcchar_t* _vcbuffer(Vcodex_t* vc, Vcchar_t* trunc, ssize_t size, ssize_t head)
#else
Vcchar_t* _vcbuffer(vc, trunc, size, head)
Vcodex_t* vc;
Vcchar_t* trunc;
ssize_t size;
ssize_t head;
#endif
{
Vcbuffer_t *b, *n;
DEBUG_DECLARE(static ssize_t, Busy=0);
#ifdef VMFL
DEBUG_DECLARE(Vmstat_t, statb); DEBUG_ASSERT(vmstat(Vmregion, &statb) >= 0);
#endif
if(!vc)
return NIL(Vcchar_t*);
if(trunc)
{
for(; vc; vc = vc->coder)
{ for(n = NIL(Vcbuffer_t*), b = vc->list; b; n = b, b = b->next)
if(trunc >= b->buf && trunc < b->buf+b->size)
break;
if(!b)
continue;
if(n)
n->next = b->next;
else vc->list = b->next;
if(size < 0 )
{ DEBUG_SET(Busy, Busy - b->size);
DEBUG_PRINT(2,"free: file=%s ", b->file);
DEBUG_PRINT(2,"line=%d ",b->line);
DEBUG_PRINT(2,"size=%d\n",b->size);
vc->busy -= b->size;
vc->nbuf -= 1;
free(b);
return NIL(Vcchar_t*);
}
if(trunc+size > b->buf+b->size)
{ b->next = vc->list;
vc->list = b;
return NIL(Vcchar_t*);
}
size += (head = trunc - (Vcchar_t*)b->buf);
if(size < 3*b->size/4 )
{ if(!(n = (Vcbuffer_t*)realloc(b, sizeof(Vcbuffer_t)+size)) )
RETURN(NIL(Vcchar_t*));
DEBUG_SET(Busy, Busy - b->size + size);
DEBUG_PRINT(2,"realloc: file=%s ", b->file);
DEBUG_PRINT(2,"line=%d ",b->line);
DEBUG_PRINT(2,"oldsize=%d ",b->size);
DEBUG_PRINT(2,"newsize=%d\n",size);
vc->busy -= n->size - size;
n->size = size;
if(n != b)
b = n;
}
b->next = vc->list;
vc->list = b;
return (Vcchar_t*)(&b->buf[head]);
}
return NIL(Vcchar_t*);
}
else if(size < 0)
{ for(; vc; vc = vc->coder)
{ if(vc->meth->eventf)
(*vc->meth->eventf)(vc, VC_FREEBUFFER, 0);
for(b = vc->list; b; b = n)
{ n = b->next;
DEBUG_SET(Busy, Busy - b->size);
DEBUG_PRINT(2,"free: file=%s ", b->file);
DEBUG_PRINT(2,"line=%d ",b->line);
DEBUG_PRINT(2,"size=%d\n",b->size);
free(b);
}
vc->list = NIL(Vcbuffer_t*);
vc->busy = 0;
vc->nbuf = 0;
}
return NIL(Vcchar_t*);
}
else
{ head = (head <= 0 ? 0 : head) + vc->head;
if(!(b = (Vcbuffer_t*)malloc(sizeof(Vcbuffer_t)+head+size)) )
RETURN(NIL(Vcchar_t*));
b->size = head+size;
b->next = vc->list;
b->file = vc->file; vc->file = NIL(char*);
b->line = vc->line; vc->line = 0;
DEBUG_SET(Busy, Busy + b->size);
DEBUG_PRINT(2,"alloc: file=%s ", b->file);
DEBUG_PRINT(2,"line=%d ",b->line);
DEBUG_PRINT(2,"size=%d\n",b->size);
vc->list = b;
vc->busy += b->size;
vc->nbuf += 1;
return (Vcchar_t*)(&b->buf[head]);
}
}