/***********************************************************************

                      CSDB Library, Free Evaluation Version 2.2.0 
                                           Release: June 9th 1997 

       Header file of the VBASE class.
       Database class for records with variable length.

                                           Copyright(c) 1994-1997 
                                                          ComBits 
                                                  The Netherlands 
***********************************************************************/

#ifndef __CSVBASE_H
#define __CSVBASE_H

#include "cstypes.h"
#include "cspage.h"
#include "cstaba.h"
#include "cscopton.h"


/////////////////////// VBASE Typedefs /////////////////////////

typedef U32 VBPO;
typedef U32 PANR;
typedef U16 OFNR;



////////////////////// VBASE class definition ///////////////////

class VBASE: public PAGE
{

 private:


   typedef struct
   {
     VBPO pos;
   } vbi;	      //VBase Index

   typedef struct
   {
     unsigned length: 15;
     unsigned delet:   1;
     U16 alloc;
   } dhd;	      //Data HeaDer

   typedef struct
   {
     VBPO   pos;
     S16    alloc;
   } edc;	      //Empty Data Chain


protected:

   TABLEa vpi;		 // Virtual Page Index.
   ARRAY  vpi_cut;	 // Virtual Page Index short CUT.

   U16	  ipp;		 // Indexes Per Page.
   U16	  ipp_offmask;
   U16	  ipp_shftrig;
   U16	  nip;		 // Number of pages currently used by the index.

   U16	  pag_s;	 // Page Shift.
   U16	  pag_o;	 // Page OR.

   edc	 *eda;		 // Empty Data Array
   U16	  esr;		 // Eda Shift Right
   U16	  enr;		 // Eda NumbeR
   int	  epc;		 // Eda Page Changed.

   U32	  numrec;	 // Number of records.
   U16	  maxrlen;	 // Max Record Length.

   int	  rel_shrink;	 // Relocate record when shrunk.

   void   init_vpi(void);
   void   init_eca(void);
   void   init_vars(void);
   void   init_defaults(void);
   void   save_vpi(void);
   void   close_vpi(void);
   void   save_eca(void);
   void   close_eca(void);
   void   reset_vpi(void);
   void   reset_eca(void);

   U32	  pag(VBPO &p)		    { return p>>pag_s;	     }
   U16	  off(VBPO &p)		    { return (U16)(p&pag_o); }
   VBPO   vbpo(PANR &p,OFNR &of)    { return (p<<pag_s)|of;  }

   csCHAR   *pos_poa(PANR p,OFNR of)  { return load_page(p)+of; }
   csCHAR   *pos_poda(PANR p,OFNR of) { return load_page_d(p)+of; }
   csCHAR   *pos_poa(VBPO  p)	    { return pos_poa(pag(p),off(p));  }
   csCHAR   *pos_poz(VBPO  p)	    { return pos_poa(p)+sizeof(dhd);  }
   csCHAR   *pos_poda(VBPO  p)	    { return pos_poda(pag(p),off(p)); }
   csCHAR   *pos_podz(VBPO  p)	    { return pos_poda(p)+sizeof(dhd); }


   dhd	 *DH(void *p) { return (dhd *)p; }

   VBPO   p2i(U32 rec);
   void   p2i(U32 rec,VBPO pos);

   int	  is_index_page(PANR p);

   U16	  data_alloc(U16 amount,PANR &page,OFNR &offset,void *&ptr);
   void   data_free(void *ptr,PANR page,OFNR  offset,U16 amount);
   U16	  data_alloc_full(U16 amount,PANR &page,OFNR &offset,void *&ptr);

   void   sort_eca(void);
   void   set_num_page(PANR n);
   int	  max_buf_locked(void )     { return 4; }
   void   numvrec(U32 l)	    { numrec=l; }

   void   head2vars(void);
   void   vars2head(void);

   virtual int check_id(U32 id);
   virtual void set_id(void);

///////////////////////// DB Header ///////////////////////////////////
   virtual int read_header(void);
   virtual int write_header(void);




////////////////////////////////////////////////////////////////////////
////////////////////// PUBLIC FUNCTIONS////////////////////////////////
////////////////////////////////////////////////////////////////////////
 public:

   VBASE(void);
   virtual
  ~VBASE(void);


//////////////////////// Compatibility functions ////////////////////////////
   csCHAR *locate(U32 k)	    { return pos_podz(p2i(k)); }

//////////////////////// Definition//////////////////////////////////////////
   int	define(csCHAR *name,U16 struclen);
   void relocate_when_shrunk(int TrueOrFalse);

//////////////////////// Open & Close////////////////////////////////////////
   int	open(csCHAR *name,U16 kb_buf=100);
   int	close(void);
   int	save(void);

//////////////////////// Locate, Read & Writes records///////////////////////
   void read_rec(U32 pos,void *ptr,U16	&length);
   void read_rec(U32 pos,U16  maxlen,void *ptr,U16  &length);
   void write_rec(U32 i,void *d,U16 len);

   csCHAR *locate_rec(S32  rec)     { return pos_poz(p2i(rec)); }
   csCHAR *locate_rec_d(S32  rec)   { return pos_podz(p2i(rec)); }

//////////////////////// Add Records/////////////////////////////////////////
   U32	append_rec(void *p,U16 len);

//////////////////////// Number of Records///////////////////////////////////
   U32	numvrec(void)	     { return numrec; }

//////////////////////// Data in Header Page/////////////////////////////////
/* Inherited
   int	data_2_header(void * ptr,U16 length);
   int	header_2_data(void * ptr,U16 length);
   U16	max_data_in_header(void);
*/

////////////////////////// Deleting////////////////////////////////////////////
   int	is_delet(U32 k)      { return !DH(pos_poa(p2i(k)))->delet; }
   void delet(U32 k)	     { DH(pos_poda(p2i(k)))->delet=0;	}
   void undelet(U32 k )      { DH(pos_poda(p2i(k)))->delet=1;	}

////////////////////////// Record Length///////////////////////////////////////
   U16	rec_len(U32 k)	     { return DH(pos_poa(p2i(k)))->length; }
   U16	max_len(void)	     { return maxrlen; }

//////////////////////// Report Writing//////////////////////////////////////
   U16	report(csCHAR *name,S16 sub=1);
   void report(FILE *fipo,S16 sub);

////////////////////////// Miscellaneous///////////////////////////////////////
/* Inherited
   int	background(void)
*/
   int	pack(void);
   int	zap(void);
   void empty(void);
   void info(void);
   int	relocate_when_shrunk(void) { return rel_shrink; }
   virtual int class_ID(void)  { return CS_CLID_VBASE; }


};


#include "cscoptof.h"

#endif
