OpenSimMirror/OpenSim/Capabilities/LLSDHelpers.cs

203 lines
9.9 KiB
C#

/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections;
using System.IO;
using System.Reflection;
using System.Xml;
using OpenMetaverse;
namespace OpenSim.Framework.Capabilities
{
public class LLSDHelpers
{
// private static readonly log4net.ILog m_log
// = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public static string SerialiseLLSDReply(object obj)
{
StringWriter sw = new StringWriter();
XmlTextWriter writer = new XmlTextWriter(sw);
writer.Formatting = Formatting.None;
writer.WriteStartElement(String.Empty, "llsd", String.Empty);
SerializeOSDType(writer, obj);
writer.WriteEndElement();
writer.Close();
//m_log.DebugFormat("[LLSD Helpers]: Generated serialized LLSD reply {0}", sw.ToString());
return sw.ToString();
}
public static string SerialiseLLSDReplyNoHeader(object obj)
{
StringWriter sw = new StringWriter();
XmlTextWriter writer = new XmlTextWriter(sw);
writer.Formatting = Formatting.None;
SerializeOSDType(writer, obj);
writer.Close();
//m_log.DebugFormat("[LLSD Helpers]: Generated serialized LLSD reply {0}", sw.ToString());
return sw.ToString();
}
private static void SerializeOSDType(XmlTextWriter writer, object obj)
{
Type myType = obj.GetType();
LLSDType[] llsdattributes = (LLSDType[]) myType.GetCustomAttributes(typeof (LLSDType), false);
if (llsdattributes.Length > 0)
{
switch (llsdattributes[0].ObjectType)
{
case "MAP":
writer.WriteStartElement(String.Empty, "map", String.Empty);
FieldInfo[] fields = myType.GetFields();
for (int i = 0; i < fields.Length; i++)
{
if (fields[i] != null && fields[i].GetValue(obj) != null)
{
object fieldValue = fields[i].GetValue(obj);
LLSDType[] fieldAttributes =
(LLSDType[]) fieldValue.GetType().GetCustomAttributes(typeof (LLSDType), false);
if (fieldAttributes.Length > 0)
{
writer.WriteStartElement(String.Empty, "key", String.Empty);
string fieldName = fields[i].Name;
fieldName = fieldName.Replace("___", "-");
writer.WriteString(fieldName);
writer.WriteEndElement();
SerializeOSDType(writer, fieldValue);
}
else
{
writer.WriteStartElement(String.Empty, "key", String.Empty);
string fieldName = fields[i].Name;
fieldName = fieldName.Replace("___", "-");
writer.WriteString(fieldName);
writer.WriteEndElement();
LLSD.LLSDWriteOne(writer, fieldValue);
// OpenMetaverse.StructuredData.LLSDParser.SerializeXmlElement(
// writer, OpenMetaverse.StructuredData.OSD.FromObject(fieldValue));
}
}
else
{
// TODO from ADAM: There is a nullref being caused by fields[i] being null
// on some computers. Unsure what is causing this, but would appreciate
// if sdague could take a look at this.
}
}
writer.WriteEndElement();
break;
case "ARRAY":
// OSDArray arrayObject = obj as OSDArray;
// ArrayList a = arrayObject.Array;
ArrayList a = (ArrayList) obj.GetType().GetField("Array").GetValue(obj);
if (a != null)
{
writer.WriteStartElement(String.Empty, "array", String.Empty);
foreach (object item in a)
{
SerializeOSDType(writer, item);
}
writer.WriteEndElement();
}
break;
}
}
else
{
LLSD.LLSDWriteOne(writer, obj);
//OpenMetaverse.StructuredData.LLSDParser.SerializeXmlElement(
// writer, OpenMetaverse.StructuredData.OSD.FromObject(obj));
}
}
public static object DeserialiseOSDMap(Hashtable llsd, object obj)
{
Type myType = obj.GetType();
LLSDType[] llsdattributes = (LLSDType[]) myType.GetCustomAttributes(typeof (LLSDType), false);
if (llsdattributes.Length > 0)
{
switch (llsdattributes[0].ObjectType)
{
case "MAP":
IDictionaryEnumerator enumerator = llsd.GetEnumerator();
while (enumerator.MoveNext())
{
string keyName = (string)enumerator.Key;
keyName = keyName.Replace("-","_");
FieldInfo field = myType.GetField(keyName);
if (field != null)
{
// if (enumerator.Value is OpenMetaverse.StructuredData.OSDMap)
if (enumerator.Value is Hashtable)
{
object fieldValue = field.GetValue(obj);
DeserialiseOSDMap((Hashtable) enumerator.Value, fieldValue);
// DeserialiseOSDMap((OpenMetaverse.StructuredData.OSDMap) enumerator.Value, fieldValue);
}
else if (enumerator.Value is ArrayList)
{
object fieldValue = field.GetValue(obj);
fieldValue.GetType().GetField("Array").SetValue(fieldValue, enumerator.Value);
//TODO
// the LLSD map/array types in the array need to be deserialised
// but first we need to know the right class to deserialise them into.
}
else if(enumerator.Value is Boolean && field.FieldType == typeof(int) )
{
int i = (bool)enumerator.Value ? 1 : 0;
field.SetValue(obj, i);
}
else if(field.FieldType == typeof(bool) && enumerator.Value is int)
{
bool b = (int)enumerator.Value != 0;
field.SetValue(obj, b);
}
else if(field.FieldType == typeof(UUID) && enumerator.Value is string)
{
UUID u;
UUID.TryParse((string)enumerator.Value, out u);
field.SetValue(obj, u);
}
else
{
field.SetValue(obj, enumerator.Value);
}
}
}
break;
}
}
return obj;
}
}
}