private Parsed ParseRgb()

in AjaxMinDll/Css/CssParser.cs [2953:3158]


        private Parsed ParseRgb()
        {
            var parsed = Parsed.False;
            if (CurrentTokenType == TokenType.Function
                && string.Compare(CurrentTokenText, "rgb(", StringComparison.OrdinalIgnoreCase) == 0)
            {
                // rgb function parsing
                var useRGB = false;
                var crunchedRGB = false;
                // converting to #rrggbb or #rgb IF we don't find any significant comments!
                // skip any space or comments
                var rgb = new int[3];

                // we're going to be building up the rgb function just in case we need it
                var sbRGB = StringBuilderPool.Acquire();
                try
                {
                    sbRGB.Append(CurrentTokenText.ToLowerInvariant());

                    var comments = NextSignificantToken();
                    if (comments.Length > 0)
                    {
                        // add the comments
                        sbRGB.Append(comments);
                        // and signal that we need to use the RGB function because of them
                        useRGB = true;
                    }

                    for (var ndx = 0; ndx < 3; ++ndx)
                    {
                        // if this isn't the first number, we better find a comma separator
                        if (ndx > 0)
                        {
                            if (CurrentTokenType == TokenType.Character && CurrentTokenText == ",")
                            {
                                // add it to the rgb string builder
                                sbRGB.Append(',');
                            }
                            else if (CurrentTokenType == TokenType.Character && CurrentTokenText == ")")
                            {
                                ReportError(0, CssErrorCode.ExpectedComma, CurrentTokenText);

                                // closing paren is the end of the function! exit the loop
                                useRGB = true;
                                break;
                            }
                            else
                            {
                                ReportError(0, CssErrorCode.ExpectedComma, CurrentTokenText);
                                sbRGB.Append(CurrentTokenText);
                                useRGB = true;
                            }

                            // skip to the next significant
                            comments = NextSignificantToken();
                            if (comments.Length > 0)
                            {
                                // add the comments
                                sbRGB.Append(comments);
                                // and signal that we need to use the RGB function because of them
                                useRGB = true;
                            }
                        }

                        // although we ALLOW negative numbers here, we'll trim them
                        // later. But in the mean time, save a negation flag.
                        var negateNumber = false;
                        if (CurrentTokenType == TokenType.Character && CurrentTokenText == "-")
                        {
                            negateNumber = true;
                            comments = NextSignificantToken();
                            if (comments.Length > 0)
                            {
                                // add the comments
                                sbRGB.Append(comments);
                                // and signal that we need to use the RGB function because of them
                                useRGB = true;
                            }
                        }

                        // we might adjust the value, so save the token text
                        var tokenText = CurrentTokenText;

                        if (CurrentTokenType != TokenType.Number && CurrentTokenType != TokenType.Percentage)
                        {
                            ReportError(0, CssErrorCode.ExpectedRgbNumberOrPercentage, CurrentTokenText);
                            useRGB = true;
                        }
                        else
                        {
                            if (CurrentTokenType == TokenType.Number)
                            {
                                // get the number value
                                float numberValue;
                                if (tokenText.TryParseSingleInvariant(out numberValue))
                                {
                                    numberValue *= (negateNumber ? -1 : 1);
                                    // make sure it's between 0 and 255
                                    if (numberValue < 0)
                                    {
                                        tokenText = "0";
                                        rgb[ndx] = 0;
                                    }
                                    else if (numberValue > 255)
                                    {
                                        tokenText = "255";
                                        rgb[ndx] = 255;
                                    }
                                    else
                                    {
                                        rgb[ndx] = System.Convert.ToInt32(numberValue);
                                    }
                                }
                                else
                                {
                                    // error -- not even a number. Keep the rgb function
                                    // (and don't change the token)
                                    useRGB = true;
                                }
                            }
                            else
                            {
                                // percentage
                                float percentageValue;
                                if (tokenText.Substring(0, tokenText.Length - 1).TryParseSingleInvariant(out percentageValue))
                                {
                                    percentageValue *= (negateNumber ? -1 : 1);
                                    if (percentageValue < 0)
                                    {
                                        tokenText = "0%";
                                        rgb[ndx] = 0;
                                    }
                                    else if (percentageValue > 100)
                                    {
                                        tokenText = "100%";
                                        rgb[ndx] = 255;
                                    }
                                    else
                                    {
                                        rgb[ndx] = System.Convert.ToInt32(percentageValue * 255 / 100);
                                    }
                                }
                                else
                                {
                                    // error -- not even a number. Keep the rgb function
                                    // (and don't change the token)
                                    useRGB = true;
                                }
                            }
                        }

                        // add the number to the rgb string builder
                        sbRGB.Append(tokenText);

                        // skip to the next significant
                        comments = NextSignificantToken();
                        if (comments.Length > 0)
                        {
                            // add the comments
                            sbRGB.Append(comments);
                            // and signal that we need to use the RGB function because of them
                            useRGB = true;
                        }
                    }

                    if (useRGB)
                    {
                        // something prevented us from collapsing the rgb function
                        // just output the rgb function we've been building up
                        Append(sbRGB.ToString());
                    }
                    else
                    {
                        // we can collapse it to either #rrggbb or #rgb
                        // calculate the full hex string and crunch it
                        var fullCode = "#{0:x2}{1:x2}{2:x2}".FormatInvariant(rgb[0], rgb[1], rgb[2]);
                        var hexString = CrunchHexColor(fullCode, Settings.ColorNames, m_noColorAbbreviation);
                        Append(hexString);

                        // set the flag so we know we don't want to add the closing paren
                        crunchedRGB = true;
                    }
                }
                finally
                {
                    sbRGB.Release();
                }

                if (CurrentTokenType == TokenType.Character && CurrentTokenText == ")")
                {
                    if (!crunchedRGB)
                    {
                        AppendCurrent();
                    }

                    SkipSpace();
                    parsed = Parsed.True;
                }
                else
                {
                    ReportError(0, CssErrorCode.ExpectedClosingParenthesis, CurrentTokenText);
                }
            }

            return parsed;
        }