#include #include /////////////////////////////////////////////////////////// // TVariant /////////////////////////////////////////////////////////// const TVariant NULL_VARIANT; void TVariant::set_null() { if (_ptr != NULL) { switch (_type) { case _alfafld: delete (TString*)_ptr; break; case _realfld: delete (real*)_ptr; break; default : break; } _ptr = NULL; } _type = _nullfld; } void TVariant::set(const char* str) { if (str != NULL) { if (_type == _alfafld) *((TString*)_ptr) = str; else { set_null(); _type = _alfafld; _ptr = new TString(str); } } else set_null(); } void TVariant::set(const real& r) { if (_type == _realfld) *((real*)_ptr) = r; else { set_null(); _type = _realfld; _ptr = new real(r); } } void TVariant::set(const TDate& d) { if (_type != _datefld) set_null(); _type = _datefld; _ptr = (void*)d.date2ansi(); } void TVariant::set(const long n) { if (_type != _longfld) set_null(); _type = _longfld; _ptr = (void*)n; } bool TVariant::is_zero() const { switch (_type) { case _datefld: case _longfld: return _ptr == NULL; case _realfld: return as_real().is_zero(); case _alfafld: return real::is_null(as_string()); default: break; } return true; } bool TVariant::is_empty() const { if (_type == _alfafld) return as_string().empty(); return is_zero(); } TDate TVariant::as_date() const { if (_type == _alfafld) return TDate(as_string()); return TDate(as_int()); } long TVariant::as_int() const { long n = 0; switch(_type) { case _datefld: case _longfld: n = (long)_ptr; break; case _realfld: n = as_real().integer(); break; case _alfafld: { const TString& str = as_string(); if (str[0] == '#') sscanf(str, "#%X", &n); else n = atoi(str); } break; default : break; } return n; } bool TVariant::as_bool() const { bool ok = false; if (_type == _alfafld) ok = strchr("1XY", as_string()[0]) != NULL; else ok = as_int() != 0; return ok; } COLOR TVariant::as_color() const { unsigned long rgb = as_int(); unsigned char r = XVT_COLOR_GET_RED(rgb); unsigned char g = XVT_COLOR_GET_GREEN(rgb); unsigned char b = XVT_COLOR_GET_BLUE(rgb); return MAKE_COLOR(r, g, b); } real TVariant::as_real() const { if (_type == _realfld) return *(real*)_ptr; switch(_type) { case _alfafld: return real(as_string()); break; case _longfld: return real(as_int()); break; default : break; } return ZERO; } bool TVariant::as_string(TString& tmp) const { tmp.cut(0); switch(_type) { case _alfafld: tmp = *(TString*)_ptr; break; case _datefld: tmp = as_date().string(); break; case _longfld: tmp << as_int(); break; case _realfld: tmp = as_real().string(); break; default: break; } return !is_null(); } const TString& TVariant::as_string() const { if (_type == _alfafld) return *(TString*)_ptr; else if (_type == _nullfld) return EMPTY_STRING; TString& tmp = get_tmp_string(); as_string(tmp); return tmp; } void TVariant::convert_to(TFieldtypes ft) { if (_type != ft) { switch (ft) { case _alfafld: set(as_string()); break; case _datefld: set(as_date()); break; case _longfld: set(as_int()); break; case _realfld: set(as_real()); break; default : set_null(); break; } } } void TVariant::copy(const TVariant& var) { switch (var._type) { case _datefld: set(var.as_date()); break; case _longfld: set(var.as_int()); break; case _realfld: set(var.as_real()); break; case _alfafld: set(var.as_string()); break; default : set_null(); break; } } bool TVariant::is_kind_of(word cid) const { return cid == CLASS_VARIANT || TSortable::is_kind_of(cid); } int TVariant::compare(const TSortable& s) const { CHECK(s.is_kind_of(CLASS_VARIANT), "Illegal Variant comparison"); const TVariant& var = (const TVariant&)s; int cmp = 0; switch (_type) { case _datefld: cmp = as_date() - var.as_date(); break; case _longfld: cmp = as_int() - var.as_int(); break; case _realfld: { const real n = as_real() - var.as_real(); cmp = n.sign(); } break; case _alfafld: cmp = as_string().compare(var.as_string()); break; default : cmp = var.is_null() ? 0 : -1; } return cmp; } TVariant& TVariant::add(const TVariant& var) { switch (_type) { case _datefld: set(as_date() + var.as_int()); break; case _longfld: set(as_int() + var.as_int()); break; case _alfafld: *(TString*)_ptr << var.as_string(); break; case _realfld: *(real*)_ptr += var.as_real(); break; default: copy(var); break; } return *this; } TVariant& TVariant::sub(const TVariant& var) { switch (_type) { case _datefld: if (var.type() == _datefld) set(as_date() - var.as_date()); else set(as_date() - var.as_int()); break; case _longfld: if (var.type() == _longfld) { set(as_int() - var.as_int()); break; } // Fall down default: { real n = as_real(); n -= var.as_real(); set(n); } break; } return *this; } /////////////////////////////////////////////////////////// // TVariant_stack /////////////////////////////////////////////////////////// TVariant& TVariant_stack::peek(int depth) { const int sp = _sp-depth-1; return (sp >= 0 && sp < _var.items()) ? (TVariant&)_var[sp] : (TVariant &)NULL_VARIANT; } bool TVariant_stack::drop() { if (_sp > 0) { _sp--; return true; } return false; } TVariant& TVariant_stack::pop() { TVariant& var = peek(0); drop(); return var; } void TVariant_stack::roll(int depth) { const int sp = _sp-depth-1; if (sp >= 0) { TObject* var = _var.remove(sp, true); _var.insert(var, _sp-1); } } void TVariant_stack::push(const TVariant& var) { if (_var.objptr(_sp) == NULL) _var.add(var, _sp); else (TVariant&)_var[_sp] = var; _sp++; } void TVariant_stack::push(long n) { const TVariant var(n); push(var); } void TVariant_stack::push(const real& n) { const TVariant var(n); push(var); } void TVariant_stack::push(const char* str) { const TVariant var(str); push(var); } void TVariant_stack::reset() { _sp = 0; } bool TVariant_stack::overflow() const { return _sp > 2048; }