System.IPv6AddressHelper.Parse C# (CSharp) Method

Parse() static private method

static private Parse ( string address, ushort numbers, int start, string &scopeId ) : bool
address string
numbers ushort
start int
scopeId string
return bool
        unsafe internal static bool Parse(string address, ushort *numbers, int start, ref string scopeId) {

            int number = 0;
            int index = 0;
            int compressorIndex = -1;
            bool numberIsValid = true;

            //This used to be a class instance member but have not been used so far
            int PrefixLength = 0;
            if (address[start] == '[') {
                ++start;
            }

            for (int i = start; i < address.Length && address[i] != ']'; ) {
                switch (address[i]) {
                   case '%':
                        if (numberIsValid) {
                           numbers[index++] = (ushort)number;
                           numberIsValid = false;
                        }

                        start = i;
                        for (++i; address[i] != ']' && address[i] != '/'; ++i) {
                            ;
                        }
                        scopeId = address.Substring(start, i-start);
                        // ignore prefix if any
                        for (; address[i] != ']'; ++i) {
                            ;
                        }
                        break;

                    case ':':
                        numbers[index++] = (ushort)number;
                        number = 0;
                        ++i;
                        if (address[i] == ':') {
                            compressorIndex = index;
                            ++i;
                        } else if ((compressorIndex < 0) && (index < 6)) {

                            //
                            // no point checking for IPv4 address if we don't
                            // have a compressor or we haven't seen 6 16-bit
                            // numbers yet
                            //

                            break;
                        }

                        //
                        // check to see if the upcoming number is really an IPv4
                        // address. If it is, convert it to 2 ushort numbers
                        //

                        for (int j = i; (address[j] != ']') &&
                                        (address[j] != ':') &&
                                        (address[j] != '%') &&
                                        (address[j] != '/') &&
                                        (j < i + 4); ++j) {

                            if (address[j] == '.') {

                                //
                                // we have an IPv4 address. Find the end of it:
                                // we know that since we have a valid IPv6
                                // address, the only things that will terminate
                                // the IPv4 address are the prefix delimiter '/'
                                // or the end-of-string (which we conveniently
                                // delimited with ']')
                                //

                                while ((address[j] != ']') && (address[j] != '/') && (address[j] != '%')) {
                                    ++j;
                                }
                                number = IPv4AddressHelper.ParseHostNumber(address, i, j);
                                numbers[index++] = (ushort)(number>>16);
                                numbers[index++] = (ushort)number;
                                i = j;

                                //
                                // set this to avoid adding another number to
                                // the array if there's a prefix
                                //

                                number = 0;
                                numberIsValid = false;
                                break;
                            }
                        }
                        break;

                    case '/':
                        if (numberIsValid) {
                            numbers[index++] = (ushort)number;
                            numberIsValid = false;
                        }

                        //
                        // since we have a valid IPv6 address string, the prefix
                        // length is the last token in the string
                        //

                        for (++i; address[i] != ']'; ++i) {
                            PrefixLength = PrefixLength * 10 + (address[i] - '0');
                        }
                        break;

                    default:
                        number = number * 16 + Uri.FromHex(address[i++]);
                        break;
                }
            }

            //
            // add number to the array if its not the prefix length or part of
            // an IPv4 address that's already been handled
            //

            if (numberIsValid) {
                numbers[index++] = (ushort)number;
            }

            //
            // if we had a compressor sequence ("::") then we need to expand the
            // numbers array
            //

            if (compressorIndex > 0) {

                int toIndex = NumberOfLabels - 1;
                int fromIndex = index - 1;

                for (int i = index - compressorIndex; i > 0 ; --i) {
                    numbers[toIndex--] = numbers[fromIndex];
                    numbers[fromIndex--] = 0;
                }
            }

            //
            // is the address loopback? Loopback is defined as one of:
            //
            //  0:0:0:0:0:0:0:1
            //  0:0:0:0:0:0:127.0.0.1       == 0:0:0:0:0:0:7F00:0001
            //  0:0:0:0:0:FFFF:127.0.0.1    == 0:0:0:0:0:FFFF:7F00:0001
            //

            return          ((numbers[0] == 0)
                            && (numbers[1] == 0)
                            && (numbers[2] == 0)
                            && (numbers[3] == 0)
                            && (numbers[4] == 0))
                           && (((numbers[5] == 0)
                                && (numbers[6] == 0)
                                && (numbers[7] == 1))
                               || (((numbers[6] == 0x7F00)
                                    && (numbers[7] == 0x0001))
                                   && ((numbers[5] == 0)
                                       || (numbers[5] == 0xFFFF))));

        }
    }