📄 pvariant.cxx
字号:
/* * * C++ Portable Types Library (PTypes) * Version 1.7.5 Released 9-Mar-2003 * * Copyright (c) 2001, 2002, 2003 Hovik Melikyan * * http://www.melikyan.com/ptypes/ * http://ptypes.sourceforge.net/ * */#include <stdlib.h>#include <stdio.h>#include <limits.h>#include "ptypes.h"#include "pasync.h"PTYPES_BEGINconst variant nullvar;static void vfatal(){ fatal(CRIT_FIRST + 60, "Variant data corrupt");}static void vconverr(large v){ throw new evariant("Value out of range: " + itostring(v));}evariant::~evariant(){}void variant::initialize(_varray* a){ tag = VAR_ARRAY; pincrement(&a->refcount); value.a = a;}void variant::initialize(component* o){ tag = VAR_OBJECT; value.o = addref(o);}void variant::initialize(const variant& v){ switch (v.tag) { case VAR_NULL: tag = VAR_NULL; break; case VAR_INT: case VAR_BOOL: case VAR_FLOAT: tag = v.tag; value = v.value; break; case VAR_STRING: initialize(PTR_TO_STRING(v.value.s)); break; case VAR_ARRAY: initialize(v.value.a); break; case VAR_OBJECT: initialize(v.value.o); break; default: vfatal(); }}void variant::finalize(){ if (tag >= VAR_COMPOUND) { switch (tag) { case VAR_STRING: PTYPES_NAMESPACE::finalize(PTR_TO_STRING(value.s)); break; case VAR_ARRAY: if (pdecrement(&value.a->refcount) == 0) delete value.a; break; case VAR_OBJECT: release(value.o); break; default: vfatal(); } } tag = VAR_NULL;}void variant::assign(large v) { finalize(); initialize(v); }void variant::assign(bool v) { finalize(); initialize(v); }void variant::assign(double v) { finalize(); initialize(v); }void variant::assign(const char* v) { finalize(); initialize(v); }void variant::assign(const string& v) { if (tag == VAR_STRING) PTR_TO_STRING(value.s) = v; else { finalize(); initialize(v); }}void variant::assign(_varray* a){ if (tag == VAR_ARRAY) if (value.a == a) return; finalize(); initialize(a);}void variant::assign(component* o){ if (tag == VAR_OBJECT) { if (value.o == o) return; else release(value.o); } else finalize(); initialize(o);}void variant::assign(const variant& v){ switch (v.tag) { case VAR_NULL: finalize(); tag = VAR_NULL; break; case VAR_INT: case VAR_BOOL: case VAR_FLOAT: finalize(); tag = v.tag; value = v.value; break; case VAR_STRING: assign(PTR_TO_STRING(v.value.s)); break; case VAR_ARRAY: assign(v.value.a); break; case VAR_OBJECT: assign(v.value.o); break; default: vfatal(); }}void clear(variant& v){ v.finalize(); v.initialize();}variant::operator int() const{ large t = operator large(); if (t < INT_MIN || t > INT_MAX) vconverr(t); return int(t);}variant::operator unsigned int() const{ large t = operator large(); if (t < 0 || t > UINT_MAX) vconverr(t); return uint(t);}variant::operator long() const{ large t = operator large(); if (t < LONG_MIN || t > LONG_MAX) vconverr(t); return int(t);}variant::operator unsigned long() const{ large t = operator large(); if (t < 0 || t > large(ULONG_MAX)) vconverr(t); return uint(t);}variant::operator large() const{ switch(tag) { case VAR_NULL: return 0; case VAR_INT: return value.i; case VAR_BOOL: return int(value.b); case VAR_FLOAT: return int(value.f); case VAR_STRING: { const char* p = PTR_TO_STRING(value.s); bool neg = *p == '-'; if (neg) p++; large t = stringtoi(p); if (t < 0) return 0; else return neg ? -t : t; } case VAR_ARRAY: return value.a->count != 0; case VAR_OBJECT: return 0; default: vfatal(); } return 0;}variant::operator bool() const{ switch(tag) { case VAR_NULL: return false; case VAR_INT: return value.i != 0; case VAR_BOOL: return value.b; case VAR_FLOAT: return value.f != 0; case VAR_STRING: return !isempty((PTR_TO_STRING(value.s))); case VAR_ARRAY: return value.a->count != 0; case VAR_OBJECT: return value.o != nil; default: vfatal(); } return false;}variant::operator double() const{ switch(tag) { case VAR_NULL: return 0; case VAR_INT: return double(value.i); case VAR_BOOL: return int(value.b); case VAR_FLOAT: return value.f; case VAR_STRING: { char* e; double t = strtod(PTR_TO_STRING(value.s), &e); if (*e != 0) return 0; else return t; } case VAR_ARRAY: return int(value.a->count != 0); case VAR_OBJECT: return 0; default: vfatal(); } return 0;}variant::operator string() const{ switch(tag) { case VAR_NULL: return nullstring; case VAR_INT: return itostring(value.i); case VAR_BOOL: return value.b ? "1" : "0"; case VAR_FLOAT: { char buf[256]; sprintf(buf, "%g", value.f); return buf; } case VAR_STRING: return PTR_TO_STRING(value.s); case VAR_ARRAY: return nullstring; case VAR_OBJECT: return nullstring; default: vfatal(); } return nullstring;}variant::operator component*() const{ if (tag == VAR_OBJECT) return value.o; else return nil;}bool variant::equal(const variant& v) const{ if (tag != v.tag) return false; switch (tag) { case VAR_NULL: return true; case VAR_INT: return value.i == v.value.i; case VAR_BOOL: return value.b == v.value.b; case VAR_FLOAT: return value.f == v.value.f; case VAR_STRING: return strcmp(value.s, v.value.s) == 0; case VAR_ARRAY: return value.a == v.value.a; case VAR_OBJECT: return value.o == v.value.o; default: vfatal(); return false; }}varobject::~varobject(){}_varray::~_varray(){}PTYPES_END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -