Commit c9b2c8f3 authored by John Brock's avatar John Brock Committed by Jon Skeet

Fixes for .NET 3.5 compatibility

* Changing DOTNET35 framework symbols in preprocessor directives to the default built-in value of NET35.
* Adding extension method StreamExtension.CopyTo for .NET 3.5 because it didn’t exist until .NET 4, and adding associated unit tests.
parent 1a8cbfd3
...@@ -83,6 +83,7 @@ csharp_EXTRA_DIST= \ ...@@ -83,6 +83,7 @@ csharp_EXTRA_DIST= \
csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs \ csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs \
csharp/src/Google.Protobuf.Test/Collections/RepeatedFieldTest.cs \ csharp/src/Google.Protobuf.Test/Collections/RepeatedFieldTest.cs \
csharp/src/Google.Protobuf.Test/Compatibility/PropertyInfoExtensionsTest.cs \ csharp/src/Google.Protobuf.Test/Compatibility/PropertyInfoExtensionsTest.cs \
csharp/src/Google.Protobuf.Test/Compatibility/StreamExtensionsTest.cs \
csharp/src/Google.Protobuf.Test/Compatibility/TypeExtensionsTest.cs \ csharp/src/Google.Protobuf.Test/Compatibility/TypeExtensionsTest.cs \
csharp/src/Google.Protobuf.Test/DeprecatedMemberTest.cs \ csharp/src/Google.Protobuf.Test/DeprecatedMemberTest.cs \
csharp/src/Google.Protobuf.Test/EqualityTester.cs \ csharp/src/Google.Protobuf.Test/EqualityTester.cs \
...@@ -125,6 +126,7 @@ csharp_EXTRA_DIST= \ ...@@ -125,6 +126,7 @@ csharp_EXTRA_DIST= \
csharp/src/Google.Protobuf/Collections/ReadOnlyDictionary.cs \ csharp/src/Google.Protobuf/Collections/ReadOnlyDictionary.cs \
csharp/src/Google.Protobuf/Collections/RepeatedField.cs \ csharp/src/Google.Protobuf/Collections/RepeatedField.cs \
csharp/src/Google.Protobuf/Compatibility/PropertyInfoExtensions.cs \ csharp/src/Google.Protobuf/Compatibility/PropertyInfoExtensions.cs \
csharp/src/Google.Protobuf/Compatibility/StreamExtensions.cs \
csharp/src/Google.Protobuf/Compatibility/TypeExtensions.cs \ csharp/src/Google.Protobuf/Compatibility/TypeExtensions.cs \
csharp/src/Google.Protobuf/FieldCodec.cs \ csharp/src/Google.Protobuf/FieldCodec.cs \
csharp/src/Google.Protobuf/FrameworkPortability.cs \ csharp/src/Google.Protobuf/FrameworkPortability.cs \
......
...@@ -34,7 +34,7 @@ using System; ...@@ -34,7 +34,7 @@ using System;
using System.Text; using System.Text;
using NUnit.Framework; using NUnit.Framework;
using System.IO; using System.IO;
#if !DOTNET35 #if !NET35
using System.Threading.Tasks; using System.Threading.Tasks;
#endif #endif
...@@ -196,7 +196,7 @@ namespace Google.Protobuf ...@@ -196,7 +196,7 @@ namespace Google.Protobuf
Assert.AreEqual(expected, actual, $"{expected.ToBase64()} != {actual.ToBase64()}"); Assert.AreEqual(expected, actual, $"{expected.ToBase64()} != {actual.ToBase64()}");
} }
#if !DOTNET35 #if !NET35
[Test] [Test]
public async Task FromStreamAsync_Seekable() public async Task FromStreamAsync_Seekable()
{ {
......
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2015 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
#if NET35
using System;
using System.IO;
using NUnit.Framework;
using Google.Protobuf.Compatibility;
namespace Google.Protobuf.Test.Compatibility
{
public class StreamExtensionsTest
{
[Test]
public void CopyToNullArgument()
{
var memoryStream = new MemoryStream();
Assert.Throws<ArgumentNullException>(() => memoryStream.CopyTo(null));
}
[Test]
public void CopyToTest()
{
byte[] bytesToStream = new byte[] { 0x31, 0x08, 0xFF, 0x00 };
Stream source = new MemoryStream(bytesToStream);
Stream destination = new MemoryStream((int)source.Length);
source.CopyTo(destination);
destination.Seek(0, SeekOrigin.Begin);
Assert.AreEqual(0x31, destination.ReadByte());
Assert.AreEqual(0x08, destination.ReadByte());
Assert.AreEqual(0xFF, destination.ReadByte());
Assert.AreEqual(0x00, destination.ReadByte());
Assert.AreEqual(-1, destination.ReadByte());
}
}
}
#endif
...@@ -34,7 +34,7 @@ using System; ...@@ -34,7 +34,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection; using System.Reflection;
#if !DOTNET35 #if !NET35
namespace Google.Protobuf.Compatibility namespace Google.Protobuf.Compatibility
{ {
public class TypeExtensionsTest public class TypeExtensionsTest
......
...@@ -158,7 +158,9 @@ namespace Google.Protobuf ...@@ -158,7 +158,9 @@ namespace Google.Protobuf
{ {
// WriteTagAndValue ignores default values // WriteTagAndValue ignores default values
var stream = new MemoryStream(); var stream = new MemoryStream();
var codedOutput = new CodedOutputStream(stream); CodedOutputStream codedOutput;
#if !NET35
codedOutput = new CodedOutputStream(stream);
codec.WriteTagAndValue(codedOutput, codec.DefaultValue); codec.WriteTagAndValue(codedOutput, codec.DefaultValue);
codedOutput.Flush(); codedOutput.Flush();
Assert.AreEqual(0, stream.Position); Assert.AreEqual(0, stream.Position);
...@@ -167,6 +169,7 @@ namespace Google.Protobuf ...@@ -167,6 +169,7 @@ namespace Google.Protobuf
{ {
Assert.AreEqual(default(T), codec.DefaultValue); Assert.AreEqual(default(T), codec.DefaultValue);
} }
#endif
// The plain ValueWriter/ValueReader delegates don't. // The plain ValueWriter/ValueReader delegates don't.
if (codec.DefaultValue != null) // This part isn't appropriate for message types. if (codec.DefaultValue != null) // This part isn't appropriate for message types.
......
...@@ -35,10 +35,13 @@ using System.Collections; ...@@ -35,10 +35,13 @@ using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Text; using System.Text;
#if !DOTNET35 #if !NET35
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
#endif #endif
#if NET35
using Google.Protobuf.Compatibility;
#endif
namespace Google.Protobuf namespace Google.Protobuf
{ {
...@@ -167,7 +170,7 @@ namespace Google.Protobuf ...@@ -167,7 +170,7 @@ namespace Google.Protobuf
return AttachBytes(bytes); return AttachBytes(bytes);
} }
#if !DOTNET35 #if !NET35
/// <summary> /// <summary>
/// Constructs a <see cref="ByteString"/> from data in the given stream, asynchronously. /// Constructs a <see cref="ByteString"/> from data in the given stream, asynchronously.
/// </summary> /// </summary>
......
...@@ -47,7 +47,7 @@ namespace Google.Protobuf.Collections ...@@ -47,7 +47,7 @@ namespace Google.Protobuf.Collections
/// </remarks> /// </remarks>
/// <typeparam name="T">The element type of the repeated field.</typeparam> /// <typeparam name="T">The element type of the repeated field.</typeparam>
public sealed class RepeatedField<T> : IList<T>, IList, IDeepCloneable<RepeatedField<T>>, IEquatable<RepeatedField<T>> public sealed class RepeatedField<T> : IList<T>, IList, IDeepCloneable<RepeatedField<T>>, IEquatable<RepeatedField<T>>
#if !DOTNET35 #if !NET35
, IReadOnlyList<T> , IReadOnlyList<T>
#endif #endif
{ {
......
...@@ -47,7 +47,7 @@ namespace Google.Protobuf.Compatibility ...@@ -47,7 +47,7 @@ namespace Google.Protobuf.Compatibility
/// </summary> /// </summary>
internal static MethodInfo GetGetMethod(this PropertyInfo target) internal static MethodInfo GetGetMethod(this PropertyInfo target)
{ {
#if DOTNET35 #if NET35
var method = target.GetGetMethod(); var method = target.GetGetMethod();
#else #else
var method = target.GetMethod; var method = target.GetMethod;
...@@ -61,7 +61,7 @@ namespace Google.Protobuf.Compatibility ...@@ -61,7 +61,7 @@ namespace Google.Protobuf.Compatibility
/// </summary> /// </summary>
internal static MethodInfo GetSetMethod(this PropertyInfo target) internal static MethodInfo GetSetMethod(this PropertyInfo target)
{ {
#if DOTNET35 #if NET35
var method = target.GetSetMethod(); var method = target.GetSetMethod();
#else #else
var method = target.SetMethod; var method = target.SetMethod;
......
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2015 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
#if NET35
using System;
using System.IO;
namespace Google.Protobuf.Compatibility
{
/// <summary>
/// Extension methods for <see cref="Stream"/> in order to provide
/// backwards compatibility with .NET 3.5
/// </summary>
public static class StreamExtensions
{
// 81920 seems to be the default buffer size used in .NET 4.5.1
private const int BUFFER_SIZE = 81920;
/// <summary>
/// Write the contents of the current stream to the destination stream
/// </summary>
public static void CopyTo(this Stream source, Stream destination)
{
if (destination == null)
{
throw new ArgumentNullException(nameof(destination));
}
byte[] buffer = new byte[BUFFER_SIZE];
int numBytesRead;
while ((numBytesRead = source.Read(buffer, 0, buffer.Length)) > 0) {
destination.Write(buffer, 0, numBytesRead);
}
}
}
}
#endif
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
using System; using System;
using System.Reflection; using System.Reflection;
#if !DOTNET35 #if !NET35
namespace Google.Protobuf.Compatibility namespace Google.Protobuf.Compatibility
{ {
/// <summary> /// <summary>
......
...@@ -831,7 +831,7 @@ namespace Google.Protobuf ...@@ -831,7 +831,7 @@ namespace Google.Protobuf
return originalName; return originalName;
} }
#if DOTNET35 #if NET35
// TODO: Consider adding functionality to TypeExtensions to avoid this difference. // TODO: Consider adding functionality to TypeExtensions to avoid this difference.
private static Dictionary<object, string> GetNameMapping(System.Type enumType) => private static Dictionary<object, string> GetNameMapping(System.Type enumType) =>
enumType.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static) enumType.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static)
......
...@@ -34,7 +34,7 @@ using System; ...@@ -34,7 +34,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
#if DOTNET35 #if NET35
// Needed for ReadOnlyDictionary, which does not exist in .NET 3.5 // Needed for ReadOnlyDictionary, which does not exist in .NET 3.5
using Google.Protobuf.Collections; using Google.Protobuf.Collections;
#endif #endif
......
...@@ -59,7 +59,7 @@ namespace Google.Protobuf.WellKnownTypes ...@@ -59,7 +59,7 @@ namespace Google.Protobuf.WellKnownTypes
if (firstInvalid == null) if (firstInvalid == null)
{ {
var writer = new StringWriter(); var writer = new StringWriter();
#if DOTNET35 #if NET35
var query = paths.Select(JsonFormatter.ToJsonName); var query = paths.Select(JsonFormatter.ToJsonName);
JsonFormatter.WriteString(writer, string.Join(",", query.ToArray())); JsonFormatter.WriteString(writer, string.Join(",", query.ToArray()));
#else #else
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment