Пример #1
0
        /// <summary>
        /// Parse a message value.
        /// </summary>
        /// <param name="reader">Reader containing the string that should be parsed.</param>
        /// <returns>Newly created header.</returns>
        /// <exception cref="ParseException">Header value is malformed.</exception>
        /// <example>
        /// sip:[email protected]:5060
        /// [email protected]:5060
        /// jonas:[email protected]
        /// sip:[email protected]
        /// mailto:[email protected]
        /// </example>
        public static SipUri Parse(ITextReader reader)
        {
            string first = reader.ReadUntil("@:");
            string scheme = null;
            string userName;
            string password = null;
            string domain;
            int port = 0;
            bool containsAt = reader.Contains('@');

            // scheme:domain:port
            // scheme:domain
            // domain:port
            if (reader.Current == ':' && !containsAt)
            {
                reader.Consume();

                //scheme:domain:port or scheme:domain
                if (IsValidScheme(first))
                {
                    scheme = first;
                    domain = reader.ReadToEnd(":");
                    if (reader.EOF)
                        return new SipUri(scheme, domain, 0);

                    //scheme:domain:port
                    reader.Consume(':');
                    first = reader.ReadToEnd();
                }
                else // domain:port or just domain
                {
                    domain = first;
                    first = reader.ReadToEnd(":");
                }

                if (!int.TryParse(first, out port))
                    throw new ParseException("Port is not a number: " + first);

                return new SipUri(scheme, domain, port);
            }
                // Can either be "scheme:username"
                // or "username:password"
                // or "scheme:username:password"
            else if (reader.Current == ':')
            {
                reader.Consume();

                // Check if we got another colon (scheme:username:password)
                string second = reader.ReadUntil(":@");
                if (reader.Current == ':')
                {
                    scheme = first;
                    userName = second;
                    reader.Consume();
                    password = reader.ReadUntil('@');
                }
                    // it's "scheme:username" or "username:password"
                else
                {
                    //TODO: Create a ProtocolProvider singleton
                    if (first == "tel" || first == "sip" || first == "sips" || first == "mailto")
                    {
                        scheme = first;
                        userName = second;
                    }
                    else
                    {
                        userName = first;
                        password = second;
                    }
                }
            }
                // only username
            else
                userName = first;

            reader.Consume(); // eat delimiter.
            domain = reader.ReadToEnd(":;");
            if (reader.Current == '\r' || userName == null)
                return null; // domain was not specified.

            // We got a port.
            if (reader.Current == ':')
            {
                reader.Consume();
                string portStr = reader.ReadToEnd(';');
                if (portStr != null)
                {
                    if (!int.TryParse(portStr, out port))
                        return null;
                }
            }

            // parse parameters
            var values = new KeyValueCollection();
            if (reader.Current == ';')
                ParseParameters(values, reader);

            return new SipUri(scheme, userName, password, domain, port, values);
        }