398 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			398 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#include <relation.h>
 | 
						||
#include <varrec.h> 
 | 
						||
 | 
						||
TVariable_field::TVariable_field(
 | 
						||
                const char * name,
 | 
						||
                const char * expr,
 | 
						||
                TTypeexp type,
 | 
						||
                int len)
 | 
						||
               : _rec(NULL), _name(name), _e(NULL), _put_string(NULL),
 | 
						||
                 _getfunc(NULL), _in_get(FALSE),_lenght(len)
 | 
						||
{                         
 | 
						||
  if (expr && *expr)
 | 
						||
  {
 | 
						||
    _e = new TExpression(expr, type);
 | 
						||
    if (TFixed_string(expr).find('-') < 0) 
 | 
						||
      _put_string = new TToken_string(expr, '+');
 | 
						||
  }   
 | 
						||
}
 | 
						||
 | 
						||
TVariable_field::TVariable_field(
 | 
						||
                const char * name,        //
 | 
						||
                VIRTUAL_GET_FUNCTION getfunc, 
 | 
						||
                int len) //  
 | 
						||
               : _rec(NULL), _name(name), _e(NULL), _put_string(NULL),
 | 
						||
                 _getfunc(getfunc), _in_get(FALSE), _lenght(len)
 | 
						||
{
 | 
						||
  CHECK(_getfunc, "You must pass a valid VIRTUAL_GET_FUNCTION");
 | 
						||
}
 | 
						||
 | 
						||
TVariable_field::TVariable_field(
 | 
						||
                const char * name,      //
 | 
						||
                const TExpression & expr,      //
 | 
						||
                TTypeexp type,
 | 
						||
                int len)          //  
 | 
						||
               : _rec(NULL), _name(name), _e(NULL), _put_string(NULL),
 | 
						||
                 _getfunc(NULL), _in_get(FALSE),_lenght(len)
 | 
						||
{                            
 | 
						||
  _e = (TExpression *) expr.dup();
 | 
						||
}
 | 
						||
 | 
						||
TVariable_field::TVariable_field(const TVariable_field & f)
 | 
						||
               : _rec(f._rec), _name(f._name), _e(NULL), _put_string(NULL),
 | 
						||
                 _getfunc(f._getfunc), _in_get(FALSE),_lenght(f._lenght)
 | 
						||
{                
 | 
						||
  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 (_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 (dirty())
 | 
						||
  {
 | 
						||
    if (_in_get)
 | 
						||
      fatal_box("Recursive get in %s", (const char *) _name);
 | 
						||
    ((TVariable_field *) this)->_in_get = true;
 | 
						||
    if (_e)        
 | 
						||
    {
 | 
						||
      CHECK(_rec, "NULL Record pointer with an expression");
 | 
						||
      _rec->set_variables(_e);
 | 
						||
      v = _e->as_string();
 | 
						||
    }
 | 
						||
    else                 
 | 
						||
      if (_getfunc)
 | 
						||
      {
 | 
						||
        CHECK(_rec, "NULL Record pointer with a function");
 | 
						||
        v = _getfunc(*_rec);
 | 
						||
      }
 | 
						||
    ((TVariable_field*) this)->_in_get = false;
 | 
						||
    ((TVariable_field*) this)->set_clean();
 | 
						||
  }
 | 
						||
  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)
 | 
						||
{
 | 
						||
  switch (logicnum)
 | 
						||
  {
 | 
						||
  case LF_DOC     : set_memo_fld("G1");  break;
 | 
						||
  case LF_RIGHEDOC: set_memo_fld("RG1"); break;
 | 
						||
  default         : break;
 | 
						||
  }
 | 
						||
 | 
						||
}
 | 
						||
 | 
						||
TVariable_rectype::TVariable_rectype(const TBaseisamfile* i)
 | 
						||
                 : TRectype(i), _memo_fld_to_load(false)
 | 
						||
{
 | 
						||
  switch (i->num())
 | 
						||
  {
 | 
						||
  case LF_DOC     : set_memo_fld("G1");  break;
 | 
						||
  case LF_RIGHEDOC: set_memo_fld("RG1"); break;
 | 
						||
  default         : break;
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
TVariable_rectype::TVariable_rectype(const TRectype& r)
 | 
						||
         : TRectype(r), _memo_fld_to_load(false)
 | 
						||
{
 | 
						||
  switch (r.num())
 | 
						||
  {
 | 
						||
  case LF_DOC     : set_memo_fld("G1");  _memo_fld_to_load = !r.empty(); break;
 | 
						||
  case LF_RIGHEDOC: set_memo_fld("RG1"); _memo_fld_to_load = !r.empty(); break;
 | 
						||
  default         : break;
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
TVariable_rectype::TVariable_rectype(const TVariable_rectype& r)
 | 
						||
         : TRectype((const TRectype &) r), _memo_fld_to_load(false) 
 | 
						||
{
 | 
						||
  _virtual_fields = r._virtual_fields; 
 | 
						||
  set_memo_fld(r._memo_fld);
 | 
						||
  _memo_fld_to_load = !r.empty(); // novit<69> del 23-04-2014
 | 
						||
}
 | 
						||
 | 
						||
void TVariable_rectype::unknown_field(const char* name) const 
 | 
						||
{
 | 
						||
  if (!auto_virtual_fields())
 | 
						||
    TRectype::unknown_field(name);
 | 
						||
}
 | 
						||
                    
 | 
						||
void TVariable_rectype::write_memo(TIsam_handle file, const TRecnotype recno)
 | 
						||
{   
 | 
						||
  if (_memo_fld.full())
 | 
						||
  {
 | 
						||
    TToken_string t(256, '\n'); 
 | 
						||
    FOR_EACH_ASSOC_OBJECT(_virtual_fields, h, key, o)
 | 
						||
    {   
 | 
						||
      const TVariable_field* vf = (TVariable_field*)o;
 | 
						||
      const TString& val = vf->get();
 | 
						||
      if (val.full() && val != "0")
 | 
						||
      {
 | 
						||
        t.add(key);
 | 
						||
        t << '=' << val;
 | 
						||
      }
 | 
						||
    }         
 | 
						||
    put(_memo_fld, t);
 | 
						||
  }
 | 
						||
  TRectype::write_memo(file, recno);
 | 
						||
}
 | 
						||
 | 
						||
void TVariable_rectype::add_field(TVariable_field * f)
 | 
						||
{                  
 | 
						||
  CHECK(f, "Null field");
 | 
						||
  CHECKS(!TRectype::exist(f->name()), "Ambiuguous virtual/physical field ", f->name());
 | 
						||
  f->set_rec(this);
 | 
						||
  _virtual_fields.add(f->name(), f, true);
 | 
						||
}                                                              
 | 
						||
 | 
						||
void TVariable_rectype::remove_field(const char * fieldname)
 | 
						||
{ 
 | 
						||
  if (fieldname)
 | 
						||
  {                      
 | 
						||
    if (_virtual_fields.is_key(fieldname))
 | 
						||
      _virtual_fields.remove(fieldname);
 | 
						||
  }
 | 
						||
  else 
 | 
						||
    _virtual_fields.destroy();
 | 
						||
}                                   
 | 
						||
 | 
						||
void TVariable_rectype::set_variables(TExpression * e) const
 | 
						||
{ 
 | 
						||
  const int items = e->numvar();
 | 
						||
  for  (int i = 0; i < items; i++)
 | 
						||
    e->setvar(i, get(e->varname(i)));
 | 
						||
}  
 | 
						||
 | 
						||
void TVariable_rectype::set_memo_fld(const char* fieldname)
 | 
						||
{                                                       
 | 
						||
  if (fieldname && *fieldname && type(fieldname) == _memofld)
 | 
						||
    _memo_fld = fieldname;
 | 
						||
  else 
 | 
						||
    _memo_fld.cut(0);
 | 
						||
}                         
 | 
						||
 | 
						||
void TVariable_rectype::init_memo(TRecnotype recno, TIsam_handle file)
 | 
						||
{  
 | 
						||
  TRectype::init_memo(recno, file); 
 | 
						||
  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;
 | 
						||
}
 | 
						||
 | 
						||
void TVariable_rectype::load_memo()
 | 
						||
{
 | 
						||
	_memo_fld_to_load = true;
 | 
						||
	get_str("DUMMY");
 | 
						||
}
 | 
						||
 | 
						||
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  ((TVariable_field *)_virtual_fields.objptr(fieldname))->lenght();
 | 
						||
  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 = (char*)strchr(s, '='); //antica porcata
 | 
						||
      if (val)
 | 
						||
      {      
 | 
						||
        *val = '\0';
 | 
						||
        val++;
 | 
						||
        if (*val)
 | 
						||
        {
 | 
						||
          TVariable_field* v = (TVariable_field*)_virtual_fields.objptr(s);    
 | 
						||
          if (v == NULL)
 | 
						||
          { 
 | 
						||
            if (TRectype::exist(s)) // Campo ex-virtuale ora diventato reale
 | 
						||
            {
 | 
						||
              CHECKS(TRectype::get(s).empty(), "Campo ex-virtuale pieno ", s);
 | 
						||
              ((TRectype*)this)->TRectype::put(s, val); 
 | 
						||
            }
 | 
						||
            else
 | 
						||
            {
 | 
						||
              v = new TVariable_field(s);
 | 
						||
              ((TVariable_rectype*)this)->add_field(v);
 | 
						||
            }
 | 
						||
          }
 | 
						||
          if (v != NULL)
 | 
						||
            v->force_value(val);
 | 
						||
        }
 | 
						||
      }
 | 
						||
    }
 | 
						||
    f = (TVariable_field*)_virtual_fields.objptr(fieldname);
 | 
						||
  }
 | 
						||
  if (f != NULL)
 | 
						||
    return f->get();  // Easier to breakpoint
 | 
						||
  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_field(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_field);
 | 
						||
}
 | 
						||
 | 
						||
// Certified 99%
 | 
						||
TVariable_rectype & TVariable_rectype::operator =(const TVariable_rectype & rec)
 | 
						||
{
 | 
						||
  TRectype::operator =(rec);
 | 
						||
  _virtual_fields = rec._virtual_fields;
 | 
						||
  for (TVariable_field * f = first_variable_field();
 | 
						||
       f != NULL; f = succ_variable_field()) 
 | 
						||
    f->set_rec(this);
 | 
						||
  return *this;
 | 
						||
}
 | 
						||
 | 
						||
// Certified 99%
 | 
						||
TRectype & TVariable_rectype::operator =(const TRectype & rec)
 | 
						||
{
 | 
						||
  TRectype::operator =(rec);
 | 
						||
  _virtual_fields.for_each(zero_virtual_field);
 | 
						||
  return *this;
 | 
						||
}
 | 
						||
 | 
						||
// Certified 99%
 | 
						||
TRectype & TVariable_rectype::operator =(const char* rec)
 | 
						||
{
 | 
						||
  TRectype::operator =(rec);
 | 
						||
  _virtual_fields.for_each(zero_virtual_field);
 | 
						||
  return *this;
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TExtrectype
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
TExtrectype::TExtrectype(const TTrec& r) : TVariable_rectype(r.num())
 | 
						||
{
 | 
						||
  delete _rec;
 | 
						||
  _length = r.len();
 | 
						||
  _rec = new char [_length];
 | 
						||
  _rd = r.rec();
 | 
						||
  if(has_memo())
 | 
						||
    init_memo(RECORD_NON_FISICO );
 | 
						||
  zero();
 | 
						||
}
 | 
						||
 | 
						||
TExtrectype::~TExtrectype()
 | 
						||
{ }
 |