mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-07-11 22:03:01 -06:00
Core: Value support for Xmlize, Jasonize
git-svn-id: svn://ultimatepp.org/upp/trunk@4651 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
4261c47291
commit
a0e6ae4a96
14 changed files with 293 additions and 60 deletions
|
|
@ -121,7 +121,7 @@ Color Blend(Color c1, Color c2, int alpha)
|
|||
|
||||
#ifdef SVO_VALUE
|
||||
INITBLOCK {
|
||||
Value::SvoRegister<Color>();
|
||||
Value::SvoRegister<Color>("Color");
|
||||
}
|
||||
#else
|
||||
INITBLOCK {
|
||||
|
|
|
|||
|
|
@ -2,43 +2,6 @@
|
|||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#ifdef SVO_VALUE
|
||||
template <class T>
|
||||
static void sReg()
|
||||
{
|
||||
if(FitsSvoValue<T>())
|
||||
Value::SvoRegister<T>();
|
||||
else
|
||||
Value::Register<T>();
|
||||
}
|
||||
|
||||
INITBLOCK
|
||||
{
|
||||
sReg<Point>();
|
||||
sReg<Point64>();
|
||||
sReg<Pointf>();
|
||||
sReg<Size>();
|
||||
sReg<Size64>();
|
||||
sReg<Sizef>();
|
||||
Value::Register<Rect>();
|
||||
Value::Register<Rect64>();
|
||||
Value::Register<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
|
||||
|
||||
//template <>
|
||||
//void Rect_<double>::Union(const Rect_<double>& r) {
|
||||
void Rect_double_Union(Rect_<double>& self, const Rect_<double>& r) {
|
||||
|
|
|
|||
|
|
@ -112,6 +112,8 @@ String AsJSON(const Value& v, const String& sep, bool pretty)
|
|||
return Format("%.16g", (double)v);
|
||||
if(IsString(v))
|
||||
return AsCString((String)v);
|
||||
if(IsNull(v))
|
||||
return "null";
|
||||
NEVER();
|
||||
return "null";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -164,7 +164,6 @@ INITBLOCK {
|
|||
sRegisterStd();
|
||||
}
|
||||
|
||||
|
||||
void Value::Serialize(Stream& s) {
|
||||
sRegisterStd();
|
||||
dword type;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ NAMESPACE_UPP
|
|||
|
||||
#ifdef SVO_VALUE
|
||||
INITBLOCK {
|
||||
Value::Register<Uuid>();
|
||||
Value::Register<Uuid>("Uuid");
|
||||
}
|
||||
#else
|
||||
INITBLOCK {
|
||||
|
|
@ -68,6 +68,16 @@ Uuid ScanUuid(const char *s)
|
|||
return id;
|
||||
}
|
||||
|
||||
void Uuid::Xmlize(XmlIO& xio)
|
||||
{
|
||||
String h;
|
||||
if(xio.IsStoring())
|
||||
h = Format(*this);
|
||||
xio.Attr("value", h);
|
||||
if(xio.IsLoading())
|
||||
*this = ScanUuid(h);
|
||||
}
|
||||
|
||||
String Uuid::ToString() const
|
||||
{
|
||||
return Format(*this);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ struct Uuid : AssignValueTypeNo<Uuid, 50, Moveable<Uuid> > {
|
|||
dword a, b, c, d;
|
||||
|
||||
void Serialize(Stream& s);
|
||||
void Xmlize(XmlIO& xio);
|
||||
bool IsNullInstance() const { return a == 0 && b == 0 && c == 0 && d == 0; }
|
||||
void SetNull() { a = b = c = d = 0; }
|
||||
|
||||
|
|
|
|||
|
|
@ -157,6 +157,40 @@ VectorMap<dword, Value::Void *(*)()>& Value::Typemap()
|
|||
return x;
|
||||
}
|
||||
|
||||
Index<String>& Value::NameNdx()
|
||||
{
|
||||
static Index<String> x;
|
||||
return x;
|
||||
}
|
||||
|
||||
Index<dword>& Value::TypeNdx()
|
||||
{
|
||||
static Index<dword> x;
|
||||
return x;
|
||||
}
|
||||
|
||||
void Value::AddName(dword type, const char *name)
|
||||
{
|
||||
NameNdx().Add(name);
|
||||
TypeNdx().Add(type);
|
||||
}
|
||||
|
||||
int Value::GetType(const char *name)
|
||||
{
|
||||
int q = NameNdx().Find(name);
|
||||
if(q < 0)
|
||||
return Null;
|
||||
return TypeNdx()[q];
|
||||
}
|
||||
|
||||
String Value::GetName(dword type)
|
||||
{
|
||||
int q = TypeNdx().Find(type);
|
||||
if(q < 0)
|
||||
return Null;
|
||||
return NameNdx()[q];
|
||||
}
|
||||
|
||||
SVO_FN(s_String, String);
|
||||
SVO_FN(s_int, int);
|
||||
SVO_FN(s_double, double);
|
||||
|
|
@ -215,22 +249,36 @@ Value::Void *ValueMapDataCreate()
|
|||
return new ValueMap::Data;
|
||||
}
|
||||
|
||||
static void sRegisterStd()
|
||||
void Value::RegisterStd()
|
||||
{
|
||||
ONCELOCK {
|
||||
RichValue<WString>::Register();
|
||||
RichValue<Complex>::Register();
|
||||
Value::Register(VALUEARRAY_V, ValueArrayDataCreate);
|
||||
Value::Register(VALUEMAP_V, ValueMapDataCreate);
|
||||
Value::Register<WString>("WString");
|
||||
Value::Register<Complex>("Complex");
|
||||
Value::Register(VALUEARRAY_V, ValueArrayDataCreate, "ValueArray");
|
||||
Value::Register(VALUEMAP_V, ValueMapDataCreate, "ValueMap");
|
||||
Value::AddName(STRING_V, "String");
|
||||
Value::AddName(INT_V, "int");
|
||||
Value::AddName(DOUBLE_V, "double");
|
||||
Value::AddName(VOID_V, "void");
|
||||
Value::AddName(DATE_V, "date");
|
||||
Value::AddName(TIME_V, "time");
|
||||
Value::AddName(INT64_V, "int64");
|
||||
Value::AddName(BOOL_V, "bool");
|
||||
Value::AddName(ERROR_V, "error");
|
||||
};
|
||||
}
|
||||
|
||||
void ValueRegisterHelper()
|
||||
{
|
||||
Value::RegisterStd();
|
||||
}
|
||||
|
||||
INITBLOCK {
|
||||
sRegisterStd();
|
||||
ValueRegisterHelper();
|
||||
}
|
||||
|
||||
void Value::Serialize(Stream& s) {
|
||||
sRegisterStd();
|
||||
RegisterStd();
|
||||
dword type;
|
||||
if(s.IsLoading()) {
|
||||
s / type;
|
||||
|
|
@ -278,15 +326,161 @@ void Value::Serialize(Stream& s) {
|
|||
}
|
||||
}
|
||||
|
||||
static String s_binary("serialized_binary");
|
||||
|
||||
void Value::Xmlize(XmlIO& xio)
|
||||
{
|
||||
RegisterStd();
|
||||
if(xio.IsStoring()) {
|
||||
dword type = GetType();
|
||||
String name = GetName(type);
|
||||
if(name.GetCount() == 0) {
|
||||
xio.SetAttr("type", s_binary);
|
||||
String s = HexString(StoreAsString(*this));
|
||||
Upp::Xmlize(xio, s);
|
||||
}
|
||||
else {
|
||||
xio.SetAttr("type", name);
|
||||
int st = data.GetSpecial();
|
||||
ASSERT_(!type || type == ERROR_V || type == UNKNOWN_V || st == STRING ||
|
||||
(IsRef() ? Typemap().Find(type) >= 0 : st < 255 && svo[st]),
|
||||
AsString(type) + " is not registred for serialization");
|
||||
if(st == VOIDV)
|
||||
return;
|
||||
if(st == STRING)
|
||||
Upp::Xmlize(xio, data);
|
||||
else
|
||||
if(IsRef())
|
||||
ptr()->Xmlize(xio);
|
||||
else
|
||||
svo[st]->Xmlize(&data, xio);
|
||||
}
|
||||
}
|
||||
else {
|
||||
String name = xio.GetAttr("type");
|
||||
if(name == s_binary) {
|
||||
String s;
|
||||
Upp::Xmlize(xio, s);
|
||||
try {
|
||||
LoadFromString(*this, ScanHexString(s));
|
||||
}
|
||||
catch(LoadingError) {
|
||||
throw XmlError("serialized_binary Error");
|
||||
}
|
||||
}
|
||||
else {
|
||||
int type = GetType(name);
|
||||
if(Upp::IsNull(type))
|
||||
throw XmlError("invalid Value type");
|
||||
Free();
|
||||
int st = (dword)type == VOID_V ? VOIDV : (dword)type == STRING_V ? STRING : type;
|
||||
if(st == STRING)
|
||||
Upp::Xmlize(xio, data);
|
||||
else
|
||||
if(st < 255 && svo[st]) {
|
||||
data.SetSpecial((byte)type);
|
||||
svo[st]->Xmlize(&data, xio);
|
||||
}
|
||||
else {
|
||||
typedef Void* (*vp)();
|
||||
vp *cr = Typemap().FindPtr(type);
|
||||
if(cr) {
|
||||
Void *p = (**cr)();
|
||||
p->Xmlize(xio);
|
||||
InitRef(p);
|
||||
}
|
||||
else
|
||||
throw XmlError("invalid Value type");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Value::Jsonize(JsonIO& jio)
|
||||
{
|
||||
RegisterStd();
|
||||
if(jio.IsStoring()) {
|
||||
dword type = GetType();
|
||||
String name = GetName(type);
|
||||
if(name.GetCount() == 0) {
|
||||
String s = HexString(StoreAsString(*this));
|
||||
jio("type", s_binary)
|
||||
("value", s);
|
||||
}
|
||||
else {
|
||||
int st = data.GetSpecial();
|
||||
ASSERT_(!type || type == ERROR_V || type == UNKNOWN_V || st == STRING ||
|
||||
(IsRef() ? Typemap().Find(type) >= 0 : st < 255 && svo[st]),
|
||||
AsString(type) + " is not registred for serialization");
|
||||
if(st == VOIDV)
|
||||
return;
|
||||
JsonIO hio;
|
||||
if(st == STRING) {
|
||||
String h = data;
|
||||
Upp::Jsonize(hio, h);
|
||||
}
|
||||
else {
|
||||
if(IsRef())
|
||||
ptr()->Jsonize(hio);
|
||||
else
|
||||
svo[st]->Jsonize(&data, hio);
|
||||
}
|
||||
ValueMap m;
|
||||
m.Add("type", name);
|
||||
m.Add("value", hio.GetResult());
|
||||
jio.Set(m);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Value g = jio.Get();
|
||||
String name = g["type"];
|
||||
Value val = g["value"];
|
||||
if(name == s_binary) {
|
||||
if(!Upp::IsString(val))
|
||||
throw JsonizeError("serialized_binary Error");
|
||||
String s = val;
|
||||
try {
|
||||
LoadFromString(*this, ScanHexString(s));
|
||||
}
|
||||
catch(LoadingError) {
|
||||
throw JsonizeError("serialized_binary Error");
|
||||
}
|
||||
}
|
||||
else {
|
||||
DDUMP(name);
|
||||
int type = GetType(name);
|
||||
if(Upp::IsNull(type))
|
||||
throw JsonizeError("invalid Value type");
|
||||
Free();
|
||||
int st = (dword)type == VOID_V ? VOIDV : (dword)type == STRING_V ? STRING : type;
|
||||
if(st == STRING) {
|
||||
if(!Upp::IsString(val))
|
||||
throw JsonizeError("serialized_binary Error");
|
||||
data = val;
|
||||
}
|
||||
else {
|
||||
JsonIO hio(val);
|
||||
if(st < 255 && svo[st]) {
|
||||
data.SetSpecial((byte)type);
|
||||
svo[st]->Jsonize(&data, hio);
|
||||
}
|
||||
else {
|
||||
typedef Void* (*vp)();
|
||||
vp *cr = Typemap().FindPtr(type);
|
||||
if(cr) {
|
||||
Void *p = (**cr)();
|
||||
p->Jsonize(hio);
|
||||
InitRef(p);
|
||||
}
|
||||
else
|
||||
throw JsonizeError("invalid Value type");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Value::Register(dword w, Void* (*c)()) init_ {
|
||||
void Value::Register(dword w, Void* (*c)(), const char *name) init_ {
|
||||
#ifdef flagCHECKINIT
|
||||
RLOG("Register valuetype " << w);
|
||||
#endif
|
||||
|
|
@ -294,6 +488,7 @@ void Value::Register(dword w, Void* (*c)()) init_ {
|
|||
ASSERT(w != UNKNOWN_V);
|
||||
ASSERT(w < 0x8000000);
|
||||
CHECK(Typemap().GetAdd(w, c) == c);
|
||||
AddName(w, name);
|
||||
}
|
||||
|
||||
String Value::ToString() const {
|
||||
|
|
|
|||
|
|
@ -81,6 +81,8 @@ public:
|
|||
virtual dword GetType() const { return VOID_V; }
|
||||
virtual bool IsNull() const { return true; }
|
||||
virtual void Serialize(Stream& s) {}
|
||||
virtual void Xmlize(XmlIO& xio) {}
|
||||
virtual void Jsonize(JsonIO& jio) {}
|
||||
virtual unsigned GetHashValue() const { return 0; }
|
||||
virtual bool IsEqual(const Void *p) { return false; }
|
||||
virtual bool IsPolyEqual(const Value& v) { return false; }
|
||||
|
|
@ -108,6 +110,15 @@ protected:
|
|||
|
||||
static VectorMap<dword, Void* (*)()>& Typemap();
|
||||
static Sval *svo[256];
|
||||
static Index<String>& NameNdx();
|
||||
static Index<dword>& TypeNdx();
|
||||
|
||||
static void AddName(dword type, const char *name);
|
||||
static int GetType(const char *name);
|
||||
static String GetName(dword type);
|
||||
static void RegisterStd();
|
||||
|
||||
friend void ValueRegisterHelper();
|
||||
|
||||
String data;
|
||||
Void *&ptr() { ASSERT(IsRef()); return *(Void **)&data; }
|
||||
|
|
@ -148,12 +159,12 @@ protected:
|
|||
String GetName() const;
|
||||
|
||||
public:
|
||||
static void Register(dword w, Void* (*c)()) init_; // Direct use deprecated
|
||||
static void Register(dword w, Void* (*c)(), const char *name = NULL) init_; // Direct use deprecated
|
||||
|
||||
template <class T>
|
||||
static void Register();
|
||||
static void Register(const char *name = NULL);
|
||||
template <class T>
|
||||
static void SvoRegister();
|
||||
static void SvoRegister(const char *name = NULL);
|
||||
|
||||
dword GetType() const;
|
||||
bool IsError() const { return GetType() == ERROR_V; }
|
||||
|
|
|
|||
|
|
@ -144,12 +144,13 @@ T& Value::GetSmall() const
|
|||
}
|
||||
|
||||
template <class T>
|
||||
void Value::SvoRegister()
|
||||
void Value::SvoRegister(const char *name)
|
||||
{
|
||||
dword t = GetValueTypeNo<T>();
|
||||
ASSERT(t < 255);
|
||||
SVO_FN(sval, T)
|
||||
svo[t] = &sval;
|
||||
AddName(t, name);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
|
|
@ -247,9 +248,10 @@ unsigned Value::GetHashValue() const
|
|||
}
|
||||
|
||||
template <class T>
|
||||
void Value::Register()
|
||||
void Value::Register(const char *name)
|
||||
{
|
||||
Value::Register(GetValueTypeNo<T>(), RichValueRep<T>::Create);
|
||||
dword t = GetValueTypeNo<T>();
|
||||
Value::Register(t, RichValueRep<T>::Create, name);
|
||||
}
|
||||
|
||||
inline
|
||||
|
|
|
|||
|
|
@ -36,6 +36,11 @@ void ValueArray::Data::Serialize(Stream& s)
|
|||
s % data;
|
||||
}
|
||||
|
||||
void ValueArray::Data::Xmlize(XmlIO& io)
|
||||
{
|
||||
Upp::Xmlize(io, data);
|
||||
}
|
||||
|
||||
unsigned ValueArray::Data::GetHashValue() const
|
||||
{
|
||||
CombineHash w(data.GetCount());
|
||||
|
|
@ -225,6 +230,12 @@ void ValueMap::Data::Serialize(Stream& s) {
|
|||
s % key % value;
|
||||
}
|
||||
|
||||
void ValueMap::Data::Xmlize(XmlIO& xio)
|
||||
{
|
||||
Upp::Xmlize(xio, key);
|
||||
Upp::Xmlize(xio, value);
|
||||
}
|
||||
|
||||
unsigned ValueMap::Data::GetHashValue() const {
|
||||
CombineHash w(key.GetCount());
|
||||
for(int i = 0; i < key.GetCount(); i++)
|
||||
|
|
@ -484,7 +495,7 @@ void Complex::Jsonize(JsonIO& jio)
|
|||
{
|
||||
double r, i;
|
||||
r = real(); i = imag();
|
||||
jio("real", r)("image", i);
|
||||
jio("real", r)("imag", i);
|
||||
*this = C(r, i);
|
||||
}
|
||||
|
||||
|
|
@ -496,5 +507,42 @@ void Complex::Serialize(Stream& s)
|
|||
*this = C(r, i);
|
||||
}
|
||||
|
||||
#ifdef SVO_VALUE
|
||||
template <class T>
|
||||
static void sReg(const char *name)
|
||||
{
|
||||
if(FitsSvoValue<T>())
|
||||
Value::SvoRegister<T>(name);
|
||||
else
|
||||
Value::Register<T>(name);
|
||||
}
|
||||
|
||||
INITBLOCK
|
||||
{
|
||||
sReg<Point>("Point");
|
||||
sReg<Point64>("Point64");
|
||||
sReg<Pointf>("Pointf");
|
||||
sReg<Size>("Size");
|
||||
sReg<Size64>("Size64");
|
||||
sReg<Sizef>("Sizef");
|
||||
Value::Register<Rect>("Rect");
|
||||
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
|
||||
|
||||
|
|
|
|||
|
|
@ -165,6 +165,7 @@ class ValueArray : AssignValueTypeNo<ValueArray, VALUEARRAY_V, Moveable<ValueArr
|
|||
virtual dword GetType() const { return VALUEARRAY_V; }
|
||||
virtual bool IsNull() const;
|
||||
virtual void Serialize(Stream& s);
|
||||
virtual void Xmlize(XmlIO& xio);
|
||||
virtual unsigned GetHashValue() const;
|
||||
virtual bool IsEqual(const Value::Void *p);
|
||||
virtual String AsString() const;
|
||||
|
|
@ -235,6 +236,7 @@ class ValueMap : AssignValueTypeNo<ValueMap, VALUEMAP_V, Moveable<ValueMap> >{
|
|||
virtual dword GetType() const { return VALUEMAP_V; }
|
||||
virtual bool IsNull() const;
|
||||
virtual void Serialize(Stream& s);
|
||||
virtual void Xmlize(XmlIO& xio);
|
||||
virtual unsigned GetHashValue() const;
|
||||
virtual bool IsEqual(const Value::Void *p);
|
||||
virtual String AsString() const;
|
||||
|
|
|
|||
|
|
@ -211,6 +211,7 @@ void Xmlize(XmlIO& xml, Color& c)
|
|||
c = Color(r, g, b);
|
||||
}
|
||||
|
||||
#ifndef SVO_VALUE
|
||||
typedef void (*ValueXmlizer)(XmlIO& xml, Value& v);
|
||||
|
||||
VectorMap<dword, ValueXmlizer>& ValueXmlizeMap()
|
||||
|
|
@ -238,7 +239,6 @@ void RegisterValueXmlize(dword type, void (*xmlize)(XmlIO& xml, Value& v), const
|
|||
ValueXmlizeName().Add(name);
|
||||
}
|
||||
|
||||
#ifndef SVO_VALUE
|
||||
REGISTER_VALUE_XMLIZE(String);
|
||||
REGISTER_VALUE_XMLIZE(WString);
|
||||
REGISTER_VALUE_XMLIZE(int);
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ const int FONT_V = 40;
|
|||
|
||||
class FontInfo;
|
||||
|
||||
class Font : AssignValueTypeNo<Font, FONT_V, Moveable<Font> >{
|
||||
class Font : public AssignValueTypeNo<Font, FONT_V, Moveable<Font> >{
|
||||
union {
|
||||
int64 data;
|
||||
struct {
|
||||
|
|
@ -366,7 +366,7 @@ void SColorDkShadow_Write(Color c);
|
|||
inline Color InvertColor() { return Color(255, 0); }
|
||||
inline Color DefaultInk() { return Black(); } //TODO!
|
||||
|
||||
class Painting : AssignValueTypeNo<Painting, 48, Moveable<Painting> > {
|
||||
class Painting : public AssignValueTypeNo<Painting, 48, Moveable<Painting> > {
|
||||
String cmd;
|
||||
ValueArray data;
|
||||
Sizef size;
|
||||
|
|
@ -617,7 +617,7 @@ public:
|
|||
template <class T> static void Register(const char *id) { AddFormat(id, &DataDrawer::FactoryFn<T>); }
|
||||
};
|
||||
|
||||
class Drawing : AssignValueTypeNo<Drawing, 49, Moveable<Drawing> > {
|
||||
class Drawing : public AssignValueTypeNo<Drawing, 49, Moveable<Drawing> > {
|
||||
Size size;
|
||||
String data;
|
||||
ValueArray val;
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ file
|
|||
Copying;
|
||||
|
||||
mainconfig
|
||||
"" = "GUI",
|
||||
"" = "GUI SVO_VALUE",
|
||||
"" = "GUI .USEMALLOC",
|
||||
"" = ".NOGTK GUI",
|
||||
"" = "GUI HEAPDBG CHECKINIT",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue