From c14eea09c236a88ac87b4824162fb4c676f394b9 Mon Sep 17 00:00:00 2001 From: John Luo Date: Thu, 10 Dec 2015 18:25:50 -0800 Subject: [PATCH 1/4] Constant Encoded StringValues #64 --- .../StringValues.cs | 27 ++++++++ .../StringValuesTests.cs | 67 +++++++++++++++++++ 2 files changed, 94 insertions(+) diff --git a/src/Microsoft.Extensions.Primitives/StringValues.cs b/src/Microsoft.Extensions.Primitives/StringValues.cs index 68a2d13a369..8e4da94510b 100644 --- a/src/Microsoft.Extensions.Primitives/StringValues.cs +++ b/src/Microsoft.Extensions.Primitives/StringValues.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Text; using System.Collections; using System.Collections.Generic; using Microsoft.Extensions.Internal; @@ -18,17 +19,36 @@ public struct StringValues : IList, IReadOnlyList, IEquatable { private readonly string[] _values; diff --git a/test/Microsoft.Extensions.Primitives.Tests/StringValuesTests.cs b/test/Microsoft.Extensions.Primitives.Tests/StringValuesTests.cs index a0299065c81..78ba8d9a572 100644 --- a/test/Microsoft.Extensions.Primitives.Tests/StringValuesTests.cs +++ b/test/Microsoft.Extensions.Primitives.Tests/StringValuesTests.cs @@ -5,6 +5,7 @@ using System.Collections; using System.Collections.Generic; using System.Linq; +using System.Text; using Xunit; namespace Microsoft.Extensions.Primitives @@ -455,5 +456,71 @@ public void Equals_StringArray(StringValues stringValues, string[] expected) Assert.True(StringValues.Equals(stringValues, expected)); Assert.False(StringValues.Equals(stringValues, notEqual)); } + + [Theory] + [MemberData(nameof(DefaultOrNullStringValues))] + [MemberData(nameof(EmptyStringValues))] + [MemberData(nameof(FilledStringValues))] + public void TryGetConstant_NullDefaultEncodingAndEncodedBytes(StringValues stringValues) + { + Encoding encoding; + byte[] bytes; + + Assert.False(stringValues.TryGetConstant(out bytes, out encoding)); + Assert.Null(encoding); + Assert.Null(bytes); + } + + [Theory] + [MemberData(nameof(DefaultOrNullStringValues))] + [MemberData(nameof(EmptyStringValues))] + public void CreateConstant_ThrowsForNullOrEmpty(StringValues stringValues) + { + Assert.Throws(() => (StringValues.CreateConstant(stringValues, Encoding.ASCII))); + } + + [Fact] + public void CreateConstant_EncodesEmptyString() + { + var stringValueConstant = StringValues.CreateConstant("", Encoding.ASCII); + byte[] bytes; + Encoding encoding; + + stringValueConstant.TryGetConstant(out bytes, out encoding); + + Assert.NotNull(bytes); + Assert.Empty(bytes); + } + + [Fact] + public void CreateConstant_EncodesUsingSpecifiedEncoding() + { + var testString = "foo bar"; + var expectedBytes = Encoding.ASCII.GetBytes(testString); + byte[] outBytes; + Encoding outEncoding; + + var constantStringValues = StringValues.CreateConstant(testString, Encoding.ASCII); + constantStringValues.TryGetConstant(out outBytes, out outEncoding); + + Assert.Equal(expectedBytes, outBytes); + Assert.Equal(Encoding.ASCII, outEncoding); + } + + [Fact] + public void TryGetConstant_ReturnsIdenticalBytesAndEncoding() + { + var encoding = Encoding.GetEncoding(20127); // US-ASCII + var constantStringValues = StringValues.CreateConstant("foo bar", encoding); + + byte[] bytes1, bytes2; + Encoding encoding1, encoding2; + constantStringValues.TryGetConstant(out bytes1, out encoding1); + constantStringValues.TryGetConstant(out bytes2, out encoding2); + + Assert.Same(bytes1, bytes2); + Assert.Same(encoding, encoding1); + Assert.Same(encoding, encoding2); + } } } From fc8e5c7ec86a9436f5fdcb382b5af016309a8fb6 Mon Sep 17 00:00:00 2001 From: John Luo Date: Fri, 11 Dec 2015 18:12:21 -0800 Subject: [PATCH 2/4] PR --- .../StringValues.cs | 46 ++++++++++++------- .../StringValuesTests.cs | 18 ++++---- 2 files changed, 38 insertions(+), 26 deletions(-) diff --git a/src/Microsoft.Extensions.Primitives/StringValues.cs b/src/Microsoft.Extensions.Primitives/StringValues.cs index 8e4da94510b..d9f9e77188e 100644 --- a/src/Microsoft.Extensions.Primitives/StringValues.cs +++ b/src/Microsoft.Extensions.Primitives/StringValues.cs @@ -21,15 +21,7 @@ public struct StringValues : IList, IReadOnlyList, IEquatable + /// Creates a new instance of with one string and compute its encoded bytes with the specified Encoding. + /// + /// The string to be encoded. + /// The to be use when computing pre-encoded bytes. + /// A which contains the pre-encoded bytes. + public static StringValues CreatePreEncoded(string value, Encoding encoding) { return new StringValues(value, encoding); } + /// + /// Try to retrieve the pre-encoded bytes of the . The return value indicates whether pre-encoded bytes exist. + /// + /// If successful, contains the pre-encoded bytes of the . + /// If successful, contains the used to compute the pre-encoded bytes. + /// true if contains pre-encoded bytes, otherwise false. + public bool TryGetPreEncoded(out byte[] bytes, out Encoding encoding) + { + bytes = _bytes; + encoding = _encoding; + return _bytes != null; + } + public static implicit operator StringValues(string value) { return new StringValues(value); @@ -438,13 +457,6 @@ public override int GetHashCode() return hcc.CombinedHash; } - public bool TryGetConstant(out byte[] bytes, out Encoding encoding) - { - bytes = _bytes; - encoding = _encoding; - return _bytes != null; - } - public struct Enumerator : IEnumerator { private readonly string[] _values; diff --git a/test/Microsoft.Extensions.Primitives.Tests/StringValuesTests.cs b/test/Microsoft.Extensions.Primitives.Tests/StringValuesTests.cs index 78ba8d9a572..d69b485b17f 100644 --- a/test/Microsoft.Extensions.Primitives.Tests/StringValuesTests.cs +++ b/test/Microsoft.Extensions.Primitives.Tests/StringValuesTests.cs @@ -466,7 +466,7 @@ public void TryGetConstant_NullDefaultEncodingAndEncodedBytes(StringValues strin Encoding encoding; byte[] bytes; - Assert.False(stringValues.TryGetConstant(out bytes, out encoding)); + Assert.False(stringValues.TryGetPreEncoded(out bytes, out encoding)); Assert.Null(encoding); Assert.Null(bytes); } @@ -476,17 +476,17 @@ public void TryGetConstant_NullDefaultEncodingAndEncodedBytes(StringValues strin [MemberData(nameof(EmptyStringValues))] public void CreateConstant_ThrowsForNullOrEmpty(StringValues stringValues) { - Assert.Throws(() => (StringValues.CreateConstant(stringValues, Encoding.ASCII))); + Assert.Throws(() => (StringValues.CreatePreEncoded(stringValues, Encoding.ASCII))); } [Fact] public void CreateConstant_EncodesEmptyString() { - var stringValueConstant = StringValues.CreateConstant("", Encoding.ASCII); + var stringValueConstant = StringValues.CreatePreEncoded("", Encoding.ASCII); byte[] bytes; Encoding encoding; - stringValueConstant.TryGetConstant(out bytes, out encoding); + stringValueConstant.TryGetPreEncoded(out bytes, out encoding); Assert.NotNull(bytes); Assert.Empty(bytes); @@ -500,8 +500,8 @@ public void CreateConstant_EncodesUsingSpecifiedEncoding() byte[] outBytes; Encoding outEncoding; - var constantStringValues = StringValues.CreateConstant(testString, Encoding.ASCII); - constantStringValues.TryGetConstant(out outBytes, out outEncoding); + var constantStringValues = StringValues.CreatePreEncoded(testString, Encoding.ASCII); + constantStringValues.TryGetPreEncoded(out outBytes, out outEncoding); Assert.Equal(expectedBytes, outBytes); Assert.Equal(Encoding.ASCII, outEncoding); @@ -511,12 +511,12 @@ public void CreateConstant_EncodesUsingSpecifiedEncoding() public void TryGetConstant_ReturnsIdenticalBytesAndEncoding() { var encoding = Encoding.GetEncoding(20127); // US-ASCII - var constantStringValues = StringValues.CreateConstant("foo bar", encoding); + var constantStringValues = StringValues.CreatePreEncoded("foo bar", encoding); byte[] bytes1, bytes2; Encoding encoding1, encoding2; - constantStringValues.TryGetConstant(out bytes1, out encoding1); - constantStringValues.TryGetConstant(out bytes2, out encoding2); + constantStringValues.TryGetPreEncoded(out bytes1, out encoding1); + constantStringValues.TryGetPreEncoded(out bytes2, out encoding2); Assert.Same(bytes1, bytes2); Assert.Same(encoding, encoding1); From 9c608c8fea2ae85165636be5a0c7f9a6fc5ac273 Mon Sep 17 00:00:00 2001 From: John Luo Date: Tue, 15 Dec 2015 20:52:49 -0800 Subject: [PATCH 3/4] Change StringValues to class --- src/Microsoft.Extensions.Primitives/StringValues.cs | 4 ++-- .../StringValuesTests.cs | 6 ------ 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/Microsoft.Extensions.Primitives/StringValues.cs b/src/Microsoft.Extensions.Primitives/StringValues.cs index d9f9e77188e..b70c098a09f 100644 --- a/src/Microsoft.Extensions.Primitives/StringValues.cs +++ b/src/Microsoft.Extensions.Primitives/StringValues.cs @@ -12,7 +12,7 @@ namespace Microsoft.Extensions.Primitives /// /// Represents zero/null, one, or many strings in an efficient way. /// - public struct StringValues : IList, IReadOnlyList, IEquatable, IEquatable, IEquatable + public class StringValues : IList, IReadOnlyList, IEquatable, IEquatable, IEquatable { private static readonly string[] EmptyArray = new string[0]; public static readonly StringValues Empty = new StringValues(EmptyArray); @@ -21,7 +21,7 @@ public struct StringValues : IList, IReadOnlyList, IEquatable DefaultOrNullStringValues { return new TheoryData { - new StringValues(), new StringValues((string)null), new StringValues((string[])null), (string)null, @@ -64,7 +63,6 @@ public static TheoryData FilledStringValuesWithExpectedStr { return new TheoryData { - { default(StringValues), (string)null }, { StringValues.Empty, (string)null }, { new StringValues(new string[] { }), (string)null }, { new StringValues(string.Empty), string.Empty }, @@ -80,7 +78,6 @@ public static TheoryData FilledStringValuesWithExpectedObj { return new TheoryData { - { default(StringValues), (object)null }, { StringValues.Empty, (object)null }, { new StringValues(new string[] { }), (object)null }, { new StringValues("abc"), (object)"abc" }, @@ -97,7 +94,6 @@ public static TheoryData FilledStringValuesWithExpected { return new TheoryData { - { default(StringValues), new string[0] }, { StringValues.Empty, new string[0] }, { new StringValues(string.Empty), new[] { string.Empty } }, { new StringValues("abc"), new[] { "abc" } }, @@ -334,8 +330,6 @@ public void DefaultNullOrEmpty_Concat(StringValues stringValues) string[] empty = new string[0]; Assert.Equal(empty, StringValues.Concat(stringValues, StringValues.Empty)); Assert.Equal(empty, StringValues.Concat(StringValues.Empty, stringValues)); - Assert.Equal(empty, StringValues.Concat(stringValues, new StringValues())); - Assert.Equal(empty, StringValues.Concat(new StringValues(), stringValues)); } [Theory] From 4671bc816b267f2af6262d68d652244f5403773a Mon Sep 17 00:00:00 2001 From: John Luo Date: Thu, 14 Jan 2016 16:27:19 -0800 Subject: [PATCH 4/4] WIP --- .../StringValues.cs | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/Microsoft.Extensions.Primitives/StringValues.cs b/src/Microsoft.Extensions.Primitives/StringValues.cs index b70c098a09f..7078720df63 100644 --- a/src/Microsoft.Extensions.Primitives/StringValues.cs +++ b/src/Microsoft.Extensions.Primitives/StringValues.cs @@ -25,23 +25,16 @@ public class StringValues : IList, IReadOnlyList, IEquatableA which contains the pre-encoded bytes. public static StringValues CreatePreEncoded(string value, Encoding encoding) { + if (value == null) + { + throw new ArgumentNullException(nameof(value)); + } + if (encoding == null) + { + throw new ArgumentNullException(nameof(encoding)); + } + return new StringValues(value, encoding); } @@ -245,7 +247,7 @@ void ICollection.Clear() public Enumerator GetEnumerator() { - return new Enumerator(ref this); + return new Enumerator(this); } IEnumerator IEnumerable.GetEnumerator() @@ -463,7 +465,7 @@ public struct Enumerator : IEnumerator private string _current; private int _index; - public Enumerator(ref StringValues values) + public Enumerator(StringValues values) { _values = values._values; _current = values._value;