/// <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 LLSDMap ParseXmlMap(XmlTextReader reader) { if (reader.NodeType != XmlNodeType.Element || reader.LocalName != "map") { throw new NotImplementedException("Expected <map>"); } LLSDMap map = new LLSDMap(); if (reader.IsEmptyElement) { reader.Read(); return(map); } if (reader.Read()) { while (true) { SkipWhitespace(reader); if (reader.NodeType == XmlNodeType.EndElement && reader.LocalName == "map") { reader.Read(); break; } if (reader.NodeType != XmlNodeType.Element || reader.LocalName != "key") { throw new LLSDException("Expected <key>"); } string key = reader.ReadString(); if (reader.NodeType != XmlNodeType.EndElement || reader.LocalName != "key") { throw new LLSDException("Expected </key>"); } if (reader.Read()) { map[key] = ParseXmlElement(reader); } else { throw new LLSDException("Failed to parse a value for key " + key); } } } return(map); }
/// <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); } }
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); }
private static void SerializeBinaryMap(MemoryStream stream, LLSDMap llsdMap) { stream.WriteByte(mapBeginBinaryMarker); byte[] binaryNumElementsNetEnd = HostToNetworkIntBytes(llsdMap.Count); stream.Write(binaryNumElementsNetEnd, 0, int32Length); foreach (KeyValuePair <string, LLSD> kvp in llsdMap) { stream.WriteByte(keyBinaryMarker); byte[] binaryKey = Encoding.UTF8.GetBytes(kvp.Key); byte[] binaryKeyLength = HostToNetworkIntBytes(binaryKey.Length); stream.Write(binaryKeyLength, 0, int32Length); stream.Write(binaryKey, 0, binaryKey.Length); SerializeBinaryElement(stream, kvp.Value); } stream.WriteByte(mapEndBinaryMarker); }
private static void SerializeNotationMap(StringWriter writer, LLSDMap llsdMap) { writer.Write(mapBeginNotationMarker); int lastIndex = llsdMap.Count - 1; int idx = 0; foreach (KeyValuePair <string, LLSD> kvp in llsdMap) { writer.Write(singleQuotesNotationMarker); writer.Write(EscapeCharacter(kvp.Key, singleQuotesNotationMarker)); writer.Write(singleQuotesNotationMarker); writer.Write(keyNotationDelimiter); SerializeNotationElement(writer, kvp.Value); if (idx < lastIndex) { writer.Write(kommaNotationDelimiter); } idx++; } writer.Write(mapEndNotationMarker); }
private static LLSD ParseNotationElement(string notationData, out int endPos) { if (notationData.Length == 0) { endPos = 0; return(null); } // Identify what type of object this is switch (notationData[0]) { case '!': endPos = 1; return(new LLSD()); case '1': endPos = 1; return(LLSD.FromBoolean(true)); case '0': endPos = 1; return(LLSD.FromBoolean(false)); case 'i': { if (notationData.Length < 2) { endPos = notationData.Length; return(LLSD.FromInteger(0)); } int value; endPos = FindEnd(notationData, 1); if (Helpers.TryParse(notationData.Substring(1, endPos - 1), out value)) { return(LLSD.FromInteger(value)); } else { return(LLSD.FromInteger(0)); } } case 'r': { if (notationData.Length < 2) { endPos = notationData.Length; return(LLSD.FromReal(0d)); } double value; endPos = FindEnd(notationData, 1); if (Helpers.TryParse(notationData.Substring(1, endPos - 1), out value)) { return(LLSD.FromReal(value)); } else { return(LLSD.FromReal(0d)); } } case 'u': { if (notationData.Length < 17) { endPos = notationData.Length; return(LLSD.FromUUID(LLUUID.Zero)); } LLUUID value; endPos = FindEnd(notationData, 1); if (Helpers.TryParse(notationData.Substring(1, endPos - 1), out value)) { return(LLSD.FromUUID(value)); } else { return(LLSD.FromUUID(LLUUID.Zero)); } } case 'b': throw new NotImplementedException("Notation binary type is unimplemented"); case 's': case '"': case '\'': if (notationData.Length < 2) { endPos = notationData.Length; return(LLSD.FromString(String.Empty)); } endPos = FindEnd(notationData, 1); return(LLSD.FromString(notationData.Substring(1, endPos - 1).Trim(new char[] { '"', '\'' }))); case 'l': throw new NotImplementedException("Notation URI type is unimplemented"); case 'd': throw new NotImplementedException("Notation date type is unimplemented"); case '[': { if (notationData.IndexOf(']') == -1) { throw new LLSDException("Invalid notation array"); } int pos = 0; LLSDArray array = new LLSDArray(); while (notationData[pos] != ']') { ++pos; // Advance past comma if need be if (notationData[pos] == ',') { ++pos; } // Allow a single whitespace character if (pos < notationData.Length && notationData[pos] == ' ') { ++pos; } int end; array.Add(ParseNotationElement(notationData.Substring(pos), out end)); pos += end; } endPos = pos + 1; return(array); } case '{': { if (notationData.IndexOf('}') == -1) { throw new LLSDException("Invalid notation map"); } int pos = 0; LLSDMap hashtable = new LLSDMap(); while (notationData[pos] != '}') { ++pos; // Advance past comma if need be if (notationData[pos] == ',') { ++pos; } // Allow a single whitespace character if (pos < notationData.Length && notationData[pos] == ' ') { ++pos; } if (notationData[pos] != '\'') { throw new LLSDException("Expected a map key"); } int endquote = notationData.IndexOf('\'', pos + 1); if (endquote == -1 || (endquote + 1) >= notationData.Length || notationData[endquote + 1] != ':') { throw new LLSDException("Invalid map format"); } string key = notationData.Substring(pos, endquote - pos); key = key.Trim(new char[] { '"', '\'' }); //key.Replace("'", String.Empty); pos += (endquote - pos) + 2; int end; hashtable[key] = ParseNotationElement(notationData.Substring(pos), out end); pos += end; } endPos = pos + 1; return(hashtable); } default: throw new LLSDException("Unknown notation value type"); } }
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; } }