428 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			428 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#include <varrec.h> 
 | 
						|
 | 
						|
#ifndef __RELATION_H
 | 
						|
#include <relation.h>
 | 
						|
#endif
 | 
						|
 | 
						|
// @doc INTERNAL
 | 
						|
//
 | 
						|
// @class TVariable_field | Oggetto campo virtuale
 | 
						|
//
 | 
						|
// @base public | TObject
 | 
						|
class TVariable_field : public TObject
 | 
						|
 | 
						|
// @author:(INTERNAL) Sandro
 | 
						|
 | 
						|
{ 
 | 
						|
  TVariable_rectype * _rec;                
 | 
						|
  TString _name;
 | 
						|
  TExpression * _e;
 | 
						|
  TString _value;
 | 
						|
  TToken_string * _put_string;
 | 
						|
  VIRTUAL_GET_FUNCTION _getfunc;
 | 
						|
  bool _destroy_expression;
 | 
						|
  
 | 
						|
public:
 | 
						|
  // @access Public Member
 | 
						|
  // @cmember Duplica il campo
 | 
						|
  virtual TObject* dup() const;
 | 
						|
 | 
						|
// @cmember ritorna il nome del campo
 | 
						|
  const char * name() const { return _name;}
 | 
						|
// @cmember ritorna il valore del campo
 | 
						|
  TString & get() const;
 | 
						|
// @cmember aggiorna il valore del campo utilizzando <p val> 
 | 
						|
  void put(const char * val);
 | 
						|
// @cmember azzera il valore del campo 
 | 
						|
  void zero();
 | 
						|
// @cmember il campo non ha formule o funzioni collegate
 | 
						|
  bool plain() const 
 | 
						|
  { return _e == NULL && _getfunc == NULL;}
 | 
						|
 | 
						|
// @ cmember Costruttore con una espressione di calcolo  
 | 
						|
  TVariable_field(const char * name, TVariable_rectype * rec = NULL, const char * expr = "", TTypeexp type = _strexpr);
 | 
						|
// @ cmember Costruttore con una funzione
 | 
						|
  TVariable_field(const char * name, TVariable_rectype * rec, VIRTUAL_GET_FUNCTION getfunc);
 | 
						|
// @ cmember Costruttore con una espressione di calcolo  
 | 
						|
  TVariable_field(const char * name, TVariable_rectype * rec, TExpression * expr, TTypeexp type = _strexpr);
 | 
						|
// @ cmember Costruttore con un variable_field 
 | 
						|
  TVariable_field(const TVariable_field & f);
 | 
						|
// @ cmember Distruttore  
 | 
						|
  ~TVariable_field();
 | 
						|
};
 | 
						|
               
 | 
						|
TVariable_field::TVariable_field(
 | 
						|
                const char * name,      //
 | 
						|
                TVariable_rectype * rec,         //
 | 
						|
                const char * expr,      //
 | 
						|
                TTypeexp type)          //  
 | 
						|
               : _rec(rec), _name(name), _e(NULL) , _getfunc(NULL),
 | 
						|
                 _put_string(NULL), _destroy_expression(TRUE)
 | 
						|
{                         
 | 
						|
  if (expr && *expr)
 | 
						|
  {
 | 
						|
    _e = new TExpression(expr, type);
 | 
						|
    if (TFixed_string(expr).find('-') == -1) _put_string = new TToken_string(expr, '+');
 | 
						|
  }   
 | 
						|
}
 | 
						|
 | 
						|
TVariable_field::TVariable_field(
 | 
						|
                const char * name,        //
 | 
						|
                TVariable_rectype * rec,         //
 | 
						|
                VIRTUAL_GET_FUNCTION getfunc) //  
 | 
						|
               : _name(name), _e(NULL) , _rec(rec), _getfunc(getfunc),
 | 
						|
                 _put_string(NULL), _destroy_expression(FALSE)
 | 
						|
{
 | 
						|
  CHECK(_getfunc, "You must pass a valid VIRTUAL_GET_FUNCTION");
 | 
						|
}
 | 
						|
 | 
						|
TVariable_field::TVariable_field(
 | 
						|
                const char * name,      //
 | 
						|
                TVariable_rectype * rec,         //
 | 
						|
                TExpression * expr,      //
 | 
						|
                TTypeexp type)          //  
 | 
						|
               : _rec(rec), _name(name), _e(expr) , _getfunc(NULL),
 | 
						|
                 _put_string(NULL), _destroy_expression(FALSE)
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
TVariable_field::TVariable_field(const TVariable_field & f)
 | 
						|
               : _rec(f._rec), _name(f._name), _e(NULL) , _getfunc(f._getfunc),
 | 
						|
                 _put_string(NULL), _destroy_expression(f._destroy_expression)
 | 
						|
{                
 | 
						|
  if (f._e)
 | 
						|
    _e = (TExpression *) f._e->dup();
 | 
						|
  if (f._put_string)
 | 
						|
    _put_string = new TToken_string(*f._put_string);
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
TVariable_field::~TVariable_field()
 | 
						|
{
 | 
						|
  if (_destroy_expression && _e) delete _e;
 | 
						|
  if (_put_string) delete _put_string;
 | 
						|
}   
 | 
						|
 | 
						|
TObject* TVariable_field::dup() const
 | 
						|
{
 | 
						|
  TVariable_field* o = new TVariable_field(*this);
 | 
						|
  return o;
 | 
						|
}    
 | 
						|
 | 
						|
TString & TVariable_field::get() const
 | 
						|
{        
 | 
						|
  TString & v = (TString &) _value;
 | 
						|
  if (_e)        
 | 
						|
  {
 | 
						|
    CHECK(_rec, "NULL Record pointer with an expression");
 | 
						|
    const int items = _e->numvar();
 | 
						|
    for  (int i = 0; i < items; i++)
 | 
						|
      _e->setvar(i, _rec->get(_e->varname(i)));
 | 
						|
      
 | 
						|
//    v = _e->type() == _strexpr ? (const char *) (*_e) : ((const real &) (*_e)).string();
 | 
						|
    v = *_e;
 | 
						|
  }
 | 
						|
  else                 
 | 
						|
    if (_getfunc)
 | 
						|
    {
 | 
						|
      CHECK(_rec, "NULL Record pointer with a function");
 | 
						|
      v = _getfunc(*_rec);
 | 
						|
    }
 | 
						|
  return v;
 | 
						|
}
 | 
						|
            
 | 
						|
void TVariable_field::put(const char * val)
 | 
						|
{      
 | 
						|
  if (!_getfunc)
 | 
						|
  {
 | 
						|
    if (_e == NULL)
 | 
						|
      _value = val;
 | 
						|
    else
 | 
						|
    {
 | 
						|
      if (_e->type() == _strexpr && _rec && _put_string)
 | 
						|
      { 
 | 
						|
        const TString work_val(val);
 | 
						|
        int start = 0;
 | 
						|
       
 | 
						|
        for (const char * s = _put_string->get(0); s && *s; s = _put_string->get())
 | 
						|
        {
 | 
						|
          TFieldref f(s, 0);       
 | 
						|
          const int len = f.len(*_rec);
 | 
						|
          f = work_val.mid(start, len);
 | 
						|
          start += len;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
            
 | 
						|
void TVariable_field::zero() 
 | 
						|
{ 
 | 
						|
  _value.cut(0);
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////
 | 
						|
//      TVariable_rectype
 | 
						|
////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
TVariable_rectype::TVariable_rectype(int logicnum)
 | 
						|
         : TRectype(logicnum), _memo_fld_to_load(FALSE)
 | 
						|
 | 
						|
  
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
TVariable_rectype::TVariable_rectype(const TBaseisamfile* i)
 | 
						|
         : TRectype(i), _memo_fld_to_load(FALSE)
 | 
						|
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
TVariable_rectype::TVariable_rectype(const TRectype& r)
 | 
						|
         : TRectype(r), _memo_fld_to_load(FALSE)
 | 
						|
  
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
TVariable_rectype::TVariable_rectype(const TVariable_rectype& r)
 | 
						|
         : TRectype((const TRectype &) r), _memo_fld_to_load(FALSE) 
 | 
						|
  
 | 
						|
{
 | 
						|
  _virtual_fields = r._virtual_fields; 
 | 
						|
  _memo_fld = r._memo_fld;
 | 
						|
}
 | 
						|
 | 
						|
void TVariable_rectype::unknown_field(const char* name) const 
 | 
						|
{
 | 
						|
  if (!auto_virtual_fields())
 | 
						|
    TRectype::unknown_field(name);
 | 
						|
}
 | 
						|
                    
 | 
						|
void TVariable_rectype::write_memo(isdef * file, const TRecnotype recno)
 | 
						|
{   
 | 
						|
  if (_memo_fld.not_empty())
 | 
						|
  {
 | 
						|
    TToken_string t(256, '\n'); 
 | 
						|
    TString s(80);
 | 
						|
    for (TVariable_field * vf = (TVariable_field *) _virtual_fields.first_item(); vf;
 | 
						|
         vf = (TVariable_field *) _virtual_fields.succ_item()) 
 | 
						|
    {              
 | 
						|
      const TString & val = vf->get();
 | 
						|
        
 | 
						|
      if (val.not_empty())
 | 
						|
      {
 | 
						|
        s = vf->name();
 | 
						|
        s << "=" << val;
 | 
						|
        t.add(s);
 | 
						|
      }
 | 
						|
    }         
 | 
						|
    put(_memo_fld, t);
 | 
						|
  }
 | 
						|
  TRectype::write_memo(file, recno);
 | 
						|
}
 | 
						|
 | 
						|
TVariable_field * TVariable_rectype::add_field(const char * fieldname, const char * expr, TTypeexp type)
 | 
						|
{ 
 | 
						|
  CHECKS(!TRectype::exist(fieldname), "Field already exist ", fieldname);
 | 
						|
  TVariable_field * f = new TVariable_field(fieldname, this, expr, type);
 | 
						|
  _virtual_fields.add(fieldname, f, TRUE);
 | 
						|
  return f;
 | 
						|
}                                                              
 | 
						|
 | 
						|
TVariable_field * TVariable_rectype::add_field(const char * fieldname, TExpression * expr,
 | 
						|
                                    TTypeexp type)
 | 
						|
{
 | 
						|
  CHECKS(!TRectype::exist(fieldname), "Field already exist ", fieldname);
 | 
						|
  TVariable_field * f = new TVariable_field(fieldname, this, expr, type);
 | 
						|
  _virtual_fields.add(fieldname, f, TRUE);
 | 
						|
  return f;
 | 
						|
}                                                              
 | 
						|
 | 
						|
TVariable_field * TVariable_rectype::add_field(const char * fieldname, VIRTUAL_GET_FUNCTION getfunc)
 | 
						|
{ 
 | 
						|
  CHECKS(!TRectype::exist(fieldname), "Field already exist ", fieldname);
 | 
						|
  CHECK(getfunc, "You must pass a valid VIRTUAL_GET_FUNCTION");
 | 
						|
  TVariable_field * f = new TVariable_field(fieldname, this, getfunc);
 | 
						|
  _virtual_fields.add(fieldname, f, TRUE);
 | 
						|
  return f;
 | 
						|
}                                   
 | 
						|
 | 
						|
void TVariable_rectype::remove_field(const char * fieldname)
 | 
						|
{ 
 | 
						|
  if (fieldname)
 | 
						|
  {                      
 | 
						|
    if (_virtual_fields.is_key(fieldname))
 | 
						|
      _virtual_fields.remove(fieldname);
 | 
						|
  }
 | 
						|
  else 
 | 
						|
    _virtual_fields.destroy();
 | 
						|
}                                   
 | 
						|
 | 
						|
const char * TVariable_rectype::get_variable_field_names(bool restart)
 | 
						|
{                                         
 | 
						|
  TVariable_field * f = (TVariable_field *) (restart ? _virtual_fields.first_item() :
 | 
						|
                                                       _virtual_fields.succ_item());
 | 
						|
  return f != NULL ? (const char *) f->name() : NULL;
 | 
						|
}                                   
 | 
						|
 | 
						|
void TVariable_rectype::set_memo_fld( const char * fieldname)
 | 
						|
{                                                       
 | 
						|
  if (fieldname && *fieldname)
 | 
						|
  {                 
 | 
						|
    CHECK(exist(fieldname), "Unknown memo field");
 | 
						|
    CHECK(type(fieldname) == _memofld, "Incorrect field type");
 | 
						|
    _memo_fld = fieldname;
 | 
						|
  }
 | 
						|
  else 
 | 
						|
   _memo_fld.cut(0);
 | 
						|
}                         
 | 
						|
 | 
						|
void TVariable_rectype::init_memo( const TRecnotype recno)
 | 
						|
{  
 | 
						|
  TRectype::init_memo(recno); 
 | 
						|
  if (recno != RECORD_NON_FISICO)
 | 
						|
   _memo_fld_to_load = _memo_fld.not_empty();
 | 
						|
}
 | 
						|
 | 
						|
TObject* TVariable_rectype::dup() const
 | 
						|
{
 | 
						|
  TVariable_rectype* o = new TVariable_rectype(*this);
 | 
						|
  return o;
 | 
						|
}
 | 
						|
 | 
						|
TFieldtypes TVariable_rectype::type(const char* fieldname) const
 | 
						|
 | 
						|
{
 | 
						|
  if (_virtual_fields.objptr(fieldname))
 | 
						|
    return _alfafld; 
 | 
						|
  return TRectype::type(fieldname);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int TVariable_rectype::length(const char* fieldname) const
 | 
						|
 | 
						|
{
 | 
						|
  if (_virtual_fields.objptr(fieldname))
 | 
						|
    return 255; 
 | 
						|
  return TRectype::length(fieldname);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int TVariable_rectype::ndec(const char* fieldname) const
 | 
						|
 | 
						|
{
 | 
						|
  if (_virtual_fields.objptr(fieldname))
 | 
						|
    return 0; 
 | 
						|
  return TRectype::ndec(fieldname);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
bool TVariable_rectype::exist(const char* fieldname) const
 | 
						|
{                   
 | 
						|
  if (_virtual_fields.is_key(fieldname))
 | 
						|
    return TRUE;
 | 
						|
  return TRectype::exist(fieldname);
 | 
						|
}
 | 
						|
 | 
						|
const TString & TVariable_rectype::get_str(const char* fieldname) const
 | 
						|
{   
 | 
						|
  TVariable_field * f = (TVariable_field *) _virtual_fields.objptr(fieldname); 
 | 
						|
  
 | 
						|
  if (_memo_fld_to_load && f == NULL)
 | 
						|
  {   
 | 
						|
    ((TVariable_rectype *) this)->_memo_fld_to_load = FALSE;                    
 | 
						|
    TToken_string values(get(_memo_fld), '\n');
 | 
						|
    for (const char * s = values.get(0); s && *s; s = values.get())
 | 
						|
    {
 | 
						|
      char * val = strchr(s, '=');
 | 
						|
      if (val)
 | 
						|
      {      
 | 
						|
        *val = '\0';
 | 
						|
        val++;
 | 
						|
        if (*val)
 | 
						|
        {
 | 
						|
          TVariable_field * v = (TVariable_field *) _virtual_fields.objptr(s);
 | 
						|
          
 | 
						|
          if (v == NULL) 
 | 
						|
            v = ((TVariable_rectype *) this)->add_field(s);
 | 
						|
          v->put(val);
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
    f = (TVariable_field *) _virtual_fields.objptr(fieldname);
 | 
						|
  }
 | 
						|
  if (f)  
 | 
						|
    return f->get();
 | 
						|
  else
 | 
						|
    return TRectype::get_str(fieldname);
 | 
						|
}
 | 
						|
 | 
						|
void TVariable_rectype::put_str(const char* fieldname, const char* val)
 | 
						|
{                                            
 | 
						|
  TVariable_field * f = (TVariable_field *) _virtual_fields.objptr(fieldname);
 | 
						|
 | 
						|
  if (f == NULL && auto_virtual_fields() && !TRectype::exist(fieldname))
 | 
						|
  {
 | 
						|
    _virtual_fields.add(fieldname, TVariable_field(fieldname));
 | 
						|
    f = (TVariable_field *) _virtual_fields.objptr(fieldname);
 | 
						|
  }
 | 
						|
  if (f)
 | 
						|
    f->put(val);
 | 
						|
  else
 | 
						|
    TRectype::put_str(fieldname, val);
 | 
						|
}
 | 
						|
 | 
						|
void TVariable_rectype::zero(const char* fieldname)
 | 
						|
  
 | 
						|
{
 | 
						|
  TVariable_field * f = (TVariable_field *) _virtual_fields.objptr(fieldname);
 | 
						|
  if (f)
 | 
						|
    f->zero();
 | 
						|
  else
 | 
						|
    TRectype::zero(fieldname);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
HIDDEN void zero_virtual_fields(const TObject & o)
 | 
						|
 | 
						|
{
 | 
						|
  TVariable_field & v = (TVariable_field &) o;
 | 
						|
  v.zero();
 | 
						|
}                              
 | 
						|
 | 
						|
void TVariable_rectype::zero(char c)
 | 
						|
  
 | 
						|
{
 | 
						|
  TRectype::zero(c);
 | 
						|
  _virtual_fields.for_each(zero_virtual_fields);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// Certified 99%
 | 
						|
TVariable_rectype & TVariable_rectype::operator =(const TVariable_rectype & rec)
 | 
						|
  
 | 
						|
{
 | 
						|
  TRectype::operator =(rec);
 | 
						|
  _virtual_fields = rec._virtual_fields;
 | 
						|
  return *this;
 | 
						|
}
 | 
						|
 | 
						|
// Certified 99%
 | 
						|
TRectype & TVariable_rectype::operator =(const TRectype & rec)
 | 
						|
  
 | 
						|
{
 | 
						|
  TRectype::operator =(rec);
 | 
						|
  _virtual_fields.for_each(zero_virtual_fields);
 | 
						|
  return *this;
 | 
						|
}
 | 
						|
 | 
						|
// Certified 99%
 | 
						|
TRectype & TVariable_rectype::operator =(const char* rec)
 | 
						|
{
 | 
						|
  TRectype::operator =(rec);
 | 
						|
  _virtual_fields.for_each(zero_virtual_fields);
 | 
						|
  return *this;
 | 
						|
}
 | 
						|
 | 
						|
  
 |