Imported Upstream version 4.0.0~alpha1

Former-commit-id: 806294f5ded97629b74c85c09952f2a74fe182d9
This commit is contained in:
Jo Shields
2015-04-07 09:35:12 +01:00
parent 283343f570
commit 3c1f479b9d
22469 changed files with 2931443 additions and 869343 deletions

View File

@ -191,10 +191,11 @@ namespace System.Net.Http.Headers
t = lexer.Scan ();
if (!lexer.IsStarStringValue (t)) {
if (!lexer.TryGetNumericValue (t, out nvalue))
long lvalue;
if (!lexer.TryGetNumericValue (t, out lvalue))
return false;
value.Length = nvalue;
value.Length = lvalue;
}
t = lexer.Scan ();

View File

@ -93,14 +93,22 @@ namespace System.Net.Http.Headers
class CollectionHeaderTypeInfo<T, U> : HeaderTypeInfo<T, U> where U : class
{
readonly int minimalCount;
TryParseListDelegate<T> parser;
readonly string separator;
readonly TryParseListDelegate<T> parser;
public CollectionHeaderTypeInfo (string name, TryParseListDelegate<T> parser, HttpHeaderKind headerKind, int minimalCount)
public CollectionHeaderTypeInfo (string name, TryParseListDelegate<T> parser, HttpHeaderKind headerKind, int minimalCount, string separator)
: base (name, null, headerKind)
{
this.parser = parser;
this.minimalCount = minimalCount;
AllowsMany = true;
this.separator = separator;
}
public override string Separator {
get {
return separator;
}
}
public override bool TryParse (string value, out object result)
@ -134,9 +142,9 @@ namespace System.Net.Http.Headers
//
// Headers with #rule for defining lists of elements or *rule for defining occurences of elements
//
public static HeaderInfo CreateMulti<T> (string name, TryParseListDelegate<T> elementParser, HttpHeaderKind headerKind, int minimalCount = 1) where T : class
public static HeaderInfo CreateMulti<T> (string name, TryParseListDelegate<T> elementParser, HttpHeaderKind headerKind, int minimalCount = 1, string separator = ", ") where T : class
{
return new CollectionHeaderTypeInfo<T, T> (name, elementParser, headerKind, minimalCount);
return new CollectionHeaderTypeInfo<T, T> (name, elementParser, headerKind, minimalCount, separator);
}
public object CreateCollection (HttpHeaders headers)
@ -144,6 +152,13 @@ namespace System.Net.Http.Headers
return CreateCollection (headers, this);
}
public virtual string Separator {
get {
// Needed for AllowsMany only
throw new NotSupportedException ();
}
}
public abstract void AddToCollection (object collection, object value);
protected abstract object CreateCollection (HttpHeaders headers, HeaderInfo headerInfo);
public abstract List<string> ToStringCollection (object collection);

View File

@ -97,7 +97,7 @@ namespace System.Net.Http.Headers
// what .NET does when one of the values is invalid
// But it better represents what is actually hold by
// the collection
return string.Join (", ", list);
return string.Join (headerInfo.Separator, list);
}
public bool TryParseAdd (string input)

View File

@ -124,12 +124,12 @@ namespace System.Net.Http.Headers
HeaderInfo.CreateSingle<RangeHeaderValue> ("Range", RangeHeaderValue.TryParse, HttpHeaderKind.Request),
HeaderInfo.CreateSingle<Uri> ("Referer", Parser.Uri.TryParse, HttpHeaderKind.Request),
HeaderInfo.CreateSingle<RetryConditionHeaderValue> ("Retry-After", RetryConditionHeaderValue.TryParse, HttpHeaderKind.Response),
HeaderInfo.CreateMulti<ProductInfoHeaderValue> ("Server", ProductInfoHeaderValue.TryParse, HttpHeaderKind.Response),
HeaderInfo.CreateMulti<ProductInfoHeaderValue> ("Server", ProductInfoHeaderValue.TryParse, HttpHeaderKind.Response, separator: " "),
HeaderInfo.CreateMulti<TransferCodingWithQualityHeaderValue> ("TE", TransferCodingWithQualityHeaderValue.TryParse, HttpHeaderKind.Request, 0),
HeaderInfo.CreateMulti<string> ("Trailer", CollectionParser.TryParse, HttpHeaderKind.Request | HttpHeaderKind.Response),
HeaderInfo.CreateMulti<TransferCodingHeaderValue> ("Transfer-Encoding", TransferCodingHeaderValue.TryParse, HttpHeaderKind.Request | HttpHeaderKind.Response),
HeaderInfo.CreateMulti<ProductHeaderValue> ("Upgrade", ProductHeaderValue.TryParse, HttpHeaderKind.Request | HttpHeaderKind.Response),
HeaderInfo.CreateMulti<ProductInfoHeaderValue> ("User-Agent", ProductInfoHeaderValue.TryParse, HttpHeaderKind.Request),
HeaderInfo.CreateMulti<ProductInfoHeaderValue> ("User-Agent", ProductInfoHeaderValue.TryParse, HttpHeaderKind.Request, separator: " "),
HeaderInfo.CreateMulti<string> ("Vary", CollectionParser.TryParse, HttpHeaderKind.Response),
HeaderInfo.CreateMulti<ViaHeaderValue> ("Via", ViaHeaderValue.TryParse, HttpHeaderKind.Request | HttpHeaderKind.Response),
HeaderInfo.CreateMulti<WarningHeaderValue> ("Warning", WarningHeaderValue.TryParse, HttpHeaderKind.Request | HttpHeaderKind.Response),
@ -458,7 +458,8 @@ namespace System.Net.Http.Headers
HeaderBucket value;
if (!headers.TryGetValue (name, out value)) {
value = new HeaderBucket (new HttpHeaderValueCollection<T> (this, known_headers [name]));
var hinfo = known_headers[name];
value = new HeaderBucket (new HttpHeaderValueCollection<T> (this, hinfo));
headers.Add (name, value);
}

View File

@ -94,7 +94,7 @@ namespace System.Net.Http.Headers
/*90*/ true, false, false, false, true, true, true, true, true, true,
/*100*/ true, true, true, true, true, true, true, true, true, true,
/*110*/ true, true, true, true, true, true, true, true, true, true,
/*120*/ true, true, true, false, true, false
/*120*/ true, true, true, false, true, false, true
};
static readonly int last_token_char = token_chars.Length;
@ -153,6 +153,11 @@ namespace System.Net.Http.Headers
return int.TryParse (GetStringValue (token), NumberStyles.None, CultureInfo.InvariantCulture, out value);
}
public bool TryGetNumericValue (Token token, out long value)
{
return long.TryParse (GetStringValue (token), NumberStyles.None, CultureInfo.InvariantCulture, out value);
}
public TimeSpan? TryGetTimeSpanValue (Token token)
{
int seconds;
@ -202,7 +207,7 @@ namespace System.Net.Http.Headers
public static bool IsValidCharacter (char input)
{
return input <= last_token_char && token_chars[input];
return input < last_token_char && token_chars[input];
}
public void EatChar ()
@ -232,10 +237,20 @@ namespace System.Net.Http.Headers
return false;
}
int parens = 1;
while (pos < s.Length) {
var ch = s[pos];
if (ch == '(') {
++parens;
++pos;
continue;
}
if (ch == ')') {
++pos;
if (--parens > 0)
continue;
var start = readToken.StartPosition;
value = s.Substring (start, pos - start);
return true;
@ -297,18 +312,11 @@ namespace System.Net.Http.Headers
// Quoted string
start = pos - 1;
while (pos < s.Length) {
ch = s[pos];
ch = s [pos++];
if (ch == '"') {
++pos;
ttype = Token.Type.QuotedString;
break;
}
// any OCTET except CTLs, but including LWS
if (ch < 32 || ch > 126)
break;
++pos;
}
break;
@ -317,13 +325,13 @@ namespace System.Net.Http.Headers
ttype = Token.Type.OpenParens;
break;
default:
if (ch <= last_token_char && token_chars[ch]) {
if (ch < last_token_char && token_chars[ch]) {
start = pos - 1;
ttype = Token.Type.Token;
while (pos < s.Length) {
ch = s[pos];
if (ch > last_token_char || !token_chars[ch]) {
if (ch >= last_token_char || !token_chars[ch]) {
break;
}

View File

@ -89,8 +89,9 @@ namespace System.Net.Http.Headers
}
t = token.Value;
if (t == Token.Type.SeparatorSemicolon && (!NameValueHeaderValue.TryParseParameters (lexer, out parameters, out t) || t != Token.Type.End))
if (t == Token.Type.SeparatorSemicolon && !NameValueHeaderValue.TryParseParameters (lexer, out parameters, out t)) {
return false;
}
parsedValue = new MediaTypeWithQualityHeaderValue ();
parsedValue.media_type = media;

View File

@ -127,6 +127,23 @@ namespace System.Net.Http.Headers
}
list.Add (element);
// Separator parsing
switch (lexer.PeekChar ()) {
case ' ':
case '\t':
lexer.EatChar ();
continue;
case -1:
if (minimalCount <= list.Count) {
result = list;
return true;
}
break;
}
return false;
}
}

View File

@ -123,8 +123,8 @@ namespace System.Net.Http.Headers
bool token_read;
do {
int? from = null, to = null;
int number;
long? from = null, to = null;
long number;
token_read = false;
t = lexer.Scan (recognizeDash: true);
@ -139,7 +139,7 @@ namespace System.Net.Http.Headers
case Token.Type.Token:
string s = lexer.GetStringValue (t);
var values = s.Split (new [] { '-' }, StringSplitOptions.RemoveEmptyEntries);
if (!int.TryParse (values[0], out number))
if (!Parser.Long.TryParse (values[0], out number))
return false;
switch (values.Length) {
@ -178,7 +178,7 @@ namespace System.Net.Http.Headers
case 2:
from = number;
if (!int.TryParse (values[1], out number))
if (!Parser.Long.TryParse (values[1], out number))
return false;
to = number;