From c28430d52771ed6950e8482095a72ee8ef0c168d Mon Sep 17 00:00:00 2001
From: UbitUmarov
Date: Mon, 15 May 2017 18:12:17 +0100
Subject: oops...
---
OpenSim/Region/Framework/Scenes/Scene.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'OpenSim/Region')
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index e709d6c..439f79d 100755
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -5446,7 +5446,7 @@ Label_GroupsDone:
///
public void ForEachClient(Action action)
{
- m_clientManager.ForEachSync(action);
+ m_clientManager.ForEach(action);
}
public int GetNumberOfClients()
--
cgit v1.1
From ef358051767546d1ae991112c80135041222018a Mon Sep 17 00:00:00 2001
From: UbitUmarov
Date: Fri, 19 May 2017 03:08:35 +0100
Subject: reWrite lsl json functions, forward slash is not escaped as LitJson
spec; code can use some cleanup. Scripts need to be recompiled
---
.../Shared/Api/Implementation/LSL_Api.cs | 769 +++++++++++++++++----
.../Shared/Api/Runtime/LSL_Constants.cs | 20 +-
2 files changed, 650 insertions(+), 139 deletions(-)
(limited to 'OpenSim/Region')
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 2000c44..d5f2e78 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -28,6 +28,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
+using System.Collections.Specialized;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
@@ -40,7 +41,7 @@ using Nini.Config;
using log4net;
using OpenMetaverse;
using OpenMetaverse.Assets;
-using OpenMetaverse.StructuredData;
+using OpenMetaverse.StructuredData; // LitJson is hidden on this
using OpenMetaverse.Packets;
using OpenMetaverse.Rendering;
using OpenSim;
@@ -16700,92 +16701,158 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return String.Empty;
}
- public LSL_String llJsonGetValue(LSL_String json, LSL_List specifiers)
+ public LSL_List llJson2List(LSL_String json)
{
- OSD o = OSDParser.DeserializeJson(json);
- OSD specVal = JsonGetSpecific(o, specifiers, 0);
+ 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];
- return specVal.AsString();
- }
+ if(first != '[' && first !='{')
+ {
+ // we already have a single element
+ LSL_List l = new LSL_List();
+ l.Add(json);
+ return l;
+ }
- public LSL_List llJson2List(LSL_String json)
- {
+ LitJson.JsonData jsdata;
try
{
- OSD o = OSDParser.DeserializeJson(json);
- return (LSL_List)ParseJsonNode(o);
+ jsdata = LitJson.JsonMapper.ToObject(json);
}
- catch (Exception)
+ catch (Exception e)
+ {
+ string m = e.Message; // debug point
+ return json;
+ }
+ try
+ {
+ return JsonParseTop(jsdata);
+ }
+ catch (Exception e)
{
- return new LSL_List(ScriptBaseClass.JSON_INVALID);
+ 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)
- return new LSL_Integer(node.AsInteger());
- if (node.Type == OSDType.Boolean)
- return new LSL_Integer(node.AsBoolean() ? 1 : 0);
- if (node.Type == OSDType.Real)
- return new LSL_Float(node.AsReal());
- 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();
- OSDArray ar = node as OSDArray;
- foreach (OSD o in ar)
- resp.Add(ParseJsonNode(o));
- return resp;
+ LSL_List retl = new LSL_List();
+ if(elem == null)
+ retl.Add((LSL_String)ScriptBaseClass.JSON_NULL);
+
+ LitJson.JsonType elemType = elem.GetJsonType();
+ switch (elemType)
+ {
+ case LitJson.JsonType.Int:
+ retl.Add(new LSL_Integer((int)elem));
+ return retl;
+ case LitJson.JsonType.Boolean:
+ retl.Add((LSL_String)((bool)elem ? ScriptBaseClass.JSON_TRUE : ScriptBaseClass.JSON_FALSE));
+ return retl;
+ case LitJson.JsonType.Double:
+ retl.Add(new LSL_Float((float)elem));
+ return retl;
+ case LitJson.JsonType.None:
+ retl.Add((LSL_String)ScriptBaseClass.JSON_NULL);
+ return retl;
+ case LitJson.JsonType.String:
+ retl.Add(new LSL_String((string)elem));
+ return retl;
+ 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);
}
- if (node.Type == OSDType.Map)
+ }
+
+ private object JsonParseTopNodes(LitJson.JsonData elem)
+ {
+ if(elem == null)
+ return ((LSL_String)ScriptBaseClass.JSON_NULL);
+
+ LitJson.JsonType elemType = elem.GetJsonType();
+ switch (elemType)
{
- LSL_List resp = new LSL_List();
- OSDMap ar = node as OSDMap;
- foreach (KeyValuePair o in ar)
- {
- resp.Add(new LSL_String(o.Key));
- resp.Add(ParseJsonNode(o.Value));
- }
- return resp;
+ 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);
}
- throw new Exception(ScriptBaseClass.JSON_INVALID);
}
public LSL_String llList2Json(LSL_String type, LSL_List values)
{
try
{
+ StringBuilder sb = new StringBuilder();
if (type == ScriptBaseClass.JSON_ARRAY)
{
- OSDArray array = new OSDArray();
+ sb.Append("[");
+ int i= 0;
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)
{
- OSDMap map = new OSDMap();
+ sb.Append("{");
for (int i = 0; i < values.Data.Length; i += 2)
{
if (!(values.Data[i] is LSL_String))
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;
}
- 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)
{
@@ -16795,7 +16862,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
else
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)
{
@@ -16804,17 +16876,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
i = ((int)o);
else
i = ((LSL_Integer)o).value;
-
- if (i == 0)
- return OSD.FromBoolean(false);
- else if (i == 1)
- return OSD.FromBoolean(true);
- return OSD.FromInteger(i);
+ return i.ToString();
}
if (o is LSL_Rotation)
- return OSD.FromString(((LSL_Rotation)o).ToString());
+ return ((LSL_Rotation)o).ToString();
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)
{
string str;
@@ -16823,137 +16890,579 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
else
str = ((LSL_String)o).m_string;
- if (str == ScriptBaseClass.JSON_NULL)
- return new OSD();
- return OSD.FromString(str);
+ if(str == ScriptBaseClass.JSON_TRUE || str == "true")
+ return "true";
+ 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];
- OSD nextVal = null;
- if (o is OSDArray)
+ int i;
+ char c;
+ 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)
- nextVal = ((OSDArray)o)[((LSL_Integer)spec).value];
+ c = s[i];
+ 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));
+ }
+ else
+ {
+ sb.Append(c);
+ }
+ break;
+ }
+ }
+ if(AddOuter)
+ sb.Append("\"");
+ return sb.ToString();
+ }
+
+ public LSL_String llJsonSetValue(LSL_String json, LSL_List specifiers, LSL_String value)
+ {
+ bool noSpecifiers = specifiers.Length == 0;
+ LitJson.JsonData workData;
+ try
+ {
+ if(noSpecifiers)
+ specifiers.Add(new LSL_Integer(0));
+
+ if(!String.IsNullOrEmpty(json))
+ workData = LitJson.JsonMapper.ToObject(json);
+ else
+ {
+ workData = new LitJson.JsonData();
+ workData.SetJsonType(LitJson.JsonType.Array);
+ }
}
- if (o is OSDMap)
+ catch (Exception e)
{
- if (spec is LSL_String)
- nextVal = ((OSDMap)o)[((LSL_String)spec).m_string];
+ string m = e.Message; // debug point
+ return ScriptBaseClass.JSON_INVALID;
}
- if (nextVal != null)
+ try
{
- if (specifiers.Data.Length - 1 > i)
- return JsonGetSpecific(nextVal, specifiers, i + 1);
+ 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;
}
- return nextVal;
- }
- public LSL_String llJsonSetValue(LSL_String json, LSL_List specifiers, LSL_String value)
- {
try
{
- OSD o = OSDParser.DeserializeJson(json);
- JsonSetSpecific(o, specifiers, 0, value);
- return OSDParser.SerializeJsonString(o);
+ string r = LitJson.JsonMapper.ToJson(workData);
+ if(noSpecifiers)
+ r = r.Substring(1,r.Length -2); // strip leading and trailing brakets
+ return r;
}
- catch (Exception)
+ catch (Exception e)
{
+ string m = e.Message; // debug point
}
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];
- // 20131224 not used object specNext = i+1 == specifiers.Data.Length ? null : specifiers.Data[i+1];
- OSD nextVal = null;
- if (o is OSDArray)
+ object spec = specifiers.Data[level];
+ 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 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)
{
- OSDArray array = ((OSDArray)o);
- if (spec is LSL_Integer)
+ if (spec is int)
{
- int v = ((LSL_Integer)spec).value;
- if (v >= array.Count)
- array.Add(JsonBuildRestOfSpec(specifiers, i + 1, val));
+ 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
- nextVal = ((OSDArray)o)[v];
+ {
+ 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 (spec is LSL_String && ((LSL_String)spec) == ScriptBaseClass.JSON_APPEND)
- array.Add(JsonBuildRestOfSpec(specifiers, i + 1, val));
}
- if (o is OSDMap)
+ else if (elemType == LitJson.JsonType.Object)
{
- if (spec is LSL_String)
+ if (spec is string)
{
- OSDMap map = ((OSDMap)o);
- if (map.ContainsKey(((LSL_String)spec).m_string))
- nextVal = map[((LSL_String)spec).m_string];
+ IOrderedDictionary e = elem as IOrderedDictionary;
+ string key = (string)spec;
+ if(e.Contains(key))
+ {
+ hasvalue = true;
+ value = (LitJson.JsonData)e[key];
+ }
else
- map.Add(((LSL_String)spec).m_string, JsonBuildRestOfSpec(specifiers, i + 1, val));
+ 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 (nextVal != null)
+
+ if (hasvalue)
{
- if (specifiers.Data.Length - 1 > i)
+ if (level < speclen)
{
- JsonSetSpecific(nextVal, specifiers, i + 1, val);
- return;
+ 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 OSD JsonBuildRestOfSpec(LSL_List specifiers, int i, LSL_String val)
+ private LitJson.JsonData JsonBuildRestOfSpec(LSL_List specifiers, int level, LSL_String val)
{
- object spec = i >= specifiers.Data.Length ? null : specifiers.Data[i];
+ 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)
- return OSD.FromString(val);
+ {
+ 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_Integer ||
- (spec is LSL_String && ((LSL_String)spec) == ScriptBaseClass.JSON_APPEND))
+ 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) )
{
- OSDArray array = new OSDArray();
- array.Add(JsonBuildRestOfSpec(specifiers, i + 1, val));
- return array;
+ 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 LSL_String)
+ else if (spec is string)
{
- OSDMap map = new OSDMap();
- map.Add((LSL_String)spec, JsonBuildRestOfSpec(specifiers, i + 1, val));
- return map;
+ 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)
+ {
+ if (spec is LSL_Integer)
+ {
+ int indx = (LSL_Integer)spec;
+ if(indx >= 0 && indx < elem.Count)
+ {
+ haveVal = true;
+ next = (LitJson.JsonData)elem[indx];
+ }
+ }
+ }
+ else if (elem.GetJsonType() == LitJson.JsonType.Object)
+ {
+ if (spec is LSL_String)
+ {
+ IOrderedDictionary e = elem as IOrderedDictionary;
+ string key = (LSL_String)spec;
+ 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
+ {
+ if(!JsonFind(jsonData, specifiers, 0, out elem))
+ return ScriptBaseClass.JSON_INVALID;
+ }
+ return JsonElementToString(elem);
+ }
+
+ private LSL_String JsonElementToString(LitJson.JsonData elem)
+ {
+ if(elem == null)
+ return ScriptBaseClass.JSON_NULL;
+
+ LitJson.JsonType elemType = elem.GetJsonType();
+ switch(elemType)
+ {
+ case LitJson.JsonType.Array:
+ return new LSL_String(LitJson.JsonMapper.ToJson(elem));
+ 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;
}
- return new OSD();
}
public LSL_String llJsonValueType(LSL_String json, LSL_List specifiers)
{
- OSD o = OSDParser.DeserializeJson(json);
- OSD specVal = JsonGetSpecific(o, specifiers, 0);
- if (specVal == null)
+ if(String.IsNullOrWhiteSpace(json))
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 !='{'))
+ {
+ 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
{
- case OSDType.Array:
+ 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 OSDType.Boolean:
- return specVal.AsBoolean() ? ScriptBaseClass.JSON_TRUE : ScriptBaseClass.JSON_FALSE;
- case OSDType.Integer:
- case OSDType.Real:
+ 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 OSDType.Map:
+ case LitJson.JsonType.Object:
return ScriptBaseClass.JSON_OBJECT;
- case OSDType.String:
- case OSDType.UUID:
+ 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 OSDType.Unknown:
+ case LitJson.JsonType.None:
return ScriptBaseClass.JSON_NULL;
+ default:
+ return ScriptBaseClass.JSON_INVALID;
}
- return ScriptBaseClass.JSON_INVALID;
}
}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index ce0fa48..a277f6c 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -29,6 +29,7 @@ using System;
using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
using LSLInteger = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
+using LSLString = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
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_PAUSE = 2;
- public const string JSON_ARRAY = "JSON_ARRAY";
- public const string JSON_OBJECT = "JSON_OBJECT";
- public const string JSON_INVALID = "JSON_INVALID";
- public const string JSON_NUMBER = "JSON_NUMBER";
- public const string JSON_STRING = "JSON_STRING";
- public const string JSON_TRUE = "JSON_TRUE";
- public const string JSON_FALSE = "JSON_FALSE";
- public const string JSON_NULL = "JSON_NULL";
- public const string JSON_APPEND = "JSON_APPEND";
+ public const string JSON_INVALID = "\uFDD0";
+ public const string JSON_OBJECT = "\uFDD1";
+ public const string JSON_ARRAY = "\uFDD2";
+ public const string JSON_NUMBER = "\uFDD3";
+ public const string JSON_STRING = "\uFDD4";
+ public const string JSON_NULL = "\uFDD5";
+ public const string JSON_TRUE = "\uFDD6";
+ public const string JSON_FALSE = "\uFDD7";
+ public const string JSON_DELETE = "\uFDD8";
+ public const string JSON_APPEND = "-1";
///
/// process name parameter as regex
--
cgit v1.1