mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-07-11 22:03:01 -06:00
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:
parent
8a8224adf6
commit
7df11e6fe1
6 changed files with 187 additions and 16 deletions
|
|
@ -258,6 +258,7 @@ NAMESPACE_UPP
|
|||
|
||||
#include "Parser.h"
|
||||
#include "XML.h"
|
||||
#include "JSON.h"
|
||||
#include "Lang.h"
|
||||
#include "i18n.h"
|
||||
#include "Topic.h"
|
||||
|
|
|
|||
|
|
@ -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
118
uppsrc/Core/JSON.cpp
Normal 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
5
uppsrc/Core/JSON.h
Normal 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);
|
||||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue