campo-sirio/include/variant.cpp

343 lines
6.3 KiB
C++
Raw Normal View History

#include <xvt.h>
#include <variant.h>
///////////////////////////////////////////////////////////
// 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;
}