private static int CompareRecords(AcceptRecord Rec1, AcceptRecord Rec2) { int i = Rec1.Quality.CompareTo(Rec2.Quality); if (i != 0) { return(i); } i = Rec2.Detail - Rec1.Detail; if (i != 0) { return(i); } return(Rec1.Order - Rec2.Order); }
/// <summary> /// Parses an accept header string. /// </summary> /// <param name="Value">Accept header string</param> /// <returns>Parsed items.</returns> public static AcceptRecord[] Parse(string Value) { List <AcceptRecord> Records = new List <AcceptRecord>(); List <KeyValuePair <string, string> > Parameters = null; StringBuilder sb = new StringBuilder(); AcceptRecord Record = null; string ParameterName = null; string ParameterValue = null; double q; int State = 0; int Order = 0; foreach (char ch in Value) { switch (State) { case 0: // Item name. if (ch <= 32) { break; } else if (ch == ';' || ch == ',') { Record = new AcceptRecord() { Item = sb.ToString().Trim(), Order = Order++ }; sb.Clear(); if (ch == ';') { State++; } else { Records.Add(Record); Record = null; } } else { sb.Append(ch); } break; case 1: // Parameter Name if (ch == '=') { ParameterName = sb.ToString().Trim(); sb.Clear(); State++; } else if (ch == ';' || ch == ',') { ParameterName = sb.ToString().Trim(); sb.Clear(); if (Parameters is null) { Parameters = new List <KeyValuePair <string, string> >(); } Parameters.Add(new KeyValuePair <string, string>(ParameterName, string.Empty)); ParameterName = null; if (ch == ',') { Record.Parameters = Parameters.ToArray(); Records.Add(Record); Record = null; Parameters = null; State = 0; } } else { sb.Append(ch); } break; case 2: // Parameter value. if (ch == '"') { State++; } else if (ch == '\'') { State += 3; } else if (ch == ';' || ch == ',') { ParameterValue = sb.ToString().Trim(); sb.Clear(); if (ParameterName == "q" && CommonTypes.TryParse(ParameterValue, out q)) { Record.Quality = q; } else { if (Parameters is null) { Parameters = new List <KeyValuePair <string, string> >(); } Parameters.Add(new KeyValuePair <string, string>(ParameterName, ParameterValue)); } ParameterName = null; ParameterValue = null; if (ch == ',') { if (!(Parameters is null)) { Record.Parameters = Parameters.ToArray(); } Records.Add(Record); Record = null; Parameters = null; State = 0; } else { State--; } } else { sb.Append(ch); } break; case 3: // "Value" if (ch == '"') { State--; } else if (ch == '\\') { State++; } else { sb.Append(ch); } break; case 4: // Escape sb.Append(ch); State--; break; case 5: // 'Value' if (ch == '\'') { State -= 3; } else if (ch == '\\') { State++; } else { sb.Append(ch); } break; case 6: // Escape sb.Append(ch); State--; break; } } switch (State) { case 0: Record = new AcceptRecord() { Item = sb.ToString().Trim(), Order = Order++ }; if (!string.IsNullOrEmpty(Record.Item)) { Records.Add(Record); } break; case 1: ParameterName = sb.ToString().Trim(); if (!string.IsNullOrEmpty(ParameterName)) { if (Parameters is null) { Parameters = new List <KeyValuePair <string, string> >(); } Parameters.Add(new KeyValuePair <string, string>(ParameterName, string.Empty)); } if (!(Parameters is null)) { Record.Parameters = Parameters.ToArray(); } Records.Add(Record); break; case 2: case 3: case 4: case 5: case 6: ParameterValue = sb.ToString().Trim(); if (ParameterName == "q" && CommonTypes.TryParse(ParameterValue, out q)) { Record.Quality = q; } else { if (Parameters is null) { Parameters = new List <KeyValuePair <string, string> >(); } Parameters.Add(new KeyValuePair <string, string>(ParameterName, ParameterValue)); } if (!(Parameters is null)) { Record.Parameters = Parameters.ToArray(); } Records.Add(Record); break; } Records.Sort(CompareRecords); return(Records.ToArray()); }