/// <summary> /// Fire the events registered for this event type asynchronously /// </summary> /// <param name="capsEvent">Capability name</param> /// <param name="body">Decoded event body</param> /// <param name="simulator">Reference to the simulator that /// generated this event</param> internal void BeginRaiseEvent(string capsEvent, StructuredData.LLSD body, Simulator simulator) { bool specialHandler = false; Caps.EventQueueCallback callback; // Default handler first, if one exists if (_EventTable.TryGetValue(String.Empty, out callback)) { if (callback != null) { CapsCallbackWrapper wrapper; wrapper.Callback = callback; wrapper.CapsEvent = capsEvent; wrapper.Body = body; wrapper.Simulator = simulator; ThreadPool.QueueUserWorkItem(_ThreadPoolCallback, wrapper); } } // Generic parser next, don't generic parse events we've manually registered for if (body.Type == StructuredData.LLSDType.Map && !_EventTable.ContainsKey(capsEvent)) { StructuredData.LLSDMap map = (StructuredData.LLSDMap)body; Packet packet = Packet.BuildPacket(capsEvent, map); if (packet != null) { NetworkManager.IncomingPacket incomingPacket; incomingPacket.Simulator = simulator; incomingPacket.Packet = packet; Logger.DebugLog("Serializing " + packet.Type.ToString() + " capability with generic handler", Client); Client.Network.PacketInbox.Enqueue(incomingPacket); specialHandler = true; } } // Explicit handler next if (_EventTable.TryGetValue(capsEvent, out callback) && callback != null) { CapsCallbackWrapper wrapper; wrapper.Callback = callback; wrapper.CapsEvent = capsEvent; wrapper.Body = body; wrapper.Simulator = simulator; ThreadPool.QueueUserWorkItem(_ThreadPoolCallback, wrapper); specialHandler = true; } if (!specialHandler) Logger.Log("Unhandled CAPS event " + capsEvent, Helpers.LogLevel.Warning, Client); }
private static LLSD DeserializeNotationMap(StringReader reader) { int character; LLSDMap llsdMap = new LLSDMap(); while (((character = PeekAndSkipWhitespace(reader)) > 0) && ((char)character != mapEndNotationMarker)) { LLSD llsdKey = DeserializeNotationElement(reader); if (llsdKey.Type != LLSDType.String) { throw new LLSDException("Notation LLSD parsing: Invalid key in map"); } string key = llsdKey.AsString(); character = ReadAndSkipWhitespace(reader); if ((char)character != keyNotationDelimiter) { throw new LLSDException("Notation LLSD parsing: Unexpected end of stream in map."); } if ((char)character != keyNotationDelimiter) { throw new LLSDException("Notation LLSD parsing: Invalid delimiter in map."); } llsdMap[key] = DeserializeNotationElement(reader); character = ReadAndSkipWhitespace(reader); if (character < 0) { throw new LLSDException("Notation LLSD parsing: Unexpected end of map discovered."); } else if ((char)character == kommaNotationDelimiter) { continue; } else if ((char)character == mapEndNotationMarker) { break; } } if (character < 0) { throw new LLSDException("Notation LLSD parsing: Unexpected end of map discovered."); } return((LLSD)llsdMap); }
/// <summary> /// Fire the events registered for this event type synchronously /// </summary> /// <param name="capsEvent">Capability name</param> /// <param name="body">Decoded event body</param> /// <param name="simulator">Reference to the simulator that /// generated this event</param> internal void RaiseEvent(string capsEvent, StructuredData.LLSD body, Simulator simulator) { bool specialHandler = false; Caps.EventQueueCallback callback; // Default handler first, if one exists if (_EventTable.TryGetValue(capsEvent, out callback)) { if (callback != null) { try { callback(capsEvent, body, simulator); } catch (Exception ex) { Logger.Log("CAPS Event Handler: " + ex.ToString(), Helpers.LogLevel.Error, Client); } } } // Generic parser next if (body.Type == StructuredData.LLSDType.Map) { StructuredData.LLSDMap map = (StructuredData.LLSDMap)body; Packet packet = Packet.BuildPacket(capsEvent, map); if (packet != null) { NetworkManager.IncomingPacket incomingPacket; incomingPacket.Simulator = simulator; incomingPacket.Packet = packet; Logger.DebugLog("Serializing " + packet.Type.ToString() + " capability with generic handler", Client); Client.Network.PacketInbox.Enqueue(incomingPacket); specialHandler = true; } } // Explicit handler next if (_EventTable.TryGetValue(capsEvent, out callback) && callback != null) { try { callback(capsEvent, body, simulator); } catch (Exception ex) { Logger.Log("CAPS Event Handler: " + ex.ToString(), Helpers.LogLevel.Error, Client); } specialHandler = true; } if (!specialHandler) Logger.Log("Unhandled CAPS event " + capsEvent, Helpers.LogLevel.Warning, Client); }
/// <summary> /// Deserializes LLSD in to a list of primitives /// </summary> /// <param name="llsd">Structure holding the serialized primitive list, /// must be of the LLSDMap type</param> /// <returns>A list of deserialized primitives</returns> public static List <Primitive> LLSDToPrimList(StructuredData.LLSD llsd) { if (llsd.Type != StructuredData.LLSDType.Map) { throw new ArgumentException("LLSD must be in the Map structure"); } StructuredData.LLSDMap map = (StructuredData.LLSDMap)llsd; List <Primitive> prims = new List <Primitive>(map.Count); foreach (KeyValuePair <string, StructuredData.LLSD> kvp in map) { Primitive prim = Primitive.FromLLSD(kvp.Value); prim.LocalID = UInt32.Parse(kvp.Key); prims.Add(prim); } return(prims); }
/// <summary> /// Uses reflection to create an LLSDMap from all of the LLSD /// serializable types in an object /// </summary> /// <param name="obj">Class or struct containing serializable types</param> /// <returns>An LLSDMap holding the serialized values from the /// container object</returns> public static LLSDMap SerializeMembers(object obj) { Type t = obj.GetType(); FieldInfo[] fields = t.GetFields(); LLSDMap map = new LLSDMap(fields.Length); for (int i = 0; i < fields.Length; i++) { FieldInfo field = fields[i]; if (!Attribute.IsDefined(field, typeof(NonSerializedAttribute))) { LLSD serializedField = LLSD.FromObject(field.GetValue(obj)); if (serializedField.Type != LLSDType.Unknown || field.FieldType == typeof(string) || field.FieldType == typeof(byte[])) { map.Add(field.Name, serializedField); } } } return(map); }
public static object ToObject(Type type, LLSD value) { if (type == typeof(ulong)) { if (value.Type == LLSDType.Binary) { byte[] bytes = value.AsBinary(); return(Utils.BytesToUInt64(bytes)); } else { return((ulong)value.AsInteger()); } } else if (type == typeof(uint)) { if (value.Type == LLSDType.Binary) { byte[] bytes = value.AsBinary(); return(Utils.BytesToUInt(bytes)); } else { return((uint)value.AsInteger()); } } else if (type == typeof(ushort)) { return((ushort)value.AsInteger()); } else if (type == typeof(byte)) { return((byte)value.AsInteger()); } else if (type == typeof(short)) { return((short)value.AsInteger()); } else if (type == typeof(string)) { return(value.AsString()); } else if (type == typeof(bool)) { return(value.AsBoolean()); } else if (type == typeof(float)) { return((float)value.AsReal()); } else if (type == typeof(double)) { return(value.AsReal()); } else if (type == typeof(int)) { return(value.AsInteger()); } else if (type == typeof(UUID)) { return(value.AsUUID()); } else if (type == typeof(Vector3)) { if (value.Type == LLSDType.Array) { return(((LLSDArray)value).AsVector3()); } else { return(Vector3.Zero); } } else if (type == typeof(Vector4)) { if (value.Type == LLSDType.Array) { return(((LLSDArray)value).AsVector4()); } else { return(Vector4.Zero); } } else if (type == typeof(Quaternion)) { if (value.Type == LLSDType.Array) { return(((LLSDArray)value).AsQuaternion()); } else { return(Quaternion.Identity); } } else { return(null); } }
/// <summary> /// /// </summary> /// <param name="reader"></param> /// <returns></returns> public static LLSD DeserializeNotation(StringReader reader) { LLSD llsd = DeserializeNotationElement(reader); return(llsd); }
private static void SerializeNotationElementFormatted(StringWriter writer, string indent, LLSD llsd) { switch (llsd.Type) { case LLSDType.Unknown: writer.Write(undefNotationValue); break; case LLSDType.Boolean: if (llsd.AsBoolean()) { writer.Write(trueNotationValueTwo); } else { writer.Write(falseNotationValueTwo); } break; case LLSDType.Integer: writer.Write(integerNotationMarker); writer.Write(llsd.AsString()); break; case LLSDType.Real: writer.Write(realNotationMarker); writer.Write(llsd.AsString()); break; case LLSDType.UUID: writer.Write(uuidNotationMarker); writer.Write(llsd.AsString()); break; case LLSDType.String: writer.Write(singleQuotesNotationMarker); writer.Write(EscapeCharacter(llsd.AsString(), singleQuotesNotationMarker)); writer.Write(singleQuotesNotationMarker); break; case LLSDType.Binary: writer.Write(binaryNotationMarker); writer.Write("64"); writer.Write(doubleQuotesNotationMarker); writer.Write(llsd.AsString()); writer.Write(doubleQuotesNotationMarker); break; case LLSDType.Date: writer.Write(dateNotationMarker); writer.Write(doubleQuotesNotationMarker); writer.Write(llsd.AsString()); writer.Write(doubleQuotesNotationMarker); break; case LLSDType.URI: writer.Write(uriNotationMarker); writer.Write(doubleQuotesNotationMarker); writer.Write(EscapeCharacter(llsd.AsString(), doubleQuotesNotationMarker)); writer.Write(doubleQuotesNotationMarker); break; case LLSDType.Array: SerializeNotationArrayFormatted(writer, indent + baseIndent, (LLSDArray)llsd); break; case LLSDType.Map: SerializeNotationMapFormatted(writer, indent + baseIndent, (LLSDMap)llsd); break; default: throw new LLSDException("Notation serialization: Not existing element discovered."); } }
/// <summary> /// /// </summary> /// <param name="reader"></param> /// <returns></returns> private static LLSD DeserializeNotationElement(StringReader reader) { int character = ReadAndSkipWhitespace(reader); if (character < 0) { return(new LLSD()); // server returned an empty file, so we're going to pass along a null LLSD object } LLSD llsd; int matching; switch ((char)character) { case undefNotationValue: llsd = new LLSD(); break; case trueNotationValueOne: llsd = LLSD.FromBoolean(true); break; case trueNotationValueTwo: matching = BufferCharactersEqual(reader, trueNotationValueTwoFull, 1); if (matching > 1 && matching < trueNotationValueTwoFull.Length) { throw new LLSDException("Notation LLSD parsing: True value parsing error:"); } llsd = LLSD.FromBoolean(true); break; case trueNotationValueThree: matching = BufferCharactersEqual(reader, trueNotationValueThreeFull, 1); if (matching > 1 && matching < trueNotationValueThreeFull.Length) { throw new LLSDException("Notation LLSD parsing: True value parsing error:"); } llsd = LLSD.FromBoolean(true); break; case falseNotationValueOne: llsd = LLSD.FromBoolean(false); break; case falseNotationValueTwo: matching = BufferCharactersEqual(reader, falseNotationValueTwoFull, 1); if (matching > 1 && matching < falseNotationValueTwoFull.Length) { throw new LLSDException("Notation LLSD parsing: True value parsing error:"); } llsd = LLSD.FromBoolean(false); break; case falseNotationValueThree: matching = BufferCharactersEqual(reader, falseNotationValueThreeFull, 1); if (matching > 1 && matching < falseNotationValueThreeFull.Length) { throw new LLSDException("Notation LLSD parsing: True value parsing error:"); } llsd = LLSD.FromBoolean(false); break; case integerNotationMarker: llsd = DeserializeNotationInteger(reader); break; case realNotationMarker: llsd = DeserializeNotationReal(reader); break; case uuidNotationMarker: char[] uuidBuf = new char[36]; if (reader.Read(uuidBuf, 0, 36) < 36) { throw new LLSDException("Notation LLSD parsing: Unexpected end of stream in UUID."); } UUID lluuid; if (!UUID.TryParse(new String(uuidBuf), out lluuid)) { throw new LLSDException("Notation LLSD parsing: Invalid UUID discovered."); } llsd = LLSD.FromUUID(lluuid); break; case binaryNotationMarker: byte[] bytes = new byte[0]; int bChar = reader.Peek(); if (bChar < 0) { throw new LLSDException("Notation LLSD parsing: Unexpected end of stream in binary."); } if ((char)bChar == sizeBeginNotationMarker) { throw new LLSDException("Notation LLSD parsing: Raw binary encoding not supported."); } else if (Char.IsDigit((char)bChar)) { char[] charsBaseEncoding = new char[2]; if (reader.Read(charsBaseEncoding, 0, 2) < 2) { throw new LLSDException("Notation LLSD parsing: Unexpected end of stream in binary."); } int baseEncoding; if (!Int32.TryParse(new String(charsBaseEncoding), out baseEncoding)) { throw new LLSDException("Notation LLSD parsing: Invalid binary encoding base."); } if (baseEncoding == 64) { if (reader.Read() < 0) { throw new LLSDException("Notation LLSD parsing: Unexpected end of stream in binary."); } string bytes64 = GetStringDelimitedBy(reader, doubleQuotesNotationMarker); bytes = Convert.FromBase64String(bytes64); } else { throw new LLSDException("Notation LLSD parsing: Encoding base" + baseEncoding + " + not supported."); } } llsd = LLSD.FromBinary(bytes); break; case stringNotationMarker: int numChars = GetLengthInBrackets(reader); if (reader.Read() < 0) { throw new LLSDException("Notation LLSD parsing: Unexpected end of stream in string."); } char[] chars = new char[numChars]; if (reader.Read(chars, 0, numChars) < numChars) { throw new LLSDException("Notation LLSD parsing: Unexpected end of stream in string."); } if (reader.Read() < 0) { throw new LLSDException("Notation LLSD parsing: Unexpected end of stream in string."); } llsd = LLSD.FromString(new String(chars)); break; case singleQuotesNotationMarker: string sOne = GetStringDelimitedBy(reader, singleQuotesNotationMarker); llsd = LLSD.FromString(sOne); break; case doubleQuotesNotationMarker: string sTwo = GetStringDelimitedBy(reader, doubleQuotesNotationMarker); llsd = LLSD.FromString(sTwo); break; case uriNotationMarker: if (reader.Read() < 0) { throw new LLSDException("Notation LLSD parsing: Unexpected end of stream in string."); } string sUri = GetStringDelimitedBy(reader, doubleQuotesNotationMarker); Uri uri; try { uri = new Uri(sUri, UriKind.RelativeOrAbsolute); } catch { throw new LLSDException("Notation LLSD parsing: Invalid Uri format detected."); } llsd = LLSD.FromUri(uri); break; case dateNotationMarker: if (reader.Read() < 0) { throw new LLSDException("Notation LLSD parsing: Unexpected end of stream in date."); } string date = GetStringDelimitedBy(reader, doubleQuotesNotationMarker); DateTime dt; if (!DateTime.TryParse(date, out dt)) { throw new LLSDException("Notation LLSD parsing: Invalid date discovered."); } llsd = LLSD.FromDate(dt); break; case arrayBeginNotationMarker: llsd = DeserializeNotationArray(reader); break; case mapBeginNotationMarker: llsd = DeserializeNotationMap(reader); break; default: throw new LLSDException("Notation LLSD parsing: Unknown type marker '" + (char)character + "'."); } return(llsd); }
private static LLSD ParseBinaryElement(MemoryStream stream) { SkipWhiteSpace(stream); LLSD llsd; int marker = stream.ReadByte(); if (marker < 0) { throw new LLSDException("Binary LLSD parsing:Unexpected end of stream."); } switch ((byte)marker) { case undefBinaryValue: llsd = new LLSD(); break; case trueBinaryValue: llsd = LLSD.FromBoolean(true); break; case falseBinaryValue: llsd = LLSD.FromBoolean(false); break; case integerBinaryMarker: int integer = NetworkToHostInt(ConsumeBytes(stream, int32Length)); llsd = LLSD.FromInteger(integer); break; case realBinaryMarker: double dbl = NetworkToHostDouble(ConsumeBytes(stream, doubleLength)); llsd = LLSD.FromReal(dbl); break; case uuidBinaryMarker: llsd = LLSD.FromUUID(new UUID(ConsumeBytes(stream, 16), 0)); break; case binaryBinaryMarker: int binaryLength = NetworkToHostInt(ConsumeBytes(stream, int32Length)); llsd = LLSD.FromBinary(ConsumeBytes(stream, binaryLength)); break; case stringBinaryMarker: int stringLength = NetworkToHostInt(ConsumeBytes(stream, int32Length)); string ss = Encoding.UTF8.GetString(ConsumeBytes(stream, stringLength)); llsd = LLSD.FromString(ss); break; case uriBinaryMarker: int uriLength = NetworkToHostInt(ConsumeBytes(stream, int32Length)); string sUri = Encoding.UTF8.GetString(ConsumeBytes(stream, uriLength)); Uri uri; try { uri = new Uri(sUri, UriKind.RelativeOrAbsolute); } catch { throw new LLSDException("Binary LLSD parsing: Invalid Uri format detected."); } llsd = LLSD.FromUri(uri); break; case dateBinaryMarker: double timestamp = NetworkToHostDouble(ConsumeBytes(stream, doubleLength)); DateTime dateTime = DateTime.SpecifyKind(Utils.Epoch, DateTimeKind.Utc); dateTime = dateTime.AddSeconds(timestamp); llsd = LLSD.FromDate(dateTime.ToLocalTime()); break; case arrayBeginBinaryMarker: llsd = ParseBinaryArray(stream); break; case mapBeginBinaryMarker: llsd = ParseBinaryMap(stream); break; default: throw new LLSDException("Binary LLSD parsing: Unknown type marker."); } return(llsd); }
private static void SerializeBinaryElement(MemoryStream stream, LLSD llsd) { switch (llsd.Type) { case LLSDType.Unknown: stream.WriteByte(undefBinaryValue); break; case LLSDType.Boolean: stream.Write(llsd.AsBinary(), 0, 1); break; case LLSDType.Integer: stream.WriteByte(integerBinaryMarker); stream.Write(llsd.AsBinary(), 0, int32Length); break; case LLSDType.Real: stream.WriteByte(realBinaryMarker); stream.Write(llsd.AsBinary(), 0, doubleLength); break; case LLSDType.UUID: stream.WriteByte(uuidBinaryMarker); stream.Write(llsd.AsBinary(), 0, 16); break; case LLSDType.String: stream.WriteByte(stringBinaryMarker); byte[] rawString = llsd.AsBinary(); byte[] stringLengthNetEnd = HostToNetworkIntBytes(rawString.Length); stream.Write(stringLengthNetEnd, 0, int32Length); stream.Write(rawString, 0, rawString.Length); break; case LLSDType.Binary: stream.WriteByte(binaryBinaryMarker); byte[] rawBinary = llsd.AsBinary(); byte[] binaryLengthNetEnd = HostToNetworkIntBytes(rawBinary.Length); stream.Write(binaryLengthNetEnd, 0, int32Length); stream.Write(rawBinary, 0, rawBinary.Length); break; case LLSDType.Date: stream.WriteByte(dateBinaryMarker); stream.Write(llsd.AsBinary(), 0, doubleLength); break; case LLSDType.URI: stream.WriteByte(uriBinaryMarker); byte[] rawURI = llsd.AsBinary(); byte[] uriLengthNetEnd = HostToNetworkIntBytes(rawURI.Length); stream.Write(uriLengthNetEnd, 0, int32Length); stream.Write(rawURI, 0, rawURI.Length); break; case LLSDType.Array: SerializeBinaryArray(stream, (LLSDArray)llsd); break; case LLSDType.Map: SerializeBinaryMap(stream, (LLSDMap)llsd); break; default: throw new LLSDException("Binary serialization: Not existing element discovered."); } }
/// <summary> /// /// </summary> /// <param name="data"></param> /// <returns></returns> public static byte[] SerializeXmlBytes(LLSD data) { return(Encoding.UTF8.GetBytes(SerializeXmlString(data))); }
/// <summary> /// /// </summary> /// <param name="reader"></param> /// <returns></returns> private static LLSD ParseXmlElement(XmlTextReader reader) { SkipWhitespace(reader); if (reader.NodeType != XmlNodeType.Element) { throw new LLSDException("Expected an element"); } string type = reader.LocalName; LLSD ret; switch (type) { case "undef": if (reader.IsEmptyElement) { reader.Read(); return(new LLSD()); } reader.Read(); SkipWhitespace(reader); ret = new LLSD(); break; case "boolean": if (reader.IsEmptyElement) { reader.Read(); return(LLSD.FromBoolean(false)); } if (reader.Read()) { string s = reader.ReadString().Trim(); if (!String.IsNullOrEmpty(s) && (s == "true" || s == "1")) { ret = LLSD.FromBoolean(true); break; } } ret = LLSD.FromBoolean(false); break; case "integer": if (reader.IsEmptyElement) { reader.Read(); return(LLSD.FromInteger(0)); } if (reader.Read()) { int value = 0; Int32.TryParse(reader.ReadString().Trim(), out value); ret = LLSD.FromInteger(value); break; } ret = LLSD.FromInteger(0); break; case "real": if (reader.IsEmptyElement) { reader.Read(); return(LLSD.FromReal(0d)); } if (reader.Read()) { double value = 0d; string str = reader.ReadString().Trim().ToLower(); if (str == "nan") { value = Double.NaN; } else { Utils.TryParseDouble(str, out value); } ret = LLSD.FromReal(value); break; } ret = LLSD.FromReal(0d); break; case "uuid": if (reader.IsEmptyElement) { reader.Read(); return(LLSD.FromUUID(UUID.Zero)); } if (reader.Read()) { UUID value = UUID.Zero; UUID.TryParse(reader.ReadString().Trim(), out value); ret = LLSD.FromUUID(value); break; } ret = LLSD.FromUUID(UUID.Zero); break; case "date": if (reader.IsEmptyElement) { reader.Read(); return(LLSD.FromDate(Utils.Epoch)); } if (reader.Read()) { DateTime value = Utils.Epoch; DateTime.TryParse(reader.ReadString().Trim(), out value); ret = LLSD.FromDate(value); break; } ret = LLSD.FromDate(Utils.Epoch); break; case "string": if (reader.IsEmptyElement) { reader.Read(); return(LLSD.FromString(String.Empty)); } if (reader.Read()) { ret = LLSD.FromString(reader.ReadString()); break; } ret = LLSD.FromString(String.Empty); break; case "binary": if (reader.IsEmptyElement) { reader.Read(); return(LLSD.FromBinary(new byte[0])); } if (reader.GetAttribute("encoding") != null && reader.GetAttribute("encoding") != "base64") { throw new LLSDException("Unsupported binary encoding: " + reader.GetAttribute("encoding")); } if (reader.Read()) { try { ret = LLSD.FromBinary(Convert.FromBase64String(reader.ReadString().Trim())); break; } catch (FormatException ex) { throw new LLSDException("Binary decoding exception: " + ex.Message); } } ret = LLSD.FromBinary(new byte[0]); break; case "uri": if (reader.IsEmptyElement) { reader.Read(); return(LLSD.FromUri(new Uri(String.Empty, UriKind.RelativeOrAbsolute))); } if (reader.Read()) { ret = LLSD.FromUri(new Uri(reader.ReadString(), UriKind.RelativeOrAbsolute)); break; } ret = LLSD.FromUri(new Uri(String.Empty, UriKind.RelativeOrAbsolute)); break; case "map": return(ParseXmlMap(reader)); case "array": return(ParseXmlArray(reader)); default: reader.Read(); ret = null; break; } if (reader.NodeType != XmlNodeType.EndElement || reader.LocalName != type) { throw new LLSDException("Expected </" + type + ">"); } else { reader.Read(); return(ret); } }
/// <summary> /// /// </summary> /// <param name="writer"></param> /// <param name="data"></param> public static void SerializeXmlElement(XmlTextWriter writer, LLSD data) { switch (data.Type) { case LLSDType.Unknown: writer.WriteStartElement(String.Empty, "undef", String.Empty); writer.WriteEndElement(); break; case LLSDType.Boolean: writer.WriteStartElement(String.Empty, "boolean", String.Empty); writer.WriteString(data.AsString()); writer.WriteEndElement(); break; case LLSDType.Integer: writer.WriteStartElement(String.Empty, "integer", String.Empty); writer.WriteString(data.AsString()); writer.WriteEndElement(); break; case LLSDType.Real: writer.WriteStartElement(String.Empty, "real", String.Empty); writer.WriteString(data.AsString()); writer.WriteEndElement(); break; case LLSDType.String: writer.WriteStartElement(String.Empty, "string", String.Empty); writer.WriteString(data.AsString()); writer.WriteEndElement(); break; case LLSDType.UUID: writer.WriteStartElement(String.Empty, "uuid", String.Empty); writer.WriteString(data.AsString()); writer.WriteEndElement(); break; case LLSDType.Date: writer.WriteStartElement(String.Empty, "date", String.Empty); writer.WriteString(data.AsString()); writer.WriteEndElement(); break; case LLSDType.URI: writer.WriteStartElement(String.Empty, "uri", String.Empty); writer.WriteString(data.AsString()); writer.WriteEndElement(); break; case LLSDType.Binary: writer.WriteStartElement(String.Empty, "binary", String.Empty); writer.WriteStartAttribute(String.Empty, "encoding", String.Empty); writer.WriteString("base64"); writer.WriteEndAttribute(); writer.WriteString(data.AsString()); writer.WriteEndElement(); break; case LLSDType.Map: LLSDMap map = (LLSDMap)data; writer.WriteStartElement(String.Empty, "map", String.Empty); foreach (KeyValuePair <string, LLSD> kvp in map) { writer.WriteStartElement(String.Empty, "key", String.Empty); writer.WriteString(kvp.Key); writer.WriteEndElement(); SerializeXmlElement(writer, kvp.Value); } writer.WriteEndElement(); break; case LLSDType.Array: LLSDArray array = (LLSDArray)data; writer.WriteStartElement(String.Empty, "array", String.Empty); for (int i = 0; i < array.Count; i++) { SerializeXmlElement(writer, array[i]); } writer.WriteEndElement(); break; } }