/// <summary> /// Reads a token or token=(token|quoted-string) from the <paramref name="lexer"/>, convert it to a key value pair and advances the <paramref name="lexer"/>. /// </summary> /// <param name="lexer">The lexer to read from.</param> /// <returns>The converted key value pair.</returns> private static KeyValuePair <string, string> ReadKeyValuePair(ref HttpHeaderValueLexer lexer) { Debug.Assert(lexer.Type == HttpHeaderValueItemType.Token, "lexer.Type == HttpHeaderValueItemType.Token"); string name = lexer.OriginalText; string value = null; lexer = lexer.ReadNext(); if (lexer.Type == HttpHeaderValueItemType.ValueSeparator) { lexer = lexer.ReadNext(); Debug.Assert( lexer.Type == HttpHeaderValueItemType.Token || lexer.Type == HttpHeaderValueItemType.QuotedString, "lexer.Type == HttpHeaderValueItemType.Token || lexer.Type == HttpHeaderValueItemType.QuotedString"); value = lexer.OriginalText; lexer = lexer.ReadNext(); } Debug.Assert( lexer.Type == HttpHeaderValueItemType.End || lexer.Type == HttpHeaderValueItemType.ElementSeparator || lexer.Type == HttpHeaderValueItemType.ParameterSeparator, "lexer.Type == HttpHeaderValueItemType.End || lexer.Type == HttpHeaderValueItemType.ElementSeparator || lexer.Type == HttpHeaderValueItemType.ParameterSeparator"); return(new KeyValuePair <string, string>(name, value)); }
/// <summary> /// Reads the content of a HTTP header from this <see cref="HttpHeaderValueLexer"/> instance to a new <see cref="HttpHeaderValue"/> instance. /// </summary> /// <returns>A new <see cref="HttpHeaderValue"/> instance populated with the content from this <see cref="HttpHeaderValueLexer"/> instance.</returns> internal HttpHeaderValue ToHttpHeaderValue() { HttpHeaderValueLexer lexer = this; Debug.Assert( lexer.Type == HttpHeaderValueItemType.Start, "lexer.Type == HttpHeaderValueItemType.Start -- Should only call this method on a lexer that's not yet been read."); HttpHeaderValue headerValue = new HttpHeaderValue(); // header = "header-name" ":" 1#element // element = token [ BWS "=" BWS (token | quoted-string) ] // *( OWS ";" [ OWS parameter ] ) // parameter = token [ BWS "=" BWS (token | quoted-string) ] while (true) { if (lexer.Type == HttpHeaderValueItemType.End) { break; } Debug.Assert( lexer.Type == HttpHeaderValueItemType.Start || lexer.Type == HttpHeaderValueItemType.ElementSeparator, "lexer.Type == HttpHeaderValueItemType.Start || lexer.Type == HttpHeaderValueItemType.ElementSeparator"); lexer = lexer.ReadNext(); Debug.Assert( lexer.Type == HttpHeaderValueItemType.Token || lexer.Type == HttpHeaderValueItemType.End, "lexer.Type == HttpHeaderValueItemType.Token || lexer.Type == HttpHeaderValueItemType.End"); if (lexer.Type == HttpHeaderValueItemType.Token) { var element = ReadHttpHeaderValueElement(ref lexer); // If multiple elements with the same name encountered, the first one wins. if (!headerValue.ContainsKey(element.Name)) { headerValue.Add(element.Name, element); } } } return(headerValue); }
/// <summary> /// Reads a <see cref="HttpHeaderValueElement"/> from <paramref name="lexer"/> and advances the <paramref name="lexer"/> forward. /// </summary> /// <param name="lexer">The lexer to read from.</param> /// <returns>The <see cref="HttpHeaderValueElement"/> that was read.</returns> private static HttpHeaderValueElement ReadHttpHeaderValueElement(ref HttpHeaderValueLexer lexer) { Debug.Assert(lexer.Type == HttpHeaderValueItemType.Token, "lexer.Type == HttpHeaderValueItemType.Token"); List <KeyValuePair <string, string> > keyValuePairs = new List <KeyValuePair <string, string> > { ReadKeyValuePair(ref lexer) }; while (lexer.Type == HttpHeaderValueItemType.ParameterSeparator) { lexer = lexer.ReadNext(); keyValuePairs.Add(ReadKeyValuePair(ref lexer)); } Debug.Assert( lexer.Type == HttpHeaderValueItemType.ElementSeparator || lexer.Type == HttpHeaderValueItemType.End, "lexer.Type == HttpHeaderValueItemType.ElementSeparator || lexer.Type == HttpHeaderValueItemType.End"); return(new HttpHeaderValueElement(keyValuePairs[0].Key, keyValuePairs[0].Value, keyValuePairs.Skip(1).ToArray())); }
/// <summary> /// Reads a token or token=(token|quoted-string) from the <paramref name="lexer"/>, convert it to a key value pair and advances the <paramref name="lexer"/>. /// </summary> /// <param name="lexer">The lexer to read from.</param> /// <returns>The converted key value pair.</returns> private static KeyValuePair<string, string> ReadKeyValuePair(ref HttpHeaderValueLexer lexer) { Debug.Assert(lexer.Type == HttpHeaderValueItemType.Token, "lexer.Type == HttpHeaderValueItemType.Token"); string name = lexer.OriginalText; string value = null; lexer = lexer.ReadNext(); if (lexer.Type == HttpHeaderValueItemType.ValueSeparator) { lexer = lexer.ReadNext(); Debug.Assert( lexer.Type == HttpHeaderValueItemType.Token || lexer.Type == HttpHeaderValueItemType.QuotedString, "lexer.Type == HttpHeaderValueItemType.Token || lexer.Type == HttpHeaderValueItemType.QuotedString"); value = lexer.OriginalText; lexer = lexer.ReadNext(); } Debug.Assert( lexer.Type == HttpHeaderValueItemType.End || lexer.Type == HttpHeaderValueItemType.ElementSeparator || lexer.Type == HttpHeaderValueItemType.ParameterSeparator, "lexer.Type == HttpHeaderValueItemType.End || lexer.Type == HttpHeaderValueItemType.ElementSeparator || lexer.Type == HttpHeaderValueItemType.ParameterSeparator"); return new KeyValuePair<string, string>(name, value); }
/// <summary> /// Reads a <see cref="HttpHeaderValueElement"/> from <paramref name="lexer"/> and advances the <paramref name="lexer"/> forward. /// </summary> /// <param name="lexer">The lexer to read from.</param> /// <returns>The <see cref="HttpHeaderValueElement"/> that was read.</returns> private static HttpHeaderValueElement ReadHttpHeaderValueElement(ref HttpHeaderValueLexer lexer) { Debug.Assert(lexer.Type == HttpHeaderValueItemType.Token, "lexer.Type == HttpHeaderValueItemType.Token"); List<KeyValuePair<string, string>> keyValuePairs = new List<KeyValuePair<string, string>> { ReadKeyValuePair(ref lexer) }; while (lexer.Type == HttpHeaderValueItemType.ParameterSeparator) { lexer = lexer.ReadNext(); keyValuePairs.Add(ReadKeyValuePair(ref lexer)); } Debug.Assert( lexer.Type == HttpHeaderValueItemType.ElementSeparator || lexer.Type == HttpHeaderValueItemType.End, "lexer.Type == HttpHeaderValueItemType.ElementSeparator || lexer.Type == HttpHeaderValueItemType.End"); return new HttpHeaderValueElement(keyValuePairs[0].Key, keyValuePairs[0].Value, keyValuePairs.Skip(1).ToArray()); }