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

                      CSDB Library, Free Evaluation Version 2.0.5 
                                       Release: January 22th 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"


/////////////////////// Some 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; }


};

#endif
