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:
cxl 2012-09-14 11:43:13 +00:00
parent 295f172c86
commit 6cf239033f
29 changed files with 98 additions and 1818 deletions

View file

@ -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)
{

View file

@ -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);

View file

@ -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"

View file

@ -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,

View file

@ -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

View file

@ -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";
}

View file

@ -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(); }

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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)

View file

@ -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) {}

View file

@ -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

View file

@ -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() {}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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");

View file

@ -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;%% ]]

View file

@ -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; }

View file

@ -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++;

View file

@ -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) {

View file

@ -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);

View file

@ -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";

View file

@ -93,8 +93,7 @@ mainconfig
"" = ".NOGTK GUI",
"" = "GUI HEAPDBG CHECKINIT",
"" = "GUI TESTINSTALL",
"" = "GUI CHECKCLIPBOARD",
"" = "GUI SVO_VALUE";
"" = "GUI CHECKCLIPBOARD";
custom() "",
"",

View file

@ -1 +0,0 @@
#define SVO_VALUE