#include #include HIDDEN bool rec_has_memo(const RecDes* rd) { for( int i = rd->NFields - 1; i >= 0; i--) if (rd->Fd[i].TypeF == _memofld) return TRUE; return FALSE; } TVariable_field::TVariable_field( const char * name, // const char * expr, // TTypeexp type, int len) // : _rec(NULL), _name(name), _e(NULL) , _getfunc(NULL), _put_string(NULL), _in_get(FALSE),_lenght(len) { 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, // VIRTUAL_GET_FUNCTION getfunc, int len) // : _name(name), _e(NULL) , _rec(NULL), _getfunc(getfunc), _put_string(NULL), _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) , _getfunc(NULL), _put_string(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) , _getfunc(f._getfunc), _put_string(NULL), _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"); const int items = _e->numvar(); for (int i = 0; i < items; i++) _e->setvar(i, _rec->get(_e->varname(i))); v = *_e; } 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) { } 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(int 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); } void TVariable_rectype::add_field(TVariable_field * f) { CHECK(f, "Null field"); CHECKS(!TRectype::exist(f->name()), "Field already exist ", 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_memo_fld( const char * fieldname) { if (fieldname && *fieldname) { CHECKS(exist(fieldname), "Unknown memo field", fieldname); CHECKS(type(fieldname) == _memofld, "Incorrect field type", fieldname); _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 ((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 = strchr(s, '='); if (val) { *val = '\0'; val++; if (*val) { TVariable_field * v = (TVariable_field *) _virtual_fields.objptr(s); if (v == NULL) { v = new TVariable_field(s); ((TVariable_rectype *) this)->add_field(v); } v->force_value(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; 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_fields); return *this; } // Certified 99% TRectype & TVariable_rectype::operator =(const char* rec) { TRectype::operator =(rec); _virtual_fields.for_each(zero_virtual_fields); return *this; } /////////////////////////////////////////////////////////// // TExtrectype /////////////////////////////////////////////////////////// TExtrectype::TExtrectype(const TTrec& r) : TVariable_rectype(r.num()) { delete _rec; _length = r.len(); _rec = new char [ _length ]; _rd = new RecDes; memcpy(_rd, r.rec(),sizeof(RecDes)); if( rec_has_memo(_rd)) init_memo(RECORD_NON_FISICO ); zero(); } TExtrectype::~TExtrectype() { delete _rd; }