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:
cxl 2012-03-03 15:49:28 +00:00
parent 4261c47291
commit a0e6ae4a96
14 changed files with 293 additions and 60 deletions

View file

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

View file

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

View file

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

View file

@ -164,7 +164,6 @@ INITBLOCK {
sRegisterStd();
}
void Value::Serialize(Stream& s) {
sRegisterStd();
dword type;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -87,7 +87,7 @@ file
Copying;
mainconfig
"" = "GUI",
"" = "GUI SVO_VALUE",
"" = "GUI .USEMALLOC",
"" = ".NOGTK GUI",
"" = "GUI HEAPDBG CHECKINIT",