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

                      CSDB Library, Free Evaluation Version 2.2.0 
                                           Release: June 9th 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"
#include "cscopton.h"


#ifdef CS_DEBUG
   #define CHECK_REC(p) check_rec(p);
#else
   #define CHECK_REC(p)
#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; }




};




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




#include "cscoptof.h"

#endif
