aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs769
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs20
2 files changed, 650 insertions, 139 deletions
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 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Collections.Specialized;
31using System.Diagnostics; 32using System.Diagnostics;
32using System.Drawing; 33using System.Drawing;
33using System.Drawing.Imaging; 34using System.Drawing.Imaging;
@@ -40,7 +41,7 @@ using Nini.Config;
40using log4net; 41using log4net;
41using OpenMetaverse; 42using OpenMetaverse;
42using OpenMetaverse.Assets; 43using OpenMetaverse.Assets;
43using OpenMetaverse.StructuredData; 44using OpenMetaverse.StructuredData; // LitJson is hidden on this
44using OpenMetaverse.Packets; 45using OpenMetaverse.Packets;
45using OpenMetaverse.Rendering; 46using OpenMetaverse.Rendering;
46using OpenSim; 47using OpenSim;
@@ -16700,92 +16701,158 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
16700 return String.Empty; 16701 return String.Empty;
16701 } 16702 }
16702 16703
16703 public LSL_String llJsonGetValue(LSL_String json, LSL_List specifiers) 16704 public LSL_List llJson2List(LSL_String json)
16704 { 16705 {
16705 OSD o = OSDParser.DeserializeJson(json); 16706 if(String.IsNullOrEmpty(json))
16706 OSD specVal = JsonGetSpecific(o, specifiers, 0); 16707 return new LSL_List();
16708 if(json == "[]")
16709 return new LSL_List();
16710 if(json == "{}")
16711 return new LSL_List();
16712 char first = ((string)json)[0];
16707 16713
16708 return specVal.AsString(); 16714 if(first != '[' && first !='{')
16709 } 16715 {
16716 // we already have a single element
16717 LSL_List l = new LSL_List();
16718 l.Add(json);
16719 return l;
16720 }
16710 16721
16711 public LSL_List llJson2List(LSL_String json) 16722 LitJson.JsonData jsdata;
16712 {
16713 try 16723 try
16714 { 16724 {
16715 OSD o = OSDParser.DeserializeJson(json); 16725 jsdata = LitJson.JsonMapper.ToObject(json);
16716 return (LSL_List)ParseJsonNode(o);
16717 } 16726 }
16718 catch (Exception) 16727 catch (Exception e)
16728 {
16729 string m = e.Message; // debug point
16730 return json;
16731 }
16732 try
16733 {
16734 return JsonParseTop(jsdata);
16735 }
16736 catch (Exception e)
16719 { 16737 {
16720 return new LSL_List(ScriptBaseClass.JSON_INVALID); 16738 string m = e.Message; // debug point
16739 return (LSL_String)ScriptBaseClass.JSON_INVALID;
16721 } 16740 }
16722 } 16741 }
16723 16742
16724 private object ParseJsonNode(OSD node) 16743 private LSL_List JsonParseTop(LitJson.JsonData elem)
16725 { 16744 {
16726 if (node.Type == OSDType.Integer) 16745 LSL_List retl = new LSL_List();
16727 return new LSL_Integer(node.AsInteger()); 16746 if(elem == null)
16728 if (node.Type == OSDType.Boolean) 16747 retl.Add((LSL_String)ScriptBaseClass.JSON_NULL);
16729 return new LSL_Integer(node.AsBoolean() ? 1 : 0); 16748
16730 if (node.Type == OSDType.Real) 16749 LitJson.JsonType elemType = elem.GetJsonType();
16731 return new LSL_Float(node.AsReal()); 16750 switch (elemType)
16732 if (node.Type == OSDType.UUID || node.Type == OSDType.String) 16751 {
16733 return new LSL_String(node.AsString()); 16752 case LitJson.JsonType.Int:
16734 if (node.Type == OSDType.Array) 16753 retl.Add(new LSL_Integer((int)elem));
16735 { 16754 return retl;
16736 LSL_List resp = new LSL_List(); 16755 case LitJson.JsonType.Boolean:
16737 OSDArray ar = node as OSDArray; 16756 retl.Add((LSL_String)((bool)elem ? ScriptBaseClass.JSON_TRUE : ScriptBaseClass.JSON_FALSE));
16738 foreach (OSD o in ar) 16757 return retl;
16739 resp.Add(ParseJsonNode(o)); 16758 case LitJson.JsonType.Double:
16740 return resp; 16759 retl.Add(new LSL_Float((float)elem));
16760 return retl;
16761 case LitJson.JsonType.None:
16762 retl.Add((LSL_String)ScriptBaseClass.JSON_NULL);
16763 return retl;
16764 case LitJson.JsonType.String:
16765 retl.Add(new LSL_String((string)elem));
16766 return retl;
16767 case LitJson.JsonType.Array:
16768 foreach (LitJson.JsonData subelem in elem)
16769 retl.Add(JsonParseTopNodes(subelem));
16770 return retl;
16771 case LitJson.JsonType.Object:
16772 IDictionaryEnumerator e = ((IOrderedDictionary)elem).GetEnumerator();
16773 while (e.MoveNext())
16774 {
16775 retl.Add(new LSL_String((string)e.Key));
16776 retl.Add(JsonParseTopNodes((LitJson.JsonData)e.Value));
16777 }
16778 return retl;
16779 default:
16780 throw new Exception(ScriptBaseClass.JSON_INVALID);
16741 } 16781 }
16742 if (node.Type == OSDType.Map) 16782 }
16783
16784 private object JsonParseTopNodes(LitJson.JsonData elem)
16785 {
16786 if(elem == null)
16787 return ((LSL_String)ScriptBaseClass.JSON_NULL);
16788
16789 LitJson.JsonType elemType = elem.GetJsonType();
16790 switch (elemType)
16743 { 16791 {
16744 LSL_List resp = new LSL_List(); 16792 case LitJson.JsonType.Int:
16745 OSDMap ar = node as OSDMap; 16793 return (new LSL_Integer((int)elem));
16746 foreach (KeyValuePair<string, OSD> o in ar) 16794 case LitJson.JsonType.Boolean:
16747 { 16795 return ((bool)elem ? (LSL_String)ScriptBaseClass.JSON_TRUE : (LSL_String)ScriptBaseClass.JSON_FALSE);
16748 resp.Add(new LSL_String(o.Key)); 16796 case LitJson.JsonType.Double:
16749 resp.Add(ParseJsonNode(o.Value)); 16797 return (new LSL_Float((float)elem));
16750 } 16798 case LitJson.JsonType.None:
16751 return resp; 16799 return ((LSL_String)ScriptBaseClass.JSON_NULL);
16800 case LitJson.JsonType.String:
16801 return (new LSL_String((string)elem));
16802 case LitJson.JsonType.Array:
16803 case LitJson.JsonType.Object:
16804 string s = LitJson.JsonMapper.ToJson(elem);
16805 return (LSL_String)s;
16806 default:
16807 throw new Exception(ScriptBaseClass.JSON_INVALID);
16752 } 16808 }
16753 throw new Exception(ScriptBaseClass.JSON_INVALID);
16754 } 16809 }
16755 16810
16756 public LSL_String llList2Json(LSL_String type, LSL_List values) 16811 public LSL_String llList2Json(LSL_String type, LSL_List values)
16757 { 16812 {
16758 try 16813 try
16759 { 16814 {
16815 StringBuilder sb = new StringBuilder();
16760 if (type == ScriptBaseClass.JSON_ARRAY) 16816 if (type == ScriptBaseClass.JSON_ARRAY)
16761 { 16817 {
16762 OSDArray array = new OSDArray(); 16818 sb.Append("[");
16819 int i= 0;
16763 foreach (object o in values.Data) 16820 foreach (object o in values.Data)
16764 { 16821 {
16765 array.Add(ListToJson(o)); 16822 sb.Append(ListToJson(o));
16823 if((i++) < values.Data.Length - 1)
16824 sb.Append(",");
16766 } 16825 }
16767 return OSDParser.SerializeJsonString(array); 16826 sb.Append("]");
16827 return (LSL_String)sb.ToString();;
16768 } 16828 }
16769 else if (type == ScriptBaseClass.JSON_OBJECT) 16829 else if (type == ScriptBaseClass.JSON_OBJECT)
16770 { 16830 {
16771 OSDMap map = new OSDMap(); 16831 sb.Append("{");
16772 for (int i = 0; i < values.Data.Length; i += 2) 16832 for (int i = 0; i < values.Data.Length; i += 2)
16773 { 16833 {
16774 if (!(values.Data[i] is LSL_String)) 16834 if (!(values.Data[i] is LSL_String))
16775 return ScriptBaseClass.JSON_INVALID; 16835 return ScriptBaseClass.JSON_INVALID;
16776 map.Add(((LSL_String)values.Data[i]).m_string, ListToJson(values.Data[i + 1])); 16836 string key = ((LSL_String)values.Data[i]).m_string;
16837 key = EscapeForJSON(key, true);
16838 sb.Append(key);
16839 sb.Append(":");
16840 sb.Append(ListToJson(values.Data[i+1]));
16841 if(i < values.Data.Length - 2)
16842 sb.Append(",");
16777 } 16843 }
16778 return OSDParser.SerializeJsonString(map); 16844 sb.Append("}");
16845 return (LSL_String)sb.ToString();
16779 } 16846 }
16780 return ScriptBaseClass.JSON_INVALID; 16847 return ScriptBaseClass.JSON_INVALID;
16781 } 16848 }
16782 catch (Exception ex) 16849 catch
16783 { 16850 {
16784 return ex.Message; 16851 return ScriptBaseClass.JSON_INVALID;
16785 } 16852 }
16786 } 16853 }
16787 16854
16788 private OSD ListToJson(object o) 16855 private string ListToJson(object o)
16789 { 16856 {
16790 if (o is LSL_Float || o is double) 16857 if (o is LSL_Float || o is double)
16791 { 16858 {
@@ -16795,7 +16862,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
16795 else 16862 else
16796 float_val = ((LSL_Float)o).value; 16863 float_val = ((LSL_Float)o).value;
16797 16864
16798 return OSD.FromReal(float_val); 16865 if(double.IsInfinity(float_val))
16866 return "\"Inf\"";
16867 if(double.IsNaN(float_val))
16868 return "\"NaN\"";
16869
16870 return ((LSL_Float)float_val).ToString();
16799 } 16871 }
16800 if (o is LSL_Integer || o is int) 16872 if (o is LSL_Integer || o is int)
16801 { 16873 {
@@ -16804,17 +16876,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
16804 i = ((int)o); 16876 i = ((int)o);
16805 else 16877 else
16806 i = ((LSL_Integer)o).value; 16878 i = ((LSL_Integer)o).value;
16807 16879 return i.ToString();
16808 if (i == 0)
16809 return OSD.FromBoolean(false);
16810 else if (i == 1)
16811 return OSD.FromBoolean(true);
16812 return OSD.FromInteger(i);
16813 } 16880 }
16814 if (o is LSL_Rotation) 16881 if (o is LSL_Rotation)
16815 return OSD.FromString(((LSL_Rotation)o).ToString()); 16882 return ((LSL_Rotation)o).ToString();
16816 if (o is LSL_Vector) 16883 if (o is LSL_Vector)
16817 return OSD.FromString(((LSL_Vector)o).ToString()); 16884 return ((LSL_Vector)o).ToString();
16818 if (o is LSL_String || o is string) 16885 if (o is LSL_String || o is string)
16819 { 16886 {
16820 string str; 16887 string str;
@@ -16823,137 +16890,579 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
16823 else 16890 else
16824 str = ((LSL_String)o).m_string; 16891 str = ((LSL_String)o).m_string;
16825 16892
16826 if (str == ScriptBaseClass.JSON_NULL) 16893 if(str == ScriptBaseClass.JSON_TRUE || str == "true")
16827 return new OSD(); 16894 return "true";
16828 return OSD.FromString(str); 16895 if(str == ScriptBaseClass.JSON_FALSE ||str == "false")
16896 return "false";
16897 if(str == ScriptBaseClass.JSON_NULL || str == "null")
16898 return "null";
16899 str.Trim();
16900 if (str[0] == '{')
16901 return str;
16902 if (str[0] == '[')
16903 return str;
16904 return EscapeForJSON(str, true);
16829 } 16905 }
16830 throw new Exception(ScriptBaseClass.JSON_INVALID); 16906 throw new IndexOutOfRangeException();
16831 } 16907 }
16832 16908
16833 private OSD JsonGetSpecific(OSD o, LSL_List specifiers, int i) 16909 private string EscapeForJSON(string s, bool AddOuter)
16834 { 16910 {
16835 object spec = specifiers.Data[i]; 16911 int i;
16836 OSD nextVal = null; 16912 char c;
16837 if (o is OSDArray) 16913 String t;
16914 int len = s.Length;
16915
16916 StringBuilder sb = new StringBuilder(len + 64);
16917 if(AddOuter)
16918 sb.Append("\"");
16919
16920 for (i = 0; i < len; i++)
16838 { 16921 {
16839 if (spec is LSL_Integer) 16922 c = s[i];
16840 nextVal = ((OSDArray)o)[((LSL_Integer)spec).value]; 16923 switch (c)
16924 {
16925 case '\\':
16926 case '"':
16927 case '/':
16928 sb.Append('\\');
16929 sb.Append(c);
16930 break;
16931 case '\b':
16932 sb.Append("\\b");
16933 break;
16934 case '\t':
16935 sb.Append("\\t");
16936 break;
16937 case '\n':
16938 sb.Append("\\n");
16939 break;
16940 case '\f':
16941 sb.Append("\\f");
16942 break;
16943 case '\r':
16944 sb.Append("\\r");
16945 break;
16946 default:
16947 if (c < ' ')
16948 {
16949 t = "000" + String.Format("X", c);
16950 sb.Append("\\u" + t.Substring(t.Length - 4));
16951 }
16952 else
16953 {
16954 sb.Append(c);
16955 }
16956 break;
16957 }
16958 }
16959 if(AddOuter)
16960 sb.Append("\"");
16961 return sb.ToString();
16962 }
16963
16964 public LSL_String llJsonSetValue(LSL_String json, LSL_List specifiers, LSL_String value)
16965 {
16966 bool noSpecifiers = specifiers.Length == 0;
16967 LitJson.JsonData workData;
16968 try
16969 {
16970 if(noSpecifiers)
16971 specifiers.Add(new LSL_Integer(0));
16972
16973 if(!String.IsNullOrEmpty(json))
16974 workData = LitJson.JsonMapper.ToObject(json);
16975 else
16976 {
16977 workData = new LitJson.JsonData();
16978 workData.SetJsonType(LitJson.JsonType.Array);
16979 }
16841 } 16980 }
16842 if (o is OSDMap) 16981 catch (Exception e)
16843 { 16982 {
16844 if (spec is LSL_String) 16983 string m = e.Message; // debug point
16845 nextVal = ((OSDMap)o)[((LSL_String)spec).m_string]; 16984 return ScriptBaseClass.JSON_INVALID;
16846 } 16985 }
16847 if (nextVal != null) 16986 try
16848 { 16987 {
16849 if (specifiers.Data.Length - 1 > i) 16988 LitJson.JsonData replace = JsonSetSpecific(workData, specifiers, 0, value);
16850 return JsonGetSpecific(nextVal, specifiers, i + 1); 16989 if(replace != null)
16990 workData = replace;
16991 }
16992 catch (Exception e)
16993 {
16994 string m = e.Message; // debug point
16995 return ScriptBaseClass.JSON_INVALID;
16851 } 16996 }
16852 return nextVal;
16853 }
16854 16997
16855 public LSL_String llJsonSetValue(LSL_String json, LSL_List specifiers, LSL_String value)
16856 {
16857 try 16998 try
16858 { 16999 {
16859 OSD o = OSDParser.DeserializeJson(json); 17000 string r = LitJson.JsonMapper.ToJson(workData);
16860 JsonSetSpecific(o, specifiers, 0, value); 17001 if(noSpecifiers)
16861 return OSDParser.SerializeJsonString(o); 17002 r = r.Substring(1,r.Length -2); // strip leading and trailing brakets
17003 return r;
16862 } 17004 }
16863 catch (Exception) 17005 catch (Exception e)
16864 { 17006 {
17007 string m = e.Message; // debug point
16865 } 17008 }
16866 return ScriptBaseClass.JSON_INVALID; 17009 return ScriptBaseClass.JSON_INVALID;
16867 } 17010 }
16868 17011
16869 private void JsonSetSpecific(OSD o, LSL_List specifiers, int i, LSL_String val) 17012 private LitJson.JsonData JsonSetSpecific(LitJson.JsonData elem, LSL_List specifiers, int level, LSL_String val)
16870 { 17013 {
16871 object spec = specifiers.Data[i]; 17014 object spec = specifiers.Data[level];
16872 // 20131224 not used object specNext = i+1 == specifiers.Data.Length ? null : specifiers.Data[i+1]; 17015 if(spec is LSL_String)
16873 OSD nextVal = null; 17016 spec = ((LSL_String)spec).m_string;
16874 if (o is OSDArray) 17017 else if (spec is LSL_Integer)
17018 spec = ((LSL_Integer)spec).value;
17019
17020 if(!(spec is string || spec is int))
17021 throw new IndexOutOfRangeException();
17022
17023 int speclen = specifiers.Data.Length - 1;
17024
17025 bool hasvalue = false;
17026 LitJson.JsonData value = null;
17027
17028 LitJson.JsonType elemType = elem.GetJsonType();
17029 if (elemType == LitJson.JsonType.Array)
16875 { 17030 {
16876 OSDArray array = ((OSDArray)o); 17031 if (spec is int)
16877 if (spec is LSL_Integer)
16878 { 17032 {
16879 int v = ((LSL_Integer)spec).value; 17033 int v = (int)spec;
16880 if (v >= array.Count) 17034 int c = elem.Count;
16881 array.Add(JsonBuildRestOfSpec(specifiers, i + 1, val)); 17035 if(v < 0 || (v != 0 && v > c))
17036 throw new IndexOutOfRangeException();
17037 if(v == c)
17038 elem.Add(JsonBuildRestOfSpec(specifiers, level + 1, val));
16882 else 17039 else
16883 nextVal = ((OSDArray)o)[v]; 17040 {
17041 hasvalue = true;
17042 value = elem[v];
17043 }
17044 }
17045 else if (spec is string)
17046 {
17047 if((string)spec == ScriptBaseClass.JSON_APPEND)
17048 elem.Add(JsonBuildRestOfSpec(specifiers, level + 1, val));
17049 else if(elem.Count < 2)
17050 {
17051 // our initial guess of array was wrong
17052 LitJson.JsonData newdata = new LitJson.JsonData();
17053 newdata.SetJsonType(LitJson.JsonType.Object);
17054 IOrderedDictionary no = newdata as IOrderedDictionary;
17055 no.Add((string)spec,JsonBuildRestOfSpec(specifiers, level + 1, val));
17056 return newdata;
17057 }
16884 } 17058 }
16885 else if (spec is LSL_String && ((LSL_String)spec) == ScriptBaseClass.JSON_APPEND)
16886 array.Add(JsonBuildRestOfSpec(specifiers, i + 1, val));
16887 } 17059 }
16888 if (o is OSDMap) 17060 else if (elemType == LitJson.JsonType.Object)
16889 { 17061 {
16890 if (spec is LSL_String) 17062 if (spec is string)
16891 { 17063 {
16892 OSDMap map = ((OSDMap)o); 17064 IOrderedDictionary e = elem as IOrderedDictionary;
16893 if (map.ContainsKey(((LSL_String)spec).m_string)) 17065 string key = (string)spec;
16894 nextVal = map[((LSL_String)spec).m_string]; 17066 if(e.Contains(key))
17067 {
17068 hasvalue = true;
17069 value = (LitJson.JsonData)e[key];
17070 }
16895 else 17071 else
16896 map.Add(((LSL_String)spec).m_string, JsonBuildRestOfSpec(specifiers, i + 1, val)); 17072 e.Add(key, JsonBuildRestOfSpec(specifiers, level + 1, val));
16897 } 17073 }
17074 else if(spec is int && (int)spec == 0)
17075 {
17076 //we are replacing a object by a array
17077 LitJson.JsonData newData = new LitJson.JsonData();
17078 newData.SetJsonType(LitJson.JsonType.Array);
17079 newData.Add(JsonBuildRestOfSpec(specifiers, level + 1, val));
17080 return newData;
17081 }
17082 }
17083 else
17084 {
17085 LitJson.JsonData newData = JsonBuildRestOfSpec(specifiers, level, val);
17086 return newData;
16898 } 17087 }
16899 if (nextVal != null) 17088
17089 if (hasvalue)
16900 { 17090 {
16901 if (specifiers.Data.Length - 1 > i) 17091 if (level < speclen)
16902 { 17092 {
16903 JsonSetSpecific(nextVal, specifiers, i + 1, val); 17093 LitJson.JsonData replace = JsonSetSpecific(value, specifiers, level + 1, val);
16904 return; 17094 if(replace != null)
17095 {
17096 if(elemType == LitJson.JsonType.Array)
17097 {
17098 if(spec is int)
17099 elem[(int)spec] = replace;
17100 else if( spec is string)
17101 {
17102 LitJson.JsonData newdata = new LitJson.JsonData();
17103 newdata.SetJsonType(LitJson.JsonType.Object);
17104 IOrderedDictionary no = newdata as IOrderedDictionary;
17105 no.Add((string)spec, replace);
17106 return newdata;
17107 }
17108 }
17109 else if(elemType == LitJson.JsonType.Object)
17110 {
17111 if(spec is string)
17112 elem[(string)spec] = replace;
17113 else if(spec is int && (int)spec == 0)
17114 {
17115 LitJson.JsonData newdata = new LitJson.JsonData();
17116 newdata.SetJsonType(LitJson.JsonType.Array);
17117 newdata.Add(replace);
17118 return newdata;
17119 }
17120 }
17121 }
17122 return null;
17123 }
17124 else if(speclen == level)
17125 {
17126 if(val == ScriptBaseClass.JSON_DELETE)
17127 {
17128 if(elemType == LitJson.JsonType.Array)
17129 {
17130 if(spec is int)
17131 {
17132 IList el = elem as IList;
17133 el.RemoveAt((int)spec);
17134 }
17135 }
17136 else if(elemType == LitJson.JsonType.Object)
17137 {
17138 if(spec is string)
17139 {
17140 IOrderedDictionary eo = elem as IOrderedDictionary;
17141 eo.Remove((string) spec);
17142 }
17143 }
17144 return null;
17145 }
17146
17147 LitJson.JsonData newval = null;
17148 float num;
17149 if(val == null || val == ScriptBaseClass.JSON_NULL || val == "null")
17150 newval = null;
17151 else if(val == ScriptBaseClass.JSON_TRUE || val == "true")
17152 newval = new LitJson.JsonData(true);
17153 else if(val == ScriptBaseClass.JSON_FALSE || val == "false")
17154 newval = new LitJson.JsonData(false);
17155 else if(float.TryParse(val, out num))
17156 {
17157 // assuming we are at en.us already
17158 if(num - (int)num == 0.0f && !val.Contains("."))
17159 newval = new LitJson.JsonData((int)num);
17160 else
17161 {
17162 num = (float)Math.Round(num,6);
17163 newval = new LitJson.JsonData((double)num);
17164 }
17165 }
17166 else
17167 {
17168 string str = val.m_string;
17169 newval = new LitJson.JsonData(str);
17170 }
17171
17172 if(elemType == LitJson.JsonType.Array)
17173 {
17174 if(spec is int)
17175 elem[(int)spec] = newval;
17176 else if( spec is string)
17177 {
17178 LitJson.JsonData newdata = new LitJson.JsonData();
17179 newdata.SetJsonType(LitJson.JsonType.Object);
17180 IOrderedDictionary no = newdata as IOrderedDictionary;
17181 no.Add((string)spec,newval);
17182 return newdata;
17183 }
17184 }
17185 else if(elemType == LitJson.JsonType.Object)
17186 {
17187 if(spec is string)
17188 elem[(string)spec] = newval;
17189 else if(spec is int && (int)spec == 0)
17190 {
17191 LitJson.JsonData newdata = new LitJson.JsonData();
17192 newdata.SetJsonType(LitJson.JsonType.Array);
17193 newdata.Add(newval);
17194 return newdata;
17195 }
17196 }
16905 } 17197 }
16906 } 17198 }
17199 if(val == ScriptBaseClass.JSON_DELETE)
17200 throw new IndexOutOfRangeException();
17201 return null;
16907 } 17202 }
16908 17203
16909 private OSD JsonBuildRestOfSpec(LSL_List specifiers, int i, LSL_String val) 17204 private LitJson.JsonData JsonBuildRestOfSpec(LSL_List specifiers, int level, LSL_String val)
16910 { 17205 {
16911 object spec = i >= specifiers.Data.Length ? null : specifiers.Data[i]; 17206 object spec = level >= specifiers.Data.Length ? null : specifiers.Data[level];
16912 // 20131224 not used object specNext = i+1 >= specifiers.Data.Length ? null : specifiers.Data[i+1]; 17207 // 20131224 not used object specNext = i+1 >= specifiers.Data.Length ? null : specifiers.Data[i+1];
16913 17208
17209 float num;
16914 if (spec == null) 17210 if (spec == null)
16915 return OSD.FromString(val); 17211 {
17212 if(val == null || val == ScriptBaseClass.JSON_NULL || val == "null")
17213 return null;
17214 if(val == ScriptBaseClass.JSON_DELETE)
17215 throw new IndexOutOfRangeException();
17216 if(val == ScriptBaseClass.JSON_TRUE || val == "true")
17217 return new LitJson.JsonData(true);
17218 if(val == ScriptBaseClass.JSON_FALSE || val == "false")
17219 return new LitJson.JsonData(false);
17220 if(val == null || val == ScriptBaseClass.JSON_NULL || val == "null")
17221 return null;
17222 if(float.TryParse(val, out num))
17223 {
17224 // assuming we are at en.us already
17225 if(num - (int)num == 0.0f && !val.Contains("."))
17226 return new LitJson.JsonData((int)num);
17227 else
17228 {
17229 num = (float)Math.Round(num,6);
17230 return new LitJson.JsonData(num);
17231 }
17232 }
17233 else
17234 {
17235 string str = val.m_string;
17236 return new LitJson.JsonData(str);
17237 }
17238 throw new IndexOutOfRangeException();
17239 }
16916 17240
16917 if (spec is LSL_Integer || 17241 if(spec is LSL_String)
16918 (spec is LSL_String && ((LSL_String)spec) == ScriptBaseClass.JSON_APPEND)) 17242 spec = ((LSL_String)spec).m_string;
17243 else if (spec is LSL_Integer)
17244 spec = ((LSL_Integer)spec).value;
17245
17246 if (spec is int ||
17247 (spec is string && ((string)spec) == ScriptBaseClass.JSON_APPEND) )
16919 { 17248 {
16920 OSDArray array = new OSDArray(); 17249 if(spec is int && (int)spec != 0)
16921 array.Add(JsonBuildRestOfSpec(specifiers, i + 1, val)); 17250 throw new IndexOutOfRangeException();
16922 return array; 17251 LitJson.JsonData newdata = new LitJson.JsonData();
17252 newdata.SetJsonType(LitJson.JsonType.Array);
17253 newdata.Add(JsonBuildRestOfSpec(specifiers, level + 1, val));
17254 return newdata;
16923 } 17255 }
16924 else if (spec is LSL_String) 17256 else if (spec is string)
16925 { 17257 {
16926 OSDMap map = new OSDMap(); 17258 LitJson.JsonData newdata = new LitJson.JsonData();
16927 map.Add((LSL_String)spec, JsonBuildRestOfSpec(specifiers, i + 1, val)); 17259 newdata.SetJsonType(LitJson.JsonType.Object);
16928 return map; 17260 IOrderedDictionary no = newdata as IOrderedDictionary;
17261 no.Add((string)spec,JsonBuildRestOfSpec(specifiers, level + 1, val));
17262 return newdata;
17263 }
17264 throw new IndexOutOfRangeException();
17265 }
17266
17267 private bool JsonFind(LitJson.JsonData elem, LSL_List specifiers, int level, out LitJson.JsonData value)
17268 {
17269 value = null;
17270 if(elem == null)
17271 return false;
17272
17273 object spec;
17274 spec = specifiers.Data[level];
17275
17276 bool haveVal = false;
17277 LitJson.JsonData next = null;
17278
17279 if (elem.GetJsonType() == LitJson.JsonType.Array)
17280 {
17281 if (spec is LSL_Integer)
17282 {
17283 int indx = (LSL_Integer)spec;
17284 if(indx >= 0 && indx < elem.Count)
17285 {
17286 haveVal = true;
17287 next = (LitJson.JsonData)elem[indx];
17288 }
17289 }
17290 }
17291 else if (elem.GetJsonType() == LitJson.JsonType.Object)
17292 {
17293 if (spec is LSL_String)
17294 {
17295 IOrderedDictionary e = elem as IOrderedDictionary;
17296 string key = (LSL_String)spec;
17297 if(e.Contains(key))
17298 {
17299 haveVal = true;
17300 next = (LitJson.JsonData)e[key];
17301 }
17302 }
17303 }
17304
17305 if (haveVal)
17306 {
17307 if(level == specifiers.Data.Length - 1)
17308 {
17309 value = next;
17310 return true;
17311 }
17312
17313 level++;
17314 if(next == null)
17315 return false;
17316
17317 LitJson.JsonType nextType = next.GetJsonType();
17318 if(nextType != LitJson.JsonType.Object && nextType != LitJson.JsonType.Array)
17319 return false;
17320
17321 return JsonFind(next, specifiers, level, out value);
17322 }
17323 return false;
17324 }
17325
17326 public LSL_String llJsonGetValue(LSL_String json, LSL_List specifiers)
17327 {
17328 if(String.IsNullOrWhiteSpace(json))
17329 return ScriptBaseClass.JSON_INVALID;
17330
17331 if(specifiers.Length > 0 && (json == "{}" || json == "[]"))
17332 return ScriptBaseClass.JSON_INVALID;
17333
17334 char first = ((string)json)[0];
17335 if((first != '[' && first !='{'))
17336 {
17337 if(specifiers.Length > 0)
17338 return ScriptBaseClass.JSON_INVALID;
17339 json = "[" + json + "]"; // could handle single element case.. but easier like this
17340 specifiers.Add((LSL_Integer)0);
17341 }
17342
17343 LitJson.JsonData jsonData;
17344 try
17345 {
17346 jsonData = LitJson.JsonMapper.ToObject(json);
17347 }
17348 catch (Exception e)
17349 {
17350 string m = e.Message; // debug point
17351 return ScriptBaseClass.JSON_INVALID;
17352 }
17353
17354 LitJson.JsonData elem = null;
17355 if(specifiers.Length == 0)
17356 elem = jsonData;
17357 else
17358 {
17359 if(!JsonFind(jsonData, specifiers, 0, out elem))
17360 return ScriptBaseClass.JSON_INVALID;
17361 }
17362 return JsonElementToString(elem);
17363 }
17364
17365 private LSL_String JsonElementToString(LitJson.JsonData elem)
17366 {
17367 if(elem == null)
17368 return ScriptBaseClass.JSON_NULL;
17369
17370 LitJson.JsonType elemType = elem.GetJsonType();
17371 switch(elemType)
17372 {
17373 case LitJson.JsonType.Array:
17374 return new LSL_String(LitJson.JsonMapper.ToJson(elem));
17375 case LitJson.JsonType.Boolean:
17376 return new LSL_String((bool)elem ? ScriptBaseClass.JSON_TRUE : ScriptBaseClass.JSON_FALSE);
17377 case LitJson.JsonType.Double:
17378 double d= (double)elem;
17379 string sd = String.Format(Culture.FormatProvider, "{0:0.0#####}",d);
17380 return new LSL_String(sd);
17381 case LitJson.JsonType.Int:
17382 int i = (int)elem;
17383 return new LSL_String(i.ToString());
17384 case LitJson.JsonType.Long:
17385 long l = (long)elem;
17386 return new LSL_String(l.ToString());
17387 case LitJson.JsonType.Object:
17388 return new LSL_String(LitJson.JsonMapper.ToJson(elem));
17389 case LitJson.JsonType.String:
17390 string s = (string)elem;
17391 return new LSL_String(s);
17392 case LitJson.JsonType.None:
17393 return ScriptBaseClass.JSON_NULL;
17394 default:
17395 return ScriptBaseClass.JSON_INVALID;
16929 } 17396 }
16930 return new OSD();
16931 } 17397 }
16932 17398
16933 public LSL_String llJsonValueType(LSL_String json, LSL_List specifiers) 17399 public LSL_String llJsonValueType(LSL_String json, LSL_List specifiers)
16934 { 17400 {
16935 OSD o = OSDParser.DeserializeJson(json); 17401 if(String.IsNullOrWhiteSpace(json))
16936 OSD specVal = JsonGetSpecific(o, specifiers, 0);
16937 if (specVal == null)
16938 return ScriptBaseClass.JSON_INVALID; 17402 return ScriptBaseClass.JSON_INVALID;
16939 switch (specVal.Type) 17403
17404 if(specifiers.Length > 0 && (json == "{}" || json == "[]"))
17405 return ScriptBaseClass.JSON_INVALID;
17406
17407 char first = ((string)json)[0];
17408 if((first != '[' && first !='{'))
17409 {
17410 if(specifiers.Length > 0)
17411 return ScriptBaseClass.JSON_INVALID;
17412 json = "[" + json + "]"; // could handle single element case.. but easier like this
17413 specifiers.Add((LSL_Integer)0);
17414 }
17415
17416 LitJson.JsonData jsonData;
17417 try
16940 { 17418 {
16941 case OSDType.Array: 17419 jsonData = LitJson.JsonMapper.ToObject(json);
17420 }
17421 catch (Exception e)
17422 {
17423 string m = e.Message; // debug point
17424 return ScriptBaseClass.JSON_INVALID;
17425 }
17426
17427 LitJson.JsonData elem = null;
17428 if(specifiers.Length == 0)
17429 elem = jsonData;
17430 else
17431 {
17432 if(!JsonFind(jsonData, specifiers, 0, out elem))
17433 return ScriptBaseClass.JSON_INVALID;
17434 }
17435
17436 if(elem == null)
17437 return ScriptBaseClass.JSON_NULL;
17438
17439 LitJson.JsonType elemType = elem.GetJsonType();
17440 switch(elemType)
17441 {
17442 case LitJson.JsonType.Array:
16942 return ScriptBaseClass.JSON_ARRAY; 17443 return ScriptBaseClass.JSON_ARRAY;
16943 case OSDType.Boolean: 17444 case LitJson.JsonType.Boolean:
16944 return specVal.AsBoolean() ? ScriptBaseClass.JSON_TRUE : ScriptBaseClass.JSON_FALSE; 17445 return (bool)elem ? ScriptBaseClass.JSON_TRUE : ScriptBaseClass.JSON_FALSE;
16945 case OSDType.Integer: 17446 case LitJson.JsonType.Double:
16946 case OSDType.Real: 17447 case LitJson.JsonType.Int:
17448 case LitJson.JsonType.Long:
16947 return ScriptBaseClass.JSON_NUMBER; 17449 return ScriptBaseClass.JSON_NUMBER;
16948 case OSDType.Map: 17450 case LitJson.JsonType.Object:
16949 return ScriptBaseClass.JSON_OBJECT; 17451 return ScriptBaseClass.JSON_OBJECT;
16950 case OSDType.String: 17452 case LitJson.JsonType.String:
16951 case OSDType.UUID: 17453 string s = (string)elem;
17454 if(s == ScriptBaseClass.JSON_NULL)
17455 return ScriptBaseClass.JSON_NULL;
17456 if(s == ScriptBaseClass.JSON_TRUE)
17457 return ScriptBaseClass.JSON_TRUE;
17458 if(s == ScriptBaseClass.JSON_FALSE)
17459 return ScriptBaseClass.JSON_FALSE;
16952 return ScriptBaseClass.JSON_STRING; 17460 return ScriptBaseClass.JSON_STRING;
16953 case OSDType.Unknown: 17461 case LitJson.JsonType.None:
16954 return ScriptBaseClass.JSON_NULL; 17462 return ScriptBaseClass.JSON_NULL;
17463 default:
17464 return ScriptBaseClass.JSON_INVALID;
16955 } 17465 }
16956 return ScriptBaseClass.JSON_INVALID;
16957 } 17466 }
16958 } 17467 }
16959 17468
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;
29using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 29using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
30using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; 30using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
31using LSLInteger = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; 31using LSLInteger = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
32using LSLString = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
32 33
33namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase 34namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
34{ 35{
@@ -834,15 +835,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
834 public const int KFM_CMD_STOP = 1; 835 public const int KFM_CMD_STOP = 1;
835 public const int KFM_CMD_PAUSE = 2; 836 public const int KFM_CMD_PAUSE = 2;
836 837
837 public const string JSON_ARRAY = "JSON_ARRAY"; 838 public const string JSON_INVALID = "\uFDD0";
838 public const string JSON_OBJECT = "JSON_OBJECT"; 839 public const string JSON_OBJECT = "\uFDD1";
839 public const string JSON_INVALID = "JSON_INVALID"; 840 public const string JSON_ARRAY = "\uFDD2";
840 public const string JSON_NUMBER = "JSON_NUMBER"; 841 public const string JSON_NUMBER = "\uFDD3";
841 public const string JSON_STRING = "JSON_STRING"; 842 public const string JSON_STRING = "\uFDD4";
842 public const string JSON_TRUE = "JSON_TRUE"; 843 public const string JSON_NULL = "\uFDD5";
843 public const string JSON_FALSE = "JSON_FALSE"; 844 public const string JSON_TRUE = "\uFDD6";
844 public const string JSON_NULL = "JSON_NULL"; 845 public const string JSON_FALSE = "\uFDD7";
845 public const string JSON_APPEND = "JSON_APPEND"; 846 public const string JSON_DELETE = "\uFDD8";
847 public const string JSON_APPEND = "-1";
846 848
847 /// <summary> 849 /// <summary>
848 /// process name parameter as regex 850 /// process name parameter as regex