mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-08-31 07:12:39 -06:00
uppsrc: OLD_VALUE completely removed, Core/Rpc: Now supports Json parameters and return values
git-svn-id: svn://ultimatepp.org/upp/trunk@5356 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
295f172c86
commit
6cf239033f
29 changed files with 98 additions and 1818 deletions
|
|
@ -165,15 +165,9 @@ Color Blend(Color c1, Color c2, int alpha)
|
|||
min(((a * (c2.GetB() - c1.GetB())) >> 8) + c1.GetB(), 255));
|
||||
}
|
||||
|
||||
#ifdef SVO_VALUE
|
||||
INITBLOCK {
|
||||
Value::SvoRegister<Color>("Color");
|
||||
}
|
||||
#else
|
||||
INITBLOCK {
|
||||
RichValue<Color>::Register();
|
||||
}
|
||||
#endif
|
||||
|
||||
int Grayscale(const Color& c)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -57,13 +57,8 @@ public:
|
|||
|
||||
Color(const Nuller&) { SetNull(); }
|
||||
|
||||
#ifdef SVO_VALUE
|
||||
operator Value() const { return SvoToValue(*this); }
|
||||
Color(const Value& q) { color = q.Get<Color>().color; }
|
||||
#else
|
||||
operator Value() const { return RichValue<Color>(*this); }
|
||||
Color(const Value& q) { color = RichValue<Color>::Extract(q).color; }
|
||||
#endif
|
||||
|
||||
operator RGBA() const;
|
||||
Color(RGBA rgba);
|
||||
|
|
|
|||
|
|
@ -281,20 +281,6 @@ NAMESPACE_UPP
|
|||
#include "Vcont.hpp"
|
||||
#include "Index.hpp"
|
||||
|
||||
#ifdef flagSVO_VALUE
|
||||
#ifndef SVO_VALUE
|
||||
#define SVO_VALUE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef flagOLD_VALUE
|
||||
#ifdef SVO_VALUE
|
||||
#undef SVO_VALUE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "OldValue.h"
|
||||
|
||||
#include "Value.h"
|
||||
#include "ValueUtil.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -98,8 +98,6 @@ file
|
|||
Callback.cpp optimize_speed,
|
||||
TimeDate.h,
|
||||
TimeDate.cpp optimize_speed,
|
||||
OldValue.h,
|
||||
OldValue.cpp optimize_speed,
|
||||
Value.h,
|
||||
Value.hpp,
|
||||
Value.cpp optimize_speed,
|
||||
|
|
|
|||
|
|
@ -72,13 +72,8 @@ struct Size_ : Moveable< Size_<T> > {
|
|||
|
||||
Size_(const Nuller&) { cx = cy = Null; }
|
||||
|
||||
#ifdef SVO_VALUE
|
||||
operator Value() const { return FitsSvoValue<Size_>() ? SvoToValue(*this) : RichToValue(*this); }
|
||||
Size_(const Value& src) { *this = src.Get<Size_>(); }
|
||||
#else
|
||||
operator Value() const { return RichValue<Size_>(*this); }
|
||||
Size_(const Value& src) { *this = RichValue<Size_>::Extract(src); }
|
||||
#endif
|
||||
|
||||
void Serialize(Stream& s) { s % cx % cy; }
|
||||
void Jsonize(JsonIO& jio) { jio("cx", cx)("cy", cy); }
|
||||
|
|
@ -181,13 +176,8 @@ struct Point_ : Moveable< Point_<T> > {
|
|||
|
||||
Point_(const Nuller&) { x = y = Null; }
|
||||
|
||||
#ifdef SVO_VALUE
|
||||
operator Value() const { return FitsSvoValue<Point_>() ? SvoToValue(*this) : RichToValue(*this); }
|
||||
Point_(const Value& src) { *this = src.Get<Point_>(); }
|
||||
#else
|
||||
operator Value() const { return RichValue<Point_>(*this); }
|
||||
Point_(const Value& src) { *this = RichValue<Point_>::Extract(src); }
|
||||
#endif
|
||||
|
||||
void Serialize(Stream& s) { s % x % y; }
|
||||
void Jsonize(JsonIO& jio) { jio("x", x)("y", y); }
|
||||
|
|
@ -726,20 +716,3 @@ double Distance(const Pointf& p1, const Pointf& p2);
|
|||
double SquaredDistance(const Pointf& p1, const Pointf& p2);
|
||||
Pointf Polar(double a);
|
||||
Pointf Polar(const Pointf& p, double r, double a);
|
||||
|
||||
#ifndef SVO_VALUE
|
||||
template<> void Xmlize(XmlIO& xml, Point& p);
|
||||
template<> void Xmlize(XmlIO& xml, Point16& p);
|
||||
template<> void Xmlize(XmlIO& xml, Point64& p);
|
||||
template<> void Xmlize(XmlIO& xml, Pointf& p);
|
||||
|
||||
template<> void Xmlize(XmlIO& xml, Size& sz);
|
||||
template<> void Xmlize(XmlIO& xml, Size16& sz);
|
||||
template<> void Xmlize(XmlIO& xml, Size64& sz);
|
||||
template<> void Xmlize(XmlIO& xml, Sizef& sz);
|
||||
|
||||
template<> void Xmlize(XmlIO& xml, Rect& r);
|
||||
template<> void Xmlize(XmlIO& xml, Rect16& r);
|
||||
template<> void Xmlize(XmlIO& xml, Rect64& r);
|
||||
template<> void Xmlize(XmlIO& xml, Rectf& r);
|
||||
#endif
|
||||
|
|
@ -51,6 +51,22 @@ Value ParseJSON(const char *s)
|
|||
}
|
||||
}
|
||||
|
||||
Json& Json::CatRaw(const char *key, const String& val)
|
||||
{
|
||||
if(text.GetCount())
|
||||
text << ',';
|
||||
text << AsJSON(key) << ":" << val;
|
||||
return *this;
|
||||
}
|
||||
|
||||
JsonArray& JsonArray::CatRaw(const String& val)
|
||||
{
|
||||
if(text.GetCount())
|
||||
text << ',';
|
||||
text << val;
|
||||
return *this;
|
||||
}
|
||||
|
||||
String AsJSON(const Value& v, const String& sep, bool pretty)
|
||||
{
|
||||
String r;
|
||||
|
|
@ -114,9 +130,7 @@ String AsJSON(const Value& v, const String& sep, bool pretty)
|
|||
return AsCString((String)v, INT_MAX, NULL, ASCSTRING_JSON);
|
||||
if(IsNull(v))
|
||||
return "null";
|
||||
#ifdef SVO_VALUE
|
||||
NEVER_("Non-JSON value in AsJSON: " + v.GetTypeName());
|
||||
#endif
|
||||
return "null";
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,14 +16,9 @@ class JsonArray;
|
|||
class Json {
|
||||
String text;
|
||||
|
||||
Json& CatRaw(const char *key, const String& val) {
|
||||
if(text.GetCount())
|
||||
text << ',';
|
||||
text << AsJSON(key) << ":" << val;
|
||||
return *this;
|
||||
}
|
||||
|
||||
public:
|
||||
Json& CatRaw(const char *key, const String& val);
|
||||
|
||||
String ToString() const { return "{" + text + "}"; }
|
||||
String operator~() const { return ToString(); }
|
||||
operator String() const { return ToString(); }
|
||||
|
|
@ -53,14 +48,9 @@ public:
|
|||
class JsonArray {
|
||||
String text;
|
||||
|
||||
JsonArray& CatRaw(const String& val) {
|
||||
if(text.GetCount())
|
||||
text << ',';
|
||||
text << val;
|
||||
return *this;
|
||||
}
|
||||
|
||||
public:
|
||||
JsonArray& CatRaw(const String& val);
|
||||
|
||||
String ToString() const { return "[" + text + "]"; }
|
||||
String operator~() const { return ToString(); }
|
||||
operator String() const { return ToString(); }
|
||||
|
|
|
|||
|
|
@ -1,681 +0,0 @@
|
|||
#include "Core.h"
|
||||
|
||||
#ifndef SVO_VALUE
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#ifndef flagSO
|
||||
const Nuller Null;
|
||||
#endif
|
||||
|
||||
#define LTIMING(x) // RTIMING(x)
|
||||
|
||||
unsigned Value::GetHashValue() const {
|
||||
return IsNull() ? 0 : ptr->GetHashValue();
|
||||
}
|
||||
|
||||
Value& Value::operator=(const Value& v) {
|
||||
if(this == &v) return *this;
|
||||
ptr->Release();
|
||||
ptr = v.ptr;
|
||||
ptr->Retain();
|
||||
return *this;
|
||||
}
|
||||
|
||||
Value::Value(const Value& v) {
|
||||
ptr = v.ptr;
|
||||
ptr->Retain();
|
||||
}
|
||||
|
||||
void Value::SetVoidVal()
|
||||
{
|
||||
ptr = &Single<Void>();
|
||||
ptr->Retain();
|
||||
}
|
||||
|
||||
Value::Value() {
|
||||
SetVoidVal();
|
||||
}
|
||||
|
||||
Value::~Value() {
|
||||
ptr->Release();
|
||||
}
|
||||
|
||||
bool Value::operator==(const Value& v) const {
|
||||
if(ptr == v.ptr) return true;
|
||||
bool an = IsNull();
|
||||
bool bn = v.IsNull();
|
||||
if(an || bn) return an && bn;
|
||||
if(GetType() == v.GetType())
|
||||
return ptr->IsEqual(v.ptr);
|
||||
return ptr->IsPolyEqual(v) || v.ptr->IsPolyEqual(*this);
|
||||
}
|
||||
|
||||
Value::Value(const String& s) { ptr = new RichValueRep<String>(s); }
|
||||
Value::Value(const WString& s) { ptr = new RichValueRep<WString>(s); }
|
||||
Value::Value(const char *s) { ptr = new RichValueRep<String>(s); }
|
||||
Value::Value(int i) { ptr = new RichValueRep<int>(i); }
|
||||
Value::Value(int64 i) { ptr = new RichValueRep<int64>(i); }
|
||||
Value::Value(double d) { ptr = new RichValueRep<double>(d); }
|
||||
Value::Value(bool b) { ptr = new RichValueRep<bool>(b); }
|
||||
Value::Value(Date d) { ptr = new RichValueRep<Date>(d); }
|
||||
Value::Value(Time t) { ptr = new RichValueRep<Time>(t); }
|
||||
Value::Value(const Nuller&) { ptr = new RichValueRep<int>(Null); }
|
||||
|
||||
Value::operator String() const
|
||||
{
|
||||
if(IsNull()) return Null;
|
||||
return GetType() == WSTRING_V ? RichValue<WString>::Extract(*this).ToString()
|
||||
: RichValue<String>::Extract(*this);
|
||||
}
|
||||
|
||||
Value::operator WString() const
|
||||
{
|
||||
if(IsNull()) return Null;
|
||||
return GetType() == WSTRING_V ? RichValue<WString>::Extract(*this)
|
||||
: RichValue<String>::Extract(*this).ToWString();
|
||||
}
|
||||
|
||||
Value::operator Date() const
|
||||
{
|
||||
if(IsNull()) return Null;
|
||||
return GetType() == DATE_V ? RichValue<Date>::Extract(*this)
|
||||
: Date(RichValue<Time>::Extract(*this));
|
||||
}
|
||||
|
||||
Value::operator Time() const
|
||||
{
|
||||
if(IsNull()) return Null;
|
||||
return GetType() == DATE_V ? ToTime(RichValue<Date>::Extract(*this))
|
||||
: RichValue<Time>::Extract(*this);
|
||||
}
|
||||
|
||||
Value::operator double() const
|
||||
{
|
||||
if(IsNull()) return Null;
|
||||
return GetType() == INT_V ? double(RichValue<int>::Extract(*this))
|
||||
: GetType() == BOOL_V ? double(RichValue<bool>::Extract(*this))
|
||||
: GetType() == INT64_V ? double(RichValue<int64>::Extract(*this))
|
||||
: RichValue<double>::Extract(*this);
|
||||
}
|
||||
|
||||
Value::operator int() const
|
||||
{
|
||||
if(IsNull()) return Null;
|
||||
return GetType() == INT_V ? RichValue<int>::Extract(*this)
|
||||
: GetType() == BOOL_V ? int(RichValue<bool>::Extract(*this))
|
||||
: GetType() == INT64_V ? int(RichValue<int64>::Extract(*this))
|
||||
: int(RichValue<double>::Extract(*this));
|
||||
}
|
||||
|
||||
Value::operator int64() const
|
||||
{
|
||||
if(IsNull()) return Null;
|
||||
return GetType() == INT_V ? int64(RichValue<int>::Extract(*this))
|
||||
: GetType() == BOOL_V ? int64(RichValue<bool>::Extract(*this))
|
||||
: GetType() == INT64_V ? RichValue<int64>::Extract(*this)
|
||||
: int64(RichValue<double>::Extract(*this));
|
||||
}
|
||||
|
||||
Value::operator bool() const
|
||||
{
|
||||
if(IsNull()) return false;
|
||||
return operator int();
|
||||
}
|
||||
|
||||
VectorMap<dword, Value::Void *(*)(Stream& s)>& Value::Typemap()
|
||||
{
|
||||
static VectorMap<dword, Value::Void *(*)(Stream& s)> x;
|
||||
return x;
|
||||
}
|
||||
|
||||
Value::Void *ValueArrayDataCreate(Stream& s)
|
||||
{
|
||||
ValueArray::Data *a = new ValueArray::Data;
|
||||
a->Serialize(s);
|
||||
return a;
|
||||
}
|
||||
|
||||
Value::Void *ValueMapDataCreate(Stream& s)
|
||||
{
|
||||
ValueMap::Data *a = new ValueMap::Data;
|
||||
a->Serialize(s);
|
||||
return a;
|
||||
}
|
||||
|
||||
static void sRegisterStd()
|
||||
{
|
||||
ONCELOCK {
|
||||
RichValue<int>::Register();
|
||||
RichValue<int64>::Register();
|
||||
RichValue<bool>::Register();
|
||||
RichValue<double>::Register();
|
||||
RichValue<String>::Register();
|
||||
RichValue<WString>::Register();
|
||||
RichValue<Date>::Register();
|
||||
RichValue<Time>::Register();
|
||||
RichValue<Complex>::Register();
|
||||
Value::Register(VALUEARRAY_V, ValueArrayDataCreate);
|
||||
Value::Register(VALUEMAP_V, ValueMapDataCreate);
|
||||
};
|
||||
}
|
||||
|
||||
INITBLOCK {
|
||||
sRegisterStd();
|
||||
}
|
||||
|
||||
void Value::Serialize(Stream& s) {
|
||||
sRegisterStd();
|
||||
dword type;
|
||||
if(s.IsLoading()) {
|
||||
s / type;
|
||||
ptr->Release();
|
||||
typedef Void* (*vp)(Stream& s);
|
||||
vp *cr = Typemap().FindPtr(type);
|
||||
if(cr)
|
||||
ptr = (**cr)(s);
|
||||
else {
|
||||
SetVoidVal();
|
||||
if(type != VOID_V && type != ERROR_V)
|
||||
s.LoadError();
|
||||
}
|
||||
}
|
||||
else {
|
||||
type = GetType();
|
||||
ASSERT_(!type || type == ERROR_V || type == UNKNOWN_V || Typemap().Find(type) >= 0,
|
||||
"Missing RichValueType<" + AsString(type) + ">::Register for " + typeid(*ptr).name() );
|
||||
s / type;
|
||||
ptr->Serialize(s);
|
||||
}
|
||||
}
|
||||
|
||||
void Value::Register(dword w, Void* (*c)(Stream& s)) init_ {
|
||||
#ifdef flagCHECKINIT
|
||||
RLOG("Register valuetype " << w);
|
||||
#endif
|
||||
AssertST();
|
||||
ASSERT(w != UNKNOWN_V);
|
||||
ASSERT(w < 0x8000000);
|
||||
CHECK(Typemap().GetAdd(w, c) == c);
|
||||
}
|
||||
|
||||
String Value::ToString() const {
|
||||
return ptr->AsString();
|
||||
}
|
||||
|
||||
class ValueErrorCls : public RichValueRep<String> {
|
||||
public:
|
||||
virtual dword GetType() const { return ERROR_V; }
|
||||
virtual bool IsNull() const { return true; }
|
||||
virtual void Serialize(Stream& s) {}
|
||||
virtual String AsString() const { return "<error: \'" + v + "\'>"; }
|
||||
|
||||
ValueErrorCls(const String& s) : RichValueRep<String>(s) {}
|
||||
};
|
||||
|
||||
Value ErrorValue(const String& s) {
|
||||
return Value(new ValueErrorCls(s));
|
||||
}
|
||||
|
||||
Value ErrorValue(const char *s) {
|
||||
return ErrorValue(String(s));
|
||||
}
|
||||
|
||||
const Value& ErrorValue() {
|
||||
static Value *p;
|
||||
ONCELOCK {
|
||||
static Value v = ErrorValue(String());
|
||||
p = &v;
|
||||
}
|
||||
return *p;
|
||||
}
|
||||
|
||||
String GetErrorText(const Value& v) {
|
||||
ASSERT(IsError(v));
|
||||
return ((RichValueRep<String> *)v.GetVoidPtr())->Get();
|
||||
}
|
||||
|
||||
// ----------------------------------
|
||||
|
||||
struct Ref::ValueRef : public RefManager {
|
||||
virtual int GetType() { return VALUE_V; }
|
||||
virtual Value GetValue(const void *ptr) { return *(Value *) ptr; }
|
||||
virtual bool IsNull(const void *ptr) { return UPP::IsNull(*(Value *) ptr); }
|
||||
virtual void SetValue(void *ptr, const Value& v) { *(Value *) ptr = v; }
|
||||
virtual void SetNull(void *ptr) { *(Value *) ptr = Null; }
|
||||
};
|
||||
|
||||
Ref::Ref(String& s) { ptr = &s; m = &Single< RichRef<String> >(); }
|
||||
Ref::Ref(WString& s) { ptr = &s; m = &Single< RichRef<WString> >(); }
|
||||
Ref::Ref(int& i) { ptr = &i; m = &Single< RichRef<int> >(); }
|
||||
Ref::Ref(int64& i) { ptr = &i; m = &Single< RichRef<int64> >(); }
|
||||
Ref::Ref(double& d) { ptr = &d; m = &Single< RichRef<double> >(); }
|
||||
Ref::Ref(bool& b) { ptr = &b; m = &Single< RichRef<bool> >(); }
|
||||
Ref::Ref(Date& d) { ptr = &d; m = &Single< RichRef<Date> >(); }
|
||||
Ref::Ref(Time& t) { ptr = &t; m = &Single< RichRef<Time> >(); }
|
||||
Ref::Ref(Value& v) { ptr = &v; m = &Single< ValueRef >(); }
|
||||
|
||||
// ----------------------------------
|
||||
|
||||
bool ValueArray::Data::IsNull() const
|
||||
{
|
||||
return this == &Single<ValueArray::NullData>();
|
||||
}
|
||||
|
||||
void ValueArray::Data::Serialize(Stream& s)
|
||||
{
|
||||
s % data;
|
||||
}
|
||||
|
||||
unsigned ValueArray::Data::GetHashValue() const
|
||||
{
|
||||
CombineHash w(data.GetCount());
|
||||
for(int i = 0; i < data.GetCount(); i++)
|
||||
w.Put(data[i].GetHashValue());
|
||||
return w;
|
||||
}
|
||||
|
||||
static bool sCmp(const Vector<Value>& a, const Vector<Value>& b)
|
||||
{
|
||||
if(&a == &b) return true;
|
||||
if(a.GetCount() != b.GetCount()) return false;
|
||||
for(int i = 0; i < a.GetCount(); i++)
|
||||
if(a[i] != b[i]) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ValueArray::Data::IsEqual(const Value::Void *p)
|
||||
{
|
||||
return sCmp(((Data *)p)->data, data);
|
||||
}
|
||||
|
||||
bool ValueArray::operator==(const ValueArray& v) const
|
||||
{
|
||||
return sCmp(data->data, v.data->data);
|
||||
}
|
||||
|
||||
static String sAsString(const Vector<Value>& v)
|
||||
{
|
||||
String s;
|
||||
s << "[";
|
||||
for(int i = 0; i < v.GetCount(); i++) {
|
||||
if(i) s << ", ";
|
||||
s << v[i];
|
||||
}
|
||||
s << "]";
|
||||
return s;
|
||||
}
|
||||
|
||||
String ValueArray::Data::AsString() const
|
||||
{
|
||||
return sAsString(data);
|
||||
}
|
||||
|
||||
Vector<Value>& ValueArray::Create()
|
||||
{
|
||||
data = new Data;
|
||||
return data->data;
|
||||
}
|
||||
|
||||
Vector<Value>& ValueArray::Clone() {
|
||||
if(data->GetRefCount() != 1) {
|
||||
Data *d = new Data;
|
||||
d->data <<= data->data;
|
||||
data->Release();
|
||||
data = d;
|
||||
}
|
||||
return data->data;
|
||||
}
|
||||
|
||||
void ValueArray::Init0()
|
||||
{
|
||||
data = &Single<NullData>();
|
||||
data->Retain();
|
||||
}
|
||||
|
||||
ValueArray::ValueArray(const ValueArray& v) {
|
||||
data = v.data;
|
||||
data->Retain();
|
||||
}
|
||||
|
||||
ValueArray::ValueArray(pick_ Vector<Value>& v)
|
||||
{
|
||||
Create() = v;
|
||||
}
|
||||
|
||||
ValueArray::ValueArray(const Vector<Value>& v, int deep)
|
||||
{
|
||||
Create() <<= v;
|
||||
}
|
||||
|
||||
ValueArray::operator Value() const {
|
||||
data->Retain();
|
||||
return Value(data);
|
||||
}
|
||||
|
||||
ValueArray::ValueArray(const Value& src)
|
||||
{
|
||||
if(!UPP::IsNull(src)) {
|
||||
if(IsType<ValueMap>(src)) {
|
||||
ValueArray v = ValueMap(src);
|
||||
data = v.data;
|
||||
data->Retain();
|
||||
return;
|
||||
}
|
||||
else {
|
||||
ASSERT(dynamic_cast<const ValueArray::Data *>(src.GetVoidPtr()));
|
||||
data = (ValueArray::Data *)src.GetVoidPtr();
|
||||
}
|
||||
}
|
||||
else
|
||||
data = &Single<NullData>();
|
||||
data->Retain();
|
||||
}
|
||||
|
||||
void ValueArray::Serialize(Stream& s) {
|
||||
if(s.IsLoading()) {
|
||||
data->Release();
|
||||
Create();
|
||||
}
|
||||
data->Serialize(s);
|
||||
}
|
||||
|
||||
ValueArray::~ValueArray() {
|
||||
ASSERT(data->GetRefCount() > 0);
|
||||
data->Release();
|
||||
}
|
||||
|
||||
ValueArray& ValueArray::operator=(const ValueArray& v) {
|
||||
v.data->Retain();
|
||||
data->Release();
|
||||
data = v.data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void ValueArray::SetCount(int n) {
|
||||
Clone().SetCount(n);
|
||||
}
|
||||
|
||||
void ValueArray::SetCount(int n, const Value& v)
|
||||
{
|
||||
Clone().SetCount(n, v);
|
||||
}
|
||||
|
||||
void ValueArray::Clear() {
|
||||
Clone().Clear();
|
||||
}
|
||||
|
||||
void ValueArray::Add(const Value& v) {
|
||||
Clone().Add(v);
|
||||
}
|
||||
|
||||
void ValueArray::Set(int i, const Value& v) {
|
||||
ASSERT(i >= 0);
|
||||
Clone().At(i) = v;
|
||||
}
|
||||
|
||||
void ValueArray::Remove(int i, int count)
|
||||
{
|
||||
Clone().Remove(i, count);
|
||||
}
|
||||
|
||||
void ValueArray::Insert(int i, const ValueArray& va)
|
||||
{
|
||||
if(va.data == data) {
|
||||
ValueArray va2 = va;
|
||||
Clone().Insert(i, va2.Get());
|
||||
}
|
||||
else
|
||||
Clone().Insert(i, va.Get());
|
||||
}
|
||||
|
||||
const Value& ValueArray::Get(int i) const {
|
||||
ASSERT(i >= 0 && i < GetCount());
|
||||
return data->data[i];
|
||||
}
|
||||
|
||||
bool ValueMap::Data::IsNull() const {
|
||||
return this == &Single<ValueMap::NullData>();
|
||||
}
|
||||
|
||||
void ValueMap::Data::Serialize(Stream& s) {
|
||||
s % key % value;
|
||||
}
|
||||
|
||||
unsigned ValueMap::Data::GetHashValue() const {
|
||||
CombineHash w(key.GetCount());
|
||||
for(int i = 0; i < key.GetCount(); i++)
|
||||
w.Put(key[i].GetHashValue());
|
||||
w.Put(value.GetHashValue());
|
||||
return w;
|
||||
}
|
||||
|
||||
static bool sIsEqual(const Index<Value>& a, const Index<Value>& b) {
|
||||
if(&a == &b) return true;
|
||||
if(a.GetCount() != b.GetCount()) return false;
|
||||
for(int i = 0; i < a.GetCount(); i++) {
|
||||
if(a[i] != b[i]) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ValueMap::Data::IsEqual(const Value::Void *p) {
|
||||
return sIsEqual(((Data *)p)->key, key) && ((Data *)p)->value == value;
|
||||
}
|
||||
|
||||
bool ValueMap::operator==(const ValueMap& v) const {
|
||||
return sIsEqual(data->key, v.data->key) && data->value == v.data->value;
|
||||
}
|
||||
|
||||
String ValueMap::Data::AsString() const
|
||||
{
|
||||
String s;
|
||||
s << "{ ";
|
||||
for(int i = 0; i < key.GetCount(); i++) {
|
||||
if(i) s << ", ";
|
||||
s << key[i] << ": " << value[i];
|
||||
}
|
||||
s << " }";
|
||||
return s;
|
||||
}
|
||||
|
||||
ValueMap::Data& ValueMap::Create()
|
||||
{
|
||||
data = new Data;
|
||||
return *data;
|
||||
}
|
||||
|
||||
ValueMap::Data& ValueMap::Clone() {
|
||||
if(data->GetRefCount() != 1) {
|
||||
Data *d = new Data;
|
||||
d->key <<= data->key;
|
||||
d->value = data->value;
|
||||
data->Release();
|
||||
data = d;
|
||||
}
|
||||
return *data;
|
||||
}
|
||||
|
||||
void ValueMap::Init0()
|
||||
{
|
||||
data = &Single<NullData>();
|
||||
data->Retain();
|
||||
}
|
||||
|
||||
ValueMap::ValueMap(const ValueMap& v)
|
||||
{
|
||||
data = v.data;
|
||||
data->Retain();
|
||||
}
|
||||
|
||||
ValueMap::ValueMap(pick_ Index<Value>& k, pick_ Vector<Value>& v)
|
||||
{
|
||||
Data& d = Create();
|
||||
d.key = k;
|
||||
d.value = ValueArray(v);
|
||||
}
|
||||
|
||||
ValueMap::ValueMap(const Index<Value>& k, const Vector<Value>& v, int deep)
|
||||
{
|
||||
Data& d = Create();
|
||||
d.key <<= k;
|
||||
Vector<Value> _v(v, 0);
|
||||
d.value = ValueArray(_v);
|
||||
}
|
||||
|
||||
ValueMap::operator Value() const {
|
||||
data->Retain();
|
||||
return Value(data);
|
||||
}
|
||||
|
||||
ValueMap::ValueMap(const Value& src)
|
||||
{
|
||||
if(!IsNull(src)) {
|
||||
if(IsType<ValueArray>(src)) {
|
||||
ValueArray va = src;
|
||||
Init0();
|
||||
for(int i = 0; i < va.GetCount(); i++)
|
||||
Add(i, va[i]);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
ASSERT(dynamic_cast<const ValueMap::Data *>(src.GetVoidPtr()));
|
||||
data = (ValueMap::Data *)src.GetVoidPtr();
|
||||
}
|
||||
}
|
||||
else
|
||||
data = &Single<NullData>();
|
||||
data->Retain();
|
||||
}
|
||||
|
||||
void ValueMap::Serialize(Stream& s) {
|
||||
if(s.IsLoading()) {
|
||||
data->Release();
|
||||
Create();
|
||||
}
|
||||
data->Serialize(s);
|
||||
}
|
||||
|
||||
ValueMap::~ValueMap() {
|
||||
ASSERT(data->GetRefCount() > 0);
|
||||
data->Release();
|
||||
}
|
||||
|
||||
ValueMap& ValueMap::operator=(const ValueMap& v) {
|
||||
v.data->Retain();
|
||||
data->Release();
|
||||
data = v.data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void ValueMap::Clear() {
|
||||
data->Release();
|
||||
Init0();
|
||||
}
|
||||
|
||||
void ValueMap::Add(const Value& key, const Value& value) {
|
||||
Data& d = Clone();
|
||||
d.key.Add(key);
|
||||
d.value.Add(value);
|
||||
}
|
||||
|
||||
void ValueMap::Set(const Value& key, const Value& value)
|
||||
{
|
||||
Data& d = Clone();
|
||||
int i = d.key.Find(key);
|
||||
if(i >= 0)
|
||||
d.value.Set(i, value);
|
||||
else {
|
||||
d.key.Add(key);
|
||||
d.value.Add(value);
|
||||
}
|
||||
}
|
||||
|
||||
void ValueMap::SetAt(int i, const Value& v) {
|
||||
Clone().value.Set(i, v);
|
||||
}
|
||||
|
||||
void ValueMap::SetKey(int i, const Value& k) {
|
||||
Clone().key.Set(i, k);
|
||||
}
|
||||
|
||||
void ValueMap::Remove(int i)
|
||||
{
|
||||
Data& d = Clone();
|
||||
d.key.Remove(i);
|
||||
d.value.Remove(i);
|
||||
}
|
||||
|
||||
const Value& ValueMap::operator[](const Value& key) const
|
||||
{
|
||||
int q = data->key.Find(key);
|
||||
return q >= 0 ? data->value[q] : ErrorValue();
|
||||
}
|
||||
|
||||
// ----------------------------------
|
||||
|
||||
int StdValueCompare(const Value& a, const Value& b, int language)
|
||||
{
|
||||
LTIMING("StdValueCompare");
|
||||
|
||||
bool na = IsNull(a), nb = IsNull(b);
|
||||
if(na || nb)
|
||||
return !na ? 1 : !nb ? -1 : 0;
|
||||
dword ta = a.GetType(), tb = b.GetType();
|
||||
if((ta == INT_V || ta == BOOL_V) && (tb == INT_V || tb == BOOL_V))
|
||||
return cmp<int>(a, b);
|
||||
if((ta == BOOL_V || ta == INT_V || ta == INT64_V || ta == DOUBLE_V)
|
||||
&& (tb == BOOL_V || tb == INT_V || tb == INT64_V || tb == DOUBLE_V))
|
||||
return cmp<double>(a, b);
|
||||
if(ta == DATE_V && tb == DATE_V)
|
||||
return cmp<Date>(a, b);
|
||||
if((ta == DATE_V || ta == TIME_V) && (tb == DATE_V || tb == TIME_V))
|
||||
return cmp<Time>(a, b);
|
||||
if((ta == STRING_V || ta == WSTRING_V) && (tb == STRING_V || tb == WSTRING_V))
|
||||
return GetLanguageInfo(language).Compare(WString(a), WString(b));
|
||||
return cmp<int>(ta, tb);
|
||||
}
|
||||
|
||||
int StdValueCompare(const Value& a, const Value& b)
|
||||
{
|
||||
return StdValueCompare(a, b, GetCurrentLanguage());
|
||||
}
|
||||
|
||||
int StdValueCompareDesc(const Value& a, const Value& b, int language)
|
||||
{
|
||||
return -StdValueCompare(a, b, language);
|
||||
}
|
||||
|
||||
int StdValueCompareDesc(const Value& a, const Value& b)
|
||||
{
|
||||
return -StdValueCompare(a, b);
|
||||
}
|
||||
|
||||
StdValueOrder::StdValueOrder(int l) : language(l) {}
|
||||
|
||||
bool StdValueOrder::operator()(const Value& a, const Value& b) const
|
||||
{
|
||||
return StdValueCompare(a, b, language) < 0;
|
||||
}
|
||||
|
||||
bool FnValueOrder::operator()(const Value& a, const Value& b) const
|
||||
{
|
||||
return (*fn)(a, b) < 0;
|
||||
}
|
||||
|
||||
bool StdValuePairOrder::operator()(const Value& k1, const Value& v1, const Value& k2, const Value& v2) const
|
||||
{
|
||||
int q = StdValueCompare(k1, k2, language);
|
||||
if(q) return q < 0;
|
||||
return StdValueCompare(v1, v2, language);
|
||||
}
|
||||
|
||||
bool FnValuePairOrder::operator()(const Value& keya, const Value& valuea, const Value& keyb, const Value& valueb) const
|
||||
{
|
||||
return (*fn)(keya, valuea, keyb, valueb) < 0;
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,787 +0,0 @@
|
|||
#ifndef SVO_VALUE
|
||||
class Value;
|
||||
class XmlIO;
|
||||
class JsonIO;
|
||||
|
||||
template <class T>
|
||||
void Jsonize(JsonIO& io, T& var);
|
||||
|
||||
template <class T>
|
||||
void Xmlize(XmlIO& xml, T& var);
|
||||
|
||||
class Id : Moveable<Id> {
|
||||
String id;
|
||||
|
||||
public:
|
||||
const String& ToString() const { return id; }
|
||||
dword GetHashValue() const { return UPP::GetHashValue(id); }
|
||||
bool IsNull() const { return UPP::IsNull(id); }
|
||||
|
||||
operator const String&() const { return ToString(); }
|
||||
const String& operator~() const { return ToString(); }
|
||||
bool operator==(const Id& b) const { return id == b.id; }
|
||||
bool operator!=(const Id& b) const { return id != b.id; }
|
||||
|
||||
operator bool() const { return id.GetCount(); }
|
||||
|
||||
Id() {}
|
||||
Id(const String& s) { id = s; }
|
||||
Id(const char *s) { id = s; }
|
||||
};
|
||||
|
||||
inline const String& Nvl(const String& a, const String& b) { return IsNull(a) ? b : a; }
|
||||
inline int Nvl(int a, int b) { return IsNull(a) ? b : a; }
|
||||
inline int64 Nvl(int64 a, int64 b) { return IsNull(a) ? b : a; }
|
||||
inline double Nvl(double a, double b) { return IsNull(a) ? b : a; }
|
||||
inline Date Nvl(Date a, Date b) { return IsNull(a) ? b : a; }
|
||||
inline Time Nvl(Time a, Time b) { return IsNull(a) ? b : a; }
|
||||
|
||||
inline int Nvl(int a) { return Nvl(a, 0); }
|
||||
inline int64 Nvl(int64 a) { return Nvl(a, (int64)0); }
|
||||
inline double Nvl(double a) { return Nvl(a, 0.0); }
|
||||
|
||||
const dword VOID_V = 0;
|
||||
|
||||
const dword INT_V = 1;
|
||||
const dword DOUBLE_V = 2;
|
||||
const dword STRING_V = 3;
|
||||
const dword DATE_V = 4;
|
||||
const dword TIME_V = 5;
|
||||
|
||||
const dword ERROR_V = 6;
|
||||
|
||||
const dword VALUE_V = 7;
|
||||
|
||||
const dword WSTRING_V = 8;
|
||||
|
||||
const dword VALUEARRAY_V = 9;
|
||||
|
||||
const dword INT64_V = 10;
|
||||
const dword BOOL_V = 11;
|
||||
|
||||
const dword VALUEMAP_V = 12;
|
||||
|
||||
const dword UNKNOWN_V = (dword)0xffffffff;
|
||||
|
||||
class Value : Moveable<Value> {
|
||||
public:
|
||||
class Void {
|
||||
protected:
|
||||
Atomic refcount;
|
||||
|
||||
public:
|
||||
void Retain() { AtomicInc(refcount); }
|
||||
void Release() { if(AtomicDec(refcount) == 0) delete this; }
|
||||
|
||||
virtual dword GetType() const { return VOID_V; }
|
||||
virtual bool IsNull() const { return true; }
|
||||
virtual void Serialize(Stream& s) {}
|
||||
virtual unsigned GetHashValue() const { return 0; }
|
||||
virtual bool IsEqual(const Void *p) { return false; }
|
||||
virtual bool IsPolyEqual(const Value& v) { return false; }
|
||||
virtual String AsString() const { return ""; }
|
||||
|
||||
Void() { AtomicWrite(refcount, 1); }
|
||||
virtual ~Void() {}
|
||||
|
||||
friend class Value;
|
||||
};
|
||||
|
||||
protected:
|
||||
static VectorMap<dword, Void* (*)(Stream& s) >& Typemap();
|
||||
|
||||
Void *ptr;
|
||||
|
||||
void SetVoidVal();
|
||||
|
||||
public:
|
||||
static void Register(dword w, Void* (*c)(Stream& s)) init_;
|
||||
|
||||
dword GetType() const { return ptr->GetType(); }
|
||||
bool IsError() const { return GetType() == ERROR_V; }
|
||||
bool IsVoid() const { return GetType() == VOID_V || IsError(); }
|
||||
bool IsNull() const { return ptr->IsNull(); }
|
||||
|
||||
template <class T>
|
||||
bool Is() const;
|
||||
|
||||
operator String() const;
|
||||
operator WString() const;
|
||||
operator Date() const;
|
||||
operator Time() const;
|
||||
operator double() const;
|
||||
operator int() const;
|
||||
operator int64() const;
|
||||
operator bool() const;
|
||||
|
||||
Value(const String& s);
|
||||
Value(const WString& s);
|
||||
Value(const char *s);
|
||||
Value(int i);
|
||||
Value(int64 i);
|
||||
Value(double d);
|
||||
Value(bool b);
|
||||
Value(Date d);
|
||||
Value(Time t);
|
||||
Value(const Nuller&);
|
||||
|
||||
bool operator==(const Value& v) const;
|
||||
bool operator!=(const Value& v) const { return !operator==(v); }
|
||||
|
||||
String ToString() const;
|
||||
|
||||
void Serialize(Stream& s);
|
||||
|
||||
unsigned GetHashValue() const;
|
||||
|
||||
Value& operator=(const Value& v);
|
||||
Value(const Value& v);
|
||||
|
||||
int GetCount() const;
|
||||
const Value& operator[](int i) const;
|
||||
const Value& operator[](const String& key) const;
|
||||
const Value& operator[](const char *key) const;
|
||||
const Value& operator[](const Id& key) const;
|
||||
|
||||
Value();
|
||||
~Value();
|
||||
|
||||
Value(Void *p) { ptr = p; }
|
||||
const Void *GetVoidPtr() const { return ptr; }
|
||||
|
||||
template <class T> // Forward compatibility
|
||||
static void Register(const char *name = NULL);
|
||||
};
|
||||
|
||||
#define VALUE_COMPARE(T) \
|
||||
inline bool operator==(const Value& v, T x) { return (T)v == x; } \
|
||||
inline bool operator==(T x, const Value& v) { return (T)v == x; } \
|
||||
inline bool operator!=(const Value& v, T x) { return (T)v != x; } \
|
||||
inline bool operator!=(T x, const Value& v) { return (T)v != x; } \
|
||||
|
||||
VALUE_COMPARE(int)
|
||||
VALUE_COMPARE(int64)
|
||||
VALUE_COMPARE(double)
|
||||
VALUE_COMPARE(bool)
|
||||
VALUE_COMPARE(Date)
|
||||
VALUE_COMPARE(Time)
|
||||
VALUE_COMPARE(String)
|
||||
VALUE_COMPARE(WString)
|
||||
|
||||
inline bool operator==(const Value& v, const char *x) { return (String)v == x; }
|
||||
inline bool operator==(const char *x, const Value& v) { return (String)v == x; }
|
||||
inline bool operator!=(const Value& v, const char *x) { return (String)v != x; }
|
||||
inline bool operator!=(const char *x, const Value& v) { return (String)v != x; }
|
||||
|
||||
inline bool operator==(const Value& v, const wchar *x) { return (WString)v == x; }
|
||||
inline bool operator==(const wchar *x, const Value& v) { return (WString)v == x; }
|
||||
inline bool operator!=(const Value& v, const wchar *x) { return (WString)v != x; }
|
||||
inline bool operator!=(const wchar *x, const Value& v) { return (WString)v != x; }
|
||||
|
||||
inline bool IsVoidValueTypeNo(int q) { return (dword)q == VOID_V; }
|
||||
inline bool IsErrorValueTypeNo(int q) { return (dword)q == ERROR_V; }
|
||||
inline bool IsStringValueTypeNo(int q) { return (dword)q == STRING_V || (dword)q == WSTRING_V; }
|
||||
|
||||
inline bool IsIntegerValueTypeNo(int q) { return (dword)q == INT_V || (dword)q == INT64_V || (dword)q == BOOL_V; }
|
||||
inline bool IsFloatValueTypeNo(int q) { return (dword)q == DOUBLE_V; }
|
||||
|
||||
inline bool IsNumberValueTypeNo(int q) { return IsIntegerValueTypeNo(q) || IsFloatValueTypeNo(q); }
|
||||
inline bool IsDateTimeValueTypeNo(int q) { return (dword)q == DATE_V || (dword)q == TIME_V; }
|
||||
|
||||
inline bool IsVoid(const Value& v) { return v.GetType() == VOID_V; }
|
||||
inline bool IsError(const Value& v) { return v.GetType() == ERROR_V; }
|
||||
inline bool IsString(const Value& v) { return v.GetType() == STRING_V || v.GetType() == WSTRING_V; }
|
||||
inline bool IsNumber(const Value& v) { return v.GetType() == DOUBLE_V || v.GetType() == INT_V
|
||||
|| v.GetType() == INT64_V || v.GetType() == BOOL_V; }
|
||||
inline bool IsDateTime(const Value& v) { return v.GetType() == DATE_V || v.GetType() == TIME_V; }
|
||||
|
||||
int StdValueCompare(const Value& a, const Value& b, int language);
|
||||
int StdValueCompare(const Value& a, const Value& b);
|
||||
|
||||
int StdValueCompareDesc(const Value& a, const Value& b, int language);
|
||||
int StdValueCompareDesc(const Value& a, const Value& b);
|
||||
|
||||
struct ValueOrder {
|
||||
virtual bool operator()(const Value& a, const Value& b) const = 0;
|
||||
virtual ~ValueOrder() {}
|
||||
};
|
||||
|
||||
struct StdValueOrder : ValueOrder {
|
||||
int language;
|
||||
|
||||
virtual bool operator()(const Value& a, const Value& b) const;
|
||||
|
||||
StdValueOrder(int l = -1);
|
||||
};
|
||||
|
||||
struct FnValueOrder : ValueOrder {
|
||||
int (*fn)(const Value& a, const Value& b);
|
||||
|
||||
virtual bool operator()(const Value& a, const Value& b) const;
|
||||
|
||||
FnValueOrder(int (*fn)(const Value& a, const Value& b)) : fn(fn) {}
|
||||
};
|
||||
|
||||
struct ValuePairOrder {
|
||||
virtual bool operator()(const Value& keya, const Value& valuea, const Value& keyb, const Value& valueb) const = 0;
|
||||
virtual ~ValuePairOrder() {}
|
||||
};
|
||||
|
||||
struct StdValuePairOrder : ValuePairOrder {
|
||||
int language;
|
||||
|
||||
virtual bool operator()(const Value& keya, const Value& valuea, const Value& keyb, const Value& valueb) const;
|
||||
|
||||
StdValuePairOrder(int l = -1);
|
||||
};
|
||||
|
||||
struct FnValuePairOrder : ValuePairOrder {
|
||||
int (*fn)(const Value& k1, const Value& v1, const Value& k2, const Value& v2);
|
||||
|
||||
virtual bool operator()(const Value& keya, const Value& valuea, const Value& keyb, const Value& valueb) const;
|
||||
|
||||
FnValuePairOrder(int (*fn)(const Value& k1, const Value& v1, const Value& k2, const Value& v2)) : fn(fn) {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline dword ValueTypeNo(const T *) { return StaticTypeNo<T>() + 0x8000000;; }
|
||||
|
||||
template<> inline dword ValueTypeNo(const int*) { return INT_V; }
|
||||
template<> inline dword ValueTypeNo(const int64*) { return INT64_V; }
|
||||
template<> inline dword ValueTypeNo(const double*) { return DOUBLE_V; }
|
||||
template<> inline dword ValueTypeNo(const bool*) { return BOOL_V; }
|
||||
template<> inline dword ValueTypeNo(const String*) { return STRING_V; }
|
||||
template<> inline dword ValueTypeNo(const WString*) { return WSTRING_V; }
|
||||
template<> inline dword ValueTypeNo(const Date*) { return DATE_V; }
|
||||
template<> inline dword ValueTypeNo(const Time*) { return TIME_V; }
|
||||
|
||||
template <class T, dword type, class B = EmptyClass>
|
||||
class AssignValueTypeNo : public B {
|
||||
public:
|
||||
friend dword ValueTypeNo(const T*) { return type; }
|
||||
|
||||
void operator=(const AssignValueTypeNo&) {} // MSC 6.0 empty base class bug fix
|
||||
};
|
||||
|
||||
template <class T, dword type, class B = EmptyClass> // Forward compatiblity
|
||||
class ValueType : public AssignValueTypeNo<T, type, B> {};
|
||||
|
||||
|
||||
|
||||
template <class T>
|
||||
dword GetValueTypeNo() { return ValueTypeNo((T*)NULL); }
|
||||
|
||||
template <class T>
|
||||
bool IsType(const Value& x, T* = 0) { return GetValueTypeNo<T>() == x.GetType(); }
|
||||
|
||||
template <class T>
|
||||
inline bool Value::Is() const
|
||||
{
|
||||
return IsType<T>(*this);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
class RawValueRep : public Value::Void {
|
||||
protected:
|
||||
T v;
|
||||
|
||||
public:
|
||||
virtual dword GetType() const { return GetValueTypeNo<T>(); }
|
||||
virtual bool IsNull() const { return false; }
|
||||
|
||||
const T& Get() const { return v; }
|
||||
RawValueRep(const T& v) : v(v) {}
|
||||
RawValueRep() {}
|
||||
static const RawValueRep *Cast(const Value::Void *p) {
|
||||
ASSERT_(dynamic_cast<const RawValueRep *>(p),
|
||||
String().Cat() << "Invalid value conversion: "
|
||||
<< typeid(*p).name() << " -> " << typeid(T).name());
|
||||
return (const RawValueRep *) p;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
bool IsTypeRaw(const Value& value, T * = 0) {
|
||||
return !IsVoid(value) && dynamic_cast<const RawValueRep<T> *>(value.GetVoidPtr());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
class RawValue : public Value {
|
||||
protected:
|
||||
typedef RawValueRep<T> Rep;
|
||||
|
||||
RawValue(Rep *rep) : Value(rep) {}
|
||||
|
||||
public:
|
||||
RawValue(const T& x) : Value(new Rep(x)) {}
|
||||
static const T& Extract(const Value& v) {
|
||||
return Rep::Cast(v.GetVoidPtr())->Get();
|
||||
}
|
||||
static const T& Extract(const Value& v, const T& dflt) {
|
||||
return IsTypeRaw<T>(v) ? Rep::Cast(v.GetVoidPtr())->Get() : dflt;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class RawPickValueRep : public RawValueRep<T> {
|
||||
public:
|
||||
RawPickValueRep(pick_ T& _v) { this->v = _v; }
|
||||
RawPickValueRep(const T& _v, int) { this->v <<= _v; }
|
||||
RawPickValueRep() {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class RawPickValue : public RawValue<T> {
|
||||
protected:
|
||||
typedef RawPickValueRep<T> PickRep;
|
||||
|
||||
public:
|
||||
RawPickValue(pick_ T& x) : RawValue<T>(new PickRep(x)) {}
|
||||
RawPickValue(const T& x, int) : RawValue<T>(new PickRep(x, 0)) {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class RawValueCreateRep : public RawValueRep<T> {
|
||||
public:
|
||||
T& Get() { return this->v; }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class RawValueCreate : public RawValue<T> {
|
||||
protected:
|
||||
typedef RawValueCreateRep<T> Rep;
|
||||
|
||||
public:
|
||||
RawValueCreate() : RawValue<T>(new Rep()) {}
|
||||
T& Get() { return ((Rep *)this->GetVoidPtr())->Get(); }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline Value RawToValue(const T& data) { return RawValue<T>(data); }
|
||||
|
||||
template <class T>
|
||||
inline Value RawPickToValue(pick_ T& data) { return RawPickValue<T>(data); }
|
||||
|
||||
template <class T>
|
||||
inline Value RawDeepToValue(const T& data) { return RawPickValue<T>(data, 0); }
|
||||
|
||||
template <class T>
|
||||
inline T& CreateRawValue(Value& v) {
|
||||
RawValueCreate<T> x;
|
||||
v = x;
|
||||
return x.Get();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline const T& ValueTo(const Value& v, T * = 0) { return RawValue<T>::Extract(v); }
|
||||
|
||||
template <class T>
|
||||
inline const T& ValueTo(const Value& v, const T& dflt) { return RawValue<T>::Extract(v, dflt); }
|
||||
|
||||
template <class T>
|
||||
inline bool IsPolyEqual(const T& x, const Value& v) {
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline unsigned ValueGetHashValue(const T& x) {
|
||||
return UPP::GetHashValue(x);
|
||||
}
|
||||
|
||||
inline bool IsPolyEqual(const bool& x, const Value& v) {
|
||||
return v.GetType() == DOUBLE_V && int(x) == double(v)
|
||||
|| v.GetType() == INT64_V && int(x) == int64(v)
|
||||
|| v.GetType() == INT_V && int(x) == int(v);
|
||||
}
|
||||
|
||||
inline bool IsPolyEqual(const int& x, const Value& v) {
|
||||
return v.GetType() == DOUBLE_V && x == double(v)
|
||||
|| v.GetType() == INT64_V && x == int64(v);
|
||||
}
|
||||
|
||||
inline bool IsPolyEqual(const int64& x, const Value& v) {
|
||||
return v.GetType() == DOUBLE_V && double(x) == double(v);
|
||||
}
|
||||
|
||||
inline bool IsPolyEqual(const Date& x, const Value& v) {
|
||||
return v.GetType() == TIME_V && ToTime(x) == Time(v);
|
||||
}
|
||||
|
||||
inline bool IsPolyEqual(const WString& x, const Value& v) {
|
||||
return v.GetType() == STRING_V && WString(v) == x;
|
||||
}
|
||||
|
||||
inline unsigned ValueGetHashValue(const bool& x) {
|
||||
return UPP::GetHashValue((double)x);
|
||||
}
|
||||
|
||||
inline unsigned ValueGetHashValue(const int& x) {
|
||||
return UPP::GetHashValue((double)x);
|
||||
}
|
||||
|
||||
inline unsigned ValueGetHashValue(const int64& x) {
|
||||
return UPP::GetHashValue((double)x);
|
||||
}
|
||||
|
||||
inline unsigned ValueGetHashValue(const Date& x) {
|
||||
return UPP::GetHashValue(ToTime(x));
|
||||
}
|
||||
|
||||
inline unsigned ValueGetHashValue(const String& x) { // Improve by specialized routines !!!
|
||||
return UPP::GetHashValue((WString)x);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
class RichValueRep : public RawValueRep<T> {
|
||||
public:
|
||||
virtual bool IsNull() const { return UPP::IsNull(this->v); }
|
||||
virtual void Serialize(Stream& s) { s % this->v; }
|
||||
virtual unsigned GetHashValue() const { return UPP::ValueGetHashValue(this->v); }
|
||||
virtual bool IsEqual(const Value::Void *p) { return Cast(p)->Get() == this->v; }
|
||||
virtual bool IsPolyEqual(const Value& b) { return UPP::IsPolyEqual(this->v, b); }
|
||||
virtual String AsString() const { return UPP::AsString(this->v); }
|
||||
|
||||
RichValueRep(const T& v) : RawValueRep<T>(v) {}
|
||||
RichValueRep(Stream& s) { Serialize(s); }
|
||||
|
||||
static Value::Void *Create(Stream& s) { return new RichValueRep(s); }
|
||||
static const RichValueRep *Cast(const Value::Void *p) {
|
||||
ASSERT_(dynamic_cast<const RichValueRep *>(p),
|
||||
String().Cat() << "Invalid value conversion: "
|
||||
<< typeid(*p).name() << " -> " << typeid(T).name());
|
||||
return (const RichValueRep *) p;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class RichValue : public Value {
|
||||
protected:
|
||||
typedef RichValueRep<T> Rep;
|
||||
|
||||
static const T& GetNull() {
|
||||
static T *q;
|
||||
ONCELOCK {
|
||||
static T x; SetNull(x);
|
||||
q = &x;
|
||||
}
|
||||
return *q;
|
||||
}
|
||||
|
||||
public:
|
||||
RichValue(const T& x) : Value(new Rep(x)) {}
|
||||
const T& Get(const Value& v) {
|
||||
if(IsNull(v)) return GetNull();
|
||||
return Rep::Cast(v.GetVoidPtr())->Get();
|
||||
}
|
||||
static void Register() init_ {
|
||||
Value::Register(GetValueTypeNo<T>(), Rep::Create);
|
||||
}
|
||||
static const T& Extract(const Value& v) {
|
||||
if(v.IsNull()) return GetNull();
|
||||
return Rep::Cast(v.GetVoidPtr())->Get();
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
void Value::Register(const char *)
|
||||
{
|
||||
RichValue<T>::Register();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline Value RichToValue(const T& data) { return RichValue<T>(data); }
|
||||
|
||||
Value ErrorValue(const char *s);
|
||||
Value ErrorValue(const String& s);
|
||||
const Value& ErrorValue();
|
||||
|
||||
String GetErrorText(const Value& v);
|
||||
|
||||
inline bool IsNull(const Value& v) { return v.IsNull(); }
|
||||
inline const Value& Nvl(const Value& a, const Value& b) { return IsNull(a) ? b : a; }
|
||||
|
||||
Value Scan(dword stdtype, const String& text, const Value& def = Null);
|
||||
|
||||
// ----------------------- Ref
|
||||
|
||||
struct RefManager {
|
||||
virtual int GetType() = 0;
|
||||
virtual Value GetValue(const void *) { return Null; }
|
||||
virtual bool IsNull(const void *) { return false; }
|
||||
virtual void SetValue(void *, const Value& v) { NEVER(); }
|
||||
virtual void SetNull(void *) { NEVER(); }
|
||||
virtual ~RefManager() {}
|
||||
};
|
||||
|
||||
|
||||
template <class T>
|
||||
struct RawRef : public RefManager {
|
||||
virtual void SetValue(void *p, const Value& v) { *(T *) p = RawValue<T>::Extract(v); }
|
||||
virtual Value GetValue(const void *p) { return RawValue<T>(*(const T *) p); }
|
||||
virtual int GetType() { return GetValueTypeNo<T>(); }
|
||||
virtual ~RawRef() {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct RichRef : public RawRef<T> {
|
||||
virtual Value GetValue(const void *p) { return RichValue<T>(*(T *) p); }
|
||||
virtual bool IsNull(const void *p) { return UPP::IsNull(*(T *) p); }
|
||||
virtual void SetValue(void *p, const Value& v) { *(T *) p = T(v); }
|
||||
virtual void SetNull(void *p) { UPP::SetNull(*(T *)p); }
|
||||
};
|
||||
|
||||
class Ref : Moveable<Ref> {
|
||||
protected:
|
||||
RefManager *m;
|
||||
void *ptr;
|
||||
struct ValueRef;
|
||||
|
||||
public:
|
||||
dword GetType() const { return m ? m->GetType() : VOID_V; }
|
||||
bool IsNull() const { return m ? m->IsNull(ptr) : true; }
|
||||
|
||||
void *GetVoidPtr() const { return ptr; }
|
||||
|
||||
void SetNull() { if(m) m->SetNull(ptr); }
|
||||
Value GetValue() const { return m ? m->GetValue(ptr) : Value(); }
|
||||
void SetValue(const Value& v) { ASSERT(m); m->SetValue(ptr, v); }
|
||||
|
||||
operator Value() const { return GetValue(); }
|
||||
Value operator~() const { return GetValue(); }
|
||||
Ref& operator=(const Value& v) { SetValue(v); return *this; }
|
||||
|
||||
Ref(String& s);
|
||||
Ref(WString& s);
|
||||
Ref(int& i);
|
||||
Ref(int64& i);
|
||||
Ref(double& d);
|
||||
Ref(bool& b);
|
||||
Ref(Date& d);
|
||||
Ref(Time& t);
|
||||
Ref(Value& v);
|
||||
Ref(void *_ptr, RefManager *_m) { ptr = _ptr, m = _m; }
|
||||
Ref() { ptr = m = NULL; }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
T& GetRef(Ref r, T *x = NULL) {
|
||||
ASSERT(GetValueTypeNo<T>() == r.GetType());
|
||||
return *(T *) r.GetVoidPtr();
|
||||
}
|
||||
|
||||
inline String& RefString(Ref f) { return GetRef<String>(f); }
|
||||
inline WString& RefWString(Ref f) { return GetRef<WString>(f); }
|
||||
inline int& RefInt(Ref f) { return GetRef<int>(f); }
|
||||
inline int64& RefInt64(Ref f) { return GetRef<int64>(f); }
|
||||
inline double& RefDouble(Ref f) { return GetRef<double>(f); }
|
||||
inline bool& RefBool(Ref f) { return GetRef<bool>(f); }
|
||||
inline Date& RefDate(Ref f) { return GetRef<Date>(f); }
|
||||
inline Time& RefTime(Ref f) { return GetRef<Time>(f); }
|
||||
inline Value& RefValue(Ref f) { ASSERT(f.GetType() == VALUE_V);
|
||||
return *(Value *)f.GetVoidPtr(); }
|
||||
|
||||
template <class T>
|
||||
Ref RawAsRef(T& x) {
|
||||
return Ref(&x, &Single< RawRef<T> >());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
Ref RichAsRef(T& x) {
|
||||
return Ref(&x, &Single< RichRef<T> >());
|
||||
}
|
||||
|
||||
#define E__Value(I) Value p##I
|
||||
#define E__Ref(I) Ref p##I
|
||||
|
||||
// ---------------------- Value Array
|
||||
|
||||
class ValueArray : AssignValueTypeNo<ValueArray, VALUEARRAY_V, Moveable<ValueArray> > {
|
||||
struct Data : Value::Void {
|
||||
virtual dword GetType() const { return VALUEARRAY_V; }
|
||||
virtual bool IsNull() const;
|
||||
virtual void Serialize(Stream& s);
|
||||
virtual unsigned GetHashValue() const;
|
||||
virtual bool IsEqual(const Value::Void *p);
|
||||
virtual String AsString() const;
|
||||
|
||||
int GetRefCount() const { return AtomicRead(refcount); }
|
||||
|
||||
Vector<Value> data;
|
||||
};
|
||||
struct NullData : Data {};
|
||||
Data *data;
|
||||
|
||||
Vector<Value>& Create();
|
||||
Vector<Value>& Clone();
|
||||
void Init0();
|
||||
|
||||
friend Value::Void *ValueArrayDataCreate(Stream& s);
|
||||
|
||||
public:
|
||||
ValueArray() { Init0(); }
|
||||
ValueArray(const ValueArray& v);
|
||||
explicit ValueArray(pick_ Vector<Value>& values);
|
||||
explicit ValueArray(const Vector<Value>& values, int deep);
|
||||
~ValueArray();
|
||||
|
||||
ValueArray& operator=(const ValueArray& v);
|
||||
|
||||
operator Value() const;
|
||||
ValueArray(const Value& src);
|
||||
|
||||
ValueArray(const Nuller&) { Init0(); }
|
||||
bool IsNull() const { return data->IsNull(); }
|
||||
|
||||
void Clear();
|
||||
void SetCount(int n);
|
||||
void SetCount(int n, const Value& v);
|
||||
int GetCount() const { return data->data.GetCount(); }
|
||||
bool IsEmpty() const { return data->data.IsEmpty(); }
|
||||
|
||||
void Add(const Value& v);
|
||||
ValueArray& operator<<(const Value& v) { Add(v); return *this; }
|
||||
void Set(int i, const Value& v);
|
||||
const Value& Get(int i) const;
|
||||
const Vector<Value>& Get() const { return data->data; }
|
||||
|
||||
void Remove(int i, int count = 1);
|
||||
void Insert(int i, const ValueArray& va);
|
||||
void Append(const ValueArray& va) { Insert(GetCount(), va); }
|
||||
|
||||
const Value& operator[](int i) const { return Get(i); }
|
||||
|
||||
unsigned GetHashValue() const { return data->GetHashValue(); }
|
||||
void Serialize(Stream& s);
|
||||
|
||||
bool operator==(const ValueArray& v) const;
|
||||
bool operator!=(const ValueArray& v) const { return !operator==(v); }
|
||||
};
|
||||
|
||||
template<> inline unsigned GetHashValue(const ValueArray& v) { return v.GetHashValue(); }
|
||||
template<> inline bool IsNull(const ValueArray& v) { return v.IsNull(); }
|
||||
|
||||
template<>
|
||||
String AsString(const ValueArray& v);
|
||||
|
||||
class ValueMap : AssignValueTypeNo<ValueMap, VALUEMAP_V, Moveable<ValueMap> >{
|
||||
struct Data : Value::Void {
|
||||
virtual dword GetType() const { return VALUEMAP_V; }
|
||||
virtual bool IsNull() const;
|
||||
virtual void Serialize(Stream& s);
|
||||
virtual unsigned GetHashValue() const;
|
||||
virtual bool IsEqual(const Value::Void *p);
|
||||
virtual String AsString() const;
|
||||
|
||||
int GetRefCount() const { return AtomicRead(refcount); }
|
||||
|
||||
Index<Value> key;
|
||||
ValueArray value;
|
||||
};
|
||||
|
||||
struct NullData : Data {};
|
||||
Data *data;
|
||||
|
||||
Data& Create();
|
||||
Data& Clone();
|
||||
void Init0();
|
||||
|
||||
friend Value::Void *ValueMapDataCreate(Stream& s);
|
||||
|
||||
public:
|
||||
ValueMap() { Init0(); }
|
||||
ValueMap(const ValueMap& v);
|
||||
ValueMap(pick_ Index<Value>& k, pick_ Vector<Value>& v);
|
||||
ValueMap(const Index<Value>& k, const Vector<Value>& v, int deep);
|
||||
~ValueMap();
|
||||
|
||||
ValueMap& operator=(const ValueMap& v);
|
||||
|
||||
operator Value() const;
|
||||
ValueMap(const Value& src);
|
||||
|
||||
ValueMap(const Nuller&) { Init0(); }
|
||||
bool IsNullInstance() const { return data->IsNull(); }
|
||||
|
||||
void Clear();
|
||||
int GetCount() const { return data->value.GetCount(); }
|
||||
bool IsEmpty() const { return data->value.IsEmpty(); }
|
||||
|
||||
void Add(const Value& key, const Value& value);
|
||||
void Add(const String& s, const Value& value) { Add(Value(s), value); }
|
||||
void Add(const char *s, const Value& value) { Add(Value(s), value); }
|
||||
void Add(Id id, const Value& value) { Add(Value(id.ToString()), value); }
|
||||
|
||||
void Set(const Value& key, const Value& value);
|
||||
void Set(const String& s, const Value& value) { Set(Value(s), value); }
|
||||
void Set(const char *s, const Value& value) { Set(Value(s), value); }
|
||||
void Set(Id id, const Value& value) { Set(Value(id.ToString()), value); }
|
||||
|
||||
void SetAt(int i, const Value& v);
|
||||
void SetKey(int i, const Value& k);
|
||||
void SetKey(int i, const String& s) { SetKey(i, Value(s)); }
|
||||
void SetKey(int i, const char* s) { SetKey(i, Value(s)); }
|
||||
void SetKey(int i, Id id) { SetKey(i, Value(id.ToString())); }
|
||||
void Remove(int i);
|
||||
|
||||
const Index<Value>& GetKeys() const { return data->key; }
|
||||
ValueArray GetValues() const { return data->value; }
|
||||
|
||||
operator ValueArray() const { return GetValues(); }
|
||||
|
||||
const Value& operator[](const Value& k) const;
|
||||
const Value& operator[](const String& s) const{ return operator[](Value(s)); }
|
||||
const Value& operator[](const char *s) const { return operator[](Value(s)); }
|
||||
const Value& operator[](const Id& k) const { return operator[](Value(k.ToString())); }
|
||||
|
||||
const Value& GetKey(int i) const { return data->key[i]; }
|
||||
const Value& GetValue(int i) const { return data->value[i]; }
|
||||
|
||||
unsigned GetHashValue() const { return data->GetHashValue(); }
|
||||
void Serialize(Stream& s);
|
||||
String ToString() const { return data->AsString(); }
|
||||
|
||||
bool operator==(const ValueMap& v) const;
|
||||
bool operator!=(const ValueMap& v) const { return !operator==(v); }
|
||||
};
|
||||
|
||||
inline bool IsValueArray(const Value& v) { return v.GetType() == VALUEARRAY_V || v.GetType() == VALUEMAP_V; }
|
||||
inline bool IsValueMap(const Value& v) { return IsValueArray(v); }
|
||||
|
||||
inline
|
||||
int Value::GetCount() const
|
||||
{
|
||||
return IsValueArray(*this) ? ValueArray(*this).GetCount() : 0;
|
||||
}
|
||||
|
||||
inline
|
||||
const Value& Value::operator[](int i) const
|
||||
{
|
||||
ASSERT(IsValueArray(*this));
|
||||
return ValueArray(*this)[i];
|
||||
}
|
||||
|
||||
inline
|
||||
const Value& Value::operator[](const String& key) const
|
||||
{
|
||||
return IsValueMap(*this) ? ValueMap(*this)[key] : ErrorValue();
|
||||
}
|
||||
|
||||
inline
|
||||
const Value& Value::operator[](const char *key) const
|
||||
{
|
||||
return IsValueMap(*this) ? ValueMap(*this)[key] : ErrorValue();
|
||||
}
|
||||
|
||||
inline
|
||||
const Value& Value::operator[](const Id& key) const
|
||||
{
|
||||
return IsValueMap(*this) ? ValueMap(*this)[key] : ErrorValue();
|
||||
}
|
||||
|
||||
class ValueGen {
|
||||
public:
|
||||
virtual Value Get() = 0;
|
||||
Value operator++() { return Get(); }
|
||||
virtual ~ValueGen() {}
|
||||
};
|
||||
#endif
|
||||
|
|
@ -80,15 +80,26 @@ RpcGet RpcRequest::Execute()
|
|||
("method", method);
|
||||
if(data.out.GetCount()) {
|
||||
JsonArray a;
|
||||
for(int i = 0; i < data.out.GetCount(); i++)
|
||||
a << JsonRpcData(data.out[i]);
|
||||
for(int i = 0; i < data.out.GetCount(); i++) {
|
||||
const Value& v = data.out[i];
|
||||
if(v.Is<RawJsonText>())
|
||||
a.CatRaw(v.To<RawJsonText>().json);
|
||||
else
|
||||
a << JsonRpcData(v);
|
||||
}
|
||||
json("params", a);
|
||||
}
|
||||
else
|
||||
if(data.out_map.GetCount()) {
|
||||
Json m;
|
||||
for(int i = 0; i < data.out_map.GetCount(); i++)
|
||||
m((String)data.out_map.GetKey(i), JsonRpcData(data.out_map.GetValue(i)));
|
||||
for(int i = 0; i < data.out_map.GetCount(); i++) {
|
||||
const Value& v = data.out_map.GetValue(i);
|
||||
String key = (String)data.out_map.GetKey(i);
|
||||
if(v.Is<RawJsonText>())
|
||||
m.CatRaw(key, v.To<RawJsonText>().json);
|
||||
else
|
||||
m(key, JsonRpcData(v));
|
||||
}
|
||||
json("params", m);
|
||||
}
|
||||
json("id", id);
|
||||
|
|
|
|||
|
|
@ -26,6 +26,10 @@ String FormatIso8601(Time t);
|
|||
Time ScanIso8601(const String& p);
|
||||
Value JsonRpcData(const Value& v);
|
||||
|
||||
struct RawJsonText {
|
||||
String json;
|
||||
};
|
||||
|
||||
void ValueCheck(bool b);
|
||||
|
||||
void ValueGet(int& n, const Value& v);
|
||||
|
|
@ -116,6 +120,7 @@ void ValuePut(Value& v, const Time& x);
|
|||
void ValuePut(Value& v, const Value& t);
|
||||
void ValuePut(Value& v, const ValueArray& va);
|
||||
void ValuePut(Value& v, const ValueMap& vm);
|
||||
void ValuePut(Value& v, const Json& json);
|
||||
|
||||
template <class T>
|
||||
Value AsXmlRpcValue(const T& x)
|
||||
|
|
|
|||
|
|
@ -124,19 +124,19 @@ String DoXmlRpc(const String& request, const char *group, const char *peeraddr)
|
|||
return Null;
|
||||
}
|
||||
|
||||
Value JsonRpcError(int code, const char *text, const Value& id)
|
||||
String JsonRpcError(int code, const char *text, const Value& id)
|
||||
{
|
||||
ValueMap m;
|
||||
m.Add("jsonrpc", "2.0");
|
||||
Json m;
|
||||
m("jsonrpc", "2.0");
|
||||
ValueMap err;
|
||||
err.Add("code", code);
|
||||
err.Add("message", text);
|
||||
m.Add("error", err);
|
||||
m.Add("id", id);
|
||||
m("error", err);
|
||||
m("id", id);
|
||||
return m;
|
||||
}
|
||||
|
||||
Value ProcessJsonRpc(const Value& v, const char *group, const char *peeraddr)
|
||||
String ProcessJsonRpc(const Value& v, const char *group, const char *peeraddr)
|
||||
{
|
||||
LLOG("Parsed JSON request: " << v);
|
||||
Value id = v["id"];
|
||||
|
|
@ -163,11 +163,14 @@ Value ProcessJsonRpc(const Value& v, const char *group, const char *peeraddr)
|
|||
}
|
||||
result = JsonRpcData(va[0]);
|
||||
}
|
||||
ValueMap m;
|
||||
m.Add("jsonrpc", "2.0");
|
||||
m.Add("result", result);
|
||||
m.Add("id", id);
|
||||
return m;
|
||||
Json json;
|
||||
json("jsonrpc", "2.0");
|
||||
if(result.Is<RawJsonText>())
|
||||
json.CatRaw("result", result.To<RawJsonText>().json);
|
||||
else
|
||||
json("result", result);
|
||||
json("id", id);
|
||||
return json;
|
||||
}
|
||||
}
|
||||
return JsonRpcError(RPC_UNKNOWN_METHOD_ERROR, "Method not found", id);
|
||||
|
|
@ -190,18 +193,13 @@ String DoJsonRpc(const String& request, const char *group, const char *peeraddr)
|
|||
{
|
||||
try {
|
||||
Value v = ParseJSON(request);
|
||||
if(v.Is<ValueMap>()) {
|
||||
Value r = ProcessJsonRpc(v, group, peeraddr);
|
||||
return r.IsVoid() ? String() : AsJSON(r);
|
||||
}
|
||||
if(v.Is<ValueMap>())
|
||||
return ProcessJsonRpc(v, group, peeraddr);
|
||||
if(v.Is<ValueArray>()) {
|
||||
JsonArray a;
|
||||
bool r = false;
|
||||
for(int i = 0; i < v.GetCount(); i++) {
|
||||
r = true;
|
||||
a << ProcessJsonRpc(v[i], group, peeraddr);
|
||||
}
|
||||
return r ? ~a : String();
|
||||
for(int i = 0; i < v.GetCount(); i++)
|
||||
a.CatRaw(ProcessJsonRpc(v[i], group, peeraddr));
|
||||
return v.GetCount() ? ~a : String();
|
||||
}
|
||||
}
|
||||
catch(CParser::Error e) {}
|
||||
|
|
|
|||
|
|
@ -152,4 +152,11 @@ void ValuePut(Value& v, const ValueMap& vm)
|
|||
v = vm;
|
||||
}
|
||||
|
||||
void ValuePut(Value& v, const Json& json)
|
||||
{
|
||||
RawJsonText x;
|
||||
x.json = json;
|
||||
v = RawToValue(x);
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
|
@ -7,13 +7,8 @@ struct Uuid : AssignValueTypeNo<Uuid, 50, Moveable<Uuid> > {
|
|||
bool IsNullInstance() const { return a == 0 && b == 0 && c == 0 && d == 0; }
|
||||
void SetNull() { a = b = c = d = 0; }
|
||||
|
||||
#ifdef SVO_VALUE
|
||||
operator Value() const { return RichToValue(*this); }
|
||||
Uuid(const Value& q) { *this = q.Get<Uuid>(); }
|
||||
#else
|
||||
operator Value() const { return RichValue<Uuid>(*this); }
|
||||
Uuid(const Value& q) { *this = RichValue<Uuid>::Extract(q); }
|
||||
#endif
|
||||
Uuid(const Nuller&) { SetNull(); }
|
||||
Uuid() {}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
#include "Core.h"
|
||||
|
||||
#ifdef SVO_VALUE
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#ifndef flagSO
|
||||
|
|
@ -595,5 +593,3 @@ String GetErrorText(const Value& v) {
|
|||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
|
@ -1,5 +1,3 @@
|
|||
#ifdef SVO_VALUE
|
||||
|
||||
class Id;
|
||||
class Value;
|
||||
class ValueArray;
|
||||
|
|
@ -310,5 +308,3 @@ String GetErrorText(const Value& v);
|
|||
|
||||
inline bool IsNull(const Value& v) { return v.IsNull(); }
|
||||
inline const Value& Nvl(const Value& a, const Value& b) { return IsNull(a) ? b : a; }
|
||||
|
||||
#endif
|
||||
|
|
@ -1,5 +1,3 @@
|
|||
#ifdef SVO_VALUE
|
||||
|
||||
inline
|
||||
Value::Value(const Value& v)
|
||||
: data(String::SPECIAL)
|
||||
|
|
@ -358,4 +356,3 @@ template <class T> // Deprecated
|
|||
Ref RichAsRef(T& x) {
|
||||
return Ref(&x, &Single< RichRef<T> >());
|
||||
}
|
||||
#endif
|
||||
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#ifdef SVO_VALUE
|
||||
|
||||
static String sAsString(const Vector<Value>& v);
|
||||
|
||||
#define LTIMING(x) // RTIMING(x)
|
||||
|
|
@ -584,8 +582,6 @@ bool FnValuePairOrder::operator()(const Value& keya, const Value& valuea, const
|
|||
return (*fn)(keya, valuea, keyb, valueb) < 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void Complex::Xmlize(XmlIO& xio)
|
||||
{
|
||||
double r, i;
|
||||
|
|
@ -610,7 +606,6 @@ void Complex::Serialize(Stream& s)
|
|||
*this = C(r, i);
|
||||
}
|
||||
|
||||
#ifdef SVO_VALUE
|
||||
template <class T>
|
||||
static void sReg(const char *name)
|
||||
{
|
||||
|
|
@ -632,20 +627,6 @@ INITBLOCK
|
|||
Value::Register<Rect64>("Rect64");
|
||||
Value::Register<Rectf>("Rectf");
|
||||
}
|
||||
#else
|
||||
INITBLOCK {
|
||||
Point p;
|
||||
RichValue<Point>::Register();
|
||||
RichValue<Point64>::Register();
|
||||
RichValue<Pointf>::Register();
|
||||
RichValue<Size>::Register();
|
||||
RichValue<Size64>::Register();
|
||||
RichValue<Sizef>::Register();
|
||||
RichValue<Rect>::Register();
|
||||
RichValue<Rect64>::Register();
|
||||
RichValue<Rectf>::Register();
|
||||
}
|
||||
#endif
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
#ifdef SVO_VALUE
|
||||
|
||||
Value Scan(dword stdtype, const String& text, const Value& def = Null);
|
||||
|
||||
inline const String& Nvl(const String& a, const String& b) { return IsNull(a) ? b : a; }
|
||||
|
|
@ -355,5 +353,3 @@ public:
|
|||
|
||||
|
||||
#include "Value.hpp"
|
||||
|
||||
#endif
|
||||
|
|
@ -154,182 +154,6 @@ VALUE_XMLIZE(byte);
|
|||
VALUE_XMLIZE(Time);
|
||||
VALUE_XMLIZE(Date);
|
||||
|
||||
#ifndef SVO_VALUE
|
||||
template <class T>
|
||||
void XmlizePoint_(XmlIO& xml, T& p)
|
||||
{
|
||||
xml
|
||||
.Attr("x", p.x)
|
||||
.Attr("y", p.y)
|
||||
;
|
||||
}
|
||||
|
||||
template<> void Xmlize(XmlIO& xml, Point& p) { XmlizePoint_(xml, p); }
|
||||
template<> void Xmlize(XmlIO& xml, Point16& p) { XmlizePoint_(xml, p); }
|
||||
template<> void Xmlize(XmlIO& xml, Point64& p) { XmlizePoint_(xml, p); }
|
||||
template<> void Xmlize(XmlIO& xml, Pointf& p) { XmlizePoint_(xml, p); }
|
||||
|
||||
template<class T>
|
||||
void XmlizeSize_(XmlIO& xml, T& sz)
|
||||
{
|
||||
xml
|
||||
.Attr("cx", sz.cx)
|
||||
.Attr("cy", sz.cy)
|
||||
;
|
||||
}
|
||||
|
||||
template<> void Xmlize(XmlIO& xml, Size& p) { XmlizeSize_(xml, p); }
|
||||
template<> void Xmlize(XmlIO& xml, Size16& p) { XmlizeSize_(xml, p); }
|
||||
template<> void Xmlize(XmlIO& xml, Size64& p) { XmlizeSize_(xml, p); }
|
||||
template<> void Xmlize(XmlIO& xml, Sizef& p) { XmlizeSize_(xml, p); }
|
||||
|
||||
template<class T>
|
||||
void XmlizeRect_(XmlIO& xml, T& r)
|
||||
{
|
||||
xml
|
||||
.Attr("left", r.left)
|
||||
.Attr("top", r.top)
|
||||
.Attr("right", r.right)
|
||||
.Attr("bottom", r.bottom)
|
||||
;
|
||||
}
|
||||
|
||||
template<> void Xmlize(XmlIO& xml, Rect& p) { XmlizeRect_(xml, p); }
|
||||
template<> void Xmlize(XmlIO& xml, Rect16& p) { XmlizeRect_(xml, p); }
|
||||
template<> void Xmlize(XmlIO& xml, Rect64& p) { XmlizeRect_(xml, p); }
|
||||
template<> void Xmlize(XmlIO& xml, Rectf& p) { XmlizeRect_(xml, p); }
|
||||
|
||||
template<>
|
||||
void Xmlize(XmlIO& xml, Color& c)
|
||||
{
|
||||
int r = c.GetR();
|
||||
int g = c.GetG();
|
||||
int b = c.GetB();
|
||||
xml
|
||||
.Attr("red", r)
|
||||
.Attr("green", g)
|
||||
.Attr("blue", b)
|
||||
;
|
||||
c = Color(r, g, b);
|
||||
}
|
||||
|
||||
typedef void (*ValueXmlizer)(XmlIO& xml, Value& v);
|
||||
|
||||
VectorMap<dword, ValueXmlizer>& ValueXmlizeMap()
|
||||
{
|
||||
static VectorMap<dword, ValueXmlizer> x;
|
||||
return x;
|
||||
}
|
||||
|
||||
Index<String>& ValueXmlizeName()
|
||||
{
|
||||
static Index<String> x;
|
||||
return x;
|
||||
}
|
||||
|
||||
INITBLOCK {
|
||||
ValueXmlizeMap();
|
||||
ValueXmlizeName();
|
||||
}
|
||||
|
||||
void RegisterValueXmlize(dword type, void (*xmlize)(XmlIO& xml, Value& v), const char *name)
|
||||
{
|
||||
ASSERT(ValueXmlizeMap().Find(type) < 0);
|
||||
ASSERT(ValueXmlizeName().Find(name) < 0);
|
||||
ValueXmlizeMap().Add(type, xmlize);
|
||||
ValueXmlizeName().Add(name);
|
||||
}
|
||||
|
||||
REGISTER_VALUE_XMLIZE(String);
|
||||
REGISTER_VALUE_XMLIZE(WString);
|
||||
REGISTER_VALUE_XMLIZE(int);
|
||||
REGISTER_VALUE_XMLIZE(double);
|
||||
REGISTER_VALUE_XMLIZE(int64);
|
||||
REGISTER_VALUE_XMLIZE(Date);
|
||||
REGISTER_VALUE_XMLIZE(Time);
|
||||
REGISTER_VALUE_XMLIZE(Point);
|
||||
REGISTER_VALUE_XMLIZE(Point64);
|
||||
REGISTER_VALUE_XMLIZE(Pointf);
|
||||
REGISTER_VALUE_XMLIZE(Size);
|
||||
REGISTER_VALUE_XMLIZE(Size64);
|
||||
REGISTER_VALUE_XMLIZE(Sizef);
|
||||
REGISTER_VALUE_XMLIZE(Rect);
|
||||
REGISTER_VALUE_XMLIZE(Rect64);
|
||||
REGISTER_VALUE_XMLIZE(Rectf);
|
||||
REGISTER_VALUE_XMLIZE(Color);
|
||||
REGISTER_VALUE_XMLIZE(ValueArray);
|
||||
REGISTER_VALUE_XMLIZE(ValueMap);
|
||||
|
||||
static String s_binary("serialized_binary");
|
||||
|
||||
template<> void Xmlize(XmlIO& xml, Value& v)
|
||||
{
|
||||
if(xml.IsStoring()) {
|
||||
dword typeno = v.GetType();
|
||||
int q = ValueXmlizeMap().Find(typeno);
|
||||
if(q < 0) {
|
||||
xml.SetAttr("type", s_binary);
|
||||
String s = HexString(StoreAsString(v));
|
||||
Xmlize(xml, s);
|
||||
}
|
||||
else {
|
||||
xml.SetAttr("type", ValueXmlizeName()[q]);
|
||||
(*ValueXmlizeMap()[q])(xml, v);
|
||||
}
|
||||
}
|
||||
else {
|
||||
String name = xml.GetAttr("type");
|
||||
if(name == s_binary) {
|
||||
String s;
|
||||
Xmlize(xml, s);
|
||||
try {
|
||||
LoadFromString(v, ScanHexString(s));
|
||||
}
|
||||
catch(LoadingError) {
|
||||
throw XmlError("serialized_binary Error");
|
||||
}
|
||||
}
|
||||
else {
|
||||
int q = ValueXmlizeName().Find(name);
|
||||
if(q < 0)
|
||||
throw XmlError("invalid Value type");
|
||||
(*ValueXmlizeMap()[q])(xml, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SVO_VALUE
|
||||
template<> void Xmlize(XmlIO& xml, ValueArray& v)
|
||||
{
|
||||
if(xml.IsStoring())
|
||||
XmlizeStore(xml, v.Get());
|
||||
else {
|
||||
Vector<Value> vv;
|
||||
Xmlize(xml, vv);
|
||||
v = ValueArray(vv);
|
||||
}
|
||||
}
|
||||
|
||||
template<> void Xmlize(XmlIO& xml, ValueMap& v)
|
||||
{
|
||||
if(xml.IsStoring()) {
|
||||
XmlizeStore(xml, v.GetKeys());
|
||||
XmlizeStore(xml, v.GetValues());
|
||||
}
|
||||
else {
|
||||
Index<Value> vv;
|
||||
Xmlize(xml, vv);
|
||||
ValueArray va;
|
||||
Xmlize(xml, va);
|
||||
ASSERT(vv.GetCount() == va.GetCount());
|
||||
v.Clear();
|
||||
for(int i = 0; i < vv.GetCount(); i++)
|
||||
v.Add(vv[i], va[i]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void XmlizeLangAttr(XmlIO& xml, int& lang, const char *id)
|
||||
{
|
||||
String l;
|
||||
|
|
|
|||
|
|
@ -125,14 +125,6 @@ template<> void Xmlize(XmlIO& xml, int16& var);
|
|||
template<> void Xmlize(XmlIO& xml, int64& var);
|
||||
template<> void Xmlize(XmlIO& xml, byte& var);
|
||||
|
||||
#ifndef SVO_VALUE
|
||||
template<> void Xmlize(XmlIO& xml, Color& c);
|
||||
template<> void Xmlize(XmlIO& xml, Value& v);
|
||||
|
||||
template<> void Xmlize(XmlIO& xml, ValueArray& v);
|
||||
template<> void Xmlize(XmlIO& xml, ValueMap& v);
|
||||
#endif
|
||||
|
||||
void XmlizeLangAttr(XmlIO& xml, int& lang, const char *id = "lang");
|
||||
void XmlizeLang(XmlIO& xml, const char *tag, int& lang, const char *id = "id");
|
||||
|
||||
|
|
|
|||
|
|
@ -68,6 +68,13 @@ represents JSON object.&]
|
|||
[s5;:Json`:`:Json`(`): [* Json]()&]
|
||||
[s2; Default constructor. Creates empty JSON object.&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:Json`:`:CatRaw`(const char`*`,const String`&`): [_^Json^ Json][@(0.0.255) `&]_[* CatRa
|
||||
w]([@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 key], [@(0.0.255) const]_[_^String^ String][@(0.0.255) `&
|
||||
]_[*@3 val])&]
|
||||
[s2;%% Appends raw text (which must be a valid JSON) [%-*@3 val] with
|
||||
[%-*@3 key].&]
|
||||
[s3;%% &]
|
||||
[s4;%% &]
|
||||
[s5;:Json`:`:Json`(const char`*`,const Value`&`): [* Json]([@(0.0.255) const]_[@(0.0.255) c
|
||||
har]_`*[*@3 key], [@(0.0.255) const]_[_^Value^ Value][@(0.0.255) `&]_[*@3 value])&]
|
||||
|
|
@ -148,6 +155,11 @@ t]&]
|
|||
[s2;%% Returns current JSON formatted text.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:JsonArray`:`:CatRaw`(const String`&`): [_^JsonArray^ JsonArray][@(0.0.255) `&]_[* CatR
|
||||
aw]([@(0.0.255) const]_[_^String^ String][@(0.0.255) `&]_[*@3 val])&]
|
||||
[s2;%% Appends raw text (which must be a valid JSON).&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:JsonArray`:`:operator`<`<`(const Value`&`): [_^JsonArray^ JsonArray][@(0.0.255) `&]_
|
||||
[* operator<<]([@(0.0.255) const]_[_^Value^ Value][@(0.0.255) `&]_[*@3 value])&]
|
||||
[s5;:JsonArray`:`:operator`<`<`(int`): [_^JsonArray^ JsonArray][@(0.0.255) `&]_[* operator<
|
||||
|
|
@ -167,4 +179,4 @@ perator<<]([@(0.0.255) const]_[_^Json^ Json][@(0.0.255) `&]_[*@3 object])&]
|
|||
[s5;:JsonArray`:`:operator`<`<`(const JsonArray`&`): [_^JsonArray^ JsonArray][@(0.0.255) `&
|
||||
]_[* operator<<]([@(0.0.255) const]_[_^JsonArray^ JsonArray][@(0.0.255) `&]_[*@3 array])&]
|
||||
[s2;%% Adds an element to JSON array.&]
|
||||
[s3;%% ]
|
||||
[s3;%% ]]
|
||||
|
|
@ -182,10 +182,8 @@ public:
|
|||
void ParseTextFlags(const char *s);
|
||||
|
||||
void Serialize(Stream& s);
|
||||
#ifdef SVO_VALUE
|
||||
void Jsonize(JsonIO& jio);
|
||||
void Xmlize(XmlIO& xio);
|
||||
#endif
|
||||
|
||||
bool operator==(Font f) const { return v.face == f.v.face && v.flags == f.v.flags &&
|
||||
v.width == f.v.width && v.height == f.v.height; }
|
||||
|
|
@ -388,10 +386,8 @@ public:
|
|||
|
||||
void Clear() { size = Null; data.Clear(); cmd.Clear(); }
|
||||
void Serialize(Stream& s) { s % cmd % data % size; }
|
||||
#ifdef SVO_VALUE
|
||||
void Xmlize(XmlIO& xio) { XmlizeBySerialize(xio, *this); }
|
||||
void Jsonize(JsonIO& jio) { JsonizeBySerialize(jio, *this); }
|
||||
#endif
|
||||
bool IsNullInstance() const { return cmd.IsEmpty(); }
|
||||
void SetNull() { size = Null; }
|
||||
bool operator==(const Painting& b) const { return cmd == b.cmd && data == b.data && size == b.size; }
|
||||
|
|
@ -652,10 +648,8 @@ public:
|
|||
void Append(Drawing& dw);
|
||||
|
||||
void Serialize(Stream& s);
|
||||
#ifdef SVO_VALUE
|
||||
void Xmlize(XmlIO& xio) { XmlizeBySerialize(xio, *this); }
|
||||
void Jsonize(JsonIO& jio) { JsonizeBySerialize(jio, *this); }
|
||||
#endif
|
||||
|
||||
bool IsNullInstance() const { return data.IsEmpty(); }
|
||||
void SetNull() { size = Null; }
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ void DrawTextEllipsis(Draw& w, int x, int y, int cx, const wchar *text, const ch
|
|||
int dtl = 0;
|
||||
int el = 0;
|
||||
for(s = ellipsis; *s; s++) {
|
||||
dtl += f[(byte)*s];
|
||||
dtl += f[*s];
|
||||
el++;
|
||||
}
|
||||
int l = 0;
|
||||
|
|
@ -20,7 +20,7 @@ void DrawTextEllipsis(Draw& w, int x, int y, int cx, const wchar *text, const ch
|
|||
l += f[(byte) text[i]];
|
||||
if(l > cx) {
|
||||
while(l + dtl > cx && i > 0) {
|
||||
l -= f[(byte) text[i]];
|
||||
l -= f[text[i]];
|
||||
i--;
|
||||
}
|
||||
i++;
|
||||
|
|
|
|||
|
|
@ -292,7 +292,6 @@ String Font::GetFaceNameStd() const
|
|||
return GetFaceName();
|
||||
}
|
||||
|
||||
#ifdef SVO_VALUE
|
||||
void Font::Jsonize(JsonIO& jio)
|
||||
{
|
||||
String n, tf;
|
||||
|
|
@ -331,7 +330,6 @@ void Font::Xmlize(XmlIO& xio)
|
|||
ParseTextFlags(tf);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
template<>
|
||||
String AsString(const Font& f) {
|
||||
|
|
|
|||
|
|
@ -236,10 +236,8 @@ public:
|
|||
String ToString() const;
|
||||
|
||||
void Serialize(Stream& s);
|
||||
#ifdef SVO_VALUE
|
||||
void Xmlize(XmlIO& xio) { XmlizeBySerialize(xio, *this); }
|
||||
void Jsonize(JsonIO& jio) { JsonizeBySerialize(jio, *this); }
|
||||
#endif
|
||||
void Xmlize(XmlIO& xio) { XmlizeBySerialize(xio, *this); }
|
||||
void Jsonize(JsonIO& jio) { JsonizeBySerialize(jio, *this); }
|
||||
void Clear();
|
||||
|
||||
Image& operator=(const Image& img);
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
description "XML viewer - with added \"path\" capability\377";
|
||||
|
||||
uses
|
||||
CtrlLib;
|
||||
|
||||
file
|
||||
XmlView.h,
|
||||
main.cpp,
|
||||
XmlView.iml,
|
||||
XmlView.rc;
|
||||
|
||||
mainconfig
|
||||
"" = "GUI SVO_VALUE";
|
||||
|
||||
description "XML viewer - with added \"path\" capability\377";
|
||||
|
||||
uses
|
||||
CtrlLib;
|
||||
|
||||
file
|
||||
XmlView.h,
|
||||
main.cpp,
|
||||
XmlView.iml,
|
||||
XmlView.rc;
|
||||
|
||||
mainconfig
|
||||
"" = "GUI";
|
||||
|
||||
|
|
|
|||
|
|
@ -93,8 +93,7 @@ mainconfig
|
|||
"" = ".NOGTK GUI",
|
||||
"" = "GUI HEAPDBG CHECKINIT",
|
||||
"" = "GUI TESTINSTALL",
|
||||
"" = "GUI CHECKCLIPBOARD",
|
||||
"" = "GUI SVO_VALUE";
|
||||
"" = "GUI CHECKCLIPBOARD";
|
||||
|
||||
custom() "",
|
||||
"",
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
#define SVO_VALUE
|
||||
Loading…
Add table
Add a link
Reference in a new issue