Core: Value has now can directly access ValueArray, ValueMap elements, JSON support

git-svn-id: svn://ultimatepp.org/upp/trunk@4127 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2011-11-04 18:19:15 +00:00
parent 8a8224adf6
commit 7df11e6fe1
6 changed files with 187 additions and 16 deletions

View file

@ -258,6 +258,7 @@ NAMESPACE_UPP
#include "Parser.h"
#include "XML.h"
#include "JSON.h"
#include "Lang.h"
#include "i18n.h"
#include "Topic.h"

View file

@ -124,6 +124,8 @@ file
XML.cpp optimize_speed,
Xmlize.h,
Xmlize.cpp optimize_speed,
JSON.h,
JSON.cpp,
Uuid.h,
Uuid.cpp optimize_speed,
Ptr.h,

118
uppsrc/Core/JSON.cpp Normal file
View file

@ -0,0 +1,118 @@
#include "Core.h"
NAMESPACE_UPP
Value ParseJSON(CParser& p)
{
if(p.IsNumber())
return p.ReadDouble();
if(p.IsString())
return p.ReadString();
if(p.Id("null"))
return Null;
if(p.Id("true"))
return true;
if(p.Id("false"))
return false;
if(p.Char('{')) {
ValueMap m;
if(!p.IsChar('}'))
do {
String key = p.ReadString();
p.PassChar(':');
m.Add(key, ParseJSON(p));
}
while(p.Char(','));
p.PassChar('}');
return m;
}
if(p.Char('[')) {
ValueArray va;
if(!p.IsChar(']'))
do
va.Add(ParseJSON(p));
while(p.Char(','));
p.PassChar(']');
return va;
}
p.ThrowError("Unrecognized JSON element");
return Null;
}
Value ParseJSON(const char *s)
{
CParser p(s);
return ParseJSON(p);
}
String AsJSON(const Value& v, const String& sep, bool pretty)
{
String r;
if(v.GetType() == VALUEMAP_V) {
r << "{";
String sep1;
if(pretty) {
r << "\r\n";
sep1 = sep + '\t';
}
ValueMap m = v;
ValueArray va = m.GetValues();
for(int i = 0; i < m.GetCount(); i++) {
if(i) {
r << ",";
if(pretty)
r << "\r\n";
}
if(pretty)
r << sep1;
r << AsCString((String)m.GetKeys()[i]) << (pretty ? ": " : ":")
<< AsJSON(va[i], sep1, pretty);
}
if(pretty)
r << "\r\n" << sep;
r << "}";
return r;
}
if(v.GetType() == VALUEARRAY_V) {
r << "[";
String sep1;
if(pretty) {
r << "\r\n";
sep1 = sep + '\t';
}
ValueArray va = v;
for(int i = 0; i < va.GetCount(); i++) {
if(i) {
r << ",";
if(pretty)
r << "\r\n";
}
if(pretty)
r << sep1;
r << AsJSON(va[i], sep1, pretty);
}
if(pretty)
r << "\r\n" << sep;
r << "]";
return r;
}
if(IsNumber(v) && IsNull(v))
return "null";
if(v.GetType() == INT_V)
return Format("%d", (int)v);
if(v.GetType() == BOOL_V)
return (bool)v ? "true" : "false";
if(IsNumber(v))
return Format("%.16g", (double)v);
if(IsString(v))
return AsCString((String)v);
NEVER();
return "null";
}
String AsJSON(const Value& v, bool pretty)
{
return AsJSON(v, String(), pretty);
}
END_UPP_NAMESPACE

5
uppsrc/Core/JSON.h Normal file
View file

@ -0,0 +1,5 @@
Value ParseJSON(CParser& p);
Value ParseJSON(const char *s);
String AsJSON(const Value& v, const String& indent, bool pretty = false);
String AsJSON(const Value& v, bool pretty = false);

View file

@ -219,8 +219,13 @@ Value ErrorValue(const char *s) {
return ErrorValue(String(s));
}
Value ErrorValue() {
return ErrorValue(String());
const Value& ErrorValue() {
static Value *p;
ONCELOCK {
static Value v = ErrorValue(String());
p = &v;
}
return *p;
}
String GetErrorText(const Value& v) {
@ -604,7 +609,7 @@ void ValueMap::Remove(int i)
d.value.Remove(i);
}
Value ValueMap::operator[](const Value& key) const
const Value& ValueMap::operator[](const Value& key) const
{
int q = data->key.Find(key);
return q >= 0 ? data->value[q] : ErrorValue();

View file

@ -147,6 +147,12 @@ public:
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();
@ -482,9 +488,9 @@ public:
template <class T>
inline Value RichToValue(const T& data) { return RichValue<T>(data); }
Value ErrorValue(const char *s);
Value ErrorValue(const String& s);
Value ErrorValue();
Value ErrorValue(const char *s);
Value ErrorValue(const String& s);
const Value& ErrorValue();
String GetErrorText(const Value& v);
@ -630,6 +636,7 @@ public:
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; }
@ -713,27 +720,60 @@ public:
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; }
const Index<Value>& GetKeys() const { return data->key; }
ValueArray GetValues() const { return data->value; }
operator ValueArray() const { return GetValues(); }
operator ValueArray() const { return GetValues(); }
Value operator[](const Value& k) const;
Value operator[](const String& s) const { return operator[](Value(s)); }
Value operator[](const char *s) const { return operator[](Value(s)); }
Value operator[](const Id& k) const { return operator[](Value(k.ToString())); }
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())); }
unsigned GetHashValue() const { return data->GetHashValue(); }
unsigned GetHashValue() const { return data->GetHashValue(); }
void Serialize(Stream& s);
String ToString() const { return data->AsString(); }
String ToString() const { return data->AsString(); }
bool operator==(const ValueMap& v) const;
bool operator!=(const ValueMap& v) const { return !operator==(v); }
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
{
ASSERT(IsValueMap(*this));
return ValueMap(*this)[key];
}
inline
const Value& Value::operator[](const char *key) const
{
ASSERT(IsValueMap(*this));
return ValueMap(*this)[key];
}
inline
const Value& Value::operator[](const Id& key) const
{
ASSERT(IsValueMap(*this));
return ValueMap(*this)[key];
}
class ValueGen {
public: