/* memory - memory handling functions
 */

#include "pico.h"

int pico_allocate(Picovars *vars,long size) {
 static int i;
 static long total_size;
 total_size=vars->filesize+size;
 i=0;
 while (total_size>0) {
  if (vars->blocks[i]==NULL) {
   vars->blocks[i]=(char *)malloc(PICO_BLOCK_SIZE);
   if (vars->blocks[i]==NULL) return(PICO_ERROR);
  }
  i++; total_size-=PICO_BLOCK_SIZE;
  if (i>=PICO_MEM_BLOCKS) return(PICO_ERROR);
 }
 return(PICO_OK);
}

int pico_readchar(Picovars *vars,long position) {
 if (position<0) return(0);
 if (position>=vars->filesize) return(0);
 return(vars->blocks[position/PICO_BLOCK_SIZE][position & (PICO_BLOCK_SIZE-1)]);
}

void pico_writechar(Picovars *vars,long position,int c) {
 if ((position<0) || (position>=vars->filesize)) return;
 if ((c<32) && (c!=10)) c=32;
 vars->blocks[position/PICO_BLOCK_SIZE][position & (PICO_BLOCK_SIZE-1)]=c;
}

void pico_insert(Picovars *vars,long position,long size) {
 static long i;
 if (size<0) {pico_remove(vars,position,-size); return;}
 if ((size<1) || (position<0) || (position>=vars->filesize)) return;
 if (pico_allocate(vars,size)==PICO_ERROR) return;
 vars->filesize+=size;
 for (i=((vars->filesize)-1); i>=(position+size); i--) {
  pico_writechar(vars,i,pico_readchar(vars,i-size));
 }
}

void pico_remove(Picovars *vars,long position,long size) {
 static long i;
 if ((size<1) || (position<0) || ((position+size)>=vars->filesize)) return;
 for (i=position; i<vars->filesize-size; i++) {
  pico_writechar(vars,i,pico_readchar(vars,i+size));
 }
 vars->filesize-=size;
}

void pico_countlines(Picovars *vars) {
 static long position;
 static int c;
 vars->numrows=0;
 for(position=0; position<vars->filesize; position++) {
  c=pico_readchar(vars,position);
  if ((c==0) || (c==10)) (vars->numrows)++;
 }
}
