/****************************************************************************
 *   gbasic_adt.h : 
 *   		a wrap up of basic system types such as int, real, VARCHAR.
 *
 *   Change Log :
 *		 11-11-1996 Initial version,  Liujian Qian
 *
 *   $Id: gadt_basic.h,v 1.4 1998/12/10 00:11:25 qian Exp $
 ***************************************************************************/

#ifndef _GBASICADT_H_
#define _GBASICADT_H_
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "gadt.h"

#ifdef USE_CHANGEREC
#include "gchangerec.h"
#endif


/**
       GFC type of int4.

DESCRIPTION
       GInt is a wrap up of the C++ type 'int'. Wraping such literal types
       up offers a uniform interface between the GFC ADTs and the underlying
       DBMS.
       
       All methods all inline functions.

TODO
       Add type conversion operators to those ADTs that have correspodants in C++.

*/
class GInt : public GADT
{
public:

    ///
    // the value
    int32	val;

public:

    // GROUP: ctors/operators
    ///
    GInt(int v=0)  {	val = v; }
    ///
    GInt(const GInt& other) {val = other.val;}
    ///
    GInt& operator=(const GInt& other) 
    {
	if(this==&other) return *this;
	val = other.val;
	return *this;
    }
    ///
    virtual uint32  getPSize()  const {return sizeof(int32);}
    ///
    int		   getV()  {return val;}

    //====================================================
    //====
    //====  major methods
    //====
    //====================================================
  
    virtual GType 	 type	   (void) const {return _Int; }    

    virtual Result	 init	  (void) {val=0; return GOk;}
    virtual Result 	 pack     (DataPipe& p) {
	GADT::pack(p);
	if(GEndian::big)  flipInt(&val);
	p.append( CONPTR(&val), sizeof(int32));
	if(GEndian::big)  flipInt(&val);
	return GOk;
    }
    
    virtual Result 	 unpack  (DataPipe& p )   {
	GADT::unpack(p);
	GAssert(!p.eop());
	p.fetch((char*)&val, sizeof(int32));
	if(GEndian::big) 
	    flipInt(&val);
	return GOk;
    }
    
    virtual Result 	 input(const char* in){
	val = atoi(in);
	return GOk;
    }
    
    virtual Result 	 output(char*& out)  {
	bp.extendTo(4);
	bp.recycle();
	char * p=(char*)bp.ptr();
	sprintf(p, "%d", val);
	out = p;
	return GOk;
    }
    
    virtual int          cmp       (const GADT& a) const {
	                               MATCHTYPE(a);
	                               if(val==((GInt&)a).val) return 0;
				       else if (val>((GInt&)a).val) return 1;
				       else  return -1;
                                    }
    
    virtual GADT* 	 clone	   () const { return new GInt; }

#ifdef USE_CHANGEREC
    virtual GCHG*	 diff      (GADT& other) const {
	GAssert(other.type() == type()); 
	GCHG_Int *tmp = new GCHG_Int;
	tmp->new_val = ((GInt&)other).val;
	return tmp;
    }

    virtual Result	 applyChg  (const GCHG* c)  {
	GAssert(c->type()==Chg_Int);
	val = ((GCHG_Int*)c)->new_val;
	return GOk;
    }
#endif

    void		 set(int v) {val = v;};
    
    //====================================================
    //====
    // GROUP:   overloaded comparison operators
    //====
    //====================================================
    
    ///
    virtual bool operator ==	(const GInt& other) const {
	                         return val == other.val; }
    ///
    virtual bool operator <     (const GInt& other) const {
	                         return val < other.val;  }
    ///
    virtual bool operator <=    (const GInt& other) const {
	                         return val <= other.val; }
    ///
    virtual bool operator >	(const GInt& other) const {
	                         return val > other.val;  }
    ///
    virtual bool operator >=	(const GInt& other) const {
	                         return val >= other.val; }
    
    friend ostream& operator<<(ostream& s, const GInt& i);
    
};  //class GInt



/**
      GFC type of 'char'.

DESCRIPTION

      You know what C/C++ 'char' is.
      
      All methods all inline functions.
*/
class GChar : public GADT
{
public:
    /// 
    // the value
    char	val;

public:
    // GROUP: ctors/operators
    ///
    GChar(char v=0)  {  val = v; }
    ///
    GChar(const GChar& other) {val = other.val;}
    ///
    GChar& operator=(const GChar& other) 
    {
	if(this==&other) return *this;
	val = other.val;
	return *this;
    }
    
    virtual uint32  getPSize() const {return sizeof(char);}
    char getV()  {return val;}

#ifdef USE_CHANGEREC
    virtual GCHG*	 diff      (GADT& other) const {
	GAssert(other.type() == type()); 
	GCHG_Char *tmp = new GCHG_Char;
	tmp->new_val = ((GChar&)other).val;
	return tmp;
    }

    virtual Result	 applyChg  (const GCHG* c)  {
	GAssert(c->type()==Chg_Char);
	val = ((GCHG_Char*)c)->new_val;
	return GOk;
    }
#endif

    //====================================================
    //====
    //====  major methods
    //====
    //====================================================
  
    virtual GType type	   (void) const {return _Char; }    

    virtual Result	 init	  (void) {val=0; return GOk;}

    virtual Result 	 pack   (DataPipe& p ){
	p.append( CONPTR(&val), sizeof(char));
	return GOk; 
    }
    
    virtual Result 	 unpack   (DataPipe& p) {
	GAssert(!p.eop());
	p.fetch((char*)&val, sizeof(char));
	return GOk;
    }
    
    virtual Result 	 input(const char* in) {
	val = in[0];
	return GOk;
    }
    
    virtual Result 	 output(char*& out) {
	bp.extendTo(4);
	bp.recycle();
	char *p = (char*)bp.ptr();
	p[0] = val;
	p[1] = '\0';
	out = p;
	return GOk;
    }

    virtual int          cmp       (const GADT& a) const {
	                               MATCHTYPE(a);
	                               if(val==((GChar&)a).val) return 0;
				       else if (val>((GChar&)a).val) return 1;
				       else return -1;
                                    }
    
    virtual GADT* 	 clone	   () const {return new GChar;}


    //====================================================
    //====
    // GROUP:   overloaded comparison operators
    //====
    //====================================================
    
    ///
    virtual bool operator ==	(const GChar& other) const {
	                         return val == other.val; }
    ///
    virtual bool operator <     (const GChar& other) const {
	                         return val < other.val;  }
    ///
    virtual bool operator <=    (const GChar& other) const {
	                         return val <= other.val; }
    ///
    virtual bool operator >	(const GChar& other) const {
	                         return val > other.val;  }
    ///
    virtual bool operator >=	(const GChar& other) const {
	                         return val >= other.val; }
    
    friend ostream& operator<<	(ostream& s, const GChar& c);
    
};  //class GChar

    

/**
      GFC type of real numbers.

DESCRIPTION
      This is an equivalent of C 'double'

*/
class GReal : public GADT
{
public:
    ///
    // the value
    double	val;

public:
    // GROUP: ctors/operators
    ///
    GReal(double v=0.0){val=v;}
    ///
    GReal(const GReal& other) {val = other.val;}
    ///
    GReal& operator=(const GReal& other) 
    {
	if(this==&other) return *this;
	val = other.val;
	return *this;
    }
    
    void    	   set	   (double v) {	val = v; }    
    double  	   getV()  {return val;}

#ifdef USE_CHANGEREC
    virtual GCHG*	 diff      (GADT& other) const {
	GAssert(other.type() == type()); 
	GCHG_Real *tmp = new GCHG_Real;
	tmp->new_val = ((GReal&)other).val;
	return tmp;
    }

    virtual Result	 applyChg  (const GCHG* c)  {
	GAssert(c->type()==Chg_Real);
	val = ((GCHG_Real*)c)->new_val;
	return GOk;
    }
#endif


    //====================================================
    //====
    //====  common methods
    //====
    //====================================================
  
    virtual GType      type	   (void) const { return _Real; }    

    virtual Result	 init	  (void) {val=0; return GOk; }

    virtual uint32        getPSize()const  {return sizeof(double);}

    virtual Result 	 pack   (DataPipe& p) {
	GADT::pack(p);
	if(GEndian::big) {
	    flipDouble(&val);
	    p.append(CONPTR(&val), sizeof(double));
	    flipDouble(&val);
	}
	else 	p.append( CONPTR(&val), sizeof(double));
	return GOk; 
    }
    
    virtual Result 	unpack (DataPipe& p ) {
	GADT::unpack(p);
	GAssert(!p.eop());
	p.fetch((char*)&val, sizeof(double));
	if(GEndian::big) 
	    flipDouble(&val);
	return GOk;
    }
    
    virtual Result 	 input(const char* in) {
	val = strtod(in, NULL);
	return GOk;
    }
    
    virtual Result 	 output(char*& out) {
	bp.extendTo(8);
	bp.recycle();
	char *p = (char*)bp.ptr();
	sprintf(p, " %f ", val);
	out = p;
	return GOk;
    }

    virtual int          cmp       (const GADT& a) const {
	                               MATCHTYPE(a);
	                               if(val==((GReal&)a).val) return 0;
				       else if (val>((GReal&)a).val) return 1;
				       else  return -1;
                                    }
    
    virtual GADT* 	 clone	   () const {return new GReal;}


    //====================================================
    //====
    // GROUP:   overloaded comparison operators
    //====
    //====================================================
    
    ///
    virtual bool operator ==	(const GReal& other) const {
	                         return val == other.val; }
    ///
    virtual bool operator <     (const GReal& other) const {
	                         return val < other.val;  }
    ///
    virtual bool operator <=    (const GReal& other) const {
	                         return val <= other.val; }
    ///
    virtual bool operator >	(const GReal& other) const {
	                         return val > other.val;  }
    ///
    virtual bool operator >=	(const GReal& other) const {
	                         return val >= other.val; }

    friend ostream&  operator <<(ostream& s, const GReal& r);
    
};  //class GReal


/**
      GFC type of VARCHAR (like what ORACLE has).

DESCRIPTION

	the value is a '\0' terminated string. 
	and len includes this '\0' .
*/
class GVarchar : public GADT
{
public:
    ///
    int		len;
    ///
    int		limit;
    ///
    // the actual character array
    char*	val;
    
public:
    // GROUP: ctors/operators
    ///
    GVarchar ( int max= MAX_STR) {init(); limit=max; }

    ///    
    GVarchar (const char* str) :val(0)
    {
	set(str);
    }
    ///
    GVarchar(const GVarchar& other) 
    {
	len = other.len;
	val = new char[len];
	GAssert(val);
	memcpy(val, other.val, len);
	limit = other.limit;
    }
    ///
    virtual ~GVarchar() 
    {
	if(val) {
	    delete [] val;
	}
    }
    ///
    GVarchar& operator= (const GVarchar& other) 
    {
	
	if(this==&other) return *this;  //avoid self-assignment

	GADT::operator=(other);	//nothing in base class is interesting 
	if(!val || len<other.len) {
	    if(val) delete [] val;
	    len = other.len;
	    val = new char[len];
	    GAssert(val);
	}
	len = other.len;
	memcpy(val, other.val, len);
	limit = other.limit;
	return *this;
    }
    
    char*  getV()  {return val;}

#ifdef USE_CHANGEREC
    virtual GCHG*	 diff      (GADT& other) const {
	GAssert(other.type() == type()); 
	GCHG_VarChar *tmp = new GCHG_VarChar;
	tmp->set(((GVarchar&)other).val);
	return tmp;
    }

    virtual Result	 applyChg  (const GCHG* c)  {
	GAssert(c->type()==Chg_VarChar);
	set( ((GCHG_VarChar*)c)->new_val );
	return GOk;
    }
#endif



    //====================================================
    //====
    //====  common methods
    //====
    //====================================================
  
    virtual GType      	 type	   (void) const { return _Varchar; }

    virtual Result	 init	  (void) {val=0; limit=len =0; return GOk;}

    virtual uint32        getPSize()const  {
	                                   return len + sizeof(int)*2 ;}

    virtual Result 	 pack   (DataPipe& p) {
	GADT::pack(p);
	p.append(CONPTR(&len), sizeof(int));
	p.append(CONPTR(&limit), sizeof(int));
	p.append(CONPTR(val), len);
	return GOk; 
    }
    
    virtual Result 	 unpack   (DataPipe& p )    {
	GADT::unpack(p);
	GAssert(!p.eop());
	p.fetch((char*)&len, sizeof(int));
	p.fetch((char*)&limit, sizeof(int));
	GAssert(len>=0);
	if(val) {
	    delete [] val;
	    val = 0;
	}
	val = new char[len];
	GAssert(val);
	p.fetch(val, len);
	val[len-1] = '\0';	//not necessary, just for debug!!!
	return GOk;
    }
    
    virtual Result 	 input(const char* in) {
	set(in);
	return GOk;
    }
    
    virtual Result 	 output(char*& out)  {
	bp.extendTo(len+1);
	bp.recycle();
	char* p= (char*)bp.ptr();
	strcpy(p, val);
	out = p;
	return GOk;
    }
    
    void                 set       (const char* s)  {
	if(val) {
	    delete []val;
	    val = 0;
	    len = limit = 0;
	}
	len = strlen(s) +1 ;
	val = new char[len];
	strncpy(val, s, len);
	val[len-1]='\0';
    }
    
    void		setLimit   (int max) { limit = max; }
    
    virtual int          cmp       (const GADT& a) const {
	                               MATCHTYPE(a);
	                               return strcmp(val, ((GVarchar&)a).val);
                                   }

    virtual GADT* 	 clone	   () const {return new GVarchar(limit);}


    //====================================================
    //====
    // GROUP:   overloaded comparison operators
    //====
    //====================================================
      
    ///
    virtual bool operator ==	(const GVarchar& other) const {
        	//this will panic: no '\0' in the end of our value
	                         return strcmp(val, other.val)==0; }
    ///    
    virtual bool operator <     (const GVarchar& other) const {
	                         return strcmp(val, other.val)<0;  }
    ///
    virtual bool operator <=    (const GVarchar& other) const {
	                         return strcmp(val, other.val)<=0; }
    ///
    virtual bool operator >	(const GVarchar& other) const {
	                         return strcmp(val, other.val)>0;  }
    ///
    virtual bool operator >=	(const GVarchar& other) const {
	                         return strcmp(val, other.val)>=0; }

    friend ostream& 	 operator <<    (ostream& s, GVarchar& v);
};  //class GVarchar


//for proper registeration of ADTs
static class _GIInt
{
    static	int cnt;
public:
    _GIInt() 
    {
	if(cnt++==0) 
	    GADTManager::registerADT( new GADTDef( _Int, "Int",	1, 0,  new GInt) );    
    }
    ~_GIInt()
    {
	if(--cnt==0) 
	    GADTManager::removeADT(_Int);
    }
} gi_int;


static class _GIChar
{
    static	int cnt;
public:
    _GIChar() 
    {
	if(cnt++==0) 
	    GADTManager::registerADT( new GADTDef( _Char, "Char", 1, 0,  new GChar) );    
    }
    ~_GIChar()
    {
	if(--cnt==0) 
	    GADTManager::removeADT(_Char);
    }
} gi_char;

static class _GIReal
{
    static	int cnt;
public:
    _GIReal() 
    {
	if(cnt++==0) 
	    GADTManager::registerADT( new GADTDef( _Real, "Real",1, 0,  new GReal) );    
    }
    ~_GIReal()
    {
	if(--cnt==0) 
	    GADTManager::removeADT(_Real);
    }
} gi_real;

static class _GIVarchar
{
    static	int cnt;
public:
    _GIVarchar() 
    {
	if(cnt++==0) 
	    GADTManager::registerADT( new GADTDef( _Varchar, "Varchar",	1, 0,  new GVarchar) );    
    }
    ~_GIVarchar()
    {
	if(--cnt==0) 
	    GADTManager::removeADT(_Varchar);
    }
} gi_varchar;

extern bool getNextWord(const char* in, char* word, int& pos);

#endif






Documentation generated by lqian@lqian-sun on Wed Jul 14 09:36:10 EDT 1999