Fix or delete old projects.

ProtoDump isn't currently useful, but will be when ToString emits JSON: fixed.
ProtoBench: deleted; we should reinstate when there's a common proto3 benchmark.
ProtoMunge: delete; not useful enough to merit fixing up.

Removed the [TestFixture] from ByteStringTest as Travis uses a recent enough version of NUnit.
pull/544/head
Jon Skeet 10 years ago
parent 286edc0fc2
commit e75a10d8ff
  1. 9
      csharp/buildall.sh
  2. 4569
      csharp/src/ProtoBench/GoogleSize.cs
  3. 6634
      csharp/src/ProtoBench/GoogleSpeed.cs
  4. 538
      csharp/src/ProtoBench/Program.cs
  5. 31
      csharp/src/ProtoBench/Properties/AssemblyInfo.cs
  6. 88
      csharp/src/ProtoBench/ProtoBench.csproj
  7. 33516
      csharp/src/ProtoBench/Unittest.cs
  8. 347
      csharp/src/ProtoBench/UnittestImport.cs
  9. 333
      csharp/src/ProtoBench/UnittestImportPublic.cs
  10. 3
      csharp/src/ProtoBench/app.config
  11. BIN
      csharp/src/ProtoBench/google_message1.dat
  12. BIN
      csharp/src/ProtoBench/google_message2.dat
  13. 35
      csharp/src/ProtoDump/Program.cs
  14. 307
      csharp/src/ProtoMunge/Program.cs
  15. 30
      csharp/src/ProtoMunge/Properties/AssemblyInfo.cs
  16. 67
      csharp/src/ProtoMunge/ProtoMunge.csproj
  17. 3
      csharp/src/ProtoMunge/app.config
  18. 1
      csharp/src/ProtocolBuffers.Test/ByteStringTest.cs
  19. 12
      csharp/src/ProtocolBuffers.sln

@ -11,13 +11,8 @@ SRC=$(dirname $0)/src
set -ex
# echo Building the solution.
# TODO(jonskeet): Re-enable building the whole solution when we have ProtoBench et al
# working again.
# xbuild /p:Configuration=$CONFIG $SRC/ProtocolBuffers.sln
xbuild /p:Configuration=$CONFIG $SRC/ProtocolBuffers/ProtocolBuffers.csproj
xbuild /p:Configuration=$CONFIG $SRC/ProtocolBuffers.Test/ProtocolBuffers.Test.csproj
echo Building the solution.
xbuild /p:Configuration=$CONFIG $SRC/ProtocolBuffers.sln
echo Running tests.
$NUNIT_CONSOLE $SRC/ProtocolBuffers.Test/bin/$CONFIG/Google.Protobuf.Test.dll

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,538 +0,0 @@
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://github.com/jskeet/dotnet-protobufs/
// Original C++/Java/Python code:
// http://code.google.com/p/protobuf/
//
// 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
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Threading;
using System.Xml;
using Google.ProtocolBuffers.Serialization;
using Google.ProtocolBuffers.TestProtos;
namespace Google.ProtocolBuffers.ProtoBench
{
/// <summary>
/// Simple benchmarking of arbitrary messages.
/// </summary>
public sealed class Program
{
private static TimeSpan MinSampleTime = TimeSpan.FromSeconds(2);
private static TimeSpan TargetTime = TimeSpan.FromSeconds(30);
private static bool Verbose = false, FastTest = false, OtherFormats = false;
// Avoid a .NET 3.5 dependency
private delegate void Action();
private delegate void BenchmarkTest(string name, long dataSize, Action action);
private static BenchmarkTest RunBenchmark;
private static string _logFile;
static void WriteLine(string format, params object[] arg)
{
if (arg.Length > 0) format = String.Format(format, arg);
Console.Out.WriteLine(format);
if (!String.IsNullOrEmpty(_logFile))
File.AppendAllText(_logFile, format + Environment.NewLine);
}
[STAThread]
public static int Main(string[] args)
{
List<string> temp = new List<string>(args);
Verbose = temp.Remove("/verbose") || temp.Remove("-verbose");
OtherFormats = temp.Remove("/formats") || temp.Remove("-formats");
foreach (string arg in temp)
{
if (arg.StartsWith("/log:", StringComparison.OrdinalIgnoreCase) || arg.StartsWith("-log:", StringComparison.OrdinalIgnoreCase))
{
_logFile = arg.Substring(5);
if (!String.IsNullOrEmpty(_logFile))
File.AppendAllText(_logFile, Environment.NewLine + "Started benchmarks at " + DateTime.Now + Environment.NewLine);
temp.Remove(arg);
break;
}
}
if (true == (FastTest = (temp.Remove("/fast") || temp.Remove("-fast"))))
{
TargetTime = TimeSpan.FromSeconds(10);
}
RunBenchmark = BenchmarkV1;
if (temp.Remove("/v2") || temp.Remove("-v2"))
{
Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.RealTime;
Process.GetCurrentProcess().ProcessorAffinity = new IntPtr(1);
RunBenchmark = BenchmarkV2;
}
if (temp.Remove("/all") || temp.Remove("-all"))
{
if (FastTest)
{
TargetTime = TimeSpan.FromSeconds(5);
}
foreach (KeyValuePair<string, string> item in MakeTests())
{
temp.Add(item.Key);
temp.Add(item.Value);
}
}
args = temp.ToArray();
if (args.Length < 2 || (args.Length%2) != 0)
{
Console.Error.WriteLine("Usage: ProtoBench [/fast] <descriptor type name> <input data>");
Console.Error.WriteLine("The descriptor type name is the fully-qualified message name,");
Console.Error.WriteLine(
"including assembly - e.g. Google.ProtocolBuffers.BenchmarkProtos.Message1,ProtoBench");
Console.Error.WriteLine("(You can specify multiple pairs of descriptor type name and input data.)");
return 1;
}
bool success = true;
for (int i = 0; i < args.Length; i += 2)
{
success &= RunTest(args[i], args[i + 1], null);
}
return success ? 0 : 1;
}
/// <summary>
/// Runs a single test. Error messages are displayed to Console.Error, and the return value indicates
/// general success/failure.
/// </summary>
public static bool RunTest(string typeName, string file, byte[] inputData)
{
WriteLine("Benchmarking {0} with file {1}", typeName, file);
IMessage defaultMessage;
try
{
defaultMessage = MessageUtil.GetDefaultMessage(typeName);
}
catch (ArgumentException e)
{
Console.Error.WriteLine(e.Message);
return false;
}
try
{
ExtensionRegistry registry = ExtensionRegistry.Empty;
inputData = inputData ?? File.ReadAllBytes(file);
MemoryStream inputStream = new MemoryStream(inputData);
ByteString inputString = ByteString.CopyFrom(inputData);
IMessage sampleMessage =
defaultMessage.WeakCreateBuilderForType().WeakMergeFrom(inputString, registry).WeakBuild();
IDictionary<string, object> dictionary = null;
byte[] jsonBytes = null, xmlBytes = null; /*no pun intended, well... maybe for xml*/
if (OtherFormats)
{
using (MemoryStream temp = new MemoryStream())
{
XmlFormatWriter.CreateInstance(temp).WriteMessage(sampleMessage);
xmlBytes = temp.ToArray();
}
using (MemoryStream temp = new MemoryStream())
{
JsonFormatWriter.CreateInstance(temp).WriteMessage(sampleMessage);
jsonBytes = temp.ToArray();
}
dictionary = new Dictionary<string, object>(StringComparer.Ordinal);
new DictionaryWriter(dictionary).WriteMessage(sampleMessage);
}
//Serializers
if (!FastTest)
{
RunBenchmark("Serialize to byte string", inputData.Length, () => sampleMessage.ToByteString());
}
RunBenchmark("Serialize to byte array", inputData.Length, () => sampleMessage.ToByteArray());
if (!FastTest)
{
RunBenchmark("Serialize to memory stream", inputData.Length,
() => sampleMessage.WriteTo(new MemoryStream()));
}
if (OtherFormats)
{
RunBenchmark("Serialize to xml", xmlBytes.Length,
() =>
{
XmlFormatWriter.CreateInstance(new MemoryStream(), Encoding.UTF8).WriteMessage(sampleMessage);
});
RunBenchmark("Serialize to json", jsonBytes.Length,
() => { JsonFormatWriter.CreateInstance().WriteMessage(sampleMessage); });
RunBenchmark("Serialize to json via xml", jsonBytes.Length,
() =>
XmlFormatWriter.CreateInstance(
JsonReaderWriterFactory.CreateJsonWriter(new MemoryStream(), Encoding.UTF8))
.SetOptions(XmlWriterOptions.OutputJsonTypes)
.WriteMessage(sampleMessage)
);
RunBenchmark("Serialize to dictionary", sampleMessage.SerializedSize,
() => new DictionaryWriter().WriteMessage(sampleMessage));
}
//Deserializers
if (!FastTest)
{
RunBenchmark("Deserialize from byte string", inputData.Length,
() => defaultMessage.WeakCreateBuilderForType()
.WeakMergeFrom(inputString, registry)
.WeakBuild()
);
}
RunBenchmark("Deserialize from byte array", inputData.Length,
() => defaultMessage.WeakCreateBuilderForType()
.WeakMergeFrom(CodedInputStream.CreateInstance(inputData), registry)
.WeakBuild()
);
if (!FastTest)
{
RunBenchmark("Deserialize from memory stream", inputData.Length,
() =>
{
inputStream.Position = 0;
defaultMessage.WeakCreateBuilderForType().WeakMergeFrom(
CodedInputStream.CreateInstance(inputStream), registry)
.WeakBuild();
});
}
if (OtherFormats)
{
RunBenchmark("Deserialize from xml", xmlBytes.Length,
() =>
XmlFormatReader.CreateInstance(xmlBytes).Merge(
defaultMessage.WeakCreateBuilderForType()).WeakBuild());
RunBenchmark("Deserialize from json", jsonBytes.Length,
() =>
JsonFormatReader.CreateInstance(jsonBytes).Merge(
defaultMessage.WeakCreateBuilderForType()).WeakBuild());
RunBenchmark("Deserialize from json via xml", jsonBytes.Length,
() =>
XmlFormatReader.CreateInstance(JsonReaderWriterFactory.CreateJsonReader(jsonBytes, XmlDictionaryReaderQuotas.Max))
.SetOptions(XmlReaderOptions.ReadNestedArrays).Merge(
defaultMessage.WeakCreateBuilderForType()).WeakBuild());
RunBenchmark("Deserialize from dictionary", sampleMessage.SerializedSize,
() =>
new DictionaryReader(dictionary).Merge(defaultMessage.WeakCreateBuilderForType()).
WeakBuild());
}
WriteLine(String.Empty);
return true;
}
catch (Exception e)
{
Console.Error.WriteLine("Error: {0}", e.Message);
Console.Error.WriteLine();
Console.Error.WriteLine("Detailed exception information: {0}", e);
return false;
}
}
private static void BenchmarkV2(string name, long dataSize, Action action)
{
Thread.BeginThreadAffinity();
TimeSpan elapsed = TimeSpan.Zero;
long runs = 0;
long totalCount = 0;
double best = double.MinValue, worst = double.MaxValue;
action();
// Run it progressively more times until we've got a reasonable sample
int iterations = 100;
elapsed = TimeAction(action, iterations);
while (elapsed.TotalMilliseconds < 1000)
{
elapsed += TimeAction(action, iterations);
iterations *= 2;
}
TimeSpan target = TimeSpan.FromSeconds(1);
elapsed = TimeAction(action, iterations);
iterations = (int) ((target.Ticks*iterations)/(double) elapsed.Ticks);
elapsed = TimeAction(action, iterations);
iterations = (int) ((target.Ticks*iterations)/(double) elapsed.Ticks);
elapsed = TimeAction(action, iterations);
iterations = (int) ((target.Ticks*iterations)/(double) elapsed.Ticks);
double first = (iterations*dataSize)/(elapsed.TotalSeconds*1024*1024);
if (Verbose)
{
WriteLine("Round ---: Count = {1,6}, Bps = {2,8:f3}", 0, iterations, first);
}
elapsed = TimeSpan.Zero;
int max = (int) TargetTime.TotalSeconds;
while (runs < max)
{
TimeSpan cycle = TimeAction(action, iterations);
// Accumulate and scale for next cycle.
double bps = (iterations*dataSize)/(cycle.TotalSeconds*1024*1024);
if (Verbose)
{
WriteLine("Round {1,3}: Count = {2,6}, Bps = {3,8:f3}",
0, runs, iterations, bps);
}
best = Math.Max(best, bps);
worst = Math.Min(worst, bps);
runs++;
elapsed += cycle;
totalCount += iterations;
iterations = (int) ((target.Ticks*totalCount)/(double) elapsed.Ticks);
}
Thread.EndThreadAffinity();
WriteLine(
"{1}: averages {2} per {3:f3}s for {4} runs; avg: {5:f3}mbps; best: {6:f3}mbps; worst: {7:f3}mbps",
0, name, totalCount/runs, elapsed.TotalSeconds/runs, runs,
(totalCount*dataSize)/(elapsed.TotalSeconds*1024*1024), best, worst);
}
private static void BenchmarkV1(string name, long dataSize, Action action)
{
// Make sure it's JITted
action();
// Run it progressively more times until we've got a reasonable sample
int iterations = 1;
TimeSpan elapsed = TimeAction(action, iterations);
while (elapsed < MinSampleTime)
{
iterations *= 2;
elapsed = TimeAction(action, iterations);
}
// Upscale the sample to the target time. Do this in floating point arithmetic
// to avoid overflow issues.
iterations = (int) ((TargetTime.Ticks/(double) elapsed.Ticks)*iterations);
elapsed = TimeAction(action, iterations);
WriteLine("{0}: {1} iterations in {2:f3}s; {3:f3}MB/s",
name, iterations, elapsed.TotalSeconds,
(iterations*dataSize)/(elapsed.TotalSeconds*1024*1024));
}
private static TimeSpan TimeAction(Action action, int iterations)
{
GC.Collect();
GC.GetTotalMemory(true);
GC.WaitForPendingFinalizers();
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < iterations; i++)
{
action();
}
sw.Stop();
return sw.Elapsed;
}
private static IEnumerable<KeyValuePair<string, string>> MakeTests()
{
//Aggregate Tests
yield return MakeWorkItem("all-types", MakeTestAllTypes());
yield return MakeWorkItem("repeated-100", MakeRepeatedTestAllTypes(100));
yield return MakeWorkItem("packed-100", MakeTestPackedTypes(100));
//Discrete Tests
foreach (KeyValuePair<string, Action<TestAllTypes.Builder>> item in MakeTestAllTypes())
{
yield return MakeWorkItem(item.Key, new[] {item});
}
foreach (KeyValuePair<string, Action<TestAllTypes.Builder>> item in MakeRepeatedTestAllTypes(100))
{
yield return MakeWorkItem(item.Key, new[] {item});
}
foreach (KeyValuePair<string, Action<TestPackedTypes.Builder>> item in MakeTestPackedTypes(100))
{
yield return MakeWorkItem(item.Key, new[] {item});
}
}
private static IEnumerable<KeyValuePair<string, Action<TestAllTypes.Builder>>> MakeTestAllTypes()
{
// Many of the raw type serializers below perform poorly due to the numerous fields defined
// in TestAllTypes.
//single values
yield return MakeItem<TestAllTypes.Builder>("int32", 1, x => x.SetOptionalInt32(1001));
yield return MakeItem<TestAllTypes.Builder>("int64", 1, x => x.SetOptionalInt64(1001));
yield return MakeItem<TestAllTypes.Builder>("uint32", 1, x => x.SetOptionalUint32(1001));
yield return MakeItem<TestAllTypes.Builder>("uint64", 1, x => x.SetOptionalUint64(1001));
yield return MakeItem<TestAllTypes.Builder>("sint32", 1, x => x.SetOptionalSint32(-1001));
yield return MakeItem<TestAllTypes.Builder>("sint64", 1, x => x.SetOptionalSint64(-1001));
yield return MakeItem<TestAllTypes.Builder>("fixed32", 1, x => x.SetOptionalFixed32(1001));
yield return MakeItem<TestAllTypes.Builder>("fixed64", 1, x => x.SetOptionalFixed64(1001));
yield return MakeItem<TestAllTypes.Builder>("sfixed32", 1, x => x.SetOptionalSfixed32(-1001));
yield return MakeItem<TestAllTypes.Builder>("sfixed64", 1, x => x.SetOptionalSfixed64(-1001));
yield return MakeItem<TestAllTypes.Builder>("float", 1, x => x.SetOptionalFloat(1001.1001f));
yield return MakeItem<TestAllTypes.Builder>("double", 1, x => x.SetOptionalDouble(1001.1001));
yield return MakeItem<TestAllTypes.Builder>("bool", 1, x => x.SetOptionalBool(true));
yield return MakeItem<TestAllTypes.Builder>("string", 1, x => x.SetOptionalString("this is a string value"))
;
yield return
MakeItem<TestAllTypes.Builder>("bytes", 1,
x =>
x.SetOptionalBytes(ByteString.CopyFromUtf8("this is an array of bytes")))
;
yield return
MakeItem<TestAllTypes.Builder>("group", 1,
x =>
x.SetOptionalGroup(
new TestAllTypes.Types.OptionalGroup.Builder().SetA(1001)));
yield return
MakeItem<TestAllTypes.Builder>("message", 1,
x =>
x.SetOptionalNestedMessage(
new TestAllTypes.Types.NestedMessage.Builder().SetBb(1001)));
yield return
MakeItem<TestAllTypes.Builder>("enum", 1,
x => x.SetOptionalNestedEnum(TestAllTypes.Types.NestedEnum.FOO));
}
private static IEnumerable<KeyValuePair<string, Action<TestAllTypes.Builder>>> MakeRepeatedTestAllTypes(int size)
{
//repeated values
yield return MakeItem<TestAllTypes.Builder>("repeated-int32", size, x => x.AddRepeatedInt32(1001));
yield return MakeItem<TestAllTypes.Builder>("repeated-int64", size, x => x.AddRepeatedInt64(1001));
yield return MakeItem<TestAllTypes.Builder>("repeated-uint32", size, x => x.AddRepeatedUint32(1001));
yield return MakeItem<TestAllTypes.Builder>("repeated-uint64", size, x => x.AddRepeatedUint64(1001));
yield return MakeItem<TestAllTypes.Builder>("repeated-sint32", size, x => x.AddRepeatedSint32(-1001));
yield return MakeItem<TestAllTypes.Builder>("repeated-sint64", size, x => x.AddRepeatedSint64(-1001));
yield return MakeItem<TestAllTypes.Builder>("repeated-fixed32", size, x => x.AddRepeatedFixed32(1001));
yield return MakeItem<TestAllTypes.Builder>("repeated-fixed64", size, x => x.AddRepeatedFixed64(1001));
yield return MakeItem<TestAllTypes.Builder>("repeated-sfixed32", size, x => x.AddRepeatedSfixed32(-1001));
yield return MakeItem<TestAllTypes.Builder>("repeated-sfixed64", size, x => x.AddRepeatedSfixed64(-1001));
yield return MakeItem<TestAllTypes.Builder>("repeated-float", size, x => x.AddRepeatedFloat(1001.1001f));
yield return MakeItem<TestAllTypes.Builder>("repeated-double", size, x => x.AddRepeatedDouble(1001.1001));
yield return MakeItem<TestAllTypes.Builder>("repeated-bool", size, x => x.AddRepeatedBool(true));
yield return
MakeItem<TestAllTypes.Builder>("repeated-string", size,
x => x.AddRepeatedString("this is a string value"));
yield return
MakeItem<TestAllTypes.Builder>("repeated-bytes", size,
x =>
x.AddRepeatedBytes(ByteString.CopyFromUtf8("this is an array of bytes")))
;
yield return
MakeItem<TestAllTypes.Builder>("repeated-group", size,
x =>
x.AddRepeatedGroup(
new TestAllTypes.Types.RepeatedGroup.Builder().SetA(1001)));
yield return
MakeItem<TestAllTypes.Builder>("repeated-message", size,
x =>
x.AddRepeatedNestedMessage(
new TestAllTypes.Types.NestedMessage.Builder().SetBb(1001)));
yield return
MakeItem<TestAllTypes.Builder>("repeated-enum", size,
x => x.AddRepeatedNestedEnum(TestAllTypes.Types.NestedEnum.FOO));
}
private static IEnumerable<KeyValuePair<string, Action<TestPackedTypes.Builder>>> MakeTestPackedTypes(int size)
{
//packed values
yield return MakeItem<TestPackedTypes.Builder>("packed-int32", size, x => x.AddPackedInt32(1001));
yield return MakeItem<TestPackedTypes.Builder>("packed-int64", size, x => x.AddPackedInt64(1001));
yield return MakeItem<TestPackedTypes.Builder>("packed-uint32", size, x => x.AddPackedUint32(1001));
yield return MakeItem<TestPackedTypes.Builder>("packed-uint64", size, x => x.AddPackedUint64(1001));
yield return MakeItem<TestPackedTypes.Builder>("packed-sint32", size, x => x.AddPackedSint32(-1001));
yield return MakeItem<TestPackedTypes.Builder>("packed-sint64", size, x => x.AddPackedSint64(-1001));
yield return MakeItem<TestPackedTypes.Builder>("packed-fixed32", size, x => x.AddPackedFixed32(1001));
yield return MakeItem<TestPackedTypes.Builder>("packed-fixed64", size, x => x.AddPackedFixed64(1001));
yield return MakeItem<TestPackedTypes.Builder>("packed-sfixed32", size, x => x.AddPackedSfixed32(-1001));
yield return MakeItem<TestPackedTypes.Builder>("packed-sfixed64", size, x => x.AddPackedSfixed64(-1001));
yield return MakeItem<TestPackedTypes.Builder>("packed-float", size, x => x.AddPackedFloat(1001.1001f));
yield return MakeItem<TestPackedTypes.Builder>("packed-double", size, x => x.AddPackedDouble(1001.1001));
yield return MakeItem<TestPackedTypes.Builder>("packed-bool", size, x => x.AddPackedBool(true));
yield return
MakeItem<TestPackedTypes.Builder>("packed-enum", size, x => x.AddPackedEnum(ForeignEnum.FOREIGN_FOO));
}
private static KeyValuePair<string, Action<T>> MakeItem<T>(string name, int repeated, Action<T> build)
where T : IBuilderLite, new()
{
if (repeated == 1)
{
return new KeyValuePair<string, Action<T>>(name, build);
}
return new KeyValuePair<string, Action<T>>(
String.Format("{0}[{1}]", name, repeated),
x =>
{
for (int i = 0; i < repeated; i++)
{
build(x);
}
}
);
}
private static KeyValuePair<string, string> MakeWorkItem<T>(string name,
IEnumerable<KeyValuePair<string, Action<T>>>
builders) where T : IBuilderLite, new()
{
T builder = new T();
foreach (KeyValuePair<string, Action<T>> item in builders)
{
item.Value(builder);
}
IMessageLite msg = builder.WeakBuild();
string fname = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "unittest_" + name + ".dat");
File.WriteAllBytes(fname, msg.ToByteArray());
return
new KeyValuePair<string, string>(
String.Format("{0},{1}", msg.GetType().FullName, msg.GetType().Assembly.GetName().Name), fname);
}
}
}

@ -1,31 +0,0 @@
using System;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("ProtoBench")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ProtoBench")]
[assembly: AssemblyCopyright("Copyright © 2009")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("2.4.1.555")]
[assembly: AssemblyVersion("2.4.1.555")]
[assembly: AssemblyFileVersion("2.4.1.555")]

@ -1,88 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{C7A4A435-2813-41C8-AA87-BD914BA5223D}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Google.ProtocolBuffers.ProtoBench</RootNamespace>
<AssemblyName>ProtoBench</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<IntermediateOutputPath>obj\Debug\</IntermediateOutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<NoStdLib>true</NoStdLib>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<IntermediateOutputPath>obj\Release\</IntermediateOutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<NoStdLib>true</NoStdLib>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
</PropertyGroup>
<ItemGroup>
<Reference Include="mscorlib" />
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="GoogleSize.cs" />
<Compile Include="GoogleSpeed.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Unittest.cs" />
<Compile Include="UnittestImport.cs" />
<Compile Include="UnittestImportPublic.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ProtocolBuffers.Serialization\ProtocolBuffers.Serialization.csproj">
<Project>{231391AF-449C-4a39-986C-AD7F270F4750}</Project>
<Name>ProtocolBuffers.Serialization</Name>
<Private>True</Private>
</ProjectReference>
<ProjectReference Include="..\ProtocolBuffers\ProtocolBuffers.csproj">
<Project>{6908BDCE-D925-43F3-94AC-A531E6DF2591}</Project>
<Name>ProtocolBuffers</Name>
<Private>True</Private>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="google_message1.dat">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="google_message2.dat">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<Folder Include="TestProtos\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

File diff suppressed because it is too large Load Diff

@ -1,347 +0,0 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: google/protobuf/unittest_import.proto
#pragma warning disable 1591, 0612, 3021
#region Designer generated code
using pb = global::Google.ProtocolBuffers;
using pbc = global::Google.ProtocolBuffers.Collections;
using pbd = global::Google.ProtocolBuffers.Descriptors;
using scg = global::System.Collections.Generic;
namespace Google.ProtocolBuffers.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public static partial class UnittestImport {
#region Extension registration
public static void RegisterAllExtensions(pb::ExtensionRegistry registry) {
}
#endregion
#region Static variables
internal static pbd::MessageDescriptor internal__static_protobuf_unittest_import_ImportMessage__Descriptor;
internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.ImportMessage, global::Google.ProtocolBuffers.TestProtos.ImportMessage.Builder> internal__static_protobuf_unittest_import_ImportMessage__FieldAccessorTable;
#endregion
#region Descriptor
public static pbd::FileDescriptor Descriptor {
get { return descriptor; }
}
private static pbd::FileDescriptor descriptor;
static UnittestImport() {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
"CiVnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0LnByb3RvEhhwcm90",
"b2J1Zl91bml0dGVzdF9pbXBvcnQaLGdvb2dsZS9wcm90b2J1Zi91bml0dGVz",
"dF9pbXBvcnRfcHVibGljLnByb3RvIhoKDUltcG9ydE1lc3NhZ2USCQoBZBgB",
"IAEoBSo8CgpJbXBvcnRFbnVtEg4KCklNUE9SVF9GT08QBxIOCgpJTVBPUlRf",
"QkFSEAgSDgoKSU1QT1JUX0JBWhAJQkMKGGNvbS5nb29nbGUucHJvdG9idWYu",
"dGVzdEgB+AEBqgIhR29vZ2xlLlByb3RvY29sQnVmZmVycy5UZXN0UHJvdG9z",
"UAA="));
pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) {
descriptor = root;
internal__static_protobuf_unittest_import_ImportMessage__Descriptor = Descriptor.MessageTypes[0];
internal__static_protobuf_unittest_import_ImportMessage__FieldAccessorTable =
new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.ImportMessage, global::Google.ProtocolBuffers.TestProtos.ImportMessage.Builder>(internal__static_protobuf_unittest_import_ImportMessage__Descriptor,
new string[] { "D", });
pb::ExtensionRegistry registry = pb::ExtensionRegistry.CreateInstance();
RegisterAllExtensions(registry);
global::Google.ProtocolBuffers.TestProtos.UnittestImportPublic.RegisterAllExtensions(registry);
return registry;
};
pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
new pbd::FileDescriptor[] {
global::Google.ProtocolBuffers.TestProtos.UnittestImportPublic.Descriptor,
}, assigner);
}
#endregion
}
#region Enums
public enum ImportEnum {
IMPORT_FOO = 7,
IMPORT_BAR = 8,
IMPORT_BAZ = 9,
}
#endregion
#region Messages
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class ImportMessage : pb::GeneratedMessage<ImportMessage, ImportMessage.Builder> {
private ImportMessage() { }
private static readonly ImportMessage defaultInstance = new ImportMessage().MakeReadOnly();
private static readonly string[] _importMessageFieldNames = new string[] { "d" };
private static readonly uint[] _importMessageFieldTags = new uint[] { 8 };
public static ImportMessage DefaultInstance {
get { return defaultInstance; }
}
public override ImportMessage DefaultInstanceForType {
get { return DefaultInstance; }
}
protected override ImportMessage ThisMessage {
get { return this; }
}
public static pbd::MessageDescriptor Descriptor {
get { return global::Google.ProtocolBuffers.TestProtos.UnittestImport.internal__static_protobuf_unittest_import_ImportMessage__Descriptor; }
}
protected override pb::FieldAccess.FieldAccessorTable<ImportMessage, ImportMessage.Builder> InternalFieldAccessors {
get { return global::Google.ProtocolBuffers.TestProtos.UnittestImport.internal__static_protobuf_unittest_import_ImportMessage__FieldAccessorTable; }
}
public const int DFieldNumber = 1;
private bool hasD;
private int d_;
public bool HasD {
get { return hasD; }
}
public int D {
get { return d_; }
}
public override bool IsInitialized {
get {
return true;
}
}
public override void WriteTo(pb::ICodedOutputStream output) {
CalcSerializedSize();
string[] field_names = _importMessageFieldNames;
if (hasD) {
output.WriteInt32(1, field_names[0], D);
}
UnknownFields.WriteTo(output);
}
private int memoizedSerializedSize = -1;
public override int SerializedSize {
get {
int size = memoizedSerializedSize;
if (size != -1) return size;
return CalcSerializedSize();
}
}
private int CalcSerializedSize() {
int size = memoizedSerializedSize;
if (size != -1) return size;
size = 0;
if (hasD) {
size += pb::CodedOutputStream.ComputeInt32Size(1, D);
}
size += UnknownFields.SerializedSize;
memoizedSerializedSize = size;
return size;
}
public static ImportMessage ParseFrom(pb::ByteString data) {
return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
}
public static ImportMessage ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
}
public static ImportMessage ParseFrom(byte[] data) {
return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
}
public static ImportMessage ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
}
public static ImportMessage ParseFrom(global::System.IO.Stream input) {
return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
}
public static ImportMessage ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
}
public static ImportMessage ParseDelimitedFrom(global::System.IO.Stream input) {
return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
}
public static ImportMessage ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
}
public static ImportMessage ParseFrom(pb::ICodedInputStream input) {
return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
}
public static ImportMessage ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
}
private ImportMessage MakeReadOnly() {
return this;
}
public static Builder CreateBuilder() { return new Builder(); }
public override Builder ToBuilder() { return CreateBuilder(this); }
public override Builder CreateBuilderForType() { return new Builder(); }
public static Builder CreateBuilder(ImportMessage prototype) {
return new Builder(prototype);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class Builder : pb::GeneratedBuilder<ImportMessage, Builder> {
protected override Builder ThisBuilder {
get { return this; }
}
public Builder() {
result = DefaultInstance;
resultIsReadOnly = true;
}
internal Builder(ImportMessage cloneFrom) {
result = cloneFrom;
resultIsReadOnly = true;
}
private bool resultIsReadOnly;
private ImportMessage result;
private ImportMessage PrepareBuilder() {
if (resultIsReadOnly) {
ImportMessage original = result;
result = new ImportMessage();
resultIsReadOnly = false;
MergeFrom(original);
}
return result;
}
public override bool IsInitialized {
get { return result.IsInitialized; }
}
protected override ImportMessage MessageBeingBuilt {
get { return PrepareBuilder(); }
}
public override Builder Clear() {
result = DefaultInstance;
resultIsReadOnly = true;
return this;
}
public override Builder Clone() {
if (resultIsReadOnly) {
return new Builder(result);
} else {
return new Builder().MergeFrom(result);
}
}
public override pbd::MessageDescriptor DescriptorForType {
get { return global::Google.ProtocolBuffers.TestProtos.ImportMessage.Descriptor; }
}
public override ImportMessage DefaultInstanceForType {
get { return global::Google.ProtocolBuffers.TestProtos.ImportMessage.DefaultInstance; }
}
public override ImportMessage BuildPartial() {
if (resultIsReadOnly) {
return result;
}
resultIsReadOnly = true;
return result.MakeReadOnly();
}
public override Builder MergeFrom(pb::IMessage other) {
if (other is ImportMessage) {
return MergeFrom((ImportMessage) other);
} else {
base.MergeFrom(other);
return this;
}
}
public override Builder MergeFrom(ImportMessage other) {
if (other == global::Google.ProtocolBuffers.TestProtos.ImportMessage.DefaultInstance) return this;
PrepareBuilder();
if (other.HasD) {
D = other.D;
}
this.MergeUnknownFields(other.UnknownFields);
return this;
}
public override Builder MergeFrom(pb::ICodedInputStream input) {
return MergeFrom(input, pb::ExtensionRegistry.Empty);
}
public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
PrepareBuilder();
pb::UnknownFieldSet.Builder unknownFields = null;
uint tag;
string field_name;
while (input.ReadTag(out tag, out field_name)) {
if(tag == 0 && field_name != null) {
int field_ordinal = global::System.Array.BinarySearch(_importMessageFieldNames, field_name, global::System.StringComparer.Ordinal);
if(field_ordinal >= 0)
tag = _importMessageFieldTags[field_ordinal];
else {
if (unknownFields == null) {
unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
}
ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
continue;
}
}
switch (tag) {
case 0: {
throw pb::InvalidProtocolBufferException.InvalidTag();
}
default: {
if (pb::WireFormat.IsEndGroupTag(tag)) {
if (unknownFields != null) {
this.UnknownFields = unknownFields.Build();
}
return this;
}
if (unknownFields == null) {
unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
}
ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
break;
}
case 8: {
result.hasD = input.ReadInt32(ref result.d_);
break;
}
}
}
if (unknownFields != null) {
this.UnknownFields = unknownFields.Build();
}
return this;
}
public bool HasD {
get { return result.hasD; }
}
public int D {
get { return result.D; }
set { SetD(value); }
}
public Builder SetD(int value) {
PrepareBuilder();
result.hasD = true;
result.d_ = value;
return this;
}
public Builder ClearD() {
PrepareBuilder();
result.hasD = false;
result.d_ = 0;
return this;
}
}
static ImportMessage() {
object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnittestImport.Descriptor, null);
}
}
#endregion
}
#endregion Designer generated code

@ -1,333 +0,0 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: google/protobuf/unittest_import_public.proto
#pragma warning disable 1591, 0612, 3021
#region Designer generated code
using pb = global::Google.ProtocolBuffers;
using pbc = global::Google.ProtocolBuffers.Collections;
using pbd = global::Google.ProtocolBuffers.Descriptors;
using scg = global::System.Collections.Generic;
namespace Google.ProtocolBuffers.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public static partial class UnittestImportPublic {
#region Extension registration
public static void RegisterAllExtensions(pb::ExtensionRegistry registry) {
}
#endregion
#region Static variables
internal static pbd::MessageDescriptor internal__static_protobuf_unittest_import_PublicImportMessage__Descriptor;
internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.PublicImportMessage, global::Google.ProtocolBuffers.TestProtos.PublicImportMessage.Builder> internal__static_protobuf_unittest_import_PublicImportMessage__FieldAccessorTable;
#endregion
#region Descriptor
public static pbd::FileDescriptor Descriptor {
get { return descriptor; }
}
private static pbd::FileDescriptor descriptor;
static UnittestImportPublic() {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
"Cixnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0X3B1YmxpYy5wcm90",
"bxIYcHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0IiAKE1B1YmxpY0ltcG9ydE1l",
"c3NhZ2USCQoBZRgBIAEoBUI+Chhjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3Sq",
"AiFHb29nbGUuUHJvdG9jb2xCdWZmZXJzLlRlc3RQcm90b3M="));
pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) {
descriptor = root;
internal__static_protobuf_unittest_import_PublicImportMessage__Descriptor = Descriptor.MessageTypes[0];
internal__static_protobuf_unittest_import_PublicImportMessage__FieldAccessorTable =
new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.PublicImportMessage, global::Google.ProtocolBuffers.TestProtos.PublicImportMessage.Builder>(internal__static_protobuf_unittest_import_PublicImportMessage__Descriptor,
new string[] { "E", });
pb::ExtensionRegistry registry = pb::ExtensionRegistry.CreateInstance();
RegisterAllExtensions(registry);
return registry;
};
pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
new pbd::FileDescriptor[] {
}, assigner);
}
#endregion
}
#region Messages
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class PublicImportMessage : pb::GeneratedMessage<PublicImportMessage, PublicImportMessage.Builder> {
private PublicImportMessage() { }
private static readonly PublicImportMessage defaultInstance = new PublicImportMessage().MakeReadOnly();
private static readonly string[] _publicImportMessageFieldNames = new string[] { "e" };
private static readonly uint[] _publicImportMessageFieldTags = new uint[] { 8 };
public static PublicImportMessage DefaultInstance {
get { return defaultInstance; }
}
public override PublicImportMessage DefaultInstanceForType {
get { return DefaultInstance; }
}
protected override PublicImportMessage ThisMessage {
get { return this; }
}
public static pbd::MessageDescriptor Descriptor {
get { return global::Google.ProtocolBuffers.TestProtos.UnittestImportPublic.internal__static_protobuf_unittest_import_PublicImportMessage__Descriptor; }
}
protected override pb::FieldAccess.FieldAccessorTable<PublicImportMessage, PublicImportMessage.Builder> InternalFieldAccessors {
get { return global::Google.ProtocolBuffers.TestProtos.UnittestImportPublic.internal__static_protobuf_unittest_import_PublicImportMessage__FieldAccessorTable; }
}
public const int EFieldNumber = 1;
private bool hasE;
private int e_;
public bool HasE {
get { return hasE; }
}
public int E {
get { return e_; }
}
public override bool IsInitialized {
get {
return true;
}
}
public override void WriteTo(pb::ICodedOutputStream output) {
CalcSerializedSize();
string[] field_names = _publicImportMessageFieldNames;
if (hasE) {
output.WriteInt32(1, field_names[0], E);
}
UnknownFields.WriteTo(output);
}
private int memoizedSerializedSize = -1;
public override int SerializedSize {
get {
int size = memoizedSerializedSize;
if (size != -1) return size;
return CalcSerializedSize();
}
}
private int CalcSerializedSize() {
int size = memoizedSerializedSize;
if (size != -1) return size;
size = 0;
if (hasE) {
size += pb::CodedOutputStream.ComputeInt32Size(1, E);
}
size += UnknownFields.SerializedSize;
memoizedSerializedSize = size;
return size;
}
public static PublicImportMessage ParseFrom(pb::ByteString data) {
return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
}
public static PublicImportMessage ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
}
public static PublicImportMessage ParseFrom(byte[] data) {
return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
}
public static PublicImportMessage ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
}
public static PublicImportMessage ParseFrom(global::System.IO.Stream input) {
return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
}
public static PublicImportMessage ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
}
public static PublicImportMessage ParseDelimitedFrom(global::System.IO.Stream input) {
return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
}
public static PublicImportMessage ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
}
public static PublicImportMessage ParseFrom(pb::ICodedInputStream input) {
return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
}
public static PublicImportMessage ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
}
private PublicImportMessage MakeReadOnly() {
return this;
}
public static Builder CreateBuilder() { return new Builder(); }
public override Builder ToBuilder() { return CreateBuilder(this); }
public override Builder CreateBuilderForType() { return new Builder(); }
public static Builder CreateBuilder(PublicImportMessage prototype) {
return new Builder(prototype);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class Builder : pb::GeneratedBuilder<PublicImportMessage, Builder> {
protected override Builder ThisBuilder {
get { return this; }
}
public Builder() {
result = DefaultInstance;
resultIsReadOnly = true;
}
internal Builder(PublicImportMessage cloneFrom) {
result = cloneFrom;
resultIsReadOnly = true;
}
private bool resultIsReadOnly;
private PublicImportMessage result;
private PublicImportMessage PrepareBuilder() {
if (resultIsReadOnly) {
PublicImportMessage original = result;
result = new PublicImportMessage();
resultIsReadOnly = false;
MergeFrom(original);
}
return result;
}
public override bool IsInitialized {
get { return result.IsInitialized; }
}
protected override PublicImportMessage MessageBeingBuilt {
get { return PrepareBuilder(); }
}
public override Builder Clear() {
result = DefaultInstance;
resultIsReadOnly = true;
return this;
}
public override Builder Clone() {
if (resultIsReadOnly) {
return new Builder(result);
} else {
return new Builder().MergeFrom(result);
}
}
public override pbd::MessageDescriptor DescriptorForType {
get { return global::Google.ProtocolBuffers.TestProtos.PublicImportMessage.Descriptor; }
}
public override PublicImportMessage DefaultInstanceForType {
get { return global::Google.ProtocolBuffers.TestProtos.PublicImportMessage.DefaultInstance; }
}
public override PublicImportMessage BuildPartial() {
if (resultIsReadOnly) {
return result;
}
resultIsReadOnly = true;
return result.MakeReadOnly();
}
public override Builder MergeFrom(pb::IMessage other) {
if (other is PublicImportMessage) {
return MergeFrom((PublicImportMessage) other);
} else {
base.MergeFrom(other);
return this;
}
}
public override Builder MergeFrom(PublicImportMessage other) {
if (other == global::Google.ProtocolBuffers.TestProtos.PublicImportMessage.DefaultInstance) return this;
PrepareBuilder();
if (other.HasE) {
E = other.E;
}
this.MergeUnknownFields(other.UnknownFields);
return this;
}
public override Builder MergeFrom(pb::ICodedInputStream input) {
return MergeFrom(input, pb::ExtensionRegistry.Empty);
}
public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
PrepareBuilder();
pb::UnknownFieldSet.Builder unknownFields = null;
uint tag;
string field_name;
while (input.ReadTag(out tag, out field_name)) {
if(tag == 0 && field_name != null) {
int field_ordinal = global::System.Array.BinarySearch(_publicImportMessageFieldNames, field_name, global::System.StringComparer.Ordinal);
if(field_ordinal >= 0)
tag = _publicImportMessageFieldTags[field_ordinal];
else {
if (unknownFields == null) {
unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
}
ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
continue;
}
}
switch (tag) {
case 0: {
throw pb::InvalidProtocolBufferException.InvalidTag();
}
default: {
if (pb::WireFormat.IsEndGroupTag(tag)) {
if (unknownFields != null) {
this.UnknownFields = unknownFields.Build();
}
return this;
}
if (unknownFields == null) {
unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
}
ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
break;
}
case 8: {
result.hasE = input.ReadInt32(ref result.e_);
break;
}
}
}
if (unknownFields != null) {
this.UnknownFields = unknownFields.Build();
}
return this;
}
public bool HasE {
get { return result.hasE; }
}
public int E {
get { return result.E; }
set { SetE(value); }
}
public Builder SetE(int value) {
PrepareBuilder();
result.hasE = true;
result.e_ = value;
return this;
}
public Builder ClearE() {
PrepareBuilder();
result.hasE = false;
result.e_ = 0;
return this;
}
}
static PublicImportMessage() {
object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnittestImportPublic.Descriptor, null);
}
}
#endregion
}
#endregion Designer generated code

@ -1,3 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0,Profile=Client"/></startup></configuration>

@ -36,6 +36,7 @@
using System;
using System.IO;
using Google.Protobuf;
namespace Google.ProtocolBuffers.ProtoDump
{
@ -53,36 +54,24 @@ namespace Google.ProtocolBuffers.ProtoDump
Console.Error.WriteLine("including assembly e.g. ProjectNamespace.Message,Company.Project");
return 1;
}
IMessage defaultMessage;
try
Type type = Type.GetType(args[0]);
if (type == null)
{
defaultMessage = MessageUtil.GetDefaultMessage(args[0]);
}
catch (ArgumentException e)
{
Console.Error.WriteLine(e.Message);
Console.Error.WriteLine("Unable to load type {0}.", args[0]);
return 1;
}
try
if (!typeof(IMessage).IsAssignableFrom(type))
{
IBuilder builder = defaultMessage.WeakCreateBuilderForType();
if (builder == null)
{
Console.Error.WriteLine("Unable to create builder");
return 1;
}
byte[] inputData = File.ReadAllBytes(args[1]);
builder.WeakMergeFrom(ByteString.CopyFrom(inputData));
Console.WriteLine(TextFormat.PrintToString(builder.WeakBuild()));
return 0;
Console.Error.WriteLine("Type {0} doesn't implement IMessage.", args[0]);
return 1;
}
catch (Exception e)
IMessage message = (IMessage) Activator.CreateInstance(type);
using (var input = File.OpenRead(args[1]))
{
Console.Error.WriteLine("Error: {0}", e.Message);
Console.Error.WriteLine();
Console.Error.WriteLine("Detailed exception information: {0}", e);
return 1;
message.MergeFrom(input);
}
Console.WriteLine(message);
return 0;
}
}
}

@ -1,307 +0,0 @@
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://github.com/jskeet/dotnet-protobufs/
// Original C++/Java/Python code:
// http://code.google.com/p/protobuf/
//
// 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
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using Google.Protobuf;
using Google.Protobuf.Descriptors;
using Google.ProtocolBuffers.Descriptors;
namespace Google.ProtocolBuffers.ProtoMunge
{
/// <summary>
/// Utility console application which takes a message descriptor and a corresponding message,
/// and produces a new message with similar but random data. The data is the same length
/// as the original, but with random values within appropriate bands. (For instance, a compressed
/// integer in the range 0-127 will end up as another integer in the same range, to keep the length
/// the same.)
/// TODO(jonskeet): Potentially refactor to use an instance instead, making it simpler to
/// be thread-safe for external use.
/// </summary>
public sealed class Program
{
private static readonly Random rng = new Random();
private static int Main(string[] args)
{
if (args.Length != 3)
{
Console.Error.WriteLine("Usage: ProtoMunge <descriptor type name> <input data> <output file>");
Console.Error.WriteLine(
"The descriptor type name is the fully-qualified message name, including assembly.");
Console.Error.WriteLine(
"(At a future date it may be possible to do this without building the .NET assembly at all.)");
return 1;
}
IMessage defaultMessage;
try
{
defaultMessage = MessageUtil.GetDefaultMessage(args[0]);
}
catch (ArgumentException e)
{
Console.Error.WriteLine(e.Message);
return 1;
}
try
{
IBuilder builder = defaultMessage.WeakCreateBuilderForType();
byte[] inputData = File.ReadAllBytes(args[1]);
builder.WeakMergeFrom(ByteString.CopyFrom(inputData));
IMessage original = builder.WeakBuild();
IMessage munged = Munge(original);
if (original.SerializedSize != munged.SerializedSize)
{
throw new Exception("Serialized sizes don't match");
}
File.WriteAllBytes(args[2], munged.ToByteArray());
return 0;
}
catch (Exception e)
{
Console.Error.WriteLine("Error: {0}", e.Message);
Console.Error.WriteLine();
Console.Error.WriteLine("Detailed exception information: {0}", e);
return 1;
}
}
/// <summary>
/// Munges a message recursively.
/// </summary>
/// <returns>A new message of the same type as the original message,
/// but munged so that all the data is desensitised.</returns>
private static IMessage Munge(IMessage message)
{
IBuilder builder = message.WeakCreateBuilderForType();
foreach (var pair in message.AllFields)
{
if (pair.Key.IsRepeated)
{
foreach (object singleValue in (IEnumerable) pair.Value)
{
builder.WeakAddRepeatedField(pair.Key, CheckedMungeValue(pair.Key, singleValue));
}
}
else
{
builder[pair.Key] = CheckedMungeValue(pair.Key, pair.Value);
}
}
IMessage munged = builder.WeakBuild();
if (message.SerializedSize != munged.SerializedSize)
{
Console.WriteLine("Sub message sizes: {0}/{1}", message.SerializedSize, munged.SerializedSize);
}
return munged;
}
/// <summary>
/// Munges a single value and checks that the length ends up the same as it was before.
/// </summary>
private static object CheckedMungeValue(FieldDescriptor fieldDescriptor, object value)
{
int currentSize = CodedOutputStream.ComputeFieldSize(fieldDescriptor.FieldType, fieldDescriptor.FieldNumber,
value);
object mungedValue = MungeValue(fieldDescriptor, value);
int mungedSize = CodedOutputStream.ComputeFieldSize(fieldDescriptor.FieldType, fieldDescriptor.FieldNumber,
mungedValue);
// Exceptions log more easily than assertions
if (currentSize != mungedSize)
{
throw new Exception("Munged value had wrong size. Field type: " + fieldDescriptor.FieldType
+ "; old value: " + value + "; new value: " + mungedValue);
}
return mungedValue;
}
/// <summary>
/// Munges a single value of the specified field descriptor. (i.e. if the field is
/// actually a repeated int, this method receives a single int value to munge, and
/// is called multiple times).
/// </summary>
private static object MungeValue(FieldDescriptor fieldDescriptor, object value)
{
switch (fieldDescriptor.FieldType)
{
case FieldType.SInt64:
case FieldType.Int64:
return (long) MungeVarint64((ulong) (long) value);
case FieldType.UInt64:
return MungeVarint64((ulong) value);
case FieldType.SInt32:
return (int) MungeVarint32((uint) (int) value);
case FieldType.Int32:
return MungeInt32((int) value);
case FieldType.UInt32:
return MungeVarint32((uint) value);
case FieldType.Double:
return rng.NextDouble();
case FieldType.Float:
return (float) rng.NextDouble();
case FieldType.Fixed64:
{
byte[] data = new byte[8];
rng.NextBytes(data);
return BitConverter.ToUInt64(data, 0);
}
case FieldType.Fixed32:
{
byte[] data = new byte[4];
rng.NextBytes(data);
return BitConverter.ToUInt32(data, 0);
}
case FieldType.Bool:
return rng.Next(2) == 1;
case FieldType.String:
return MungeString((string) value);
case FieldType.Group:
case FieldType.Message:
return Munge((IMessage) value);
case FieldType.Bytes:
return MungeByteString((ByteString) value);
case FieldType.SFixed64:
{
byte[] data = new byte[8];
rng.NextBytes(data);
return BitConverter.ToInt64(data, 0);
}
case FieldType.SFixed32:
{
byte[] data = new byte[4];
rng.NextBytes(data);
return BitConverter.ToInt32(data, 0);
}
case FieldType.Enum:
return MungeEnum(fieldDescriptor, (EnumValueDescriptor) value);
default:
// TODO(jonskeet): Different exception?
throw new ArgumentException("Invalid field descriptor");
}
}
private static object MungeString(string original)
{
foreach (char c in original)
{
if (c > 127)
{
throw new ArgumentException("Can't handle non-ascii yet");
}
}
char[] chars = new char[original.Length];
// Convert to pure ASCII - no control characters.
for (int i = 0; i < chars.Length; i++)
{
chars[i] = (char) rng.Next(32, 127);
}
return new string(chars);
}
/// <summary>
/// Int32 fields are slightly strange - we need to keep the sign the same way it is:
/// negative numbers can munge to any other negative number (it'll always take
/// 10 bytes) but positive numbers have to stay positive, so we can't use the
/// full range of 32 bits.
/// </summary>
private static int MungeInt32(int value)
{
if (value < 0)
{
return rng.Next(int.MinValue, 0);
}
int length = CodedOutputStream.ComputeRawVarint32Size((uint) value);
uint min = length == 1 ? 0 : 1U << ((length - 1)*7);
uint max = length == 5 ? int.MaxValue : (1U << (length*7)) - 1;
return (int) NextRandomUInt64(min, max);
}
private static uint MungeVarint32(uint original)
{
int length = CodedOutputStream.ComputeRawVarint32Size(original);
uint min = length == 1 ? 0 : 1U << ((length - 1)*7);
uint max = length == 5 ? uint.MaxValue : (1U << (length*7)) - 1;
return (uint) NextRandomUInt64(min, max);
}
private static ulong MungeVarint64(ulong original)
{
int length = CodedOutputStream.ComputeRawVarint64Size(original);
ulong min = length == 1 ? 0 : 1UL << ((length - 1)*7);
ulong max = length == 10 ? ulong.MaxValue : (1UL << (length*7)) - 1;
return NextRandomUInt64(min, max);
}
/// <summary>
/// Returns a random number in the range [min, max] (both inclusive).
/// </summary>
private static ulong NextRandomUInt64(ulong min, ulong max)
{
if (min > max)
{
throw new ArgumentException("min must be <= max; min=" + min + "; max = " + max);
}
ulong range = max - min;
// This isn't actually terribly good at very large ranges - but it doesn't really matter for the sake
// of this program.
return min + (ulong) (range*rng.NextDouble());
}
private static object MungeEnum(FieldDescriptor fieldDescriptor, EnumValueDescriptor original)
{
// Find all the values which get encoded to the same size as the current value, and pick one at random
int originalSize = CodedOutputStream.ComputeRawVarint32Size((uint) original.Number);
List<EnumValueDescriptor> sameSizeValues = new List<EnumValueDescriptor>();
foreach (EnumValueDescriptor candidate in fieldDescriptor.EnumType.Values)
{
if (CodedOutputStream.ComputeRawVarint32Size((uint) candidate.Number) == originalSize)
{
sameSizeValues.Add(candidate);
}
}
return sameSizeValues[rng.Next(sameSizeValues.Count)];
}
private static object MungeByteString(ByteString byteString)
{
byte[] data = new byte[byteString.Length];
rng.NextBytes(data);
return ByteString.CopyFrom(data);
}
}
}

@ -1,30 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("ProtoMunge")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ProtoMunge")]
[assembly: AssemblyCopyright("Copyright © 2008")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("2.4.1.555")]
[assembly: AssemblyVersion("2.4.1.555")]
[assembly: AssemblyFileVersion("2.4.1.555")]

@ -1,67 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<EnvironmentFlavor>CLIENTPROFILE</EnvironmentFlavor>
<EnvironmentTemplate>NET35</EnvironmentTemplate>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{8F09AF72-3327-4FA7-BC09-070B80221AB9}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Google.ProtocolBuffers.ProtoMunge</RootNamespace>
<AssemblyName>ProtoMunge</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<IntermediateOutputPath>obj\Debug\</IntermediateOutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<NoStdLib>true</NoStdLib>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<IntermediateOutputPath>obj\Release\</IntermediateOutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<NoStdLib>true</NoStdLib>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
</PropertyGroup>
<ItemGroup>
<Reference Include="mscorlib" />
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ProtocolBuffers\ProtocolBuffers.csproj">
<Project>{6908BDCE-D925-43F3-94AC-A531E6DF2591}</Project>
<Name>ProtocolBuffers</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

@ -1,3 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0,Profile=Client"/></startup></configuration>

@ -40,7 +40,6 @@ using NUnit.Framework;
namespace Google.Protobuf
{
[TestFixture]
public class ByteStringTest
{
[Test]

@ -10,10 +10,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AddressBook", "AddressBook\
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProtoDump", "ProtoDump\ProtoDump.csproj", "{D7282E99-2DC3-405B-946F-177DB2FD2AE2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProtoMunge", "ProtoMunge\ProtoMunge.csproj", "{8F09AF72-3327-4FA7-BC09-070B80221AB9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProtoBench", "ProtoBench\ProtoBench.csproj", "{C7A4A435-2813-41C8-AA87-BD914BA5223D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -36,14 +32,6 @@ Global
{D7282E99-2DC3-405B-946F-177DB2FD2AE2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D7282E99-2DC3-405B-946F-177DB2FD2AE2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D7282E99-2DC3-405B-946F-177DB2FD2AE2}.Release|Any CPU.Build.0 = Release|Any CPU
{8F09AF72-3327-4FA7-BC09-070B80221AB9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8F09AF72-3327-4FA7-BC09-070B80221AB9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8F09AF72-3327-4FA7-BC09-070B80221AB9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8F09AF72-3327-4FA7-BC09-070B80221AB9}.Release|Any CPU.Build.0 = Release|Any CPU
{C7A4A435-2813-41C8-AA87-BD914BA5223D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C7A4A435-2813-41C8-AA87-BD914BA5223D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C7A4A435-2813-41C8-AA87-BD914BA5223D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C7A4A435-2813-41C8-AA87-BD914BA5223D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

Loading…
Cancel
Save