Beispiel #1
0
        internal static string[] ParseMultipartIdentifier(string name, string leftQuote, string rightQuote, char separator, int limit, bool removequotes, string property, bool ThrowOnEmptyMultipartName)
        {
            if (limit <= 0)
            {
                throw ADP.InvalidMultipartNameToManyParts(property, name, limit);
            }
            if (((-1 != leftQuote.IndexOf(separator)) || (-1 != rightQuote.IndexOf(separator))) || (leftQuote.Length != rightQuote.Length))
            {
                throw ADP.InvalidMultipartNameIncorrectUsageOfQuotes(property, name);
            }
            string[]      ary      = new string[limit];
            int           index    = 0;
            MPIState      state    = MPIState.MPI_Value;
            StringBuilder builder  = new StringBuilder(name.Length);
            StringBuilder builder2 = null;
            char          ch2      = ' ';

            for (int i = 0; i < name.Length; i++)
            {
                int  num5;
                char ch = name[i];
                switch (state)
                {
                case MPIState.MPI_Value:
                {
                    if (!IsWhitespace(ch))
                    {
                        if (ch != separator)
                        {
                            break;
                        }
                        ary[index] = string.Empty;
                        IncrementStringCount(name, ary, ref index, property);
                    }
                    continue;
                }

                case MPIState.MPI_ParseNonQuote:
                {
                    if (ch != separator)
                    {
                        goto Label_0135;
                    }
                    ary[index] = builder.ToString();
                    IncrementStringCount(name, ary, ref index, property);
                    state = MPIState.MPI_Value;
                    continue;
                }

                case MPIState.MPI_LookForSeparator:
                {
                    if (!IsWhitespace(ch))
                    {
                        if (ch != separator)
                        {
                            throw ADP.InvalidMultipartNameIncorrectUsageOfQuotes(property, name);
                        }
                        IncrementStringCount(name, ary, ref index, property);
                        state = MPIState.MPI_Value;
                    }
                    continue;
                }

                case MPIState.MPI_LookForNextCharOrSeparator:
                {
                    if (IsWhitespace(ch))
                    {
                        goto Label_01DD;
                    }
                    if (ch != separator)
                    {
                        goto Label_01BB;
                    }
                    IncrementStringCount(name, ary, ref index, property);
                    state = MPIState.MPI_Value;
                    continue;
                }

                case MPIState.MPI_ParseQuote:
                {
                    if (ch != ch2)
                    {
                        goto Label_0203;
                    }
                    if (!removequotes)
                    {
                        builder.Append(ch);
                    }
                    state = MPIState.MPI_RightQuote;
                    continue;
                }

                case MPIState.MPI_RightQuote:
                {
                    if (ch != ch2)
                    {
                        goto Label_021E;
                    }
                    builder.Append(ch);
                    state = MPIState.MPI_ParseQuote;
                    continue;
                }

                default:
                {
                    continue;
                }
                }
                if (-1 != (num5 = leftQuote.IndexOf(ch)))
                {
                    ch2            = rightQuote[num5];
                    builder.Length = 0;
                    if (!removequotes)
                    {
                        builder.Append(ch);
                    }
                    state = MPIState.MPI_ParseQuote;
                }
                else
                {
                    if (-1 != rightQuote.IndexOf(ch))
                    {
                        throw ADP.InvalidMultipartNameIncorrectUsageOfQuotes(property, name);
                    }
                    builder.Length = 0;
                    builder.Append(ch);
                    state = MPIState.MPI_ParseNonQuote;
                }
                continue;
Label_0135:
                if (-1 != rightQuote.IndexOf(ch))
                {
                    throw ADP.InvalidMultipartNameIncorrectUsageOfQuotes(property, name);
                }
                if (-1 != leftQuote.IndexOf(ch))
                {
                    throw ADP.InvalidMultipartNameIncorrectUsageOfQuotes(property, name);
                }
                if (IsWhitespace(ch))
                {
                    ary[index] = builder.ToString();
                    if (builder2 == null)
                    {
                        builder2 = new StringBuilder();
                    }
                    builder2.Length = 0;
                    builder2.Append(ch);
                    state = MPIState.MPI_LookForNextCharOrSeparator;
                }
                else
                {
                    builder.Append(ch);
                }
                continue;
Label_01BB:
                builder.Append(builder2);
                builder.Append(ch);
                ary[index] = builder.ToString();
                state      = MPIState.MPI_ParseNonQuote;
                continue;
Label_01DD:
                builder2.Append(ch);
                continue;
Label_0203:
                builder.Append(ch);
                continue;
Label_021E:
                if (ch == separator)
                {
                    ary[index] = builder.ToString();
                    IncrementStringCount(name, ary, ref index, property);
                    state = MPIState.MPI_Value;
                }
                else
                {
                    if (!IsWhitespace(ch))
                    {
                        throw ADP.InvalidMultipartNameIncorrectUsageOfQuotes(property, name);
                    }
                    ary[index] = builder.ToString();
                    state      = MPIState.MPI_LookForSeparator;
                }
            }
            switch (state)
            {
            case MPIState.MPI_Value:
            case MPIState.MPI_LookForSeparator:
            case MPIState.MPI_LookForNextCharOrSeparator:
                break;

            case MPIState.MPI_ParseNonQuote:
            case MPIState.MPI_RightQuote:
                ary[index] = builder.ToString();
                break;

            default:
                throw ADP.InvalidMultipartNameIncorrectUsageOfQuotes(property, name);
            }
            if (ary[0] == null)
            {
                if (ThrowOnEmptyMultipartName)
                {
                    throw ADP.InvalidMultipartName(property, name);
                }
                return(ary);
            }
            int num3 = (limit - index) - 1;

            if (num3 > 0)
            {
                for (int j = limit - 1; j >= num3; j--)
                {
                    ary[j]        = ary[j - num3];
                    ary[j - num3] = null;
                }
            }
            return(ary);
        }
        internal static string[] ParseMultipartIdentifier(string name, string leftQuote, string rightQuote, char separator, int limit, bool removequotes, string property, bool ThrowOnEmptyMultipartName)
        {
            if (limit <= 0)
            {
                throw ADP.InvalidMultipartNameToManyParts(property, name, limit);
            }

            if (-1 != leftQuote.IndexOf(separator) || -1 != rightQuote.IndexOf(separator) || leftQuote.Length != rightQuote.Length)
            {
                throw ADP.InvalidMultipartNameIncorrectUsageOfQuotes(property, name);
            }

            string[] parsedNames = new string[limit];                      // return string array
            int      stringCount = 0;                                      // index of current string in the buffer
            MPIState state       = MPIState.MPI_Value;                     // Initalize the starting state

            StringBuilder sb             = new StringBuilder(name.Length); // String buffer to hold the string being currently built, init the string builder so it will never be resized
            StringBuilder whitespaceSB   = null;                           // String buffer to hold whitespace used when parsing nonquoted strings  'a b .  c d' = 'a b' and 'c d'
            char          rightQuoteChar = ' ';                            // Right quote character to use given the left quote character found.

            for (int index = 0; index < name.Length; ++index)
            {
                char testchar = name[index];
                switch (state)
                {
                case MPIState.MPI_Value:
                {
                    int quoteIndex;
                    if (IsWhitespace(testchar))
                    {            // Is White Space then skip the whitespace
                        continue;
                    }
                    else
                    if (testchar == separator)
                    {          // If we found a separator, no string was found, initalize the string we are parsing to Empty and the next one to Empty.
                               // This is NOT a redundent setting of string.Empty it solves the case where we are parsing ".foo" and we should be returning null, null, empty, foo
                        parsedNames[stringCount] = string.Empty;
                        IncrementStringCount(name, parsedNames, ref stringCount, property);
                    }
                    else
                    if (-1 != (quoteIndex = leftQuote.IndexOf(testchar)))
                    {                                            // If we are a left quote
                        rightQuoteChar = rightQuote[quoteIndex]; // record the corresponding right quote for the left quote
                        sb.Length      = 0;
                        if (!removequotes)
                        {
                            sb.Append(testchar);
                        }
                        state = MPIState.MPI_ParseQuote;
                    }
                    else
                    if (-1 != rightQuote.IndexOf(testchar))
                    {         // If we shouldn't see a right quote
                        throw ADP.InvalidMultipartNameIncorrectUsageOfQuotes(property, name);
                    }
                    else
                    {
                        sb.Length = 0;
                        sb.Append(testchar);
                        state = MPIState.MPI_ParseNonQuote;
                    }
                    break;
                }

                case MPIState.MPI_ParseNonQuote:
                {
                    if (testchar == separator)
                    {
                        parsedNames[stringCount] = sb.ToString();         // set the currently parsed string
                        IncrementStringCount(name, parsedNames, ref stringCount, property);
                        state = MPIState.MPI_Value;
                    }
                    else         // Quotes are not valid inside a non-quoted name
                    if (-1 != rightQuote.IndexOf(testchar))
                    {
                        throw ADP.InvalidMultipartNameIncorrectUsageOfQuotes(property, name);
                    }
                    else
                    if (-1 != leftQuote.IndexOf(testchar))
                    {
                        throw ADP.InvalidMultipartNameIncorrectUsageOfQuotes(property, name);
                    }
                    else
                    if (IsWhitespace(testchar))
                    {                                             // If it is Whitespace
                        parsedNames[stringCount] = sb.ToString(); // Set the currently parsed string
                        if (null == whitespaceSB)
                        {
                            whitespaceSB = new StringBuilder();
                        }
                        whitespaceSB.Length = 0;
                        whitespaceSB.Append(testchar);          // start to record the whitespace, if we are parsing a name like "foo bar" we should return "foo bar"
                        state = MPIState.MPI_LookForNextCharOrSeparator;
                    }
                    else
                    {
                        sb.Append(testchar);
                    }
                    break;
                }

                case MPIState.MPI_LookForNextCharOrSeparator:
                {
                    if (!IsWhitespace(testchar))
                    {         // If it is not whitespace
                        if (testchar == separator)
                        {
                            IncrementStringCount(name, parsedNames, ref stringCount, property);
                            state = MPIState.MPI_Value;
                        }
                        else
                        {         // If its not a separator and not whitespace
                            sb.Append(whitespaceSB);
                            sb.Append(testchar);
                            parsedNames[stringCount] = sb.ToString();         // Need to set the name here in case the string ends here.
                            state = MPIState.MPI_ParseNonQuote;
                        }
                    }
                    else
                    {
                        whitespaceSB.Append(testchar);
                    }
                    break;
                }

                case MPIState.MPI_ParseQuote:
                {
                    if (testchar == rightQuoteChar)
                    {            // if se are on a right quote see if we are escapeing the right quote or ending the quoted string
                        if (!removequotes)
                        {
                            sb.Append(testchar);
                        }
                        state = MPIState.MPI_RightQuote;
                    }
                    else
                    {
                        sb.Append(testchar);         // Append what we are currently parsing
                    }
                    break;
                }

                case MPIState.MPI_RightQuote:
                {
                    if (testchar == rightQuoteChar)
                    {         // If the next char is a another right quote then we were escapeing the right quote
                        sb.Append(testchar);
                        state = MPIState.MPI_ParseQuote;
                    }
                    else
                    if (testchar == separator)
                    {              // If its a separator then record what we've parsed
                        parsedNames[stringCount] = sb.ToString();
                        IncrementStringCount(name, parsedNames, ref stringCount, property);
                        state = MPIState.MPI_Value;
                    }
                    else
                    if (!IsWhitespace(testchar))
                    {         // If it is not whitespace we got problems
                        throw ADP.InvalidMultipartNameIncorrectUsageOfQuotes(property, name);
                    }
                    else
                    {                                  // It is a whitespace character so the following char should be whitespace, separator, or end of string anything else is bad
                        parsedNames[stringCount] = sb.ToString();
                        state = MPIState.MPI_LookForSeparator;
                    }
                    break;
                }

                case MPIState.MPI_LookForSeparator:
                {
                    if (!IsWhitespace(testchar))
                    {         // If it is not whitespace
                        if (testchar == separator)
                        {     // If it is a separator
                            IncrementStringCount(name, parsedNames, ref stringCount, property);
                            state = MPIState.MPI_Value;
                        }
                        else
                        {         // Othewise not a separator
                            throw ADP.InvalidMultipartNameIncorrectUsageOfQuotes(property, name);
                        }
                    }
                    break;
                }
                }
            }

            // Resolve final states after parsing the string
            switch (state)
            {
            case MPIState.MPI_Value:           // These states require no extra action
            case MPIState.MPI_LookForSeparator:
            case MPIState.MPI_LookForNextCharOrSeparator:
                break;

            case MPIState.MPI_ParseNonQuote:     // Dump what ever was parsed
            case MPIState.MPI_RightQuote:
                parsedNames[stringCount] = sb.ToString();
                break;

            case MPIState.MPI_ParseQuote:     // Invalid Ending States
            default:
                throw ADP.InvalidMultipartNameIncorrectUsageOfQuotes(property, name);
            }

            if (parsedNames[0] == null)
            {
                if (ThrowOnEmptyMultipartName)
                {
                    throw ADP.InvalidMultipartName(property, name); // Name is entirely made up of whitespace
                }
            }
            else
            {
                // Shuffle the parsed name, from left justification to right justification, ie [a][b][null][null] goes to [null][null][a][b]
                int offset = limit - stringCount - 1;
                if (offset > 0)
                {
                    for (int x = limit - 1; x >= offset; --x)
                    {
                        parsedNames[x]          = parsedNames[x - offset];
                        parsedNames[x - offset] = null;
                    }
                }
            }
            return(parsedNames);
        }
        /// <summary>
        /// Core function  for parsing the multipart identifer string.
        /// Note:  Left quote strings need to correspond 1 to 1 with the right quote strings
        /// example: "ab" "cd",  passed in for the left and the right quote
        /// would set a or b as a starting quote character.
        ///  If a is the starting quote char then c would be the ending quote char
        /// otherwise if b is the starting quote char then d would be the ending quote character.
        /// </summary>
        /// <param name="name">string to parse</param>
        /// <param name="leftQuote">set of characters which are valid quoteing characters to initiate a quote</param>
        /// <param name="rightQuote">set of characters which are valid to stop a quote, array index's correspond to the the leftquote array.</param>
        /// <param name="separator">separator to use</param>
        /// <returns></returns>
        internal static List <string> ParseMultipartIdentifier(string name, string leftQuote, string rightQuote, char separator)
        {
            Debug.Assert(-1 == leftQuote.IndexOf(separator) && -1 == rightQuote.IndexOf(separator) && leftQuote.Length == rightQuote.Length, "Incorrect usage of quotes");

            List <string> parsedNames = new List <string>();

            parsedNames.Add(null);
            int      stringCount = 0;                                      // index of current string in the list
            MPIState state       = MPIState.MPI_Value;                     // Initalize the starting state

            StringBuilder sb             = new StringBuilder(name.Length); // String buffer to hold the string being currently built, init the string builder so it will never be resized
            StringBuilder whitespaceSB   = null;                           // String buffer to hold white space used when parsing nonquoted strings  'a b .  c d' = 'a b' and 'c d'
            char          rightQuoteChar = ' ';                            // Right quote character to use given the left quote character found.

            for (int index = 0; index < name.Length; ++index)
            {
                char testchar = name[index];
                switch (state)
                {
                case MPIState.MPI_Value:
                {
                    int quoteIndex;
                    if (IsWhitespace(testchar))
                    {            // Is White Space then skip the whitespace
                        continue;
                    }
                    else
                    if (testchar == separator)
                    {              // If we found a separator, no string was found, initalize the string we are parsing to Empty and the next one to Empty.
                        // This is NOT a redundent setting of string.Empty it solves the case where we are parsing ".foo" and we should be returning null, null, empty, foo
                        parsedNames[stringCount] = string.Empty;
                        IncrementStringCount(parsedNames, ref stringCount);
                    }
                    else
                    if (-1 != (quoteIndex = leftQuote.IndexOf(testchar)))
                    {                                            // If we are a left quote
                        rightQuoteChar = rightQuote[quoteIndex]; // record the corresponding right quote for the left quote
                        sb.Length      = 0;
                        state          = MPIState.MPI_ParseQuote;
                    }
                    else
                    if (-1 != rightQuote.IndexOf(testchar))
                    {                     // If we shouldn't see a right quote
                        throw EntityUtil.ADP_InvalidMultipartNameDelimiterUsage();
                    }
                    else
                    {
                        sb.Length = 0;
                        sb.Append(testchar);
                        state = MPIState.MPI_ParseNonQuote;
                    }
                    break;
                }

                case MPIState.MPI_ParseNonQuote:
                {
                    if (testchar == separator)
                    {
                        parsedNames[stringCount] = sb.ToString();         // set the currently parsed string
                        IncrementStringCount(parsedNames, ref stringCount);
                        state = MPIState.MPI_Value;
                    }
                    else         // Quotes are not valid inside a non-quoted name
                    if (-1 != rightQuote.IndexOf(testchar))
                    {
                        throw EntityUtil.ADP_InvalidMultipartNameDelimiterUsage();
                    }
                    else
                    if (-1 != leftQuote.IndexOf(testchar))
                    {
                        throw EntityUtil.ADP_InvalidMultipartNameDelimiterUsage();
                    }
                    else
                    if (IsWhitespace(testchar))
                    {                                             // If it is Whitespace
                        parsedNames[stringCount] = sb.ToString(); // Set the currently parsed string
                        if (null == whitespaceSB)
                        {
                            whitespaceSB = new StringBuilder();
                        }
                        whitespaceSB.Length = 0;
                        whitespaceSB.Append(testchar);                      // start to record the white space, if we are parsing a name like "name with space" we should return "name with space"
                        state = MPIState.MPI_LookForNextCharOrSeparator;
                    }
                    else
                    {
                        sb.Append(testchar);
                    }
                    break;
                }

                case MPIState.MPI_LookForNextCharOrSeparator:
                {
                    if (!IsWhitespace(testchar))
                    {         // If it is not whitespace
                        if (testchar == separator)
                        {
                            IncrementStringCount(parsedNames, ref stringCount);
                            state = MPIState.MPI_Value;
                        }
                        else
                        {         // If its not a separator and not whitespace
                            sb.Append(whitespaceSB);
                            sb.Append(testchar);
                            parsedNames[stringCount] = sb.ToString();         // Need to set the name here in case the string ends here.
                            state = MPIState.MPI_ParseNonQuote;
                        }
                    }
                    else
                    {
                        whitespaceSB.Append(testchar);
                    }
                    break;
                }

                case MPIState.MPI_ParseQuote:
                {
                    if (testchar == rightQuoteChar)
                    {            // if se are on a right quote see if we are escapeing the right quote or ending the quoted string
                        state = MPIState.MPI_RightQuote;
                    }
                    else
                    {
                        sb.Append(testchar);         // Append what we are currently parsing
                    }
                    break;
                }

                case MPIState.MPI_RightQuote:
                {
                    if (testchar == rightQuoteChar)
                    {         // If the next char is a another right quote then we were escapeing the right quote
                        sb.Append(testchar);
                        state = MPIState.MPI_ParseQuote;
                    }
                    else
                    if (testchar == separator)
                    {                  // If its a separator then record what we've parsed
                        parsedNames[stringCount] = sb.ToString();
                        IncrementStringCount(parsedNames, ref stringCount);
                        state = MPIState.MPI_Value;
                    }
                    else
                    if (!IsWhitespace(testchar))
                    {                 // If it is not white space we got problems
                        throw EntityUtil.ADP_InvalidMultipartNameDelimiterUsage();
                    }
                    else
                    {                                          // It is a whitespace character so the following char should be whitespace, separator, or end of string anything else is bad
                        parsedNames[stringCount] = sb.ToString();
                        state = MPIState.MPI_LookForSeparator;
                    }
                    break;
                }

                case MPIState.MPI_LookForSeparator:
                {
                    if (!IsWhitespace(testchar))
                    {         // If it is not whitespace
                        if (testchar == separator)
                        {     // If it is a separator
                            IncrementStringCount(parsedNames, ref stringCount);
                            state = MPIState.MPI_Value;
                        }
                        else
                        {         // Othewise not a separator
                            throw EntityUtil.ADP_InvalidMultipartNameDelimiterUsage();
                        }
                    }
                    break;
                }
                }
            }

            // Resolve final states after parsing the string
            switch (state)
            {
            case MPIState.MPI_Value:           // These states require no extra action
            case MPIState.MPI_LookForSeparator:
            case MPIState.MPI_LookForNextCharOrSeparator:
                break;

            case MPIState.MPI_ParseNonQuote:     // Dump what ever was parsed
            case MPIState.MPI_RightQuote:
                parsedNames[stringCount] = sb.ToString();
                break;

            case MPIState.MPI_ParseQuote:     // Invalid Ending States
            default:
                throw EntityUtil.ADP_InvalidMultipartNameDelimiterUsage();
            }
            return(parsedNames);
        }