reWrite lsl json functions, forward slash is not escaped as LitJson spec; code can use some cleanup. Scripts need to be recompiled

httptests
UbitUmarov 2017-05-19 03:08:35 +01:00
parent c5d0c69a35
commit ef35805176
2 changed files with 658 additions and 147 deletions

View File

@ -28,6 +28,7 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics; using System.Diagnostics;
using System.Drawing; using System.Drawing;
using System.Drawing.Imaging; using System.Drawing.Imaging;
@ -40,7 +41,7 @@ using Nini.Config;
using log4net; using log4net;
using OpenMetaverse; using OpenMetaverse;
using OpenMetaverse.Assets; using OpenMetaverse.Assets;
using OpenMetaverse.StructuredData; using OpenMetaverse.StructuredData; // LitJson is hidden on this
using OpenMetaverse.Packets; using OpenMetaverse.Packets;
using OpenMetaverse.Rendering; using OpenMetaverse.Rendering;
using OpenSim; using OpenSim;
@ -16700,92 +16701,158 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return String.Empty; return String.Empty;
} }
public LSL_String llJsonGetValue(LSL_String json, LSL_List specifiers)
{
OSD o = OSDParser.DeserializeJson(json);
OSD specVal = JsonGetSpecific(o, specifiers, 0);
return specVal.AsString();
}
public LSL_List llJson2List(LSL_String json) public LSL_List llJson2List(LSL_String json)
{ {
if(String.IsNullOrEmpty(json))
return new LSL_List();
if(json == "[]")
return new LSL_List();
if(json == "{}")
return new LSL_List();
char first = ((string)json)[0];
if(first != '[' && first !='{')
{
// we already have a single element
LSL_List l = new LSL_List();
l.Add(json);
return l;
}
LitJson.JsonData jsdata;
try try
{ {
OSD o = OSDParser.DeserializeJson(json); jsdata = LitJson.JsonMapper.ToObject(json);
return (LSL_List)ParseJsonNode(o);
} }
catch (Exception) catch (Exception e)
{ {
return new LSL_List(ScriptBaseClass.JSON_INVALID); string m = e.Message; // debug point
return json;
}
try
{
return JsonParseTop(jsdata);
}
catch (Exception e)
{
string m = e.Message; // debug point
return (LSL_String)ScriptBaseClass.JSON_INVALID;
} }
} }
private object ParseJsonNode(OSD node) private LSL_List JsonParseTop(LitJson.JsonData elem)
{ {
if (node.Type == OSDType.Integer) LSL_List retl = new LSL_List();
return new LSL_Integer(node.AsInteger()); if(elem == null)
if (node.Type == OSDType.Boolean) retl.Add((LSL_String)ScriptBaseClass.JSON_NULL);
return new LSL_Integer(node.AsBoolean() ? 1 : 0);
if (node.Type == OSDType.Real) LitJson.JsonType elemType = elem.GetJsonType();
return new LSL_Float(node.AsReal()); switch (elemType)
if (node.Type == OSDType.UUID || node.Type == OSDType.String)
return new LSL_String(node.AsString());
if (node.Type == OSDType.Array)
{ {
LSL_List resp = new LSL_List(); case LitJson.JsonType.Int:
OSDArray ar = node as OSDArray; retl.Add(new LSL_Integer((int)elem));
foreach (OSD o in ar) return retl;
resp.Add(ParseJsonNode(o)); case LitJson.JsonType.Boolean:
return resp; retl.Add((LSL_String)((bool)elem ? ScriptBaseClass.JSON_TRUE : ScriptBaseClass.JSON_FALSE));
} return retl;
if (node.Type == OSDType.Map) case LitJson.JsonType.Double:
{ retl.Add(new LSL_Float((float)elem));
LSL_List resp = new LSL_List(); return retl;
OSDMap ar = node as OSDMap; case LitJson.JsonType.None:
foreach (KeyValuePair<string, OSD> o in ar) retl.Add((LSL_String)ScriptBaseClass.JSON_NULL);
{ return retl;
resp.Add(new LSL_String(o.Key)); case LitJson.JsonType.String:
resp.Add(ParseJsonNode(o.Value)); retl.Add(new LSL_String((string)elem));
} return retl;
return resp; case LitJson.JsonType.Array:
foreach (LitJson.JsonData subelem in elem)
retl.Add(JsonParseTopNodes(subelem));
return retl;
case LitJson.JsonType.Object:
IDictionaryEnumerator e = ((IOrderedDictionary)elem).GetEnumerator();
while (e.MoveNext())
{
retl.Add(new LSL_String((string)e.Key));
retl.Add(JsonParseTopNodes((LitJson.JsonData)e.Value));
} }
return retl;
default:
throw new Exception(ScriptBaseClass.JSON_INVALID); throw new Exception(ScriptBaseClass.JSON_INVALID);
} }
}
private object JsonParseTopNodes(LitJson.JsonData elem)
{
if(elem == null)
return ((LSL_String)ScriptBaseClass.JSON_NULL);
LitJson.JsonType elemType = elem.GetJsonType();
switch (elemType)
{
case LitJson.JsonType.Int:
return (new LSL_Integer((int)elem));
case LitJson.JsonType.Boolean:
return ((bool)elem ? (LSL_String)ScriptBaseClass.JSON_TRUE : (LSL_String)ScriptBaseClass.JSON_FALSE);
case LitJson.JsonType.Double:
return (new LSL_Float((float)elem));
case LitJson.JsonType.None:
return ((LSL_String)ScriptBaseClass.JSON_NULL);
case LitJson.JsonType.String:
return (new LSL_String((string)elem));
case LitJson.JsonType.Array:
case LitJson.JsonType.Object:
string s = LitJson.JsonMapper.ToJson(elem);
return (LSL_String)s;
default:
throw new Exception(ScriptBaseClass.JSON_INVALID);
}
}
public LSL_String llList2Json(LSL_String type, LSL_List values) public LSL_String llList2Json(LSL_String type, LSL_List values)
{ {
try try
{ {
StringBuilder sb = new StringBuilder();
if (type == ScriptBaseClass.JSON_ARRAY) if (type == ScriptBaseClass.JSON_ARRAY)
{ {
OSDArray array = new OSDArray(); sb.Append("[");
int i= 0;
foreach (object o in values.Data) foreach (object o in values.Data)
{ {
array.Add(ListToJson(o)); sb.Append(ListToJson(o));
if((i++) < values.Data.Length - 1)
sb.Append(",");
} }
return OSDParser.SerializeJsonString(array); sb.Append("]");
return (LSL_String)sb.ToString();;
} }
else if (type == ScriptBaseClass.JSON_OBJECT) else if (type == ScriptBaseClass.JSON_OBJECT)
{ {
OSDMap map = new OSDMap(); sb.Append("{");
for (int i = 0; i < values.Data.Length; i += 2) for (int i = 0; i < values.Data.Length; i += 2)
{ {
if (!(values.Data[i] is LSL_String)) if (!(values.Data[i] is LSL_String))
return ScriptBaseClass.JSON_INVALID; return ScriptBaseClass.JSON_INVALID;
map.Add(((LSL_String)values.Data[i]).m_string, ListToJson(values.Data[i + 1])); string key = ((LSL_String)values.Data[i]).m_string;
key = EscapeForJSON(key, true);
sb.Append(key);
sb.Append(":");
sb.Append(ListToJson(values.Data[i+1]));
if(i < values.Data.Length - 2)
sb.Append(",");
} }
return OSDParser.SerializeJsonString(map); sb.Append("}");
return (LSL_String)sb.ToString();
} }
return ScriptBaseClass.JSON_INVALID; return ScriptBaseClass.JSON_INVALID;
} }
catch (Exception ex) catch
{ {
return ex.Message; return ScriptBaseClass.JSON_INVALID;
} }
} }
private OSD ListToJson(object o) private string ListToJson(object o)
{ {
if (o is LSL_Float || o is double) if (o is LSL_Float || o is double)
{ {
@ -16795,7 +16862,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
else else
float_val = ((LSL_Float)o).value; float_val = ((LSL_Float)o).value;
return OSD.FromReal(float_val); if(double.IsInfinity(float_val))
return "\"Inf\"";
if(double.IsNaN(float_val))
return "\"NaN\"";
return ((LSL_Float)float_val).ToString();
} }
if (o is LSL_Integer || o is int) if (o is LSL_Integer || o is int)
{ {
@ -16804,17 +16876,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
i = ((int)o); i = ((int)o);
else else
i = ((LSL_Integer)o).value; i = ((LSL_Integer)o).value;
return i.ToString();
if (i == 0)
return OSD.FromBoolean(false);
else if (i == 1)
return OSD.FromBoolean(true);
return OSD.FromInteger(i);
} }
if (o is LSL_Rotation) if (o is LSL_Rotation)
return OSD.FromString(((LSL_Rotation)o).ToString()); return ((LSL_Rotation)o).ToString();
if (o is LSL_Vector) if (o is LSL_Vector)
return OSD.FromString(((LSL_Vector)o).ToString()); return ((LSL_Vector)o).ToString();
if (o is LSL_String || o is string) if (o is LSL_String || o is string)
{ {
string str; string str;
@ -16823,137 +16890,579 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
else else
str = ((LSL_String)o).m_string; str = ((LSL_String)o).m_string;
if (str == ScriptBaseClass.JSON_NULL) if(str == ScriptBaseClass.JSON_TRUE || str == "true")
return new OSD(); return "true";
return OSD.FromString(str); if(str == ScriptBaseClass.JSON_FALSE ||str == "false")
return "false";
if(str == ScriptBaseClass.JSON_NULL || str == "null")
return "null";
str.Trim();
if (str[0] == '{')
return str;
if (str[0] == '[')
return str;
return EscapeForJSON(str, true);
} }
throw new Exception(ScriptBaseClass.JSON_INVALID); throw new IndexOutOfRangeException();
} }
private OSD JsonGetSpecific(OSD o, LSL_List specifiers, int i) private string EscapeForJSON(string s, bool AddOuter)
{ {
object spec = specifiers.Data[i]; int i;
OSD nextVal = null; char c;
if (o is OSDArray) String t;
int len = s.Length;
StringBuilder sb = new StringBuilder(len + 64);
if(AddOuter)
sb.Append("\"");
for (i = 0; i < len; i++)
{ {
if (spec is LSL_Integer) c = s[i];
nextVal = ((OSDArray)o)[((LSL_Integer)spec).value]; switch (c)
{
case '\\':
case '"':
case '/':
sb.Append('\\');
sb.Append(c);
break;
case '\b':
sb.Append("\\b");
break;
case '\t':
sb.Append("\\t");
break;
case '\n':
sb.Append("\\n");
break;
case '\f':
sb.Append("\\f");
break;
case '\r':
sb.Append("\\r");
break;
default:
if (c < ' ')
{
t = "000" + String.Format("X", c);
sb.Append("\\u" + t.Substring(t.Length - 4));
} }
if (o is OSDMap) else
{ {
if (spec is LSL_String) sb.Append(c);
nextVal = ((OSDMap)o)[((LSL_String)spec).m_string];
} }
if (nextVal != null) break;
{
if (specifiers.Data.Length - 1 > i)
return JsonGetSpecific(nextVal, specifiers, i + 1);
} }
return nextVal; }
if(AddOuter)
sb.Append("\"");
return sb.ToString();
} }
public LSL_String llJsonSetValue(LSL_String json, LSL_List specifiers, LSL_String value) public LSL_String llJsonSetValue(LSL_String json, LSL_List specifiers, LSL_String value)
{ {
bool noSpecifiers = specifiers.Length == 0;
LitJson.JsonData workData;
try try
{ {
OSD o = OSDParser.DeserializeJson(json); if(noSpecifiers)
JsonSetSpecific(o, specifiers, 0, value); specifiers.Add(new LSL_Integer(0));
return OSDParser.SerializeJsonString(o);
} if(!String.IsNullOrEmpty(json))
catch (Exception) workData = LitJson.JsonMapper.ToObject(json);
else
{ {
workData = new LitJson.JsonData();
workData.SetJsonType(LitJson.JsonType.Array);
}
}
catch (Exception e)
{
string m = e.Message; // debug point
return ScriptBaseClass.JSON_INVALID;
}
try
{
LitJson.JsonData replace = JsonSetSpecific(workData, specifiers, 0, value);
if(replace != null)
workData = replace;
}
catch (Exception e)
{
string m = e.Message; // debug point
return ScriptBaseClass.JSON_INVALID;
}
try
{
string r = LitJson.JsonMapper.ToJson(workData);
if(noSpecifiers)
r = r.Substring(1,r.Length -2); // strip leading and trailing brakets
return r;
}
catch (Exception e)
{
string m = e.Message; // debug point
} }
return ScriptBaseClass.JSON_INVALID; return ScriptBaseClass.JSON_INVALID;
} }
private void JsonSetSpecific(OSD o, LSL_List specifiers, int i, LSL_String val) private LitJson.JsonData JsonSetSpecific(LitJson.JsonData elem, LSL_List specifiers, int level, LSL_String val)
{ {
object spec = specifiers.Data[i]; object spec = specifiers.Data[level];
// 20131224 not used object specNext = i+1 == specifiers.Data.Length ? null : specifiers.Data[i+1]; if(spec is LSL_String)
OSD nextVal = null; spec = ((LSL_String)spec).m_string;
if (o is OSDArray) else if (spec is LSL_Integer)
spec = ((LSL_Integer)spec).value;
if(!(spec is string || spec is int))
throw new IndexOutOfRangeException();
int speclen = specifiers.Data.Length - 1;
bool hasvalue = false;
LitJson.JsonData value = null;
LitJson.JsonType elemType = elem.GetJsonType();
if (elemType == LitJson.JsonType.Array)
{
if (spec is int)
{
int v = (int)spec;
int c = elem.Count;
if(v < 0 || (v != 0 && v > c))
throw new IndexOutOfRangeException();
if(v == c)
elem.Add(JsonBuildRestOfSpec(specifiers, level + 1, val));
else
{
hasvalue = true;
value = elem[v];
}
}
else if (spec is string)
{
if((string)spec == ScriptBaseClass.JSON_APPEND)
elem.Add(JsonBuildRestOfSpec(specifiers, level + 1, val));
else if(elem.Count < 2)
{
// our initial guess of array was wrong
LitJson.JsonData newdata = new LitJson.JsonData();
newdata.SetJsonType(LitJson.JsonType.Object);
IOrderedDictionary no = newdata as IOrderedDictionary;
no.Add((string)spec,JsonBuildRestOfSpec(specifiers, level + 1, val));
return newdata;
}
}
}
else if (elemType == LitJson.JsonType.Object)
{
if (spec is string)
{
IOrderedDictionary e = elem as IOrderedDictionary;
string key = (string)spec;
if(e.Contains(key))
{
hasvalue = true;
value = (LitJson.JsonData)e[key];
}
else
e.Add(key, JsonBuildRestOfSpec(specifiers, level + 1, val));
}
else if(spec is int && (int)spec == 0)
{
//we are replacing a object by a array
LitJson.JsonData newData = new LitJson.JsonData();
newData.SetJsonType(LitJson.JsonType.Array);
newData.Add(JsonBuildRestOfSpec(specifiers, level + 1, val));
return newData;
}
}
else
{
LitJson.JsonData newData = JsonBuildRestOfSpec(specifiers, level, val);
return newData;
}
if (hasvalue)
{
if (level < speclen)
{
LitJson.JsonData replace = JsonSetSpecific(value, specifiers, level + 1, val);
if(replace != null)
{
if(elemType == LitJson.JsonType.Array)
{
if(spec is int)
elem[(int)spec] = replace;
else if( spec is string)
{
LitJson.JsonData newdata = new LitJson.JsonData();
newdata.SetJsonType(LitJson.JsonType.Object);
IOrderedDictionary no = newdata as IOrderedDictionary;
no.Add((string)spec, replace);
return newdata;
}
}
else if(elemType == LitJson.JsonType.Object)
{
if(spec is string)
elem[(string)spec] = replace;
else if(spec is int && (int)spec == 0)
{
LitJson.JsonData newdata = new LitJson.JsonData();
newdata.SetJsonType(LitJson.JsonType.Array);
newdata.Add(replace);
return newdata;
}
}
}
return null;
}
else if(speclen == level)
{
if(val == ScriptBaseClass.JSON_DELETE)
{
if(elemType == LitJson.JsonType.Array)
{
if(spec is int)
{
IList el = elem as IList;
el.RemoveAt((int)spec);
}
}
else if(elemType == LitJson.JsonType.Object)
{
if(spec is string)
{
IOrderedDictionary eo = elem as IOrderedDictionary;
eo.Remove((string) spec);
}
}
return null;
}
LitJson.JsonData newval = null;
float num;
if(val == null || val == ScriptBaseClass.JSON_NULL || val == "null")
newval = null;
else if(val == ScriptBaseClass.JSON_TRUE || val == "true")
newval = new LitJson.JsonData(true);
else if(val == ScriptBaseClass.JSON_FALSE || val == "false")
newval = new LitJson.JsonData(false);
else if(float.TryParse(val, out num))
{
// assuming we are at en.us already
if(num - (int)num == 0.0f && !val.Contains("."))
newval = new LitJson.JsonData((int)num);
else
{
num = (float)Math.Round(num,6);
newval = new LitJson.JsonData((double)num);
}
}
else
{
string str = val.m_string;
newval = new LitJson.JsonData(str);
}
if(elemType == LitJson.JsonType.Array)
{
if(spec is int)
elem[(int)spec] = newval;
else if( spec is string)
{
LitJson.JsonData newdata = new LitJson.JsonData();
newdata.SetJsonType(LitJson.JsonType.Object);
IOrderedDictionary no = newdata as IOrderedDictionary;
no.Add((string)spec,newval);
return newdata;
}
}
else if(elemType == LitJson.JsonType.Object)
{
if(spec is string)
elem[(string)spec] = newval;
else if(spec is int && (int)spec == 0)
{
LitJson.JsonData newdata = new LitJson.JsonData();
newdata.SetJsonType(LitJson.JsonType.Array);
newdata.Add(newval);
return newdata;
}
}
}
}
if(val == ScriptBaseClass.JSON_DELETE)
throw new IndexOutOfRangeException();
return null;
}
private LitJson.JsonData JsonBuildRestOfSpec(LSL_List specifiers, int level, LSL_String val)
{
object spec = level >= specifiers.Data.Length ? null : specifiers.Data[level];
// 20131224 not used object specNext = i+1 >= specifiers.Data.Length ? null : specifiers.Data[i+1];
float num;
if (spec == null)
{
if(val == null || val == ScriptBaseClass.JSON_NULL || val == "null")
return null;
if(val == ScriptBaseClass.JSON_DELETE)
throw new IndexOutOfRangeException();
if(val == ScriptBaseClass.JSON_TRUE || val == "true")
return new LitJson.JsonData(true);
if(val == ScriptBaseClass.JSON_FALSE || val == "false")
return new LitJson.JsonData(false);
if(val == null || val == ScriptBaseClass.JSON_NULL || val == "null")
return null;
if(float.TryParse(val, out num))
{
// assuming we are at en.us already
if(num - (int)num == 0.0f && !val.Contains("."))
return new LitJson.JsonData((int)num);
else
{
num = (float)Math.Round(num,6);
return new LitJson.JsonData(num);
}
}
else
{
string str = val.m_string;
return new LitJson.JsonData(str);
}
throw new IndexOutOfRangeException();
}
if(spec is LSL_String)
spec = ((LSL_String)spec).m_string;
else if (spec is LSL_Integer)
spec = ((LSL_Integer)spec).value;
if (spec is int ||
(spec is string && ((string)spec) == ScriptBaseClass.JSON_APPEND) )
{
if(spec is int && (int)spec != 0)
throw new IndexOutOfRangeException();
LitJson.JsonData newdata = new LitJson.JsonData();
newdata.SetJsonType(LitJson.JsonType.Array);
newdata.Add(JsonBuildRestOfSpec(specifiers, level + 1, val));
return newdata;
}
else if (spec is string)
{
LitJson.JsonData newdata = new LitJson.JsonData();
newdata.SetJsonType(LitJson.JsonType.Object);
IOrderedDictionary no = newdata as IOrderedDictionary;
no.Add((string)spec,JsonBuildRestOfSpec(specifiers, level + 1, val));
return newdata;
}
throw new IndexOutOfRangeException();
}
private bool JsonFind(LitJson.JsonData elem, LSL_List specifiers, int level, out LitJson.JsonData value)
{
value = null;
if(elem == null)
return false;
object spec;
spec = specifiers.Data[level];
bool haveVal = false;
LitJson.JsonData next = null;
if (elem.GetJsonType() == LitJson.JsonType.Array)
{ {
OSDArray array = ((OSDArray)o);
if (spec is LSL_Integer) if (spec is LSL_Integer)
{ {
int v = ((LSL_Integer)spec).value; int indx = (LSL_Integer)spec;
if (v >= array.Count) if(indx >= 0 && indx < elem.Count)
array.Add(JsonBuildRestOfSpec(specifiers, i + 1, val)); {
else haveVal = true;
nextVal = ((OSDArray)o)[v]; next = (LitJson.JsonData)elem[indx];
} }
else if (spec is LSL_String && ((LSL_String)spec) == ScriptBaseClass.JSON_APPEND)
array.Add(JsonBuildRestOfSpec(specifiers, i + 1, val));
} }
if (o is OSDMap) }
else if (elem.GetJsonType() == LitJson.JsonType.Object)
{ {
if (spec is LSL_String) if (spec is LSL_String)
{ {
OSDMap map = ((OSDMap)o); IOrderedDictionary e = elem as IOrderedDictionary;
if (map.ContainsKey(((LSL_String)spec).m_string)) string key = (LSL_String)spec;
nextVal = map[((LSL_String)spec).m_string]; if(e.Contains(key))
{
haveVal = true;
next = (LitJson.JsonData)e[key];
}
}
}
if (haveVal)
{
if(level == specifiers.Data.Length - 1)
{
value = next;
return true;
}
level++;
if(next == null)
return false;
LitJson.JsonType nextType = next.GetJsonType();
if(nextType != LitJson.JsonType.Object && nextType != LitJson.JsonType.Array)
return false;
return JsonFind(next, specifiers, level, out value);
}
return false;
}
public LSL_String llJsonGetValue(LSL_String json, LSL_List specifiers)
{
if(String.IsNullOrWhiteSpace(json))
return ScriptBaseClass.JSON_INVALID;
if(specifiers.Length > 0 && (json == "{}" || json == "[]"))
return ScriptBaseClass.JSON_INVALID;
char first = ((string)json)[0];
if((first != '[' && first !='{'))
{
if(specifiers.Length > 0)
return ScriptBaseClass.JSON_INVALID;
json = "[" + json + "]"; // could handle single element case.. but easier like this
specifiers.Add((LSL_Integer)0);
}
LitJson.JsonData jsonData;
try
{
jsonData = LitJson.JsonMapper.ToObject(json);
}
catch (Exception e)
{
string m = e.Message; // debug point
return ScriptBaseClass.JSON_INVALID;
}
LitJson.JsonData elem = null;
if(specifiers.Length == 0)
elem = jsonData;
else else
map.Add(((LSL_String)spec).m_string, JsonBuildRestOfSpec(specifiers, i + 1, val));
}
}
if (nextVal != null)
{ {
if (specifiers.Data.Length - 1 > i) if(!JsonFind(jsonData, specifiers, 0, out elem))
{ return ScriptBaseClass.JSON_INVALID;
JsonSetSpecific(nextVal, specifiers, i + 1, val);
return;
}
} }
return JsonElementToString(elem);
} }
private OSD JsonBuildRestOfSpec(LSL_List specifiers, int i, LSL_String val) private LSL_String JsonElementToString(LitJson.JsonData elem)
{ {
object spec = i >= specifiers.Data.Length ? null : specifiers.Data[i]; if(elem == null)
// 20131224 not used object specNext = i+1 >= specifiers.Data.Length ? null : specifiers.Data[i+1]; return ScriptBaseClass.JSON_NULL;
if (spec == null) LitJson.JsonType elemType = elem.GetJsonType();
return OSD.FromString(val); switch(elemType)
if (spec is LSL_Integer ||
(spec is LSL_String && ((LSL_String)spec) == ScriptBaseClass.JSON_APPEND))
{ {
OSDArray array = new OSDArray(); case LitJson.JsonType.Array:
array.Add(JsonBuildRestOfSpec(specifiers, i + 1, val)); return new LSL_String(LitJson.JsonMapper.ToJson(elem));
return array; case LitJson.JsonType.Boolean:
return new LSL_String((bool)elem ? ScriptBaseClass.JSON_TRUE : ScriptBaseClass.JSON_FALSE);
case LitJson.JsonType.Double:
double d= (double)elem;
string sd = String.Format(Culture.FormatProvider, "{0:0.0#####}",d);
return new LSL_String(sd);
case LitJson.JsonType.Int:
int i = (int)elem;
return new LSL_String(i.ToString());
case LitJson.JsonType.Long:
long l = (long)elem;
return new LSL_String(l.ToString());
case LitJson.JsonType.Object:
return new LSL_String(LitJson.JsonMapper.ToJson(elem));
case LitJson.JsonType.String:
string s = (string)elem;
return new LSL_String(s);
case LitJson.JsonType.None:
return ScriptBaseClass.JSON_NULL;
default:
return ScriptBaseClass.JSON_INVALID;
} }
else if (spec is LSL_String)
{
OSDMap map = new OSDMap();
map.Add((LSL_String)spec, JsonBuildRestOfSpec(specifiers, i + 1, val));
return map;
}
return new OSD();
} }
public LSL_String llJsonValueType(LSL_String json, LSL_List specifiers) public LSL_String llJsonValueType(LSL_String json, LSL_List specifiers)
{ {
OSD o = OSDParser.DeserializeJson(json); if(String.IsNullOrWhiteSpace(json))
OSD specVal = JsonGetSpecific(o, specifiers, 0);
if (specVal == null)
return ScriptBaseClass.JSON_INVALID; return ScriptBaseClass.JSON_INVALID;
switch (specVal.Type)
if(specifiers.Length > 0 && (json == "{}" || json == "[]"))
return ScriptBaseClass.JSON_INVALID;
char first = ((string)json)[0];
if((first != '[' && first !='{'))
{ {
case OSDType.Array: if(specifiers.Length > 0)
return ScriptBaseClass.JSON_ARRAY;
case OSDType.Boolean:
return specVal.AsBoolean() ? ScriptBaseClass.JSON_TRUE : ScriptBaseClass.JSON_FALSE;
case OSDType.Integer:
case OSDType.Real:
return ScriptBaseClass.JSON_NUMBER;
case OSDType.Map:
return ScriptBaseClass.JSON_OBJECT;
case OSDType.String:
case OSDType.UUID:
return ScriptBaseClass.JSON_STRING;
case OSDType.Unknown:
return ScriptBaseClass.JSON_NULL;
}
return ScriptBaseClass.JSON_INVALID; return ScriptBaseClass.JSON_INVALID;
json = "[" + json + "]"; // could handle single element case.. but easier like this
specifiers.Add((LSL_Integer)0);
}
LitJson.JsonData jsonData;
try
{
jsonData = LitJson.JsonMapper.ToObject(json);
}
catch (Exception e)
{
string m = e.Message; // debug point
return ScriptBaseClass.JSON_INVALID;
}
LitJson.JsonData elem = null;
if(specifiers.Length == 0)
elem = jsonData;
else
{
if(!JsonFind(jsonData, specifiers, 0, out elem))
return ScriptBaseClass.JSON_INVALID;
}
if(elem == null)
return ScriptBaseClass.JSON_NULL;
LitJson.JsonType elemType = elem.GetJsonType();
switch(elemType)
{
case LitJson.JsonType.Array:
return ScriptBaseClass.JSON_ARRAY;
case LitJson.JsonType.Boolean:
return (bool)elem ? ScriptBaseClass.JSON_TRUE : ScriptBaseClass.JSON_FALSE;
case LitJson.JsonType.Double:
case LitJson.JsonType.Int:
case LitJson.JsonType.Long:
return ScriptBaseClass.JSON_NUMBER;
case LitJson.JsonType.Object:
return ScriptBaseClass.JSON_OBJECT;
case LitJson.JsonType.String:
string s = (string)elem;
if(s == ScriptBaseClass.JSON_NULL)
return ScriptBaseClass.JSON_NULL;
if(s == ScriptBaseClass.JSON_TRUE)
return ScriptBaseClass.JSON_TRUE;
if(s == ScriptBaseClass.JSON_FALSE)
return ScriptBaseClass.JSON_FALSE;
return ScriptBaseClass.JSON_STRING;
case LitJson.JsonType.None:
return ScriptBaseClass.JSON_NULL;
default:
return ScriptBaseClass.JSON_INVALID;
}
} }
} }

View File

@ -29,6 +29,7 @@ using System;
using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
using LSLInteger = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; using LSLInteger = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
using LSLString = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
{ {
@ -834,15 +835,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
public const int KFM_CMD_STOP = 1; public const int KFM_CMD_STOP = 1;
public const int KFM_CMD_PAUSE = 2; public const int KFM_CMD_PAUSE = 2;
public const string JSON_ARRAY = "JSON_ARRAY"; public const string JSON_INVALID = "\uFDD0";
public const string JSON_OBJECT = "JSON_OBJECT"; public const string JSON_OBJECT = "\uFDD1";
public const string JSON_INVALID = "JSON_INVALID"; public const string JSON_ARRAY = "\uFDD2";
public const string JSON_NUMBER = "JSON_NUMBER"; public const string JSON_NUMBER = "\uFDD3";
public const string JSON_STRING = "JSON_STRING"; public const string JSON_STRING = "\uFDD4";
public const string JSON_TRUE = "JSON_TRUE"; public const string JSON_NULL = "\uFDD5";
public const string JSON_FALSE = "JSON_FALSE"; public const string JSON_TRUE = "\uFDD6";
public const string JSON_NULL = "JSON_NULL"; public const string JSON_FALSE = "\uFDD7";
public const string JSON_APPEND = "JSON_APPEND"; public const string JSON_DELETE = "\uFDD8";
public const string JSON_APPEND = "-1";
/// <summary> /// <summary>
/// process name parameter as regex /// process name parameter as regex