<commit_before>﻿//-----------------------------------------------------------------------
// <copyright file="Address.cs" company="Akka.NET Project">
//     Copyright (C) 2009-2016 Lightbend Inc. <http://www.lightbend.com>
//     Copyright (C) 2013-2016 Akka.NET project <https://github.com/akkadotnet/akka.net>
// </copyright>
//-----------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using Akka.Util;

namespace Akka.Actor
{
    /// <summary>
    ///  The address specifies the physical location under which an Actor can be
    ///  reached. Examples are local addresses, identified by the <see cref="ActorSystem"/>'s
    /// name, and remote addresses, identified by protocol, host and port.
    ///  
    /// This class is sealed to allow use as a case class (copy method etc.); if
    /// for example a remote transport would want to associate additional
    /// information with an address, then this must be done externally.
    /// </summary>
    [DebuggerDisplay("{Protocol}://{System}@{Host}:{Port}/")]
    public sealed class Address : IEquatable<Address>, ISurrogated
#if CLONEABLE
        , ICloneable
#endif
    {
        /// <summary>
        /// Pseudo address for all systems
        /// </summary>
        public static readonly Address AllSystems = new Address("akka", "all-systems");

        private readonly Lazy<string> _toString;
        private readonly string _host;
        private readonly int? _port;
        private readonly string _system;
        private readonly string _protocol;

        /// <summary>
        /// TBD
        /// </summary>
        /// <param name="protocol">TBD</param>
        /// <param name="system">TBD</param>
        /// <param name="host">TBD</param>
        /// <param name="port">TBD</param>
        public Address(string protocol, string system, string host = null, int? port = null)
        {
            _protocol = protocol;
            _system = system;
            _host = host != null ? host.ToLowerInvariant() : null;
            _port = port;
            _toString = CreateLazyToString();
        }

        /// <summary>
        /// TBD
        /// </summary>
        public string Host => _host;

        /// <summary>
        /// TBD
        /// </summary>
        public int? Port => _port;

        /// <summary>
        /// TBD
        /// </summary>
        public string System => _system;

        /// <summary>
        /// TBD
        /// </summary>
        public string Protocol => _protocol;

        /// <summary>
        /// Returns true if this Address is only defined locally. It is not safe to send locally scoped addresses to remote
        ///  hosts. See also <see cref="HasGlobalScope"/>
        /// </summary>
        public bool HasLocalScope
        {
            get { return string.IsNullOrEmpty(Host); }
        }

        /// <summary>
        /// Returns true if this Address is usable globally. Unlike locally defined addresses <see cref="HasLocalScope"/>
        /// addresses of global scope are safe to sent to other hosts, as they globally and uniquely identify an addressable
        /// entity.
        /// </summary>
        public bool HasGlobalScope => !string.IsNullOrEmpty(Host);

        private Lazy<string> CreateLazyToString()
        {
            return new Lazy<string>(() =>
            {
                var sb = new StringBuilder();
                sb.AppendFormat("{0}://{1}", Protocol, System);
                if (!string.IsNullOrWhiteSpace(Host))
                    sb.AppendFormat("@{0}", Host);
                if (Port.HasValue)
                    sb.AppendFormat(":{0}", Port.Value);

                return sb.ToString();
            }, true);
        }

        /// <summary>
        /// Returns a <see cref="string" /> that represents this instance.
        /// </summary>
        /// <returns>
        /// A <see cref="string" /> that represents this instance.
        /// </returns>
        public override string ToString() => _toString.Value;

        /// <summary>
        /// Determines whether the specified <see cref="Address" />, is equal to this instance.
        /// </summary>
        /// <param name="other">The <see cref="Address" /> to compare with this instance.</param>
        /// <returns>
        ///   <c>true</c> if the specified <see cref="Address" /> is equal to this instance; otherwise, <c>false</c>.
        /// </returns>
        public bool Equals(Address other)
        {
            if (ReferenceEquals(null, other)) return false;
            if (ReferenceEquals(this, other)) return true;
            return string.Equals(Host, other.Host) && Port == other.Port && string.Equals(System, other.System) && string.Equals(Protocol, other.Protocol);
        }

        /// <summary>
        /// Determines whether the specified <see cref="object" />, is equal to this instance.
        /// </summary>
        /// <param name="obj">The <see cref="object" /> to compare with this instance.</param>
        /// <returns>
        ///   <c>true</c> if the specified <see cref="object" /> is equal to this instance; otherwise, <c>false</c>.
        /// </returns>
        public override bool Equals(object obj) => obj is Address && Equals((Address)obj);

        /// <summary>
        /// Returns a hash code for this instance.
        /// </summary>
        /// <returns>
        /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. 
        /// </returns>
        public override int GetHashCode()
        {
            unchecked
            {
                var hashCode = (Host != null ? Host.GetHashCode() : 0);
                hashCode = (hashCode * 397) ^ Port.GetHashCode();
                hashCode = (hashCode * 397) ^ (System != null ? System.GetHashCode() : 0);
                hashCode = (hashCode * 397) ^ (Protocol != null ? Protocol.GetHashCode() : 0);
                return hashCode;
            }
        }

        /// <summary>
        /// Creates a new copy with the same properties as the current address.
        /// </summary>
        /// <returns>A new copy of the current address</returns>
        public object Clone()
        {
            return new Address(Protocol, System, Host, Port);
        }

        /// <summary>
        /// Creates a new <see cref="Address"/> with a given <paramref name="protocol"/>.
        /// </summary>
        /// <note>
        /// This method is immutable and returns a new instance of the address.
        /// </note>
        /// <param name="protocol">The protocol used to configure the new address.</param>
        /// <returns>A new address with the provided <paramref name="protocol" />.</returns>
        public Address WithProtocol(string protocol)
        {
            return new Address(protocol, System, Host, Port);
        }

        /// <summary>
        /// Creates a new <see cref="Address"/> with a given <paramref name="system"/>.
        /// </summary>
        /// <note>
        /// This method is immutable and returns a new instance of the address.
        /// </note>
        /// <param name="system">The system used to configure the new address.</param>
        /// <returns>A new address with the provided <paramref name="system" />.</returns>
        public Address WithSystem(string system)
        {
            return new Address(Protocol, system, Host, Port);
        }

        /// <summary>
        /// Creates a new <see cref="Address"/> with a given <paramref name="host"/>.
        /// </summary>
        /// <note>
        /// This method is immutable and returns a new instance of the address.
        /// </note>
        /// <param name="host">The host used to configure the new address.</param>
        /// <returns>A new address with the provided <paramref name="host" />.</returns>
        public Address WithHost(string host = null)
        {
            return new Address(Protocol, System, host, Port);
        }

        /// <summary>
        /// Creates a new <see cref="Address"/> with a given <paramref name="port"/>.
        /// </summary>
        /// <note>
        /// This method is immutable and returns a new instance of the address.
        /// </note>
        /// <param name="port">The port used to configure the new address.</param>
        /// <returns>A new address with the provided <paramref name="port" />.</returns>
        public Address WithPort(int? port = null)
        {
            return new Address(Protocol, System, Host, port);
        }

        /// <summary>
        /// Compares two specified addresses for equality.
        /// </summary>
        /// <param name="left">The first address used for comparison</param>
        /// <param name="right">The second address used for comparison</param>
        /// <returns><c>true</c> if both addresses are equal; otherwise <c>false</c></returns>
        public static bool operator ==(Address left, Address right)
        {
            return Equals(left, right);
        }

        /// <summary>
        /// Compares two specified addresses for inequality.
        /// </summary>
        /// <param name="left">The first address used for comparison</param>
        /// <param name="right">The second address used for comparison</param>
        /// <returns><c>true</c> if both addresses are not equal; otherwise <c>false</c></returns>
        public static bool operator !=(Address left, Address right)
        {
            return !Equals(left, right);
        }

        /// <summary>
        /// TBD
        /// </summary>
        /// <returns>TBD</returns>
        public string HostPort()
        {
            return ToString().Substring(Protocol.Length + 3);
        }

        /// <summary>
        /// Parses a new <see cref="Address"/> from a given string
        /// </summary>
        /// <param name="address">The address to parse</param>
        /// <returns>A populated <see cref="Address"/> object with host and port included, if available</returns>
        /// <exception cref="UriFormatException">Thrown if the address is not able to be parsed</exception>
        public static Address Parse(string address)
        {
            var uri = new Uri(address);
            var protocol = uri.Scheme;

            if (string.IsNullOrEmpty(uri.UserInfo))
            {
                var systemName = uri.Host;
                
                return new Address(protocol, systemName);
            }
            else
            {
                var systemName = uri.UserInfo;
                var host = uri.Host;
                /*
                 * Aaronontheweb: in the event that an Address is passed in with port 0, the Uri converts it to -1 (which is invalid.)
                 */
                var port = uri.Port;

                return new Address(protocol, systemName, host, port);
            }
        }

        /// <summary>
        /// TBD
        /// </summary>
        public class AddressSurrogate : ISurrogate
        {
            /// <summary>
            /// TBD
            /// </summary>
            public string Protocol { get; set; }
            /// <summary>
            /// TBD
            /// </summary>
            public string System { get; set; }
            /// <summary>
            /// TBD
            /// </summary>
            public string Host { get; set; }
            /// <summary>
            /// TBD
            /// </summary>
            public int? Port { get; set; }
            /// <summary>
            /// TBD
            /// </summary>
            /// <param name="system">TBD</param>
            /// <returns>TBD</returns>
            public ISurrogated FromSurrogate(ActorSystem system)
            {
                return new Address(Protocol, System, Host, Port);
            }
        }

        /// <summary>
        /// TBD
        /// </summary>
        /// <param name="system">TBD</param>
        /// <returns>TBD</returns>
        public ISurrogate ToSurrogate(ActorSystem system)
        {
            return new AddressSurrogate()
            {
                Host = Host,
                Port = Port,
                System = System,
                Protocol = Protocol
            };
        }
    }

    /// <summary>
    /// Extractor class for so-called "relative actor paths" - as in "relative URI", not
    /// "relative to some other actors."
    /// 
    /// Examples:
    /// 
    ///  * "grand/child"
    ///  * "/user/hello/world"
    /// </summary>
    public static class RelativeActorPath
    {

        /// <summary>
        /// TBD
        /// </summary>
        /// <param name="addr">TBD</param>
        /// <returns>TBD</returns>
        public static IEnumerable<string> Unapply(string addr)
        {
            try
            {
                Uri uri;
                bool isRelative = Uri.TryCreate(addr, UriKind.Relative, out uri);
                if (!isRelative) return null;

                var finalAddr = addr;
                if (!addr.StartsWith("/"))
                {
                    //hack to cause the URI not to explode when we're only given an actor name
                    finalAddr = "/" + addr;
                }

                return finalAddr.Split('/').SkipWhile(string.IsNullOrEmpty);
            }
            catch (UriFormatException)
            {
                return null;
            }
        }
    }
}

<commit_msg>approvals API cleanup<commit_after>﻿//-----------------------------------------------------------------------
// <copyright file="Address.cs" company="Akka.NET Project">
//     Copyright (C) 2009-2016 Lightbend Inc. <http://www.lightbend.com>
//     Copyright (C) 2013-2016 Akka.NET project <https://github.com/akkadotnet/akka.net>
// </copyright>
//-----------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using Akka.Util;

namespace Akka.Actor
{
    /// <summary>
    ///  The address specifies the physical location under which an Actor can be
    ///  reached. Examples are local addresses, identified by the <see cref="ActorSystem"/>'s
    /// name, and remote addresses, identified by protocol, host and port.
    ///  
    /// This class is sealed to allow use as a case class (copy method etc.); if
    /// for example a remote transport would want to associate additional
    /// information with an address, then this must be done externally.
    /// </summary>
    public sealed class Address : IEquatable<Address>, ISurrogated
#if CLONEABLE
        , ICloneable
#endif
    {
        /// <summary>
        /// Pseudo address for all systems
        /// </summary>
        public static readonly Address AllSystems = new Address("akka", "all-systems");

        private readonly Lazy<string> _toString;
        private readonly string _host;
        private readonly int? _port;
        private readonly string _system;
        private readonly string _protocol;

        /// <summary>
        /// TBD
        /// </summary>
        /// <param name="protocol">TBD</param>
        /// <param name="system">TBD</param>
        /// <param name="host">TBD</param>
        /// <param name="port">TBD</param>
        public Address(string protocol, string system, string host = null, int? port = null)
        {
            _protocol = protocol;
            _system = system;
            _host = host != null ? host.ToLowerInvariant() : null;
            _port = port;
            _toString = CreateLazyToString();
        }

        /// <summary>
        /// TBD
        /// </summary>
        public string Host => _host;

        /// <summary>
        /// TBD
        /// </summary>
        public int? Port => _port;

        /// <summary>
        /// TBD
        /// </summary>
        public string System => _system;

        /// <summary>
        /// TBD
        /// </summary>
        public string Protocol => _protocol;

        /// <summary>
        /// Returns true if this Address is only defined locally. It is not safe to send locally scoped addresses to remote
        ///  hosts. See also <see cref="HasGlobalScope"/>
        /// </summary>
        public bool HasLocalScope
        {
            get { return string.IsNullOrEmpty(Host); }
        }

        /// <summary>
        /// Returns true if this Address is usable globally. Unlike locally defined addresses <see cref="HasLocalScope"/>
        /// addresses of global scope are safe to sent to other hosts, as they globally and uniquely identify an addressable
        /// entity.
        /// </summary>
        public bool HasGlobalScope => !string.IsNullOrEmpty(Host);

        private Lazy<string> CreateLazyToString()
        {
            return new Lazy<string>(() =>
            {
                var sb = new StringBuilder();
                sb.AppendFormat("{0}://{1}", Protocol, System);
                if (!string.IsNullOrWhiteSpace(Host))
                    sb.AppendFormat("@{0}", Host);
                if (Port.HasValue)
                    sb.AppendFormat(":{0}", Port.Value);

                return sb.ToString();
            }, true);
        }

        /// <summary>
        /// Returns a <see cref="string" /> that represents this instance.
        /// </summary>
        /// <returns>
        /// A <see cref="string" /> that represents this instance.
        /// </returns>
        public override string ToString() => _toString.Value;

        /// <summary>
        /// Determines whether the specified <see cref="Address" />, is equal to this instance.
        /// </summary>
        /// <param name="other">The <see cref="Address" /> to compare with this instance.</param>
        /// <returns>
        ///   <c>true</c> if the specified <see cref="Address" /> is equal to this instance; otherwise, <c>false</c>.
        /// </returns>
        public bool Equals(Address other)
        {
            if (ReferenceEquals(null, other)) return false;
            if (ReferenceEquals(this, other)) return true;
            return string.Equals(Host, other.Host) && Port == other.Port && string.Equals(System, other.System) && string.Equals(Protocol, other.Protocol);
        }

        /// <summary>
        /// Determines whether the specified <see cref="object" />, is equal to this instance.
        /// </summary>
        /// <param name="obj">The <see cref="object" /> to compare with this instance.</param>
        /// <returns>
        ///   <c>true</c> if the specified <see cref="object" /> is equal to this instance; otherwise, <c>false</c>.
        /// </returns>
        public override bool Equals(object obj) => obj is Address && Equals((Address)obj);

        /// <summary>
        /// Returns a hash code for this instance.
        /// </summary>
        /// <returns>
        /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. 
        /// </returns>
        public override int GetHashCode()
        {
            unchecked
            {
                var hashCode = (Host != null ? Host.GetHashCode() : 0);
                hashCode = (hashCode * 397) ^ Port.GetHashCode();
                hashCode = (hashCode * 397) ^ (System != null ? System.GetHashCode() : 0);
                hashCode = (hashCode * 397) ^ (Protocol != null ? Protocol.GetHashCode() : 0);
                return hashCode;
            }
        }

        /// <summary>
        /// Creates a new copy with the same properties as the current address.
        /// </summary>
        /// <returns>A new copy of the current address</returns>
        public object Clone()
        {
            return new Address(Protocol, System, Host, Port);
        }

        /// <summary>
        /// Creates a new <see cref="Address"/> with a given <paramref name="protocol"/>.
        /// </summary>
        /// <note>
        /// This method is immutable and returns a new instance of the address.
        /// </note>
        /// <param name="protocol">The protocol used to configure the new address.</param>
        /// <returns>A new address with the provided <paramref name="protocol" />.</returns>
        public Address WithProtocol(string protocol)
        {
            return new Address(protocol, System, Host, Port);
        }

        /// <summary>
        /// Creates a new <see cref="Address"/> with a given <paramref name="system"/>.
        /// </summary>
        /// <note>
        /// This method is immutable and returns a new instance of the address.
        /// </note>
        /// <param name="system">The system used to configure the new address.</param>
        /// <returns>A new address with the provided <paramref name="system" />.</returns>
        public Address WithSystem(string system)
        {
            return new Address(Protocol, system, Host, Port);
        }

        /// <summary>
        /// Creates a new <see cref="Address"/> with a given <paramref name="host"/>.
        /// </summary>
        /// <note>
        /// This method is immutable and returns a new instance of the address.
        /// </note>
        /// <param name="host">The host used to configure the new address.</param>
        /// <returns>A new address with the provided <paramref name="host" />.</returns>
        public Address WithHost(string host = null)
        {
            return new Address(Protocol, System, host, Port);
        }

        /// <summary>
        /// Creates a new <see cref="Address"/> with a given <paramref name="port"/>.
        /// </summary>
        /// <note>
        /// This method is immutable and returns a new instance of the address.
        /// </note>
        /// <param name="port">The port used to configure the new address.</param>
        /// <returns>A new address with the provided <paramref name="port" />.</returns>
        public Address WithPort(int? port = null)
        {
            return new Address(Protocol, System, Host, port);
        }

        /// <summary>
        /// Compares two specified addresses for equality.
        /// </summary>
        /// <param name="left">The first address used for comparison</param>
        /// <param name="right">The second address used for comparison</param>
        /// <returns><c>true</c> if both addresses are equal; otherwise <c>false</c></returns>
        public static bool operator ==(Address left, Address right)
        {
            return Equals(left, right);
        }

        /// <summary>
        /// Compares two specified addresses for inequality.
        /// </summary>
        /// <param name="left">The first address used for comparison</param>
        /// <param name="right">The second address used for comparison</param>
        /// <returns><c>true</c> if both addresses are not equal; otherwise <c>false</c></returns>
        public static bool operator !=(Address left, Address right)
        {
            return !Equals(left, right);
        }

        /// <summary>
        /// TBD
        /// </summary>
        /// <returns>TBD</returns>
        public string HostPort()
        {
            return ToString().Substring(Protocol.Length + 3);
        }

        /// <summary>
        /// Parses a new <see cref="Address"/> from a given string
        /// </summary>
        /// <param name="address">The address to parse</param>
        /// <returns>A populated <see cref="Address"/> object with host and port included, if available</returns>
        /// <exception cref="UriFormatException">Thrown if the address is not able to be parsed</exception>
        public static Address Parse(string address)
        {
            var uri = new Uri(address);
            var protocol = uri.Scheme;

            if (string.IsNullOrEmpty(uri.UserInfo))
            {
                var systemName = uri.Host;
                
                return new Address(protocol, systemName);
            }
            else
            {
                var systemName = uri.UserInfo;
                var host = uri.Host;
                /*
                 * Aaronontheweb: in the event that an Address is passed in with port 0, the Uri converts it to -1 (which is invalid.)
                 */
                var port = uri.Port;

                return new Address(protocol, systemName, host, port);
            }
        }

        /// <summary>
        /// TBD
        /// </summary>
        public class AddressSurrogate : ISurrogate
        {
            /// <summary>
            /// TBD
            /// </summary>
            public string Protocol { get; set; }
            /// <summary>
            /// TBD
            /// </summary>
            public string System { get; set; }
            /// <summary>
            /// TBD
            /// </summary>
            public string Host { get; set; }
            /// <summary>
            /// TBD
            /// </summary>
            public int? Port { get; set; }
            /// <summary>
            /// TBD
            /// </summary>
            /// <param name="system">TBD</param>
            /// <returns>TBD</returns>
            public ISurrogated FromSurrogate(ActorSystem system)
            {
                return new Address(Protocol, System, Host, Port);
            }
        }

        /// <summary>
        /// TBD
        /// </summary>
        /// <param name="system">TBD</param>
        /// <returns>TBD</returns>
        public ISurrogate ToSurrogate(ActorSystem system)
        {
            return new AddressSurrogate()
            {
                Host = Host,
                Port = Port,
                System = System,
                Protocol = Protocol
            };
        }
    }

    /// <summary>
    /// Extractor class for so-called "relative actor paths" - as in "relative URI", not
    /// "relative to some other actors."
    /// 
    /// Examples:
    /// 
    ///  * "grand/child"
    ///  * "/user/hello/world"
    /// </summary>
    public static class RelativeActorPath
    {

        /// <summary>
        /// TBD
        /// </summary>
        /// <param name="addr">TBD</param>
        /// <returns>TBD</returns>
        public static IEnumerable<string> Unapply(string addr)
        {
            try
            {
                Uri uri;
                bool isRelative = Uri.TryCreate(addr, UriKind.Relative, out uri);
                if (!isRelative) return null;

                var finalAddr = addr;
                if (!addr.StartsWith("/"))
                {
                    //hack to cause the URI not to explode when we're only given an actor name
                    finalAddr = "/" + addr;
                }

                return finalAddr.Split('/').SkipWhile(string.IsNullOrEmpty);
            }
            catch (UriFormatException)
            {
                return null;
            }
        }
    }
}


{'fraction_non_alphanumeric': 0.14120353194331084, 'fraction_numerical': 0.002597017140313126, 'mean_word_length': 1.5123497064032063, 'pattern_counts': {'":': 2, '<': 383, '<?xml version=': 0, '>': 399, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6250488', 'n_tokens_mistral': 6874, 'n_tokens_neox': 6639, 'n_words': 2183}