/*->c.buffer */


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "os.h"
#include "bbc.h"
#include "h.sprite"
#include "h.wimp"
#include "h.werr"
#include "h.flex"


#include "h.wos"
#include "h.fsx"
#include "h.def"


#include "h.buffer"




os_error * bf_dump(buffer * b)
{
 os_error * ep;

 ep=fs_write(b->fh,b->data,b->p);
 b->length+=b->p;
 b->p=0;

 return(ep);
}



static os_error * bf_load(buffer * b)
{
 os_error * ep;
 int        read;

 if(b->size>=b->length) read=b->length;
 else                   read=b->size;

 ep=fs_read(b->fh,b->data,read);
 b->length-=read;
 b->end=read;
 b->p=0;

 return(ep);
}



os_error * bf_put(buffer * b,int c)
{
 os_error * ep;

 ep=NULL;

 if(b->p<b->size) b->data[b->p++]=c;
 else
 {
  ep=bf_dump(b);
  if(b->p<b->size) b->data[b->p++]=c;
 }

 return(ep);
}



os_error * bf_get(buffer * b,int * c)
{
 os_error * ep;

 ep=NULL;

 if(b->p<b->end) *c=b->data[b->p++];
 else
 {
  ep=bf_load(b);
  if(b->p<b->end) *c=b->data[b->p++];
  else            *c=EOF;
 }

 return(ep);
}



os_error * bf_run(buffer * b,int len)
{
 os_error * ep;
 int        read;
 int        size;

 ep=NULL;

 if((b->p+len)>b->end)
 {
  memmove(b->data,b->data+b->p,b->end-b->p);
  size=b->p;

  if(size>=b->length) read=b->length;
  else                read=size;

  ep=fs_read(b->fh,b->data+(b->end-b->p),read);
  b->length-=read;
  b->end=read+(b->end-b->p);
  b->p=0;
 }

 return(ep);
}




os_error * bf_alloc(buffer * b,int size,int fh,int length)
{
 os_error * ep;

 b->fh=fh;
 b->p=0;
 b->length=length;
 b->end=0;

 ep=NULL;

 do
 {
  ep=flex_alloce((flex_ptr)&b->data,size);
  if(!ep)
  {
   b->size=size;
   break;
  }
  size/=2;
 } while(size>128);

 if(length && !ep) ep=bf_load(b);

 return(ep);
}


os_error * bf_dealloc(buffer * b)
{
 os_error * ep;

 ep=NULL;

 flex_free((flex_ptr)&b->data);

 return(ep);
}



