Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/monodevelop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/BinaryMessage.cs403
-rw-r--r--main/tests/MonoDevelop.Core.Tests/MonoDevelop.Core.Execution/BinaryMessageTests.cs125
-rw-r--r--main/tests/MonoDevelop.Core.Tests/MonoDevelop.Core.Tests.csproj8
-rw-r--r--main/tests/MonoDevelop.Core.Tests/packages.config4
4 files changed, 429 insertions, 111 deletions
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/BinaryMessage.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/BinaryMessage.cs
index 8eb7fd4a5c..59cb40333b 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/BinaryMessage.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/BinaryMessage.cs
@@ -228,53 +228,105 @@ namespace MonoDevelop.Core.Execution
void WriteArray (BinaryWriter bw, object val)
{
Array array = (Array)val;
- bw.Write (array.Length);
-
- var et = val.GetType ().GetElementType ();
-
- if (et == typeof(byte)) {
- bw.Write ((byte)TypeCode.Byte);
- bw.Write ((byte [])val);
- } else if (et == typeof(short)) {
- bw.Write ((byte)TypeCode.Int16);
- foreach (var v in (short [])val)
- bw.Write (v);
- } else if (et == typeof(int)) {
- bw.Write ((byte)TypeCode.Int32);
- foreach (var v in (int [])val)
- bw.Write (v);
- } else if (et == typeof(long)) {
- bw.Write ((byte)TypeCode.Int64);
- foreach (var v in (long [])val)
- bw.Write (v);
- } else if (et == typeof(float)) {
- bw.Write ((byte)TypeCode.Single);
- foreach (var v in (float [])val)
- bw.Write (v);
- } else if (et == typeof(double)) {
- bw.Write ((byte)TypeCode.Double);
- foreach (var v in (double [])val)
- bw.Write (v);
- } else if (et == typeof(string)) {
- bw.Write ((byte)TypeCode.String);
- foreach (var v in (string [])val)
- bw.Write (v ?? NullString);
- } else if (et == typeof(bool)) {
- bw.Write ((byte)TypeCode.Boolean);
- foreach (var v in (bool [])val)
- bw.Write (v);
- } else if (et == typeof(DateTime)) {
- bw.Write ((byte)TypeCode.DateTime);
- foreach (var v in (DateTime [])val)
- bw.Write (v.Ticks);
- } else if (et == typeof(TimeSpan)) {
- bw.Write ((byte)TypeCode.TimeSpan);
- foreach (var v in (TimeSpan [])val)
- bw.Write (v.Ticks);
+ int rank = array.Rank;
+ bw.Write (array.Rank);
+ for (int i = 0; i < rank; ++i)
+ bw.Write (array.GetLength (rank));
+
+ var type = val.GetType ();
+ var et = type.GetElementType ();
+
+ if (rank == 1) {
+ if (et == typeof (byte)) {
+ bw.Write ((byte)TypeCode.Byte);
+ bw.Write ((byte [])val);
+ } else if (et == typeof (short)) {
+ bw.Write ((byte)TypeCode.Int16);
+ foreach (var v in (short [])val)
+ bw.Write (v);
+ } else if (et == typeof (int)) {
+ bw.Write ((byte)TypeCode.Int32);
+ foreach (var v in (int [])val)
+ bw.Write (v);
+ } else if (et == typeof (long)) {
+ bw.Write ((byte)TypeCode.Int64);
+ foreach (var v in (long [])val)
+ bw.Write (v);
+ } else if (et == typeof (float)) {
+ bw.Write ((byte)TypeCode.Single);
+ foreach (var v in (float [])val)
+ bw.Write (v);
+ } else if (et == typeof (double)) {
+ bw.Write ((byte)TypeCode.Double);
+ foreach (var v in (double [])val)
+ bw.Write (v);
+ } else if (et == typeof (string)) {
+ bw.Write ((byte)TypeCode.String);
+ foreach (var v in (string [])val)
+ bw.Write (v ?? NullString);
+ } else if (et == typeof (bool)) {
+ bw.Write ((byte)TypeCode.Boolean);
+ foreach (var v in (bool [])val)
+ bw.Write (v);
+ } else if (et == typeof (DateTime)) {
+ bw.Write ((byte)TypeCode.DateTime);
+ foreach (var v in (DateTime [])val)
+ bw.Write (v.Ticks);
+ } else if (et == typeof (TimeSpan)) {
+ bw.Write ((byte)TypeCode.TimeSpan);
+ foreach (var v in (TimeSpan [])val)
+ bw.Write (v.Ticks);
+ } else {
+ bw.Write ((byte)TypeCode.Object);
+ foreach (var elem in array)
+ WriteValue (bw, elem);
+ }
} else {
- bw.Write ((byte)TypeCode.Object);
- foreach (var elem in array)
- WriteValue (bw, elem);
+ if (et == typeof (byte)) {
+ bw.Write ((byte)TypeCode.Byte);
+ foreach (byte v in array)
+ bw.Write (v);
+ } else if (et == typeof (short)) {
+ bw.Write ((byte)TypeCode.Int16);
+ foreach (short v in array)
+ bw.Write (v);
+ } else if (et == typeof (int)) {
+ bw.Write ((byte)TypeCode.Int32);
+ foreach (int v in array)
+ bw.Write (v);
+ } else if (et == typeof (long)) {
+ bw.Write ((byte)TypeCode.Int64);
+ foreach (long v in array)
+ bw.Write (v);
+ } else if (et == typeof (float)) {
+ bw.Write ((byte)TypeCode.Single);
+ foreach (float v in array)
+ bw.Write (v);
+ } else if (et == typeof (double)) {
+ bw.Write ((byte)TypeCode.Double);
+ foreach (double v in array)
+ bw.Write (v);
+ } else if (et == typeof (string)) {
+ bw.Write ((byte)TypeCode.String);
+ foreach (string v in array)
+ bw.Write (v ?? NullString);
+ } else if (et == typeof (bool)) {
+ bw.Write ((byte)TypeCode.Boolean);
+ foreach (bool v in array)
+ bw.Write (v);
+ } else if (et == typeof (DateTime)) {
+ bw.Write ((byte)TypeCode.DateTime);
+ foreach (DateTime v in array)
+ bw.Write (v.Ticks);
+ } else if (et == typeof (TimeSpan)) {
+ bw.Write ((byte)TypeCode.TimeSpan);
+ foreach (TimeSpan v in array)
+ bw.Write (v.Ticks);
+ } else {
+ bw.Write ((byte)TypeCode.Object);
+ foreach (var elem in array)
+ WriteValue (bw, elem);
+ }
}
}
@@ -340,78 +392,207 @@ namespace MonoDevelop.Core.Execution
throw new NotSupportedException ("code: " + t);
}
- static object ReadArray (BinaryReader br)
+ internal class MultiDimensionalIterator
{
- int count = br.ReadInt32 ();
- var type = (TypeCode)br.ReadByte ();
+ Array arr;
+ readonly int [] indices, lengths;
+ bool first;
- switch (type) {
- case TypeCode.Object: {
- var a = new object [count];
- for (int n = 0; n < count; n++)
- a [n] = ReadValue (br);
- return a;
- }
- case TypeCode.Double: {
- var a = new double [count];
- for (int n = 0; n < count; n++)
- a [n] = br.ReadDouble ();
- return a;
- }
- case TypeCode.Byte: {
- return br.ReadBytes (count);
- }
- case TypeCode.Int16: {
- var a = new short [count];
- for (int n = 0; n < count; n++)
- a [n] = br.ReadInt16 ();
- return a;
- }
- case TypeCode.Int32: {
- var a = new int [count];
- for (int n = 0; n < count; n++)
- a [n] = br.ReadInt32 ();
- return a;
- }
- case TypeCode.Int64: {
- var a = new long [count];
- for (int n = 0; n < count; n++)
- a [n] = br.ReadInt64 ();
- return a;
- }
- case TypeCode.Single: {
- var a = new float [count];
- for (int n = 0; n < count; n++)
- a [n] = br.ReadSingle ();
- return a;
+ public MultiDimensionalIterator (Array arr)
+ {
+ this.arr = arr;
+ lengths = new int [arr.Rank];
+ indices = new int [arr.Rank];
+ first = true;
+
+ for (int i = 0; i < arr.Rank; ++i)
+ lengths [i] = arr.GetLength (i);
+ }
+
+ public void Fill (Func<object> fill)
+ {
+ (bool, int []) res;
+ while ((res = TryMoveNext ()).Item1) {
+ arr.SetValue (fill (), res.Item2);
}
- case TypeCode.String: {
- var a = new string [count];
- for (int n = 0; n < count; n++) {
- string s = br.ReadString ();
- if (s == NullString)
- s = null;
- a [n] = s;
+ }
+
+ public (bool, int []) TryMoveNext ()
+ {
+ return TryMoveNextInternal (indices.Length - 1);
+ }
+
+ (bool, int []) TryMoveNextInternal (int lastRank)
+ {
+ if (lastRank == -1)
+ return (false, indices);
+
+ if (lengths [lastRank] != 0) {
+ if (first) {
+ first = false;
+ return (true, indices);
}
- return a;
+
+ indices [lastRank]++;
+ // We reached the last element, try bumping previous dimension
+ if (indices [lastRank] != lengths [lastRank])
+ return (true, indices);
+
+ // We're done.
+ if (lastRank == 0)
+ return (false, indices);
+
+ for (int i = lastRank; i < indices.Length; ++i)
+ indices [i] = 0;
+
}
- case TypeCode.Boolean: {
- var a = new bool [count];
- for (int n = 0; n < count; n++)
- a [n] = br.ReadBoolean ();
- return a;
+ int newRank = lastRank - 1;
+ return TryMoveNextInternal (newRank);
+ }
+ }
+
+ static object ReadArray (BinaryReader br)
+ {
+ int rank = br.ReadInt32 ();
+ int[] lengths = new int [rank];
+
+ var type = (TypeCode)br.ReadByte ();
+
+ if (rank == 1) {
+ int count = lengths [0];
+ switch (type) {
+ case TypeCode.Object: {
+ var a = new object [count];
+ for (int n = 0; n < count; n++)
+ a [n] = ReadValue (br);
+ return a;
+ }
+ case TypeCode.Double: {
+ var a = new double [count];
+ for (int n = 0; n < count; n++)
+ a [n] = br.ReadDouble ();
+ return a;
+ }
+ case TypeCode.Byte: {
+ return br.ReadBytes (count);
+ }
+ case TypeCode.Int16: {
+ var a = new short [count];
+ for (int n = 0; n < count; n++)
+ a [n] = br.ReadInt16 ();
+ return a;
+ }
+ case TypeCode.Int32: {
+ var a = new int [count];
+ for (int n = 0; n < count; n++)
+ a [n] = br.ReadInt32 ();
+ return a;
+ }
+ case TypeCode.Int64: {
+ var a = new long [count];
+ for (int n = 0; n < count; n++)
+ a [n] = br.ReadInt64 ();
+ return a;
+ }
+ case TypeCode.Single: {
+ var a = new float [count];
+ for (int n = 0; n < count; n++)
+ a [n] = br.ReadSingle ();
+ return a;
+ }
+ case TypeCode.String: {
+ var a = new string [count];
+ for (int n = 0; n < count; n++) {
+ string s = br.ReadString ();
+ if (s == NullString)
+ s = null;
+ a [n] = s;
+ }
+ return a;
+ }
+ case TypeCode.Boolean: {
+ var a = new bool [count];
+ for (int n = 0; n < count; n++)
+ a [n] = br.ReadBoolean ();
+ return a;
+ }
+ case TypeCode.DateTime: {
+ var a = new DateTime [count];
+ for (int n = 0; n < count; n++)
+ a [n] = new DateTime (br.ReadInt64 ());
+ return a;
+ }
+ case TypeCode.TimeSpan: {
+ var a = new TimeSpan [count];
+ for (int n = 0; n < count; n++)
+ a [n] = new TimeSpan (br.ReadInt64 ());
+ return a;
+ }
}
- case TypeCode.DateTime: {
- var a = new DateTime [count];
- for (int n = 0; n < count; n++)
- a [n] = new DateTime (br.ReadInt64 ());
- return a;
+ } else {
+ int [] indices = new int [lengths.Length];
+ switch (type) {
+ case TypeCode.Object: {
+ var a = Array.CreateInstance (typeof (object), lengths);
+ new MultiDimensionalIterator (a).Fill (() => ReadValue (br));
+ return a;
}
- case TypeCode.TimeSpan: {
- var a = new TimeSpan [count];
- for (int n = 0; n < count; n++)
- a [n] = new TimeSpan (br.ReadInt64 ());
- return a;
+ case TypeCode.Double: {
+ var a = Array.CreateInstance (typeof (double), lengths);
+ new MultiDimensionalIterator (a).Fill (() => br.ReadDouble ());
+ return a;
+ }
+ case TypeCode.Byte: {
+ var a = Array.CreateInstance (typeof (byte), lengths);
+ new MultiDimensionalIterator (a).Fill (() => br.ReadByte ());
+ return a;
+ //return br.ReadBytes (count);
+ }
+ case TypeCode.Int16: {
+ var a = Array.CreateInstance (typeof (short), lengths);
+ new MultiDimensionalIterator (a).Fill (() => br.ReadInt16 ());
+ return a;
+ }
+ case TypeCode.Int32: {
+ var a = Array.CreateInstance (typeof (int), lengths);
+ new MultiDimensionalIterator (a).Fill (() => br.ReadInt32 ());
+ return a;
+ }
+ case TypeCode.Int64: {
+ var a = Array.CreateInstance (typeof (long), lengths);
+ new MultiDimensionalIterator (a).Fill (() => br.ReadInt64 ());
+ return a;
+ }
+ case TypeCode.Single: {
+ var a = Array.CreateInstance (typeof (float), lengths);
+ new MultiDimensionalIterator (a).Fill (() => br.ReadSingle ());
+ return a;
+ }
+ case TypeCode.String: {
+ var a = Array.CreateInstance (typeof (string), lengths);
+ new MultiDimensionalIterator (a).Fill (() => {
+ string s = br.ReadString ();
+ if (s == NullString)
+ s = null;
+ return s;
+ });
+ return a;
+ }
+ case TypeCode.Boolean: {
+ var a = Array.CreateInstance (typeof (bool), lengths);
+ new MultiDimensionalIterator (a).Fill (() => br.ReadBoolean ());
+ return a;
+ }
+ case TypeCode.DateTime: {
+ var a = Array.CreateInstance (typeof (DateTime), lengths);
+ new MultiDimensionalIterator (a).Fill (() => new DateTime (br.ReadInt64 ()));
+ return a;
+ }
+ case TypeCode.TimeSpan: {
+ var a = Array.CreateInstance (typeof (TimeSpan), lengths);
+ new MultiDimensionalIterator (a).Fill (() => new TimeSpan (br.ReadInt64 ()));
+ return a;
+ }
}
}
throw new NotSupportedException ("Array of " + type);
diff --git a/main/tests/MonoDevelop.Core.Tests/MonoDevelop.Core.Execution/BinaryMessageTests.cs b/main/tests/MonoDevelop.Core.Tests/MonoDevelop.Core.Execution/BinaryMessageTests.cs
new file mode 100644
index 0000000000..16a02315ad
--- /dev/null
+++ b/main/tests/MonoDevelop.Core.Tests/MonoDevelop.Core.Execution/BinaryMessageTests.cs
@@ -0,0 +1,125 @@
+//
+// BinaryMessage.cs
+//
+// Author:
+// Marius Ungureanu <maungu@microsoft.com>
+//
+// Copyright (c) 2017
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System;
+using NUnit.Framework;
+
+namespace MonoDevelop.Core.Execution
+{
+ [TestFixture]
+ public class BinaryMessageTests
+ {
+ public class Data
+ {
+ public Data (Array arr, int expectedEnumerations, int[][] expectedValues)
+ {
+ ExpectedEnumerations = expectedEnumerations;
+ Array = arr;
+ }
+
+ public int ExpectedEnumerations { get; }
+ public Array Array { get; }
+ }
+
+ public Data [] TestCase = {
+ new Data (new int[1, 2, 3], 6, new int[][] {
+ new int[] {0, 0, 0},
+ new int[] {0, 0, 1},
+ new int[] {0, 0, 2},
+ new int[] {0, 1, 0},
+ new int[] {0, 1, 1},
+ new int[] {0, 1, 2},
+ }),
+ new Data (new int[0, 0, 0], 0, new int[][] {}),
+ new Data (new int[0, 0, 1], 1, new int[][] { new int[] { 0, 0, 0 } }),
+ new Data (new int[3, 3, 3], 27, new int[][] {
+ new int[] {0, 0, 0},
+ new int[] {0, 0, 1},
+ new int[] {0, 0, 2},
+
+ new int[] {0, 1, 0},
+ new int[] {0, 1, 1},
+ new int[] {0, 1, 2},
+
+ new int[] {0, 2, 0},
+ new int[] {0, 2, 1},
+ new int[] {0, 2, 2},
+
+ new int[] {1, 0, 0},
+ new int[] {1, 0, 1},
+ new int[] {1, 0, 2},
+
+ new int[] {1, 1, 0},
+ new int[] {1, 1, 1},
+ new int[] {1, 1, 2},
+
+ new int[] {1, 2, 0},
+ new int[] {1, 2, 1},
+ new int[] {1, 2, 2},
+
+ new int[] {2, 0, 0},
+ new int[] {2, 0, 1},
+ new int[] {2, 0, 2},
+
+ new int[] {2, 1, 0},
+ new int[] {2, 1, 1},
+ new int[] {2, 1, 2},
+
+ new int[] {2, 2, 0},
+ new int[] {2, 2, 1},
+ new int[] {2, 2, 2},
+ }),
+ };
+
+ [TestCaseSource ("TestCase")]
+ public void TestIteration (Data data)
+ {
+ var iter = new BinaryMessage.MultiDimensionalIterator (data.Array);
+ int count = 0;
+ (bool, int []) res;
+ while ((res = iter.TryMoveNext ()).Item1) {
+ count++;
+ }
+
+ Assert.AreEqual (data.ExpectedEnumerations, count);
+ }
+
+ [Test]
+ public void TestFill ()
+ {
+ int count = 0;
+ var toFill = new int [3, 3, 3];
+
+ var iter = new BinaryMessage.MultiDimensionalIterator (toFill);
+ iter.Fill (() => count++);
+
+ int expected = 0;
+ foreach (var val in toFill) {
+ Assert.AreEqual (expected, val);
+ expected++;
+ }
+ }
+ }
+}
diff --git a/main/tests/MonoDevelop.Core.Tests/MonoDevelop.Core.Tests.csproj b/main/tests/MonoDevelop.Core.Tests/MonoDevelop.Core.Tests.csproj
index 8cbe6811d0..97681c5e92 100644
--- a/main/tests/MonoDevelop.Core.Tests/MonoDevelop.Core.Tests.csproj
+++ b/main/tests/MonoDevelop.Core.Tests/MonoDevelop.Core.Tests.csproj
@@ -37,6 +37,9 @@
<HintPath>..\..\packages\Microsoft.CodeAnalysis.CSharp.2.3.2\lib\netstandard1.3\Microsoft.CodeAnalysis.CSharp.dll</HintPath>
<Private>False</Private>
</Reference>
+ <Reference Include="System.ValueTuple">
+ <HintPath>..\..\packages\System.ValueTuple.4.3.1\lib\netstandard1.0\System.ValueTuple.dll</HintPath>
+ </Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Test.cs" />
@@ -90,11 +93,13 @@
<Compile Include="MonoDevelop.Projects\GenericProjectTests.cs" />
<Compile Include="MonoDevelop.Projects\NetStandardProjectTests.cs" />
<Compile Include="MonoDevelop.Projects\BuilderManagerTests.cs" />
+ <Compile Include="MonoDevelop.Core.Execution\BinaryMessageTests.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="MonoDevelop.Core\" />
<Folder Include="MonoDevelop.Core.Assemblies\" />
<Folder Include="MonoDevelop.Projects\" />
+ <Folder Include="MonoDevelop.Core.Execution\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\core\MonoDevelop.Core\MonoDevelop.Core.csproj">
@@ -116,5 +121,8 @@
<Name>GuiUnit_NET_4_5</Name>
</ProjectReference>
</ItemGroup>
+ <ItemGroup>
+ <None Include="packages.config" />
+ </ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project> \ No newline at end of file
diff --git a/main/tests/MonoDevelop.Core.Tests/packages.config b/main/tests/MonoDevelop.Core.Tests/packages.config
new file mode 100644
index 0000000000..9958f16fbb
--- /dev/null
+++ b/main/tests/MonoDevelop.Core.Tests/packages.config
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="System.ValueTuple" version="4.3.1" targetFramework="net461" />
+</packages> \ No newline at end of file