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

                      CSDB Library, Free Evaluation Version 2.0.5 
                                       Release: January 22th 1997 

       Header file of the RBASE class.
       This class maintains a database 100% in RAM.

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

#ifndef __CSRBASE_H
#define __CSRBASE_H

#include <csdir.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include "csbase.h"


#ifdef CS_DEBUG
   #define CHECK_REC(p) check_rec(p);
#else
   #define CHECK_REC(p)
#endif



#ifdef _CP_001
#pragma warn -sig
#endif

#ifdef _MSC_VER
#pragma warning(disable : 4051 4135)
#endif



//////////////////////////////////////////////////////////////////////////

class RBASE: public BASE
{


protected:

   U16    lenrec;
   U16    recpage;
   U16    rec_foot;
   U16    len_rec_plus_foot;
   S32    NUMREC;
   S32    lrco;
   S32    wrco;
   S32    rrco;
   int    buff_nr;
   void **buff_in;
   S32    headoff;      // Offset to the first page in file.
   U16    headpagesize;
   U8     exit_or_rc;
   S16    ilock;
   S32    cur_rec;

protected:


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


   int  has_been_updated(void) { return ((lrco+wrco)>0); }

   void check_rec(S32 l);

   S32  r2p(S32 rec)     { return (1+(rec-1)/recpage); }
   U16  oinp(S32 rec)    { return (((U16 )((rec-1)%recpage))*len_rec_plus_foot); }

   void exit_on_error(int tf)   { exit_or_rc=tf; }

   csCHAR *load_page(S32 page)  { return (csCHAR *)buff_in[page]; }
   int  add_page(void );

   S32  pos_infile(S32 pagnr)           { return headoff+pagnr*lenpage; }
   void buffer_2_file(S32 pos,void *buf);
   void file_2_buffer(S32 pos,void *buf);

   void header_page_size(size_t n);
// int  open_it(void);
// int  close_it(void);

   int  close2(void);

////////////////////////////////////////////////////////////////////////////
//////////////////// Public Functions //////////////////////////////////////
////////////////////////////////////////////////////////////////////////////


public:

   RBASE(void);
   virtual
  ~RBASE(void);



//////////////////////// Compatibility function ////////////////////////
   void speed_option_121(void)   { smallest_page(); }



///////////////////////////////////////////////////////////////////////////
// The next functions are normally inherited from the page class,
// but RBASE has to implement them itself.



   ////////////////// Data in Header Page /////////////////////////////////

   int  data_2_header(void * ptr,U16 length);
   int  header_2_data(void * ptr,U16 length);
   U16  max_data_in_header(void);



///////////////////////// Define ///////////////////////////////////////
/* Inherited
   void page_size(U16 length);
   U16  page_size(void) ;

*/

   void smallest_page(void)      { recpage=1; }
   int  define(csCHAR *name,U16  reclen);


////////////////////////// Open & Close ///////////////////////////////
   int  open(csCHAR *name,S16 kb=100);
   int  open(void)              { return is_open; }
   int  close();
   int  save(void);


//////////////////////// Locking ////////////////////////////////////////////
   int  ignore_lock(int TrueOrFalse) { return ilock=TrueOrFalse; }
   int  ignore_lock(void)            { return ilock; }
   int  set_lock(int TrueOrFalse);
   int  is_locked(void);

////////////////////////// Record Length ///////////////////////////////////////
   U16  lengthrec(void)   { return lenrec; }


//////////////////////// Locate, Read & Writes records  ///////////////////////
   csCHAR *locate_rec_l(S32  rec)   { lrco++; return load_page(r2p(rec))+oinp(rec); }
   csCHAR *locate_rec_ld(S32  rec)  { lrco++; return load_page(r2p(rec))+oinp(rec); }
   csCHAR *locate_rec(S32 rec)      { lrco++; return load_page(r2p(rec))+oinp(rec); }
   csCHAR *locate_rec_d(S32 rec)    { lrco++; return load_page(r2p(rec))+oinp(rec); }

   void locate_double(S32 rec1,void *&d1,S32 rec2,void *&d2);
   void locate_double_d(S32 rec1,void *&d1,S32 rec2,void *&d2);

   void read_rec(  S32 rec, void *d);
   void write_rec( S32 rec, void *d);

//////////////////////// Add Records /////////////////////////////////////////

   S32 append_rec(void *data);
   S32 append_rec(void);

////////////////////////// Deleting ////////////////////////////////////////////


   void set_delet(S32 r,int tf);
   void undelet(void *d)  { *((csCHAR *)d+lengthrec())=0; }
   void delet(void *d)    { *((csCHAR *)d+lengthrec())=1; }
   int  is_delet(void *d) { return *((csCHAR *)d+lengthrec()); }

   int  is_delet(S32 l)  { return is_delet(locate_rec(l)); }
   void delet(S32 r)      { set_delet(r,TRUE); }
   void undelet(S32 r )  { set_delet(r,FALSE); }

//////////////////////// Number of Records ///////////////////////////////////

   S32  numrec(void)      { return NUMREC; }
   void set_numrec(S32 n) { NUMREC=n; set_num_page(r2p(n)); }
   void dec_numrec(void ) { NUMREC--; }

////////////////////////// Current /////////////////////////////////////////////

   S32  set_current(S32  rec);
   S32  current(void)    { return cur_rec; }
   S32  skip(S32  delta) { S32  l=current(); return (set_current(l+delta)-l); }
   S32  next(S32  delta) { return skip(delta); }
   S32  prev(S32  delta) { return -skip(-delta); }

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




////////////////////////// Miscellaneous ///////////////////////////////////////
/* Inherited
   int  background(void)
*/

//   int empty(void);

   int  pack(void);
// void zap(void);
   void info(void);
   virtual int class_ID(void)  { return CS_CLID_RBASE; }

///////////////////////// Dummy functions /////////////////////////////////
// Fake functions to ensure compatibility
// with TBASE.

   void dirty(void *) {}
   U16  number_buff_max(void)    { return U16_MAX;  }
   U16  number_buff_min(void)    { return 1; }
   void max_with_priority(int ,U16){}
   int  max_with_priority(int )    { return U16_MAX; }
   void number_buff(U16 ,U16 )     {}
   void number_buff_min(U16)       {}
   int  background(void)           { return TRUE; }




};




////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////



#ifdef _CP_001
#pragma warn .sig
#endif


#ifdef _MSC_VER
#pragma warning(default : 4051 4135)
#endif



#endif
