/// <summary> /// INTERNAL API /// </summary> /// <param name="name">The full name of the actor, including the UID if known</param> /// <returns>A new (string name, int uid) instance.</returns> internal static (string name, int uid) GetNameAndUid(string name) { var i = name.IndexOf('#'); return(i < 0 ? (name, UndefinedUid) : (name.Substring(0, i), SpanHacks.Parse(name.AsSpan(i + 1)))); }
/// <summary> /// Parses a new <see cref="Address"/> from a given path /// </summary> /// <param name="span">The span of address to parse</param> /// <param name="address">If <c>true</c>, the parsed <see cref="Address"/>. Otherwise <c>null</c>.</param> /// <param name="absolutUri">If <c>true</c>, the absolut uri of the path. Otherwise default.</param> /// <returns><c>true</c> if the <see cref="Address"/> could be parsed, <c>false</c> otherwise.</returns> public static bool TryParse(ReadOnlySpan <char> span, out Address address, out ReadOnlySpan <char> absolutUri) { address = default; absolutUri = default; var firstColonPos = span.IndexOf(':'); if (firstColonPos == -1) // not an absolute Uri { return(false); } if (firstColonPos < 4 || 255 < firstColonPos) { //invalid scheme length return(false); } Span <char> fullScheme = stackalloc char[firstColonPos]; span.Slice(0, firstColonPos).ToLowerInvariant(fullScheme); if (!fullScheme.StartsWith("akka".AsSpan())) { //invalid scheme return(false); } span = span.Slice(firstColonPos + 1); if (span.Length < 2 || !(span[0] == '/' && span[1] == '/')) { return(false); } span = span.Slice(2); // move past the double // // cut the absolute Uri off var uriStart = span.IndexOf('/'); if (uriStart > -1) { absolutUri = span.Slice(uriStart); span = span.Slice(0, uriStart); } else { absolutUri = "/".AsSpan(); } var firstAtPos = span.IndexOf('@'); string sysName; if (firstAtPos == -1) { // dealing with an absolute local Uri sysName = span.ToString(); address = new Address(fullScheme.ToString(), sysName); return(true); } // dealing with a remote Uri sysName = span.Slice(0, firstAtPos).ToString(); span = span.Slice(firstAtPos + 1); /* * Need to check for: * - IPV4 / hostnames * - IPV6 (must be surrounded by '[]') according to spec. */ string host; // check for IPV6 first var openBracket = span.IndexOf('['); var closeBracket = span.IndexOf(']'); if (openBracket > -1 && closeBracket > openBracket) { // found an IPV6 address host = span.Slice(openBracket, closeBracket - openBracket + 1).ToString(); span = span.Slice(closeBracket + 1); // advance past the address // need to check for trailing colon var secondColonPos = span.IndexOf(':'); if (secondColonPos == -1) { return(false); } span = span.Slice(secondColonPos + 1); } else { var secondColonPos = span.IndexOf(':'); if (secondColonPos == -1) { return(false); } host = span.Slice(0, secondColonPos).ToString(); // move past the host span = span.Slice(secondColonPos + 1); } if (SpanHacks.TryParse(span, out var port) && port >= 0) { address = new Address(fullScheme.ToString(), sysName, host, port); return(true); } return(false); }