Merge branch 'master' of github.com:google/protobuf

Change-Id: If3fb07754a734bae610d95124528e073515ac525
pull/734/head
Jisi Liu 9 years ago
commit c3bc155ace
  1. 3
      .gitignore
  2. 4
      BUILD
  3. 354
      Makefile.am
  4. 4
      Protobuf.podspec
  5. 29
      appveyor.bat
  6. 66
      appveyor.yml
  7. 1
      benchmarks/google_size.proto
  8. 1
      benchmarks/google_speed.proto
  9. 45
      cmake/CMakeLists.txt
  10. 1
      cmake/extract_includes.bat.in
  11. 103
      cmake/install.cmake
  12. 1
      cmake/libprotobuf-lite.cmake
  13. 1
      cmake/libprotobuf.cmake
  14. 4
      cmake/libprotoc.cmake
  15. 1
      cmake/protobuf-config-version.cmake.in
  16. 27
      cmake/protobuf-config.cmake.in
  17. 139
      cmake/protobuf-module.cmake.in
  18. 14
      conformance/Makefile.am
  19. 0
      conformance/failure_list_csharp.txt
  20. 15
      conformance/failure_list_ruby.txt
  21. 28
      csharp/.gitignore
  22. 44
      csharp/README.md
  23. 8
      csharp/build/BuildAll.bat
  24. 122
      csharp/build/Common.targets
  25. 59
      csharp/build/Google.ProtocolBuffers.nuspec
  26. 60
      csharp/build/Google.ProtocolBuffersLite.nuspec
  27. 2
      csharp/build/RunBenchmarks.bat
  28. 20
      csharp/build/build.bat
  29. 241
      csharp/build/build.csproj
  30. 248
      csharp/build/googlecode_upload.py
  31. 79
      csharp/build/nuspec.xsd
  32. 186
      csharp/build/publish.csproj
  33. 167
      csharp/build/target.csproj
  34. 13
      csharp/build_packages.bat
  35. 9
      csharp/buildall.sh
  36. 74
      csharp/generate_protos.sh
  37. BIN
      csharp/keys/Google.Protobuf.public.snk
  38. BIN
      csharp/keys/Google.ProtocolBuffers.snk
  39. 5
      csharp/keys/README.md
  40. 13
      csharp/keys/generate_new_key.bat
  41. 71
      csharp/protos/extest/unittest_extras_full.proto
  42. 115
      csharp/protos/extest/unittest_extras_lite.proto
  43. 53
      csharp/protos/extest/unittest_extras_xmltest.proto
  44. 141
      csharp/protos/extest/unittest_issues.proto
  45. 119
      csharp/protos/unittest_issues.proto
  46. 26
      csharp/src/AddressBook/AddPerson.cs
  47. 15
      csharp/src/AddressBook/AddressBook.csproj
  48. 1314
      csharp/src/AddressBook/Addressbook.cs
  49. 16
      csharp/src/AddressBook/ListPeople.cs
  50. 8
      csharp/src/AddressBook/Program.cs
  51. 17
      csharp/src/AddressBook/Properties/AssemblyInfo.cs
  52. 78
      csharp/src/AddressBook/SampleUsage.cs
  53. 2
      csharp/src/AddressBook/app.config
  54. 6
      csharp/src/Google.Protobuf.Conformance/App.config
  55. 2380
      csharp/src/Google.Protobuf.Conformance/Conformance.cs
  56. 126
      csharp/src/Google.Protobuf.Conformance/Google.Protobuf.Conformance.csproj
  57. 126
      csharp/src/Google.Protobuf.Conformance/Program.cs
  58. 113
      csharp/src/Google.Protobuf.Conformance/Properties/AssemblyInfo.cs
  59. 17
      csharp/src/Google.Protobuf.JsonDump/Google.Protobuf.JsonDump.csproj
  60. 46
      csharp/src/Google.Protobuf.JsonDump/Program.cs
  61. 17
      csharp/src/Google.Protobuf.JsonDump/Properties/AssemblyInfo.cs
  62. 2
      csharp/src/Google.Protobuf.JsonDump/app.config
  63. 36
      csharp/src/Google.Protobuf.Test/ByteStringTest.cs
  64. 53
      csharp/src/Google.Protobuf.Test/CodedInputStreamExtensions.cs
  65. 365
      csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs
  66. 182
      csharp/src/Google.Protobuf.Test/CodedOutputStreamTest.cs
  67. 570
      csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs
  68. 603
      csharp/src/Google.Protobuf.Test/Collections/RepeatedFieldTest.cs
  69. 98
      csharp/src/Google.Protobuf.Test/Compatibility/PropertyInfoExtensionsTest.cs
  70. 133
      csharp/src/Google.Protobuf.Test/Compatibility/TypeExtensionsTest.cs
  71. 55
      csharp/src/Google.Protobuf.Test/DeprecatedMemberTest.cs
  72. 64
      csharp/src/Google.Protobuf.Test/EqualityTester.cs
  73. 195
      csharp/src/Google.Protobuf.Test/FieldCodecTest.cs
  74. 655
      csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs
  75. 80
      csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj
  76. 23
      csharp/src/Google.Protobuf.Test/IssuesTest.cs
  77. 419
      csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs
  78. 0
      csharp/src/Google.Protobuf.Test/Properties/AppManifest.xml
  79. 20
      csharp/src/Google.Protobuf.Test/Properties/AssemblyInfo.cs
  80. 548
      csharp/src/Google.Protobuf.Test/Reflection/DescriptorsTest.cs
  81. 218
      csharp/src/Google.Protobuf.Test/Reflection/FieldAccessTest.cs
  82. 42
      csharp/src/Google.Protobuf.Test/SampleEnum.cs
  83. 99
      csharp/src/Google.Protobuf.Test/SampleMessages.cs
  84. 62
      csharp/src/Google.Protobuf.Test/TestCornerCases.cs
  85. 1417
      csharp/src/Google.Protobuf.Test/TestProtos/MapUnittestProto3.cs
  86. 158
      csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportProto3.cs
  87. 144
      csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportPublicProto3.cs
  88. 1355
      csharp/src/Google.Protobuf.Test/TestProtos/UnittestIssues.cs
  89. 5830
      csharp/src/Google.Protobuf.Test/TestProtos/UnittestProto3.cs
  90. 2283
      csharp/src/Google.Protobuf.Test/TestProtos/UnittestWellKnownTypes.cs
  91. 104
      csharp/src/Google.Protobuf.Test/WellKnownTypes/DurationTest.cs
  92. 84
      csharp/src/Google.Protobuf.Test/WellKnownTypes/TimestampTest.cs
  93. 349
      csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs
  94. 0
      csharp/src/Google.Protobuf.Test/packages.config
  95. 56
      csharp/src/Google.Protobuf.sln
  96. 33
      csharp/src/Google.Protobuf/ByteArray.cs
  97. 156
      csharp/src/Google.Protobuf/ByteString.cs
  98. 1221
      csharp/src/Google.Protobuf/CodedInputStream.cs
  99. 304
      csharp/src/Google.Protobuf/CodedOutputStream.ComputeSize.cs
  100. 708
      csharp/src/Google.Protobuf/CodedOutputStream.cs
  101. Some files were not shown because too many files have changed in this diff Show More

3
.gitignore vendored

@ -79,8 +79,7 @@ java/target
javanano/target javanano/target
# Windows native output. # Windows native output.
vsprojects/Debug cmake/build
vsprojects/Release
# NuGet packages: we want the repository configuration, but not the # NuGet packages: we want the repository configuration, but not the
# packages themselves. # packages themselves.

@ -162,10 +162,10 @@ cc_library(
"src/google/protobuf/compiler/cpp/cpp_string_field.cc", "src/google/protobuf/compiler/cpp/cpp_string_field.cc",
"src/google/protobuf/compiler/csharp/csharp_enum.cc", "src/google/protobuf/compiler/csharp/csharp_enum.cc",
"src/google/protobuf/compiler/csharp/csharp_enum_field.cc", "src/google/protobuf/compiler/csharp/csharp_enum_field.cc",
"src/google/protobuf/compiler/csharp/csharp_extension.cc",
"src/google/protobuf/compiler/csharp/csharp_field_base.cc", "src/google/protobuf/compiler/csharp/csharp_field_base.cc",
"src/google/protobuf/compiler/csharp/csharp_generator.cc", "src/google/protobuf/compiler/csharp/csharp_generator.cc",
"src/google/protobuf/compiler/csharp/csharp_helpers.cc", "src/google/protobuf/compiler/csharp/csharp_helpers.cc",
"src/google/protobuf/compiler/csharp/csharp_map_field.cc",
"src/google/protobuf/compiler/csharp/csharp_message.cc", "src/google/protobuf/compiler/csharp/csharp_message.cc",
"src/google/protobuf/compiler/csharp/csharp_message_field.cc", "src/google/protobuf/compiler/csharp/csharp_message_field.cc",
"src/google/protobuf/compiler/csharp/csharp_primitive_field.cc", "src/google/protobuf/compiler/csharp/csharp_primitive_field.cc",
@ -174,7 +174,7 @@ cc_library(
"src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc", "src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc",
"src/google/protobuf/compiler/csharp/csharp_source_generator_base.cc", "src/google/protobuf/compiler/csharp/csharp_source_generator_base.cc",
"src/google/protobuf/compiler/csharp/csharp_umbrella_class.cc", "src/google/protobuf/compiler/csharp/csharp_umbrella_class.cc",
"src/google/protobuf/compiler/csharp/csharp_writer.cc", "src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc",
"src/google/protobuf/compiler/java/java_context.cc", "src/google/protobuf/compiler/java/java_context.cc",
"src/google/protobuf/compiler/java/java_doc_comment.cc", "src/google/protobuf/compiler/java/java_doc_comment.cc",
"src/google/protobuf/compiler/java/java_enum.cc", "src/google/protobuf/compiler/java/java_enum.cc",

@ -40,254 +40,112 @@ clean-local:
pkgconfigdir = $(libdir)/pkgconfig pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = protobuf.pc protobuf-lite.pc pkgconfig_DATA = protobuf.pc protobuf-lite.pc
csharp_EXTRA_DIST= \ csharp_EXTRA_DIST= \
csharp/src/ProtocolBuffers.sln \ csharp/CHANGES.txt \
csharp/src/ProtocolBuffersLite.Test/TestProtos/UnittestImportPublicLite.cs \ csharp/README.md \
csharp/src/ProtocolBuffersLite.Test/TestProtos/UnittestExtrasLite.cs \ csharp/build_packages.bat \
csharp/src/ProtocolBuffersLite.Test/TestProtos/UnittestExtrasFull.cs \ csharp/buildall.sh \
csharp/src/ProtocolBuffersLite.Test/TestProtos/UnittestImport.cs \ csharp/generate_protos.sh \
csharp/src/ProtocolBuffersLite.Test/TestProtos/UnittestLiteImportsNonlite.cs \ csharp/keys/Google.Protobuf.public.snk \
csharp/src/ProtocolBuffersLite.Test/TestProtos/UnittestImportLite.cs \ csharp/keys/README.md \
csharp/src/ProtocolBuffersLite.Test/TestProtos/Unittest.cs \ csharp/protos/unittest_issues.proto \
csharp/src/ProtocolBuffersLite.Test/TestProtos/UnittestLite.cs \ csharp/src/AddressBook/AddPerson.cs \
csharp/src/ProtocolBuffersLite.Test/TestProtos/UnittestImportPublic.cs \ csharp/src/AddressBook/AddressBook.csproj \
csharp/src/ProtocolBuffersLite.Test/ExtendableMessageLiteTest.cs \ csharp/src/AddressBook/Addressbook.cs \
csharp/src/ProtocolBuffersLite.Test/packages.config \ csharp/src/AddressBook/ListPeople.cs \
csharp/src/ProtocolBuffersLite.Test/LiteTest.cs \ csharp/src/AddressBook/Program.cs \
csharp/src/ProtocolBuffersLite.Test/AbstractMessageLiteTest.cs \ csharp/src/AddressBook/Properties/AssemblyInfo.cs \
csharp/src/ProtocolBuffersLite.Test/MissingFieldAndExtensionTest.cs \ csharp/src/AddressBook/SampleUsage.cs \
csharp/src/ProtocolBuffersLite.Test/ProtocolBuffersLite.Test.csproj \ csharp/src/AddressBook/app.config \
csharp/src/ProtocolBuffersLite.Test/App.xaml.cs \ csharp/src/Google.Protobuf.JsonDump/Google.Protobuf.JsonDump.csproj \
csharp/src/ProtocolBuffersLite.Test/InteropLiteTest.cs \ csharp/src/Google.Protobuf.JsonDump/Program.cs \
csharp/src/ProtocolBuffersLite.Test/ExtendableBuilderLiteTest.cs \ csharp/src/Google.Protobuf.JsonDump/Properties/AssemblyInfo.cs \
csharp/src/ProtocolBuffersLite.Test/App.xaml \ csharp/src/Google.Protobuf.JsonDump/app.config \
csharp/src/ProtocolBuffersLite.Test/TestLiteByApi.cs \ csharp/src/Google.Protobuf.Test/ByteStringTest.cs \
csharp/src/ProtocolBuffersLite.Test/Properties/AppManifest.xml \ csharp/src/Google.Protobuf.Test/CodedInputStreamExtensions.cs \
csharp/src/ProtocolBuffersLite.Test/Properties/OutOfBrowserSettings.xml \ csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs \
csharp/src/ProtocolBuffersLite.Test/ProtocolBuffersLiteMixed.Test.csproj \ csharp/src/Google.Protobuf.Test/CodedOutputStreamTest.cs \
csharp/src/ProtocolBuffersLite.Test/AbstractBuilderLiteTest.cs \ csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs \
csharp/src/ProtoDump/ProtoDump.csproj \ csharp/src/Google.Protobuf.Test/Collections/RepeatedFieldTest.cs \
csharp/src/ProtoDump/app.config \ csharp/src/Google.Protobuf.Test/DeprecatedMemberTest.cs \
csharp/src/ProtoDump/Program.cs \ csharp/src/Google.Protobuf.Test/EqualityTester.cs \
csharp/src/ProtoDump/Properties/AssemblyInfo.cs \ csharp/src/Google.Protobuf.Test/FieldCodecTest.cs \
csharp/src/ProtocolBuffers.Serialization/AbstractReader.cs \ csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs \
csharp/src/ProtocolBuffers.Serialization/JsonFormatReader.cs \ csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj \
csharp/src/ProtocolBuffers.Serialization/JsonTextCursor.cs \ csharp/src/Google.Protobuf.Test/IssuesTest.cs \
csharp/src/ProtocolBuffers.Serialization/ProtocolBuffers.Serialization.csproj \ csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs \
csharp/src/ProtocolBuffers.Serialization/DictionaryWriter.cs \ csharp/src/Google.Protobuf.Test/Properties/AppManifest.xml \
csharp/src/ProtocolBuffers.Serialization/AbstractWriter.cs \ csharp/src/Google.Protobuf.Test/Properties/AssemblyInfo.cs \
csharp/src/ProtocolBuffers.Serialization/ProtocolBuffersLite.Serialization.csproj \ csharp/src/Google.Protobuf.Test/Reflection/DescriptorsTest.cs \
csharp/src/ProtocolBuffers.Serialization/XmlReaderOptions.cs \ csharp/src/Google.Protobuf.Test/SampleEnum.cs \
csharp/src/ProtocolBuffers.Serialization/AbstractTextReader.cs \ csharp/src/Google.Protobuf.Test/SampleMessages.cs \
csharp/src/ProtocolBuffers.Serialization/XmlWriterOptions.cs \ csharp/src/Google.Protobuf.Test/TestCornerCases.cs \
csharp/src/ProtocolBuffers.Serialization/JsonFormatWriter.cs \ csharp/src/Google.Protobuf.Test/TestProtos/MapUnittestProto3.cs \
csharp/src/ProtocolBuffers.Serialization/Properties/AssemblyInfo.cs \ csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportProto3.cs \
csharp/src/ProtocolBuffers.Serialization/DictionaryReader.cs \ csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportPublicProto3.cs \
csharp/src/ProtocolBuffers.Serialization/Extensions.cs \ csharp/src/Google.Protobuf.Test/TestProtos/UnittestIssues.cs \
csharp/src/ProtocolBuffers.Serialization/AbstractTextWriter.cs \ csharp/src/Google.Protobuf.Test/TestProtos/UnittestProto3.cs \
csharp/src/ProtocolBuffers.Serialization/XmlFormatWriter.cs \ csharp/src/Google.Protobuf.Test/TestProtos/UnittestWellKnownTypes.cs \
csharp/src/ProtocolBuffers.Serialization/Http/FormUrlEncodedReader.cs \ csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs \
csharp/src/ProtocolBuffers.Serialization/Http/MessageFormatOptions.cs \ csharp/src/Google.Protobuf.Test/packages.config \
csharp/src/ProtocolBuffers.Serialization/Http/MessageFormatFactory.cs \ csharp/src/Google.Protobuf.sln \
csharp/src/ProtocolBuffers.Serialization/XmlFormatReader.cs \ csharp/src/Google.Protobuf/ByteArray.cs \
csharp/src/ProtocolBuffers.Serialization/RecursionLimitExceeded.cs \ csharp/src/Google.Protobuf/ByteString.cs \
csharp/src/ProtoBench/GoogleSize.cs \ csharp/src/Google.Protobuf/CodedInputStream.cs \
csharp/src/ProtoBench/GoogleSpeed.cs \ csharp/src/Google.Protobuf/CodedOutputStream.ComputeSize.cs \
csharp/src/ProtoBench/UnittestImport.cs \ csharp/src/Google.Protobuf/CodedOutputStream.cs \
csharp/src/ProtoBench/google_message1.dat \ csharp/src/Google.Protobuf/Collections/MapField.cs \
csharp/src/ProtoBench/ProtoBench.csproj \ csharp/src/Google.Protobuf/Collections/ReadOnlyDictionary.cs \
csharp/src/ProtoBench/app.config \ csharp/src/Google.Protobuf/Collections/RepeatedField.cs \
csharp/src/ProtoBench/Program.cs \ csharp/src/Google.Protobuf/FieldCodec.cs \
csharp/src/ProtoBench/google_message2.dat \ csharp/src/Google.Protobuf/FrameworkPortability.cs \
csharp/src/ProtoBench/Properties/AssemblyInfo.cs \ csharp/src/Google.Protobuf/Google.Protobuf.csproj \
csharp/src/ProtoBench/Unittest.cs \ csharp/src/Google.Protobuf/Google.Protobuf.nuspec \
csharp/src/ProtoBench/UnittestImportPublic.cs \ csharp/src/Google.Protobuf/IMessage.cs \
csharp/src/ProtoMunge/app.config \ csharp/src/Google.Protobuf/InvalidProtocolBufferException.cs \
csharp/src/ProtoMunge/Program.cs \ csharp/src/Google.Protobuf/JsonFormatter.cs \
csharp/src/ProtoMunge/Properties/AssemblyInfo.cs \ csharp/src/Google.Protobuf/LimitedInputStream.cs \
csharp/src/ProtoMunge/ProtoMunge.csproj \ csharp/src/Google.Protobuf/MessageExtensions.cs \
csharp/src/ProtocolBuffers/GeneratedMessage.cs \ csharp/src/Google.Protobuf/MessageParser.cs \
csharp/src/ProtocolBuffers/ICodedInputStream.cs \ csharp/src/Google.Protobuf/Preconditions.cs \
csharp/src/ProtocolBuffers/AbstractBuilder.cs \ csharp/src/Google.Protobuf/Properties/AssemblyInfo.cs \
csharp/src/ProtocolBuffers/FieldSet.cs \ csharp/src/Google.Protobuf/Reflection/DescriptorBase.cs \
csharp/src/ProtocolBuffers/TextGenerator.cs \ csharp/src/Google.Protobuf/Reflection/DescriptorPool.cs \
csharp/src/ProtocolBuffers/CodedInputStream.cs \ csharp/src/Google.Protobuf/Reflection/DescriptorProtoFile.cs \
csharp/src/ProtocolBuffers/GeneratedExtensionLite.cs \ csharp/src/Google.Protobuf/Reflection/DescriptorUtil.cs \
csharp/src/ProtocolBuffers/FrameworkPortability.cs \ csharp/src/Google.Protobuf/Reflection/DescriptorValidationException.cs \
csharp/src/ProtocolBuffers/SortedList.cs \ csharp/src/Google.Protobuf/Reflection/EnumDescriptor.cs \
csharp/src/ProtocolBuffers/CodedOutputStream.ComputeSize.cs \ csharp/src/Google.Protobuf/Reflection/EnumValueDescriptor.cs \
csharp/src/ProtocolBuffers/ExtendableMessage.cs \ csharp/src/Google.Protobuf/Reflection/FieldAccessorBase.cs \
csharp/src/ProtocolBuffers/Descriptors/ServiceDescriptor.cs \ csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs \
csharp/src/ProtocolBuffers/Descriptors/DescriptorBase.cs \ csharp/src/Google.Protobuf/Reflection/FieldType.cs \
csharp/src/ProtocolBuffers/Descriptors/EnumDescriptor.cs \ csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs \
csharp/src/ProtocolBuffers/Descriptors/PackageDescriptor.cs \ csharp/src/Google.Protobuf/Reflection/GeneratedCodeInfo.cs \
csharp/src/ProtocolBuffers/Descriptors/FileDescriptor.cs \ csharp/src/Google.Protobuf/Reflection/IDescriptor.cs \
csharp/src/ProtocolBuffers/Descriptors/DescriptorValidationException.cs \ csharp/src/Google.Protobuf/Reflection/IFieldAccessor.cs \
csharp/src/ProtocolBuffers/Descriptors/IndexedDescriptorBase.cs \ csharp/src/Google.Protobuf/Reflection/MapFieldAccessor.cs \
csharp/src/ProtocolBuffers/Descriptors/MessageDescriptor.cs \ csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs \
csharp/src/ProtocolBuffers/Descriptors/MethodDescriptor.cs \ csharp/src/Google.Protobuf/Reflection/MethodDescriptor.cs \
csharp/src/ProtocolBuffers/Descriptors/DescriptorUtil.cs \ csharp/src/Google.Protobuf/Reflection/OneofAccessor.cs \
csharp/src/ProtocolBuffers/Descriptors/MappedType.cs \ csharp/src/Google.Protobuf/Reflection/OneofDescriptor.cs \
csharp/src/ProtocolBuffers/Descriptors/FieldType.cs \ csharp/src/Google.Protobuf/Reflection/PackageDescriptor.cs \
csharp/src/ProtocolBuffers/Descriptors/FieldMappingAttribute.cs \ csharp/src/Google.Protobuf/Reflection/PartialClasses.cs \
csharp/src/ProtocolBuffers/Descriptors/IDescriptor.cs \ csharp/src/Google.Protobuf/Reflection/ReflectionUtil.cs \
csharp/src/ProtocolBuffers/Descriptors/EnumValueDescriptor.cs \ csharp/src/Google.Protobuf/Reflection/RepeatedFieldAccessor.cs \
csharp/src/ProtocolBuffers/Descriptors/FieldDescriptor.cs \ csharp/src/Google.Protobuf/Reflection/ServiceDescriptor.cs \
csharp/src/ProtocolBuffers/Descriptors/DescriptorPool.cs \ csharp/src/Google.Protobuf/Reflection/SingleFieldAccessor.cs \
csharp/src/ProtocolBuffers/Delegates.cs \ csharp/src/Google.Protobuf/WellKnownTypes/Any.cs \
csharp/src/ProtocolBuffers/AbstractMessageLite.cs \ csharp/src/Google.Protobuf/WellKnownTypes/Api.cs \
csharp/src/ProtocolBuffers/IMessageLite.cs \ csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs \
csharp/src/ProtocolBuffers/TextFormat.cs \ csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs \
csharp/src/ProtocolBuffers/Collections/Enumerables.cs \ csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs \
csharp/src/ProtocolBuffers/Collections/PopsicleList.cs \ csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs \
csharp/src/ProtocolBuffers/Collections/IPopsicleList.cs \ csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs \
csharp/src/ProtocolBuffers/Collections/ReadOnlyDictionary.cs \ csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs \
csharp/src/ProtocolBuffers/Collections/Dictionaries.cs \ csharp/src/Google.Protobuf/WellKnownTypes/Type.cs \
csharp/src/ProtocolBuffers/Collections/Lists.cs \ csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs \
csharp/src/ProtocolBuffers/IMessage.cs \ csharp/src/Google.Protobuf/WireFormat.cs \
csharp/src/ProtocolBuffers/TextTokenizer.cs \ csharp/src/packages/repositories.config
csharp/src/ProtocolBuffers/ByteString.cs \
csharp/src/ProtocolBuffers/AbstractBuilderLite.cs \
csharp/src/ProtocolBuffers/GeneratedExtensionBase.cs \
csharp/src/ProtocolBuffers/EnumLite.cs \
csharp/src/ProtocolBuffers/ByteArray.cs \
csharp/src/ProtocolBuffers/ExtensionInfo.cs \
csharp/src/ProtocolBuffers/MessageStreamIterator.cs \
csharp/src/ProtocolBuffers/DynamicMessage.cs \
csharp/src/ProtocolBuffers/ExtendableMessageLite.cs \
csharp/src/ProtocolBuffers/ICodedOutputStream.cs \
csharp/src/ProtocolBuffers/GeneratedRepeatExtension.cs \
csharp/src/ProtocolBuffers/IBuilderLite.cs \
csharp/src/ProtocolBuffers/UnknownField.cs \
csharp/src/ProtocolBuffers/ThrowHelper.cs \
csharp/src/ProtocolBuffers/UnknownFieldSet.cs \
csharp/src/ProtocolBuffers/AbstractMessage.cs \
csharp/src/ProtocolBuffers/GeneratedBuilderLite.cs \
csharp/src/ProtocolBuffers/NameHelpers.cs \
csharp/src/ProtocolBuffers/DescriptorProtos/PartialClasses.cs \
csharp/src/ProtocolBuffers/DescriptorProtos/IDescriptorProto.cs \
csharp/src/ProtocolBuffers/DescriptorProtos/DescriptorProtoFile.cs \
csharp/src/ProtocolBuffers/ExtendableBuilder.cs \
csharp/src/ProtocolBuffers/FieldAccess/IFieldAccessor.cs \
csharp/src/ProtocolBuffers/FieldAccess/SinglePrimitiveAccessor.cs \
csharp/src/ProtocolBuffers/FieldAccess/SingleEnumAccessor.cs \
csharp/src/ProtocolBuffers/FieldAccess/RepeatedPrimitiveAccessor.cs \
csharp/src/ProtocolBuffers/FieldAccess/FieldAccessorTable.cs \
csharp/src/ProtocolBuffers/FieldAccess/RepeatedMessageAccessor.cs \
csharp/src/ProtocolBuffers/FieldAccess/RepeatedEnumAccessor.cs \
csharp/src/ProtocolBuffers/FieldAccess/ReflectionUtil.cs \
csharp/src/ProtocolBuffers/FieldAccess/SingleMessageAccessor.cs \
csharp/src/ProtocolBuffers/Properties/AssemblyInfo.cs \
csharp/src/ProtocolBuffers/IBuilder.cs \
csharp/src/ProtocolBuffers/ExtensionRegistry.cs \
csharp/src/ProtocolBuffers/CodedOutputStream.cs \
csharp/src/ProtocolBuffers/MessageStreamWriter.cs \
csharp/src/ProtocolBuffers/MessageUtil.cs \
csharp/src/ProtocolBuffers/UninitializedMessageException.cs \
csharp/src/ProtocolBuffers/ProtocolBuffersLite.csproj \
csharp/src/ProtocolBuffers/InvalidProtocolBufferException.cs \
csharp/src/ProtocolBuffers/ProtocolBuffers.csproj \
csharp/src/ProtocolBuffers/ExtendableBuilderLite.cs \
csharp/src/ProtocolBuffers/GeneratedMessageLite.cs \
csharp/src/ProtocolBuffers/GeneratedSingleExtension.cs \
csharp/src/ProtocolBuffers/ExtensionRegistryLite.cs \
csharp/src/ProtocolBuffers/WireFormat.cs \
csharp/src/ProtocolBuffers/GeneratedBuilder.cs \
csharp/src/AddressBook/ListPeople.cs \
csharp/src/AddressBook/Addressbook.cs \
csharp/src/AddressBook/AddPerson.cs \
csharp/src/AddressBook/AddressBook.csproj \
csharp/src/AddressBook/SampleUsage.cs \
csharp/src/AddressBook/app.config \
csharp/src/AddressBook/Program.cs \
csharp/src/AddressBook/Properties/AssemblyInfo.cs \
csharp/src/packages/repositories.config \
csharp/src/ProtocolBuffers.Test/AbstractMessageTest.cs \
csharp/src/ProtocolBuffers.Test/TestProtos/GoogleSize.cs \
csharp/src/ProtocolBuffers.Test/TestProtos/GoogleSpeed.cs \
csharp/src/ProtocolBuffers.Test/TestProtos/UnittestEnormousDescriptor.cs \
csharp/src/ProtocolBuffers.Test/TestProtos/UnknownEnumTest.cs \
csharp/src/ProtocolBuffers.Test/TestProtos/UnittestMset.cs \
csharp/src/ProtocolBuffers.Test/TestProtos/UnittestImport.cs \
csharp/src/ProtocolBuffers.Test/TestProtos/UnittestCustomOptions.cs \
csharp/src/ProtocolBuffers.Test/TestProtos/UnittestOptimizeFor.cs \
csharp/src/ProtocolBuffers.Test/TestProtos/UnittestNoFieldPresence.cs \
csharp/src/ProtocolBuffers.Test/TestProtos/Unittest.cs \
csharp/src/ProtocolBuffers.Test/TestProtos/UnittestIssues.cs \
csharp/src/ProtocolBuffers.Test/TestProtos/UnittestExtrasXmltest.cs \
csharp/src/ProtocolBuffers.Test/TestProtos/UnittestImportPublic.cs \
csharp/src/ProtocolBuffers.Test/TestProtos/UnittestDropUnknownFields.cs \
csharp/src/ProtocolBuffers.Test/CodedInputStreamTest.cs \
csharp/src/ProtocolBuffers.Test/packages.config \
csharp/src/ProtocolBuffers.Test/TestReaderForUrlEncoded.cs \
csharp/src/ProtocolBuffers.Test/ByteStringTest.cs \
csharp/src/ProtocolBuffers.Test/ReusableBuilderTest.cs \
csharp/src/ProtocolBuffers.Test/TestUtil.cs \
csharp/src/ProtocolBuffers.Test/TestResources.cs \
csharp/src/ProtocolBuffers.Test/Collections/PopsicleListTest.cs \
csharp/src/ProtocolBuffers.Test/ProtocolBuffers.Test.csproj \
csharp/src/ProtocolBuffers.Test/IssuesTest.cs \
csharp/src/ProtocolBuffers.Test/UnknownFieldSetTest.cs \
csharp/src/ProtocolBuffers.Test/TestMimeMessageFormats.cs \
csharp/src/ProtocolBuffers.Test/App.xaml.cs \
csharp/src/ProtocolBuffers.Test/DeprecatedMemberTest.cs \
csharp/src/ProtocolBuffers.Test/DynamicMessageTest.cs \
csharp/src/ProtocolBuffers.Test/MessageStreamWriterTest.cs \
csharp/src/ProtocolBuffers.Test/NameHelpersTest.cs \
csharp/src/ProtocolBuffers.Test/GeneratedMessageTest.cs \
csharp/src/ProtocolBuffers.Test/TestWriterFormatXml.cs \
csharp/src/ProtocolBuffers.Test/ExtendableMessageTest.cs \
csharp/src/ProtocolBuffers.Test/WireFormatTest.cs \
csharp/src/ProtocolBuffers.Test/TestWriterFormatJson.cs \
csharp/src/ProtocolBuffers.Test/MessageUtilTest.cs \
csharp/src/ProtocolBuffers.Test/App.xaml \
csharp/src/ProtocolBuffers.Test/Properties/AppManifest.xml \
csharp/src/ProtocolBuffers.Test/Properties/AssemblyInfo.cs \
csharp/src/ProtocolBuffers.Test/Properties/OutOfBrowserSettings.xml \
csharp/src/ProtocolBuffers.Test/TextFormatTest.cs \
csharp/src/ProtocolBuffers.Test/CodedOutputStreamTest.cs \
csharp/src/ProtocolBuffers.Test/MessageTest.cs \
csharp/src/ProtocolBuffers.Test/DescriptorsTest.cs \
csharp/src/ProtocolBuffers.Test/Compatibility/DictionaryCompatibilityTests.cs \
csharp/src/ProtocolBuffers.Test/Compatibility/JsonCompatibilityTests.cs \
csharp/src/ProtocolBuffers.Test/Compatibility/TextCompatibilityTests.cs \
csharp/src/ProtocolBuffers.Test/Compatibility/TestResources.cs \
csharp/src/ProtocolBuffers.Test/Compatibility/google_message1.dat \
csharp/src/ProtocolBuffers.Test/Compatibility/CompatibilityTests.cs \
csharp/src/ProtocolBuffers.Test/Compatibility/google_message2.dat \
csharp/src/ProtocolBuffers.Test/Compatibility/XmlCompatibilityTests.cs \
csharp/src/ProtocolBuffers.Test/Compatibility/BinaryCompatibilityTests.cs \
csharp/src/ProtocolBuffers.Test/GeneratedBuilderTest.cs \
csharp/src/ProtocolBuffers.Test/ReflectionTester.cs \
csharp/src/ProtocolBuffers.Test/FieldPresenceTest.cs \
csharp/src/ProtocolBuffers.Test/TestCornerCases.cs \
csharp/src/ProtocolBuffers.Test/MessageStreamIteratorTest.cs \
csharp/buildall.sh \
csharp/README.md \
csharp/.gitignore \
csharp/protos/extest/unittest_extras_lite.proto \
csharp/protos/extest/unittest_extras_xmltest.proto \
csharp/protos/extest/unittest_extras_full.proto \
csharp/protos/extest/unittest_issues.proto \
csharp/generate_protos.sh \
csharp/CHANGES.txt \
csharp/keys/generate_new_key.bat \
csharp/keys/Google.ProtocolBuffers.snk \
csharp/testdata/golden_message \
csharp/testdata/text_format_unittest_data.txt \
csharp/testdata/golden_packed_fields_message \
csharp/testdata/text_format_unittest_extensions_data.txt \
csharp/build/build.bat \
csharp/build/googlecode_upload.py \
csharp/build/build.csproj \
csharp/build/Google.ProtocolBuffersLite.nuspec \
csharp/build/Common.targets \
csharp/build/Google.ProtocolBuffers.nuspec \
csharp/build/target.csproj \
csharp/build/nuspec.xsd \
csharp/build/BuildAll.bat \
csharp/build/RunBenchmarks.bat \
csharp/build/publish.csproj
java_EXTRA_DIST= \ java_EXTRA_DIST= \
java/src/main/java/com/google/protobuf/AbstractMessage.java \ java/src/main/java/com/google/protobuf/AbstractMessage.java \

@ -18,7 +18,7 @@ Pod::Spec.new do |s|
'objectivec/google/protobuf/*.pbobjc.{h,m}' 'objectivec/google/protobuf/*.pbobjc.{h,m}'
s.header_mappings_dir = 'objectivec' s.header_mappings_dir = 'objectivec'
s.ios.deployment_target = '6.0' s.ios.deployment_target = '7.1'
s.osx.deployment_target = '10.8' s.osx.deployment_target = '10.9'
s.requires_arc = false s.requires_arc = false
end end

@ -0,0 +1,29 @@
setlocal
IF %language%==cpp GOTO build_cpp
IF %language%==csharp GOTO build_csharp
echo Unsupported language %language%. Exiting.
goto :error
:build_cpp
echo Building C++
mkdir build_msvc
cd build_msvc
cmake -G "%generator%" -DBUILD_SHARED_LIBS=%BUILD_DLL% ../cmake
msbuild protobuf.sln /p:Platform=%vcplatform% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" || goto error
cd %configuration%
tests.exe || goto error
goto :EOF
:build_csharp
echo Building C#
cd csharp\src
nuget restore
msbuild Google.Protobuf.sln /p:Platform="Any CPU" /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" || goto error
nunit-console Google.Protobuf.Test\bin\%configuration%\Google.Protobuf.Test.dll || goto error
goto :EOF
:error
echo Failed!
EXIT /b %ERRORLEVEL%

@ -1,34 +1,32 @@
# Only test one combination: "Visual Studio 12 + Win64 + Debug + DLL". We can # Only test one combination: "Visual Studio 12 + Win64 + Debug + DLL". We can
# test more combinations but AppVeyor just takes too long to finish (each # test more combinations but AppVeyor just takes too long to finish (each
# combination takes ~15mins). # combination takes ~15mins).
platform: platform:
- Win64 - Win64
configuration: configuration:
- Debug - Debug
environment: environment:
matrix: matrix:
- BUILD_DLL: ON - language: cpp
BUILD_DLL: ON
install:
- ps: Start-FileDownload https://googlemock.googlecode.com/files/gmock-1.7.0.zip - language: csharp
- 7z x gmock-1.7.0.zip
- rename gmock-1.7.0 gmock install:
- ps: Start-FileDownload https://googlemock.googlecode.com/files/gmock-1.7.0.zip
before_build: - 7z x gmock-1.7.0.zip
- if %platform%==Win32 set generator=Visual Studio 12 - rename gmock-1.7.0 gmock
- if %platform%==Win64 set generator=Visual Studio 12 Win64
- if %platform%==Win32 set vcplatform=Win32 before_build:
- if %platform%==Win64 set vcplatform=x64 - if %platform%==Win32 set generator=Visual Studio 12
- if %platform%==Win64 set generator=Visual Studio 12 Win64
build_script: - if %platform%==Win32 set vcplatform=Win32
- mkdir build_msvc - if %platform%==Win64 set vcplatform=x64
- cd build_msvc
- cmake -G "%generator%" -DBUILD_SHARED_LIBS=%BUILD_DLL% ../cmake build_script:
- msbuild protobuf.sln /p:Platform=%vcplatform% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" - CALL appveyor.bat
- cd %configuration%
- tests.exe skip_commits:
message: /.*\[skip appveyor\].*/
skip_commits:
message: /.*\[skip appveyor\].*/

@ -4,7 +4,6 @@ package benchmarks;
option java_outer_classname = "GoogleSize"; option java_outer_classname = "GoogleSize";
option optimize_for = CODE_SIZE; option optimize_for = CODE_SIZE;
option csharp_namespace = "Google.ProtocolBuffers.TestProtos";
message SizeMessage1 { message SizeMessage1 {
required string field1 = 1; required string field1 = 1;

@ -4,7 +4,6 @@ package benchmarks;
option java_outer_classname = "GoogleSpeed"; option java_outer_classname = "GoogleSpeed";
option optimize_for = SPEED; option optimize_for = SPEED;
option csharp_namespace = "Google.ProtocolBuffers.TestProtos";
message SpeedMessage1 { message SpeedMessage1 {
required string field1 = 1; required string field1 = 1;

@ -1,13 +1,42 @@
# Minimum CMake required
cmake_minimum_required(VERSION 2.8) cmake_minimum_required(VERSION 2.8)
# Project
project(protobuf C CXX) project(protobuf C CXX)
# Options
option(BUILD_TESTING "Build tests" ON) option(BUILD_TESTING "Build tests" ON)
option(BUILD_SHARED_LIBS "Build Shared Libraries" OFF) option(BUILD_SHARED_LIBS "Build Shared Libraries" OFF)
if (MSVC) if (MSVC)
option(ZLIB "Build with zlib support" OFF) option(ZLIB "Build with zlib support" OFF)
endif (MSVC) endif (MSVC)
# Path to main configure script
set(protobuf_CONFIGURE_SCRIPT "../configure.ac")
# Parse version from configure script
file(STRINGS "${protobuf_CONFIGURE_SCRIPT}" protobuf_VERSION_LINE
LIMIT_COUNT 1
REGEX "^AC_INIT")
# Replace special characters
string(REPLACE "(" "_" protobuf_VERSION_LINE ${protobuf_VERSION_LINE})
string(REPLACE ")" "_" protobuf_VERSION_LINE ${protobuf_VERSION_LINE})
string(REPLACE "[" "_" protobuf_VERSION_LINE ${protobuf_VERSION_LINE})
string(REPLACE "]" "_" protobuf_VERSION_LINE ${protobuf_VERSION_LINE})
# Parse version string
string(REGEX REPLACE "^AC_INIT__Protocol Buffers_,_([^_]+).*$" "\\1"
protobuf_VERSION_STRING "${protobuf_VERSION_LINE}")
# Parse version tweaks
string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+).*$" "\\1"
protobuf_VERSION_MAJOR "${protobuf_VERSION_STRING}")
string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+).*$" "\\2"
protobuf_VERSION_MINOR "${protobuf_VERSION_STRING}")
string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+).*$" "\\3"
protobuf_VERSION_PATCH "${protobuf_VERSION_STRING}")
# Package version
set(protobuf_VERSION
"${protobuf_VERSION_MAJOR}.${protobuf_VERSION_MINOR}.${protobuf_VERSION_PATCH}")
add_definitions(-DGOOGLE_PROTOBUF_CMAKE_BUILD) add_definitions(-DGOOGLE_PROTOBUF_CMAKE_BUILD)
find_package(Threads REQUIRED) find_package(Threads REQUIRED)
@ -43,6 +72,19 @@ endif (HAVE_ZLIB)
if (MSVC) if (MSVC)
if (BUILD_SHARED_LIBS) if (BUILD_SHARED_LIBS)
add_definitions(-DPROTOBUF_USE_DLLS) add_definitions(-DPROTOBUF_USE_DLLS)
else (BUILD_SHARED_LIBS)
# In case we are building static libraries, link also the runtime library statically
# so that MSVCR*.DLL is not required at runtime.
# https://msdn.microsoft.com/en-us/library/2kzt1wy3.aspx
# This is achieved by replacing msvc option /MD with /MT and /MDd with /MTd
# http://www.cmake.org/Wiki/CMake_FAQ#How_can_I_build_my_MSVC_application_with_a_static_runtime.3F
foreach(flag_var
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
if(${flag_var} MATCHES "/MD")
string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
endif(${flag_var} MATCHES "/MD")
endforeach(flag_var)
endif (BUILD_SHARED_LIBS) endif (BUILD_SHARED_LIBS)
add_definitions(/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305) add_definitions(/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305)
endif (MSVC) endif (MSVC)
@ -73,6 +115,9 @@ include(libprotobuf-lite.cmake)
include(libprotobuf.cmake) include(libprotobuf.cmake)
include(libprotoc.cmake) include(libprotoc.cmake)
include(protoc.cmake) include(protoc.cmake)
if (BUILD_TESTING) if (BUILD_TESTING)
include(tests.cmake) include(tests.cmake)
endif (BUILD_TESTING) endif (BUILD_TESTING)
include(install.cmake)

@ -21,6 +21,7 @@ copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\code_generato
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\command_line_interface.h include\google\protobuf\compiler\command_line_interface.h copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\command_line_interface.h include\google\protobuf\compiler\command_line_interface.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\cpp\cpp_generator.h include\google\protobuf\compiler\cpp\cpp_generator.h copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\cpp\cpp_generator.h include\google\protobuf\compiler\cpp\cpp_generator.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\csharp\csharp_generator.h include\google\protobuf\compiler\csharp\csharp_generator.h copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\csharp\csharp_generator.h include\google\protobuf\compiler\csharp\csharp_generator.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\csharp\csharp_names.h include\google\protobuf\compiler\csharp\csharp_names.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\importer.h include\google\protobuf\compiler\importer.h copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\importer.h include\google\protobuf\compiler\importer.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\java\java_generator.h include\google\protobuf\compiler\java\java_generator.h copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\java\java_generator.h include\google\protobuf\compiler\java\java_generator.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\java\java_names.h include\google\protobuf\compiler\java\java_names.h copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\java\java_names.h include\google\protobuf\compiler\java\java_names.h

@ -0,0 +1,103 @@
include(GNUInstallDirs)
foreach(_library
libprotobuf-lite
libprotobuf
libprotoc)
set_property(TARGET ${_library}
PROPERTY INTERFACE_INCLUDE_DIRECTORIES
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
install(TARGETS ${_library} EXPORT protobuf-targets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${_library}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${_library}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${_library})
endforeach()
install(TARGETS protoc EXPORT protobuf-targets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT protoc)
if(TRUE)
file(STRINGS extract_includes.bat.in _extract_strings
REGEX "^copy")
foreach(_extract_string ${_extract_strings})
string(REPLACE "copy \${PROTOBUF_SOURCE_WIN32_PATH}\\" ""
_extract_string ${_extract_string})
string(REPLACE "\\" "/" _extract_string ${_extract_string})
string(REGEX MATCH "^[^ ]+"
_extract_from ${_extract_string})
string(REGEX REPLACE "^${_extract_from} ([^$]+)" "\\1"
_extract_to ${_extract_string})
get_filename_component(_extract_from "${protobuf_SOURCE_DIR}/${_extract_from}" ABSOLUTE)
get_filename_component(_extract_name ${_extract_to} NAME)
get_filename_component(_extract_to ${_extract_to} PATH)
string(REPLACE "include/" "${CMAKE_INSTALL_INCLUDEDIR}/"
_extract_to "${_extract_to}")
if(EXISTS "${_extract_from}")
install(FILES "${_extract_from}"
DESTINATION "${_extract_to}"
COMPONENT protobuf-headers
RENAME "${_extract_name}")
else()
message(AUTHOR_WARNING "The file \"${_extract_from}\" is listed in "
"\"${protobuf_SOURCE_DIR}/cmake/extract_includes.bat.in\" "
"but there not exists. The file will not be installed.")
endif()
endforeach()
endif()
# Internal function for parsing auto tools scripts
function(_protobuf_auto_list FILE_NAME VARIABLE)
file(STRINGS ${FILE_NAME} _strings)
set(_list)
foreach(_string ${_strings})
set(_found)
string(REGEX MATCH "^[ \t]*${VARIABLE}[ \t]*=[ \t]*" _found "${_string}")
if(_found)
string(LENGTH "${_found}" _length)
string(SUBSTRING "${_string}" ${_length} -1 _draft_list)
foreach(_item ${_draft_list})
string(STRIP "${_item}" _item)
list(APPEND _list "${_item}")
endforeach()
endif()
endforeach()
set(${VARIABLE} ${_list} PARENT_SCOPE)
endfunction()
# Install well-known type proto files
_protobuf_auto_list("../src/Makefile.am" nobase_dist_proto_DATA)
foreach(_file ${nobase_dist_proto_DATA})
get_filename_component(_file_from "../src/${_file}" ABSOLUTE)
get_filename_component(_file_name ${_file} NAME)
get_filename_component(_file_path ${_file} PATH)
if(EXISTS "${_file_from}")
install(FILES "${_file_from}"
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${_file_path}"
COMPONENT protobuf-protos
RENAME "${_file_name}")
else()
message(AUTHOR_WARNING "The file \"${_file_from}\" is listed in "
"\"${protobuf_SOURCE_DIR}/../src/Makefile.am\" as nobase_dist_proto_DATA "
"but there not exists. The file will not be installed.")
endif()
endforeach()
# Export configuration
install(EXPORT protobuf-targets
DESTINATION "lib/cmake/protobuf"
COMPONENT protobuf-export)
configure_file(protobuf-config.cmake.in
protobuf-config.cmake @ONLY)
configure_file(protobuf-config-version.cmake.in
protobuf-config-version.cmake @ONLY)
configure_file(protobuf-module.cmake.in
protobuf-module.cmake @ONLY)
install(FILES
"${protobuf_BINARY_DIR}/protobuf-config.cmake"
"${protobuf_BINARY_DIR}/protobuf-config-version.cmake"
"${protobuf_BINARY_DIR}/protobuf-module.cmake"
DESTINATION "lib/cmake/protobuf"
COMPONENT protobuf-export)

@ -25,6 +25,7 @@ set(libprotobuf_lite_files
add_library(libprotobuf-lite ${libprotobuf_lite_files}) add_library(libprotobuf-lite ${libprotobuf_lite_files})
target_link_libraries(libprotobuf-lite ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries(libprotobuf-lite ${CMAKE_THREAD_LIBS_INIT})
target_include_directories(libprotobuf-lite PUBLIC ${protobuf_source_dir}/src)
set_target_properties(libprotobuf-lite PROPERTIES set_target_properties(libprotobuf-lite PROPERTIES
COMPILE_DEFINITIONS LIBPROTOBUF_EXPORTS COMPILE_DEFINITIONS LIBPROTOBUF_EXPORTS
OUTPUT_NAME ${LIB_PREFIX}protobuf-lite) OUTPUT_NAME ${LIB_PREFIX}protobuf-lite)

@ -56,6 +56,7 @@ set(libprotobuf_files
add_library(libprotobuf ${libprotobuf_lite_files} ${libprotobuf_files}) add_library(libprotobuf ${libprotobuf_lite_files} ${libprotobuf_files})
target_link_libraries(libprotobuf ${CMAKE_THREAD_LIBS_INIT} ${ZLIB_LIBRARIES}) target_link_libraries(libprotobuf ${CMAKE_THREAD_LIBS_INIT} ${ZLIB_LIBRARIES})
target_include_directories(libprotobuf PUBLIC ${protobuf_source_dir}/src)
set_target_properties(libprotobuf PROPERTIES set_target_properties(libprotobuf PROPERTIES
COMPILE_DEFINITIONS LIBPROTOBUF_EXPORTS COMPILE_DEFINITIONS LIBPROTOBUF_EXPORTS
OUTPUT_NAME ${LIB_PREFIX}protobuf) OUTPUT_NAME ${LIB_PREFIX}protobuf)

@ -16,10 +16,10 @@ set(libprotoc_files
${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_string_field.cc ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_string_field.cc
${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_enum.cc ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_enum.cc
${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_enum_field.cc ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_enum_field.cc
${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_extension.cc
${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_field_base.cc ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_field_base.cc
${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_generator.cc ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_generator.cc
${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_helpers.cc ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_helpers.cc
${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_map_field.cc
${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_message.cc ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_message.cc
${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_message_field.cc ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_message_field.cc
${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc
@ -28,7 +28,7 @@ set(libprotoc_files
${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc
${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_source_generator_base.cc ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_source_generator_base.cc
${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_umbrella_class.cc ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_umbrella_class.cc
${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_writer.cc ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc
${protobuf_source_dir}/src/google/protobuf/compiler/java/java_context.cc ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_context.cc
${protobuf_source_dir}/src/google/protobuf/compiler/java/java_doc_comment.cc ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_doc_comment.cc
${protobuf_source_dir}/src/google/protobuf/compiler/java/java_enum.cc ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_enum.cc

@ -0,0 +1 @@
set(PACKAGE_VERSION @protobuf_VERSION@)

@ -0,0 +1,27 @@
# Version info variables
set(PROTOBUF_VERSION "@protobuf_VERSION@")
set(PROTOBUF_VERSION_STRING "@protobuf_VERSION_STRING@")
# Current dir
get_filename_component(_PROTOBUF_PACKAGE_PREFIX
"${CMAKE_CURRENT_LIST_FILE}" PATH)
# Imported targets
include("${_PROTOBUF_PACKAGE_PREFIX}/protobuf-targets.cmake")
# Compute the installation prefix relative to this file.
get_filename_component(_PROTOBUF_IMPORT_PREFIX
"${_PROTOBUF_PACKAGE_PREFIX}" PATH)
get_filename_component(_PROTOBUF_IMPORT_PREFIX
"${_PROTOBUF_IMPORT_PREFIX}" PATH)
get_filename_component(_PROTOBUF_IMPORT_PREFIX
"${_PROTOBUF_IMPORT_PREFIX}" PATH)
# CMake FindProtobuf module compatible file
if(NOT DEFINED PROTOBUF_MODULE_COMPATIBLE OR "${PROTOBUF_MODULE_COMPATIBLE}")
include("${_PROTOBUF_PACKAGE_PREFIX}/protobuf-module.cmake")
endif()
# Cleanup temporary variables.
set(_PROTOBUF_PACKAGE_PREFIX)
set(_PROTOBUF_IMPORT_PREFIX)

@ -0,0 +1,139 @@
if(PROTOBUF_SRC_ROOT_FOLDER)
message(AUTHOR_WARNING "Variable PROTOBUF_SRC_ROOT_FOLDER defined, but not"
" used in CONFIG mode")
endif()
function(PROTOBUF_GENERATE_CPP SRCS HDRS)
if(NOT ARGN)
message(SEND_ERROR "Error: PROTOBUF_GENERATE_CPP() called without any proto files")
return()
endif()
if(PROTOBUF_GENERATE_CPP_APPEND_PATH)
# Create an include path for each file specified
foreach(FIL ${ARGN})
get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
get_filename_component(ABS_PATH ${ABS_FIL} PATH)
list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
if(${_contains_already} EQUAL -1)
list(APPEND _protobuf_include_path -I ${ABS_PATH})
endif()
endforeach()
else()
set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR})
endif()
# Add well-known type protos include path
list(APPEND _protobuf_include_path
-I "${_PROTOBUF_IMPORT_PREFIX}/@CMAKE_INSTALL_INCLUDEDIR@")
if(DEFINED PROTOBUF_IMPORT_DIRS)
foreach(DIR ${PROTOBUF_IMPORT_DIRS})
get_filename_component(ABS_PATH ${DIR} ABSOLUTE)
list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
if(${_contains_already} EQUAL -1)
list(APPEND _protobuf_include_path -I ${ABS_PATH})
endif()
endforeach()
endif()
set(${SRCS})
set(${HDRS})
foreach(FIL ${ARGN})
get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
get_filename_component(FIL_WE ${FIL} NAME_WE)
list(APPEND ${SRCS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc")
list(APPEND ${HDRS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h")
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc"
"${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h"
COMMAND ${PROTOBUF_PROTOC_EXECUTABLE}
ARGS --cpp_out ${CMAKE_CURRENT_BINARY_DIR} ${_protobuf_include_path} ${ABS_FIL}
DEPENDS ${ABS_FIL} ${PROTOBUF_PROTOC_EXECUTABLE}
COMMENT "Running C++ protocol buffer compiler on ${FIL}"
VERBATIM)
endforeach()
set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE)
set(${SRCS} ${${SRCS}} PARENT_SCOPE)
set(${HDRS} ${${HDRS}} PARENT_SCOPE)
endfunction()
# Internal function: search for normal library as well as a debug one
# if the debug one is specified also include debug/optimized keywords
# in *_LIBRARIES variable
function(_protobuf_find_libraries name filename)
get_target_property(${name}_LIBRARY lib${filename}
IMPORTED_LOCATION_RELEASE)
set(${name}_LIBRARY "${${name}_LIBRARY}" PARENT_SCOPE)
get_target_property(${name}_LIBRARY_DEBUG lib${filename}
IMPORTED_LOCATION_DEBUG)
set(${name}_LIBRARY_DEBUG "${${name}_LIBRARY_DEBUG}" PARENT_SCOPE)
if(NOT ${name}_LIBRARY_DEBUG)
# There is no debug library
set(${name}_LIBRARY_DEBUG ${${name}_LIBRARY} PARENT_SCOPE)
set(${name}_LIBRARIES ${${name}_LIBRARY} PARENT_SCOPE)
else()
# There IS a debug library
set(${name}_LIBRARIES
optimized ${${name}_LIBRARY}
debug ${${name}_LIBRARY_DEBUG}
PARENT_SCOPE
)
endif()
endfunction()
# Internal function: find threads library
function(_protobuf_find_threads)
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
find_package(Threads)
if(Threads_FOUND)
list(APPEND PROTOBUF_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
set(PROTOBUF_LIBRARIES "${PROTOBUF_LIBRARIES}" PARENT_SCOPE)
endif()
endfunction()
#
# Main.
#
# By default have PROTOBUF_GENERATE_CPP macro pass -I to protoc
# for each directory where a proto file is referenced.
if(NOT DEFINED PROTOBUF_GENERATE_CPP_APPEND_PATH)
set(PROTOBUF_GENERATE_CPP_APPEND_PATH TRUE)
endif()
# The Protobuf library
_protobuf_find_libraries(PROTOBUF protobuf)
# The Protobuf Lite library
_protobuf_find_libraries(PROTOBUF_LITE protobuf-lite)
# The Protobuf Protoc Library
_protobuf_find_libraries(PROTOBUF_PROTOC protoc)
if(UNIX)
_protobuf_find_threads()
endif()
# Set the include directory
set(PROTOBUF_INCLUDE_DIR "${_PROTOBUF_IMPORT_PREFIX}/@CMAKE_INSTALL_INCLUDEDIR@")
# Set the protoc Executable
get_target_property(PROTOBUF_PROTOC_EXECUTABLE protoc
IMPORTED_LOCATION_RELEASE)
if(NOT PROTOBUF_PROTOC_EXECUTABLE)
get_target_property(PROTOBUF_PROTOC_EXECUTABLE protoc
IMPORTED_LOCATION_DEBUG)
endif()
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(PROTOBUF DEFAULT_MSG
PROTOBUF_LIBRARY PROTOBUF_INCLUDE_DIR)
if(PROTOBUF_FOUND)
set(PROTOBUF_INCLUDE_DIRS ${PROTOBUF_INCLUDE_DIR})
endif()

@ -40,7 +40,7 @@ $(protoc_outputs): protoc_middleman
BUILT_SOURCES = $(protoc_outputs) BUILT_SOURCES = $(protoc_outputs)
CLEANFILES = $(protoc_outputs) protoc_middleman javac_middleman conformance-java CLEANFILES = $(protoc_outputs) protoc_middleman javac_middleman conformance-java conformance-csharp
MAINTAINERCLEANFILES = \ MAINTAINERCLEANFILES = \
Makefile.in Makefile.in
@ -55,6 +55,15 @@ conformance-java: javac_middleman
@echo 'java -classpath .:../java/target/classes ConformanceJava "$$@"' >> conformance-java @echo 'java -classpath .:../java/target/classes ConformanceJava "$$@"' >> conformance-java
@chmod +x conformance-java @chmod +x conformance-java
# Currently the conformance code is alongside the rest of the C#
# source, as it's easier to maintain there. We assume we've already
# built that, so we just need a script to run it.
conformance-csharp:
@echo "Writing shortcut script conformance-csharp..."
@echo '#! /bin/sh' > conformance-csharp
@echo 'mono ../csharp/src/Google.Protobuf.Conformance/bin/Release/Google.Protobuf.Conformance.exe "$$@"' >> conformance-csharp
@chmod +x conformance-csharp
# Targets for actually running tests. # Targets for actually running tests.
test_cpp: protoc_middleman conformance-test-runner conformance-cpp test_cpp: protoc_middleman conformance-test-runner conformance-cpp
./conformance-test-runner --failure_list failure_list_cpp.txt ./conformance-cpp ./conformance-test-runner --failure_list failure_list_cpp.txt ./conformance-cpp
@ -62,5 +71,8 @@ test_cpp: protoc_middleman conformance-test-runner conformance-cpp
test_java: protoc_middleman conformance-test-runner conformance-java test_java: protoc_middleman conformance-test-runner conformance-java
./conformance-test-runner ./conformance-java ./conformance-test-runner ./conformance-java
test_csharp: protoc_middleman conformance-test-runner conformance-csharp
./conformance-test-runner --failure_list failure_list_csharp.txt ./conformance-csharp
test_ruby: protoc_middleman conformance-test-runner test_ruby: protoc_middleman conformance-test-runner
RUBYLIB=../ruby/lib:. ./conformance-test-runner --failure_list failure_list_ruby.txt ./conformance_ruby.rb RUBYLIB=../ruby/lib:. ./conformance-test-runner --failure_list failure_list_ruby.txt ./conformance_ruby.rb

@ -1,17 +1,2 @@
JsonInput.HelloWorld.JsonOutput JsonInput.HelloWorld.JsonOutput
JsonInput.HelloWorld.ProtobufOutput JsonInput.HelloWorld.ProtobufOutput
ProtobufInput.PrematureEofBeforeUnknownValue.DOUBLE
ProtobufInput.PrematureEofBeforeUnknownValue.FIXED32
ProtobufInput.PrematureEofBeforeUnknownValue.FIXED64
ProtobufInput.PrematureEofBeforeUnknownValue.FLOAT
ProtobufInput.PrematureEofBeforeUnknownValue.SFIXED32
ProtobufInput.PrematureEofBeforeUnknownValue.SFIXED64
ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.BYTES
ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.MESSAGE
ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.STRING
ProtobufInput.PrematureEofInsideUnknownValue.DOUBLE
ProtobufInput.PrematureEofInsideUnknownValue.FIXED32
ProtobufInput.PrematureEofInsideUnknownValue.FIXED64
ProtobufInput.PrematureEofInsideUnknownValue.FLOAT
ProtobufInput.PrematureEofInsideUnknownValue.SFIXED32
ProtobufInput.PrematureEofInsideUnknownValue.SFIXED64

28
csharp/.gitignore vendored

@ -3,25 +3,14 @@
# #
src/AddressBook/bin src/AddressBook/bin
src/AddressBook/obj src/AddressBook/obj
src/ProtocolBuffers/bin/ src/Google.Protobuf/bin/
src/ProtocolBuffers/obj/ src/Google.Protobuf/obj/
src/ProtocolBuffers/objCF src/Google.Protobuf.Conformance/bin/
src/ProtocolBuffers.Serialization/bin/ src/Google.Protobuf.Conformance/obj/
src/ProtocolBuffers.Serialization/obj/ src/Google.Protobuf.Test/bin/
src/ProtocolBuffers.Test/bin/ src/Google.Protobuf.Test/obj/
src/ProtocolBuffers.Test/obj/ src/Google.Protobuf.JsonDump/bin/
src/ProtocolBuffersLite.Test/bin/ src/Google.Protobuf.JsonDump/obj/
src/ProtocolBuffersLite.Test/obj/
src/ProtoBench/bin/
src/ProtoBench/obj/
src/ProtoDump/bin/
src/ProtoDump/obj/
src/ProtoGen/bin/
src/ProtoGen/obj/
src/ProtoGen.Test/bin/
src/ProtoGen.Test/obj/
src/ProtoMunge/bin/
src/ProtoMunge/obj/
mono/bin mono/bin
mono/tmp mono/tmp
mono/protoc mono/protoc
@ -36,6 +25,7 @@ lib/NUnit
# #
*.user *.user
*.suo *.suo
*.nupkg
_ReSharper.* _ReSharper.*
*.sln.cache *.sln.cache
mono/TestResult.xml mono/TestResult.xml

@ -1,33 +1,45 @@
This directory contains the C# Protocol Buffers runtime library. This directory contains the C# Protocol Buffers runtime library.
Warning: experimental!
======================
This code is still under significant churn. Unlike the original port,
it only supports proto3 (but not *all* of proto3 yet) - there are no
unknown fields or extensions, for example. protoc will (eventually)
deliberately fail if it is asked to generate C# code for proto2
messages other than descriptor.proto, which is still required for
reflection. (It's currently exposed publicly, but won't be
eventually.)
Also unlike the original port, the new version embraces mutability -
there are no builder types. We plan to add "freezing" operations as
well as cloning, however.
Usage Usage
===== =====
The easiest way to use C# protocol buffers in your project is to use the [Google.ProtocolBuffers NuGet package](http://www.nuget.org/packages/Google.ProtocolBuffers/). This package is the legacy package for C# protocol buffers, but it will work fine with C# code generated by `protoc` if you use proto2 syntax (The API of the runtime library haven't changed so far). Use `protoc` with the `--csharp_out` option to generate C# files in the specified directory.
Include these in your C# project, and add a reference to the `Google.Protobuf` project. Currently
there is no NuGet package for this, but we will be building one as soon as the API is stable.
Supported platforms
===================
*WARNING: If you specify `syntax = "proto3";` in your .proto files, the generated code won't necessarily work with the legacy NuGet package. So before we officially add proto3 support, always use `syntax = "proto2";` (the default) in your protos.* The runtime library is built as a portable class library, supporting:
We will definitely release a new NuGet package for the runtime library in the future. The new runtime library WILL contain significant semantic, backwardly-incompatible changes in proto handling (mostly because we will be adding proto3 support and we will be using that oportunity to make some design changes). So keep in mind that you will need to regenerate your proto files and switch to a new NuGet package once the new version of runtime library becomes available. - .NET 4.5
- Windows 8
- Windows Phone Silverlight 8
- Windows Phone 8.1
- .NET Core (dnxcore)
Building Building
======== ========
Open the `src/ProtocolBuffers.sln` solution in Visual Studio. Click "Build solution" to build the solution. You should be able to run the NUnit test from Test Explorer (you might need to install NUnit Visual Studio add-in). Open the `src/Google.Protobuf.sln` solution in Visual Studio. Click "Build solution" to build the solution. You should be able to run the NUnit test from Test Explorer (you might need to install NUnit Visual Studio add-in).
Supported Visual Studio versions are VS2013 (update 4) and VS2015. On Linux, you can also use Monodevelop 5.9 (older versions might work fine). Supported Visual Studio versions are VS2013 (update 4) and VS2015. On Linux, you can also use Monodevelop 5.9 (older versions might work fine).
Proto2 & Proto3
===============
*WARNING: Only proto2 is supported for now, proto3 is under construction.*
C# protocol buffers are currently under development and you should expect semantic, backward-incompatible changes in the future.
Also, as of now, only proto2 is supported. Proto3 support for C# is currently in progress
(both design & implementation) and you should not expect any of the proto3 features to work.
In fact, always use `syntax = "proto2";` in your .proto files for now, unless you are feeling like experimenting.
History of C# protobufs History of C# protobufs
======================= =======================

@ -1,8 +0,0 @@
@echo off
SET BUILD_TARGET=%~1
SET BUILD_CONFIG=%~2
IF "%BUILD_TARGET%"=="" SET BUILD_TARGET=Rebuild
IF "%BUILD_CONFIG%"=="" SET BUILD_CONFIG=Debug
CMD.exe /Q /C "CD %~dp0 && %WINDIR%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe /nologo build.csproj /t:%BUILD_TARGET% /toolsversion:4.0 "/p:Configuration=%BUILD_CONFIG%" %3 %4 %5 %6

@ -1,122 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- **********************************************************************************************
Targets For Clean
*********************************************************************************************** -->
<Target Name="_CleanFolder">
<Message Importance="normal" Text="Removing temporary directory '$(CleanFolderDirectory)'"/>
<Error Text="Can not remove empty directory name." Condition=" '$(CleanFolderDirectory)' == '' " />
<Exec WorkingDirectory="$(MSBuildProjectDirectory)" Condition="Exists($(CleanFolderDirectory))" Outputs="@(Ignore)"
Command="MOVE /Y &quot;$(CleanFolderDirectory)&quot; &quot;$(CleanFolderDirectory)-deleted&quot; > NUL" />
<RemoveDir Directories="$(CleanFolderDirectory)-deleted" Condition="Exists('$(CleanFolderDirectory)-deleted')" />
</Target>
<Target Name="_CleanTempOutput">
<MSBuild Projects="$(MSBuildProjectFullPath)" Properties="CleanFolderDirectory=%(TempBuildFolder.Identity);" Targets="_CleanFolder" />
</Target>
<Target Name="_CleanAll" DependsOnTargets="_CleanTempOutput">
<MakeDir Directories="$(BuildTempDirectory)" />
<MakeDir Directories="$(BuildOutputDirectory)" />
</Target>
<!-- **********************************************************************************************
Targets For Build
*********************************************************************************************** -->
<Target Name="_CompileAll">
<MSBuild Projects="$(MSBuildProjectFullPath)" Properties="SolutionTarget=Rebuild;" Targets="_BuildAllConfigurations" />
</Target>
<Target Name="_BuildAllConfigurations">
<MSBuild Properties="TargetVersion=cf20;Configuration=$(Configuration);Platform=$(Platform);" Targets="$(SolutionTarget)" Projects="$(MSBuildProjectDirectory)\target.csproj" />
<MSBuild Properties="TargetVersion=cf35;Configuration=$(Configuration);Platform=$(Platform);" Targets="$(SolutionTarget)" Projects="$(MSBuildProjectDirectory)\target.csproj" />
<MSBuild Properties="TargetVersion=net20;Configuration=$(Configuration);Platform=$(Platform);" Targets="$(SolutionTarget)" Projects="$(MSBuildProjectDirectory)\target.csproj" />
<MSBuild Properties="TargetVersion=net35;Configuration=$(Configuration);Platform=$(Platform);" Targets="$(SolutionTarget)" Projects="$(MSBuildProjectDirectory)\target.csproj" />
<MSBuild Properties="TargetVersion=net40;Configuration=$(Configuration);Platform=$(Platform);" Targets="$(SolutionTarget)" Projects="$(MSBuildProjectDirectory)\target.csproj" />
<MSBuild Properties="TargetVersion=sl20;Configuration=$(Configuration);Platform=$(Platform);" Targets="$(SolutionTarget)" Projects="$(MSBuildProjectDirectory)\target.csproj" />
<MSBuild Properties="TargetVersion=sl30;Configuration=$(Configuration);Platform=$(Platform);" Targets="$(SolutionTarget)" Projects="$(MSBuildProjectDirectory)\target.csproj" />
<MSBuild Properties="TargetVersion=sl40;Configuration=$(Configuration);Platform=$(Platform);" Targets="$(SolutionTarget)" Projects="$(MSBuildProjectDirectory)\target.csproj" />
<MSBuild Properties="TargetVersion=pl40;Configuration=$(Configuration);Platform=$(Platform);" Targets="$(SolutionTarget)" Projects="$(MSBuildProjectDirectory)\target.csproj" />
</Target>
<!-- **********************************************************************************************
Targets For Tools
*********************************************************************************************** -->
<Target Name="_BuildTools">
<MSBuild Targets="Build" ToolsVersion="3.5" Projects="$(ProjectDirectory)\src\ProtocolBuffers.sln" Properties="Configuration=Release;Platform=Any CPU;" />
<Copy SourceFiles="%(ToolsOutputItem.Identity)" DestinationFolder="$(BuildOutputDirectory)\tools" />
<Copy SourceFiles="$(LibDirectory)\NUnit-config\nunit-console.v2.0.config" DestinationFiles="$(NUnitExePath).config" />
<Exec
WorkingDirectory="%(ToolsTestContainer.RootDir)%(ToolsTestContainer.Directory)"
Command="&quot;$(NUnitExePath)&quot; /nologo /noshadow &quot;%(ToolsTestContainer.Identity)&quot; /xml:&quot;$(BuildTempDirectory)\%(ToolsTestContainer.Filename).xml&quot;" />
</Target>
<!-- **********************************************************************************************
Targets For GenerateSource
*********************************************************************************************** -->
<Target Name="_GenerateProjects">
<Exec Command="&quot;$(CsProjectProjector)&quot; csproj_templates src\ProtocolBuffersLibrary.sln" WorkingDirectory="$(ProjectDirectory)" />
</Target>
<Target Name="_CleanTempSource">
<MSBuild Projects="$(MSBuildProjectFullPath)" Properties="CleanFolderDirectory=$(SourceTempDirectory);" Targets="_CleanFolder" />
<MakeDir Directories="$(SourceTempDirectory)" />
</Target>
<Target Name="_GenerateSource" DependsOnTargets="_CleanTempSource">
<Message Importance="high" Text="Generating source from proto files" />
<Exec Command="&quot;$(ProtocExePath)&quot; --proto_path=$(ProtosDirectory) --descriptor_set_out=compiled.pb @(Protos->'%(RelativeDir)%(Filename)%(Extension)', ' ')" WorkingDirectory="$(SourceTempDirectory)" />
<Exec Command="&quot;$(ProtogenExePath)&quot; compiled.pb" WorkingDirectory="$(SourceTempDirectory)" />
</Target>
<Target Name="_CopyGeneratedSource" DependsOnTargets="_GenerateSource">
<Copy SourceFiles="%(GeneratedSource.Identity)" DestinationFiles="%(GeneratedSource.TargetDirectory)\%(GeneratedSource.Filename)%(GeneratedSource.Extension)" />
</Target>
<!-- **********************************************************************************************
Targets For Package
*********************************************************************************************** -->
<Target Name="_PackageAll">
<MSBuild Projects="$(MSBuildProjectFullPath)" Properties="SolutionTarget=_Publish;" Targets="_BuildAllConfigurations" />
</Target>
<Target Name="_GeneratePackage">
<Copy SourceFiles="@(StaticPackageItem)" DestinationFolder="$(BuildOutputPackage)\%(StaticPackageItem.TargetDirectory)\%(StaticPackageItem.RecursiveDir)" />
<Exec Command="&quot;$(ZipExePath)&quot; a -tzip $(BuildTempDirectory)\$(PackageName)-binaries.zip * -x!*.pdb -r" WorkingDirectory="$(BuildOutputPackage)" />
<Exec Command="&quot;$(ZipExePath)&quot; a -tzip $(BuildTempDirectory)\$(PackageName)-symbols.zip * -r" WorkingDirectory="$(BuildOutputPackage)" />
</Target>
<!-- **********************************************************************************************
Targets For Benchmark
*********************************************************************************************** -->
<Target Name="_RunBenchmarks">
<ItemGroup>
<BenchmarkParameter Include="Google.ProtocolBuffers.ProtoBench.SizeMessage1,ProtoBench" />
<BenchmarkParameter Include="google_message1.dat" />
<BenchmarkParameter Include="Google.ProtocolBuffers.ProtoBench.SpeedMessage1,ProtoBench" />
<BenchmarkParameter Include="google_message1.dat" />
<BenchmarkParameter Include="Google.ProtocolBuffers.ProtoBench.SizeMessage2,ProtoBench" />
<BenchmarkParameter Include="google_message2.dat" />
<BenchmarkParameter Include="Google.ProtocolBuffers.ProtoBench.SpeedMessage2,ProtoBench" />
<BenchmarkParameter Include="google_message2.dat" />
</ItemGroup>
<Message Text="Running ProtoBench.exe" />
<Exec Command="ProtoBench.exe $(BenchmarkArgs) @(BenchmarkParameter->'%(Identity)', ' ') &quot;/log:$(BenchmarkOutputFile)&quot;"
WorkingDirectory="$(SourceDirectory)\ProtoBench\bin\NET35\Release" />
</Target>
</Project>

@ -1,59 +0,0 @@
<?xml version="1.0"?>
<package xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="nuspec.xsd">
<metadata>
<id>Google.ProtocolBuffers</id>
<version>$version$</version>
<owners>Jon Skeet</owners>
<authors>Jon Skeet</authors>
<licenseUrl>http://code.google.com/p/protobuf-csharp-port/source/browse/license.txt</licenseUrl>
<projectUrl>http://code.google.com/p/protobuf-csharp-port/</projectUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<copyright>Copyright 2008 Google Inc. All rights reserved.</copyright>
<tags>Protocol Buffers Binary Serialization Format Google</tags>
<title>Google.ProtocolBuffers</title>
<summary>A managed code generator and library for Google's data interchange format.</summary>
<description><![CDATA[
Protocol Buffers is a binary serialization format and technology, released to the open source community by Google in 2008.
Its primary use is to produce small fast binary representations of a 'message' or object for serialization or transportation.
There are various implementations of Protocol Buffers in .NET. This project is a fairly close port of the Google Java implementation.
There are two main parts:
tools/protoc.exe, which takes the textual representation of the protocol buffer and turns it into a binary representation for use with ProtoGen.exe.
tools/ProtoGen.exe, which takes binary representations of protocol buffer descriptors (as generated by the "stock" protoc binary supplied by Google) and creates C# source code. This is only required at build time.
lib/*/Google.ProtocolBuffers.dll, which is a supporting library. This is required at execution time.
lib/*/Google.ProtocolBuffers.Serialization.dll, a supplementary library that provides extensions for reading and writing protocol buffers to xml, json, and others.
LINKS:
Project Home - http://code.google.com/p/protobuf-csharp-port
Online Help - http://help.protobuffers.net
Developer Guide - http://code.google.com/apis/protocolbuffers/docs/overview.html
Language Guide - http://code.google.com/apis/protocolbuffers/docs/proto.html
]]></description>
<references>
<reference file="Google.ProtocolBuffers.dll"/>
<reference file="Google.ProtocolBuffers.Serialization.dll"/>
</references>
</metadata>
<files>
<!-- Release Binaries -->
<file src="..\build_output\Release\**\Google.ProtocolBuffers.???" target="lib\" />
<file src="..\build_output\Release\**\Google.ProtocolBuffers.Serialization.???" target="lib\" />
<!-- Tools -->
<file src="..\build_output\tools\**\*" target="tools\" />
<file src="..\build_output\protos\**\*" target="tools\" />
<!-- Content -->
<file src="..\build_output\CHANGES.txt" target="tools\"/>
<file src="..\build_output\license.txt" target="tools\"/>
<file src="..\build_output\tools\protoc-license.txt" target="tools\"/>
<!-- Source -->
<file src="..\src\ProtocolBuffers\**\*.cs" target="src\ProtocolBuffers\"/>
<file src="..\src\ProtocolBuffers.Serialization\**\*.cs" target="src\ProtocolBuffers.Serialization\"/>
</files>
</package>

@ -1,60 +0,0 @@
<?xml version="1.0"?>
<package xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="nuspec.xsd">
<metadata>
<id>Google.ProtocolBuffersLite</id>
<version>$version$</version>
<owners>Jon Skeet</owners>
<authors>Jon Skeet</authors>
<licenseUrl>http://code.google.com/p/protobuf-csharp-port/source/browse/license.txt</licenseUrl>
<projectUrl>http://code.google.com/p/protobuf-csharp-port/</projectUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<copyright>Copyright 2008 Google Inc. All rights reserved.</copyright>
<tags>Protocol Buffers Binary Serialization Format Google</tags>
<title>Google.ProtocolBuffersLite</title>
<summary>A managed code generator and library for Google's data interchange format.</summary>
<description><![CDATA[
Protocol Buffers is a binary serialization format and technology, released to the open source community by Google in 2008.
Its primary use is to produce small fast binary representations of a 'message' or object for serialization or transportation.
There are various implementations of Protocol Buffers in .NET. This project is a fairly close port of the Google Java implementation.
There are two main parts:
tools/protoc.exe, which takes the textual representation of the protocol buffer and turns it into a binary representation for use with ProtoGen.exe.
tools/ProtoGen.exe, which takes binary representations of protocol buffer descriptors (as generated by the "stock" protoc binary supplied by Google) and creates C# source code. This is only required at build time.
lib/*/Google.ProtocolBuffersLite.dll, which is a supporting library. This is required at execution time.
lib/*/Google.ProtocolBuffersLite.Serialization.dll, a supplementary library that provides extensions for reading and writing protocol buffers to xml, json, and others.
LINKS:
Project Home - http://code.google.com/p/protobuf-csharp-port
Online Help - http://help.protobuffers.net
Developer Guide - http://code.google.com/apis/protocolbuffers/docs/overview.html
Language Guide - http://code.google.com/apis/protocolbuffers/docs/proto.html
]]></description>
<references>
<reference file="Google.ProtocolBuffersLite.dll"/>
<reference file="Google.ProtocolBuffersLite.Serialization.dll"/>
</references>
</metadata>
<files>
<!-- Release Binaries -->
<file src="..\build_output\Release\**\Google.ProtocolBuffersLite.???" target="lib\" />
<file src="..\build_output\Release\**\Google.ProtocolBuffersLite.Serialization.???" target="lib\" />
<!-- Tools -->
<file src="..\build_output\tools\**\*" target="tools\" />
<file src="..\build_output\protos\**\*" target="tools\" />
<!-- Content -->
<file src="..\build_output\CHANGES.txt" target="tools\"/>
<file src="..\build_output\license.txt" target="tools\"/>
<file src="..\build_output\tools\protoc-license.txt" target="tools\"/>
<!-- Source -->
<file src="..\src\ProtocolBuffers\**\*.cs" target="src\ProtocolBuffers\"/>
<file src="..\src\ProtocolBuffers.Serialization\**\*.cs" target="src\ProtocolBuffers.Serialization\"/>
</files>
</package>

@ -1,2 +0,0 @@
@echo off
CMD.exe /Q /C "CD %~dp0 && %WINDIR%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe /nologo build.csproj /toolsversion:4.0 /t:RunBenchmarks %1 %2 %3 %4

@ -1,20 +0,0 @@
@echo off
SET BUILD_VERSION=%~1
SET BUILD_TARGET=%~2
SET BUILD_CONFIG=%~3
IF NOT "%BUILD_VERSION%"=="" GOTO RUN
ECHO.
ECHO Usage: build.bat platform [target] [config] [msbuild arguments]
ECHO.
ECHO - platform: CF20, CF35, NET20, NET35, NET40, PL40, SL20, SL30, or SL40
ECHO - [target]: Rebuild, Clean, Build, Test, or Publish
ECHO - [config]: Debug or Release
ECHO.
EXIT /B 1
:RUN
IF "%BUILD_TARGET%"=="" SET BUILD_TARGET=Rebuild
IF "%BUILD_CONFIG%"=="" SET BUILD_CONFIG=Debug
CMD.exe /Q /C "CD %~dp0 && %WINDIR%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe /nologo target.csproj /toolsversion:4.0 %4 %5 %6 "/t:%BUILD_TARGET%" "/p:Configuration=%BUILD_CONFIG%;TargetVersion=%BUILD_VERSION%"

@ -1,241 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- build targets -->
<Target Name="Clean" DependsOnTargets="_CleanAll" />
<Target Name="BuildTools" DependsOnTargets="_BuildTools" />
<Target Name="GenerateProjects" DependsOnTargets="_GenerateProjects" />
<Target Name="GenerateSource" DependsOnTargets="_GenerateSource;_CopyGeneratedSource" />
<Target Name="RebuildSource" DependsOnTargets="Clean;BuildTools;GenerateSource" />
<Target Name="Build" DependsOnTargets="GenerateProjects;BuildTools;GenerateSource;_CompileAll" />
<Target Name="Rebuild" DependsOnTargets="Clean;Build" />
<Target Name="GeneratePackage" DependsOnTargets="_PackageAll;_GeneratePackage" />
<Target Name="FullBuild" DependsOnTargets="Rebuild;GeneratePackage" />
<!-- misc targets -->
<Target Name="RunBenchmarks" DependsOnTargets="_CleanAll;_BuildTools;_RunBenchmarks" />
<PropertyGroup>
<ProjectName>Protocol Buffers</ProjectName>
<Configuration Condition=" '$(Configuration)' == '' ">Release</Configuration>
<Platform Condition=" '$(Platform)' == '' ">Any CPU</Platform>
<!--Directory Paths-->
<ProjectDirectory>$(MSBuildProjectDirectory)\..</ProjectDirectory>
<SourceDirectory>$(ProjectDirectory)\src</SourceDirectory>
<LibDirectory>$(ProjectDirectory)\lib</LibDirectory>
<ProtosDirectory>$(ProjectDirectory)\protos</ProtosDirectory>
<SourceTempDirectory>$(ProjectDirectory)\build_temp\GeneratedSource</SourceTempDirectory>
<BuildTempDirectory>$(ProjectDirectory)\build_temp</BuildTempDirectory>
<BuildOutputDirectory>$(ProjectDirectory)\build_output</BuildOutputDirectory>
<BuildOutputPackage>$(BuildOutputDirectory)</BuildOutputPackage>
<BenchmarkArgs>/v2 /fast /formats</BenchmarkArgs>
<BenchmarkOutputFile>$(BuildTempDirectory)\..\BenchmarkResults.txt</BenchmarkOutputFile>
<BenchmarkProtosDirectory>$(ProjectDirectory)\benchmarks</BenchmarkProtosDirectory>
<PackageName Condition=" '$(PackageName)' == '' ">$(Configuration)</PackageName>
<!--Tool Paths-->
<ProtocExePath>$(BuildOutputDirectory)\tools\protoc.exe</ProtocExePath>
<ProtogenExePath>$(BuildOutputDirectory)\tools\protogen.exe</ProtogenExePath>
<NUnitExePath>$(LibDirectory)\NUnit\tools\nunit-console.exe</NUnitExePath>
<CsProjectProjector>$(LibDirectory)\CsProjectProjector\CsProjectProjector.exe</CsProjectProjector>
<ZipExePath>$(LibDirectory)\7-Zip 9.20\7za.exe</ZipExePath>
</PropertyGroup>
<Import Project="Common.targets"/>
<!-- Proto Files -->
<ItemGroup>
<Protos Include="$(ProtosDirectory)\extest\unittest_issues.proto" />
<Protos Include="$(ProtosDirectory)\extest\unittest_extras.proto" />
<Protos Include="$(ProtosDirectory)\extest\unittest_extras_full.proto" />
<Protos Include="$(ProtosDirectory)\extest\unittest_extras_lite.proto" />
<Protos Include="$(ProtosDirectory)\extest\unittest_extras_xmltest.proto" />
<Protos Include="$(ProtosDirectory)\extest\unittest_generic_services.proto" />
<Protos Include="$(ProtosDirectory)\extest\unittest_rpc_interop.proto" />
<Protos Include="$(ProtosDirectory)\extest\unittest_rpc_interop_lite.proto" />
<Protos Include="$(ProtosDirectory)\google\protobuf\descriptor.proto" />
<Protos Include="$(ProtosDirectory)\google\protobuf\csharp_options.proto" />
<Protos Include="$(ProtosDirectory)\google\protobuf\unittest.proto" />
<Protos Include="$(ProtosDirectory)\google\protobuf\unittest_csharp_options.proto" />
<Protos Include="$(ProtosDirectory)\google\protobuf\unittest_custom_options.proto" />
<Protos Include="$(ProtosDirectory)\google\protobuf\unittest_embed_optimize_for.proto" />
<Protos Include="$(ProtosDirectory)\google\protobuf\unittest_empty.proto" />
<Protos Include="$(ProtosDirectory)\google\protobuf\unittest_import.proto" />
<Protos Include="$(ProtosDirectory)\google\protobuf\unittest_import_lite.proto" />
<Protos Include="$(ProtosDirectory)\google\protobuf\unittest_lite.proto" />
<Protos Include="$(ProtosDirectory)\google\protobuf\unittest_lite_imports_nonlite.proto" />
<Protos Include="$(ProtosDirectory)\google\protobuf\unittest_mset.proto" />
<Protos Include="$(ProtosDirectory)\google\protobuf\unittest_no_generic_services.proto" />
<Protos Include="$(ProtosDirectory)\google\protobuf\unittest_optimize_for.proto" />
<Protos Include="$(ProtosDirectory)\google\test\google_size.proto" />
<Protos Include="$(ProtosDirectory)\google\test\google_speed.proto" />
<Protos Include="$(ProtosDirectory)\tutorial\addressbook.proto" />
<!-- for benchmark -->
<Protos Include="$(ProtosDirectory)\benchmarks\google_size.proto" />
<Protos Include="$(ProtosDirectory)\benchmarks\google_speed.proto" />
</ItemGroup>
<!-- Generated Source -->
<ItemGroup>
<!-- Main protos -->
<GeneratedSource Include="$(SourceTempDirectory)\CSharpOptions.cs">
<TargetDirectory>$(SourceDirectory)\ProtocolBuffers\DescriptorProtos</TargetDirectory>
</GeneratedSource>
<GeneratedSource Include="$(SourceTempDirectory)\DescriptorProtoFile.cs">
<TargetDirectory>$(SourceDirectory)\ProtocolBuffers\DescriptorProtos</TargetDirectory>
</GeneratedSource>
<!-- Address book sample -->
<GeneratedSource Include="$(SourceTempDirectory)\AddressBookProtos.cs">
<TargetDirectory>$(SourceDirectory)\AddressBook</TargetDirectory>
</GeneratedSource>
<!-- Unit test -->
<GeneratedSource Include="$(SourceTempDirectory)\UnitTestExtrasProtoFile.cs">
<TargetDirectory>$(SourceDirectory)\ProtocolBuffers.Test\TestProtos</TargetDirectory>
</GeneratedSource>
<GeneratedSource Include="$(SourceTempDirectory)\UnitTestExtrasIssuesProtoFile.cs">
<TargetDirectory>$(SourceDirectory)\ProtocolBuffers.Test\TestProtos</TargetDirectory>
</GeneratedSource>
<GeneratedSource Include="$(SourceTempDirectory)\UnitTestXmlSerializerTestProtoFile.cs">
<TargetDirectory>$(SourceDirectory)\ProtocolBuffers.Test\TestProtos</TargetDirectory>
</GeneratedSource>
<GeneratedSource Include="$(SourceTempDirectory)\UnitTestCSharpOptionsProtoFile.cs">
<TargetDirectory>$(SourceDirectory)\ProtocolBuffers.Test\TestProtos</TargetDirectory>
</GeneratedSource>
<GeneratedSource Include="$(SourceTempDirectory)\UnitTestCustomOptionsProtoFile.cs">
<TargetDirectory>$(SourceDirectory)\ProtocolBuffers.Test\TestProtos</TargetDirectory>
</GeneratedSource>
<GeneratedSource Include="$(SourceTempDirectory)\UnitTestEmbedOptimizeForProtoFile.cs">
<TargetDirectory>$(SourceDirectory)\ProtocolBuffers.Test\TestProtos</TargetDirectory>
</GeneratedSource>
<GeneratedSource Include="$(SourceTempDirectory)\UnitTestEmptyProtoFile.cs">
<TargetDirectory>$(SourceDirectory)\ProtocolBuffers.Test\TestProtos</TargetDirectory>
</GeneratedSource>
<GeneratedSource Include="$(SourceTempDirectory)\UnitTestImportLiteProtoFile.cs">
<TargetDirectory>$(SourceDirectory)\ProtocolBuffers.Test\TestProtos</TargetDirectory>
</GeneratedSource>
<GeneratedSource Include="$(SourceTempDirectory)\UnitTestImportProtoFile.cs">
<TargetDirectory>$(SourceDirectory)\ProtocolBuffers.Test\TestProtos</TargetDirectory>
</GeneratedSource>
<GeneratedSource Include="$(SourceTempDirectory)\UnitTestMessageSetProtoFile.cs">
<TargetDirectory>$(SourceDirectory)\ProtocolBuffers.Test\TestProtos</TargetDirectory>
</GeneratedSource>
<GeneratedSource Include="$(SourceTempDirectory)\UnitTestNoGenericServicesProtoFile.cs">
<TargetDirectory>$(SourceDirectory)\ProtocolBuffers.Test\TestProtos</TargetDirectory>
</GeneratedSource>
<GeneratedSource Include="$(SourceTempDirectory)\UnitTestOptimizeForProtoFile.cs">
<TargetDirectory>$(SourceDirectory)\ProtocolBuffers.Test\TestProtos</TargetDirectory>
</GeneratedSource>
<GeneratedSource Include="$(SourceTempDirectory)\UnitTestProtoFile.cs">
<TargetDirectory>$(SourceDirectory)\ProtocolBuffers.Test\TestProtos</TargetDirectory>
</GeneratedSource>
<GeneratedSource Include="$(SourceTempDirectory)\UnitTestRpcInterop.cs">
<TargetDirectory>$(SourceDirectory)\ProtocolBuffers.Test\TestProtos</TargetDirectory>
</GeneratedSource>
<GeneratedSource Include="$(SourceTempDirectory)\UnitTestRpcInteropLite.cs">
<TargetDirectory>$(SourceDirectory)\ProtocolBuffersLite.Test\TestProtos</TargetDirectory>
</GeneratedSource>
<GeneratedSource Include="$(SourceTempDirectory)\UnitTestGenericServices.cs">
<TargetDirectory>$(SourceDirectory)\ProtocolBuffers.Test\TestProtos</TargetDirectory>
</GeneratedSource>
<!-- Lite unit test -->
<GeneratedSource Include="$(SourceTempDirectory)\UnitTestExtrasFullProtoFile.cs">
<TargetDirectory>$(SourceDirectory)\ProtocolBuffersLite.Test\TestProtos</TargetDirectory>
</GeneratedSource>
<GeneratedSource Include="$(SourceTempDirectory)\UnitTestExtrasLiteProtoFile.cs">
<TargetDirectory>$(SourceDirectory)\ProtocolBuffersLite.Test\TestProtos</TargetDirectory>
</GeneratedSource>
<GeneratedSource Include="$(SourceTempDirectory)\UnitTestImportLiteProtoFile.cs">
<TargetDirectory>$(SourceDirectory)\ProtocolBuffersLite.Test\TestProtos</TargetDirectory>
</GeneratedSource>
<GeneratedSource Include="$(SourceTempDirectory)\UnitTestImportProtoFile.cs">
<TargetDirectory>$(SourceDirectory)\ProtocolBuffersLite.Test\TestProtos</TargetDirectory>
</GeneratedSource>
<GeneratedSource Include="$(SourceTempDirectory)\UnitTestLiteImportNonLiteProtoFile.cs">
<TargetDirectory>$(SourceDirectory)\ProtocolBuffersLite.Test\TestProtos</TargetDirectory>
</GeneratedSource>
<GeneratedSource Include="$(SourceTempDirectory)\UnitTestLiteProtoFile.cs">
<TargetDirectory>$(SourceDirectory)\ProtocolBuffersLite.Test\TestProtos</TargetDirectory>
</GeneratedSource>
<GeneratedSource Include="$(SourceTempDirectory)\UnitTestProtoFile.cs">
<TargetDirectory>$(SourceDirectory)\ProtocolBuffersLite.Test\TestProtos</TargetDirectory>
</GeneratedSource>
<GeneratedSource Include="$(SourceTempDirectory)\UnitTestGoogleSizeProtoFile.cs">
<TargetDirectory>$(SourceDirectory)\ProtocolBuffers.Test\TestProtos</TargetDirectory>
</GeneratedSource>
<GeneratedSource Include="$(SourceTempDirectory)\UnitTestGoogleSpeedProtoFile.cs">
<TargetDirectory>$(SourceDirectory)\ProtocolBuffers.Test\TestProtos</TargetDirectory>
</GeneratedSource>
<GeneratedSource Include="$(SourceTempDirectory)\GoogleSizeProtoFile.cs">
<TargetDirectory>$(SourceDirectory)\ProtoBench\TestProtos</TargetDirectory>
</GeneratedSource>
<GeneratedSource Include="$(SourceTempDirectory)\GoogleSpeedProtoFile.cs">
<TargetDirectory>$(SourceDirectory)\ProtoBench\TestProtos</TargetDirectory>
</GeneratedSource>
<GeneratedSource Include="$(SourceTempDirectory)\UnitTestImportProtoFile.cs">
<TargetDirectory>$(SourceDirectory)\ProtoBench\TestProtos</TargetDirectory>
</GeneratedSource>
<GeneratedSource Include="$(SourceTempDirectory)\UnitTestProtoFile.cs">
<TargetDirectory>$(SourceDirectory)\ProtoBench\TestProtos</TargetDirectory>
</GeneratedSource>
</ItemGroup>
<!-- Package Items -->
<ItemGroup>
<StaticPackageItem Include="$(ProjectDirectory)\CHANGES.txt" />
<StaticPackageItem Include="$(ProjectDirectory)\license.txt" />
<StaticPackageItem Include="$(ProjectDirectory)\protos\google\protobuf\descriptor.proto">
<TargetDirectory>\protos\google\protobuf</TargetDirectory>
</StaticPackageItem>
<StaticPackageItem Include="$(ProjectDirectory)\protos\google\protobuf\compiler\plugin.proto">
<TargetDirectory>\protos\google\protobuf\compiler</TargetDirectory>
</StaticPackageItem>
<StaticPackageItem Include="$(ProjectDirectory)\protos\google\protobuf\csharp_options.proto">
<TargetDirectory>\protos\google\protobuf</TargetDirectory>
</StaticPackageItem>
<StaticPackageItem Include="$(ProjectDirectory)\protos\tutorial\addressbook.proto">
<TargetDirectory>\protos\tutorial</TargetDirectory>
</StaticPackageItem>
</ItemGroup>
<!-- Tools -->
<ItemGroup>
<ToolsTestContainer Include="$(SourceDirectory)\ProtoGen.Test\bin\NET35\Release\Google.ProtocolBuffers.ProtoGen.Test.dll" />
<ToolsOutputItem Include="$(SourceDirectory)\ProtocolBuffers\bin\NET35\Release\Google.ProtocolBuffers.dll" />
<ToolsOutputItem Include="$(SourceDirectory)\ProtocolBuffers.Serialization\bin\NET35\Release\Google.ProtocolBuffers.Serialization.dll" />
<ToolsOutputItem Include="$(SourceDirectory)\ProtoGen\bin\NET35\Release\ProtoGen.exe" />
<ToolsOutputItem Include="$(SourceDirectory)\ProtoGen\bin\NET35\Release\ProtoGen.exe.config" />
<ToolsOutputItem Include="$(SourceDirectory)\ProtoMunge\bin\NET35\Release\ProtoMunge.exe" />
<ToolsOutputItem Include="$(SourceDirectory)\ProtoDump\bin\NET35\Release\ProtoDump.exe" />
<ToolsOutputItem Include="$(SourceDirectory)\ProtoBench\bin\NET35\Release\ProtoBench.exe" />
<ToolsOutputItem Include="$(LibDirectory)\protoc.exe" />
<ToolsOutputItem Include="$(LibDirectory)\protoc-license.txt" />
</ItemGroup>
<!-- Temporary Directories -->
<ItemGroup>
<TempBuildFolder Include="$(BuildTempDirectory)" />
<TempBuildFolder Include="$(BuildOutputDirectory)" />
<TempBuildFolder Include="$(SourceDirectory)\AddressBook\obj" />
<TempBuildFolder Include="$(SourceDirectory)\AddressBook\bin" />
<TempBuildFolder Include="$(SourceDirectory)\ProtoBench\obj" />
<TempBuildFolder Include="$(SourceDirectory)\ProtoBench\bin" />
<TempBuildFolder Include="$(SourceDirectory)\ProtocolBuffers\obj" />
<TempBuildFolder Include="$(SourceDirectory)\ProtocolBuffers\bin" />
<TempBuildFolder Include="$(SourceDirectory)\ProtocolBuffers.Serialization\obj" />
<TempBuildFolder Include="$(SourceDirectory)\ProtocolBuffers.Serialization\bin" />
<TempBuildFolder Include="$(SourceDirectory)\ProtocolBuffers.Test\obj" />
<TempBuildFolder Include="$(SourceDirectory)\ProtocolBuffers.Test\bin" />
<TempBuildFolder Include="$(SourceDirectory)\ProtocolBuffersLite.Test\obj" />
<TempBuildFolder Include="$(SourceDirectory)\ProtocolBuffersLite.Test\bin" />
<TempBuildFolder Include="$(SourceDirectory)\ProtoDump\obj" />
<TempBuildFolder Include="$(SourceDirectory)\ProtoDump\bin" />
<TempBuildFolder Include="$(SourceDirectory)\ProtoGen\obj" />
<TempBuildFolder Include="$(SourceDirectory)\ProtoGen\bin" />
<TempBuildFolder Include="$(SourceDirectory)\ProtoGen.Test\obj" />
<TempBuildFolder Include="$(SourceDirectory)\ProtoGen.Test\bin" />
<TempBuildFolder Include="$(SourceDirectory)\ProtoMunge\obj" />
<TempBuildFolder Include="$(SourceDirectory)\ProtoMunge\bin" />
</ItemGroup>
</Project>

@ -1,248 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2006, 2007 Google Inc. All Rights Reserved.
# Author: danderson@google.com (David Anderson)
#
# Script for uploading files to a Google Code project.
#
# This is intended to be both a useful script for people who want to
# streamline project uploads and a reference implementation for
# uploading files to Google Code projects.
#
# To upload a file to Google Code, you need to provide a path to the
# file on your local machine, a small summary of what the file is, a
# project name, and a valid account that is a member or owner of that
# project. You can optionally provide a list of labels that apply to
# the file. The file will be uploaded under the same name that it has
# in your local filesystem (that is, the "basename" or last path
# component). Run the script with '--help' to get the exact syntax
# and available options.
#
# Note that the upload script requests that you enter your
# googlecode.com password. This is NOT your Gmail account password!
# This is the password you use on googlecode.com for committing to
# Subversion and uploading files. You can find your password by going
# to http://code.google.com/hosting/settings when logged in with your
# Gmail account. If you have already committed to your project's
# Subversion repository, the script will automatically retrieve your
# credentials from there (unless disabled, see the output of '--help'
# for details).
#
# If you are looking at this script as a reference for implementing
# your own Google Code file uploader, then you should take a look at
# the upload() function, which is the meat of the uploader. You
# basically need to build a multipart/form-data POST request with the
# right fields and send it to https://PROJECT.googlecode.com/files .
# Authenticate the request using HTTP Basic authentication, as is
# shown below.
#
# Licensed under the terms of the Apache Software License 2.0:
# http://www.apache.org/licenses/LICENSE-2.0
#
# Questions, comments, feature requests and patches are most welcome.
# Please direct all of these to the Google Code users group:
# http://groups.google.com/group/google-code-hosting
"""Google Code file uploader script.
"""
__author__ = 'danderson@google.com (David Anderson)'
import httplib
import os.path
import optparse
import getpass
import base64
import sys
def upload(file, project_name, user_name, password, summary, labels=None):
"""Upload a file to a Google Code project's file server.
Args:
file: The local path to the file.
project_name: The name of your project on Google Code.
user_name: Your Google account name.
password: The googlecode.com password for your account.
Note that this is NOT your global Google Account password!
summary: A small description for the file.
labels: an optional list of label strings with which to tag the file.
Returns: a tuple:
http_status: 201 if the upload succeeded, something else if an
error occured.
http_reason: The human-readable string associated with http_status
file_url: If the upload succeeded, the URL of the file on Google
Code, None otherwise.
"""
# The login is the user part of user@gmail.com. If the login provided
# is in the full user@domain form, strip it down.
if user_name.endswith('@gmail.com'):
user_name = user_name[:user_name.index('@gmail.com')]
form_fields = [('summary', summary)]
if labels is not None:
form_fields.extend([('label', l.strip()) for l in labels])
content_type, body = encode_upload_request(form_fields, file)
upload_host = '%s.googlecode.com' % project_name
upload_uri = '/files'
auth_token = base64.b64encode('%s:%s'% (user_name, password))
headers = {
'Authorization': 'Basic %s' % auth_token,
'User-Agent': 'Googlecode.com uploader v0.9.4',
'Content-Type': content_type,
}
server = httplib.HTTPSConnection(upload_host)
server.request('POST', upload_uri, body, headers)
resp = server.getresponse()
server.close()
if resp.status == 201:
location = resp.getheader('Location', None)
else:
location = None
return resp.status, resp.reason, location
def encode_upload_request(fields, file_path):
"""Encode the given fields and file into a multipart form body.
fields is a sequence of (name, value) pairs. file is the path of
the file to upload. The file will be uploaded to Google Code with
the same file name.
Returns: (content_type, body) ready for httplib.HTTP instance
"""
BOUNDARY = '----------Googlecode_boundary_reindeer_flotilla'
CRLF = '\r\n'
body = []
# Add the metadata about the upload first
for key, value in fields:
body.extend(
['--' + BOUNDARY,
'Content-Disposition: form-data; name="%s"' % key,
'',
value,
])
# Now add the file itself
file_name = os.path.basename(file_path)
f = open(file_path, 'rb')
file_content = f.read()
f.close()
body.extend(
['--' + BOUNDARY,
'Content-Disposition: form-data; name="filename"; filename="%s"'
% file_name,
# The upload server determines the mime-type, no need to set it.
'Content-Type: application/octet-stream',
'',
file_content,
])
# Finalize the form body
body.extend(['--' + BOUNDARY + '--', ''])
return 'multipart/form-data; boundary=%s' % BOUNDARY, CRLF.join(body)
def upload_find_auth(file_path, project_name, summary, labels=None,
user_name=None, password=None, tries=3):
"""Find credentials and upload a file to a Google Code project's file server.
file_path, project_name, summary, and labels are passed as-is to upload.
Args:
file_path: The local path to the file.
project_name: The name of your project on Google Code.
summary: A small description for the file.
labels: an optional list of label strings with which to tag the file.
config_dir: Path to Subversion configuration directory, 'none', or None.
user_name: Your Google account name.
tries: How many attempts to make.
"""
while tries > 0:
if user_name is None:
# Read username if not specified or loaded from svn config, or on
# subsequent tries.
sys.stdout.write('Please enter your googlecode.com username: ')
sys.stdout.flush()
user_name = sys.stdin.readline().rstrip()
if password is None:
# Read password if not loaded from svn config, or on subsequent tries.
print 'Please enter your googlecode.com password.'
print '** Note that this is NOT your Gmail account password! **'
print 'It is the password you use to access Subversion repositories,'
print 'and can be found here: http://code.google.com/hosting/settings'
password = getpass.getpass()
status, reason, url = upload(file_path, project_name, user_name, password,
summary, labels)
# Returns 403 Forbidden instead of 401 Unauthorized for bad
# credentials as of 2007-07-17.
if status in [httplib.FORBIDDEN, httplib.UNAUTHORIZED]:
# Rest for another try.
user_name = password = None
tries = tries - 1
else:
# We're done.
break
return status, reason, url
def main():
parser = optparse.OptionParser(usage='googlecode-upload.py -s SUMMARY '
'-p PROJECT [options] FILE')
parser.add_option('-s', '--summary', dest='summary',
help='Short description of the file')
parser.add_option('-p', '--project', dest='project',
help='Google Code project name')
parser.add_option('-u', '--user', dest='user',
help='Your Google Code username')
parser.add_option('-w', '--password', dest='password',
help='Your Google Code password')
parser.add_option('-l', '--labels', dest='labels',
help='An optional list of comma-separated labels to attach '
'to the file')
options, args = parser.parse_args()
if not options.summary:
parser.error('File summary is missing.')
elif not options.project:
parser.error('Project name is missing.')
elif len(args) < 1:
parser.error('File to upload not provided.')
elif len(args) > 1:
parser.error('Only one file may be specified.')
file_path = args[0]
if options.labels:
labels = options.labels.split(',')
else:
labels = None
status, reason, url = upload_find_auth(file_path, options.project,
options.summary, labels,
options.user, options.password)
if url:
print 'The file was uploaded successfully.'
print 'URL: %s' % url
return 0
else:
print 'An error occurred. Your file was not uploaded.'
print 'Google Code upload server said: %s (%s)' % (reason, status)
return 1
if __name__ == '__main__':
sys.exit(main())

@ -1,79 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- original location: https://hg01.codeplex.com/nuget/raw-file/tip/src/Core/Authoring/nuspec.xsd -->
<xs:schema id="nuspec" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="package">
<xs:complexType>
<xs:sequence>
<xs:element name="metadata" maxOccurs="1" minOccurs="1">
<xs:complexType>
<xs:all>
<xs:element name="id" maxOccurs="1" minOccurs="1" type="xs:string" />
<xs:element name="version" maxOccurs="1" minOccurs="1" type="xs:string" />
<xs:element name="title" maxOccurs="1" minOccurs="0" type="xs:string" />
<xs:element name="authors" maxOccurs="1" minOccurs="1" type="xs:string" />
<xs:element name="owners" maxOccurs="1" minOccurs="0" type="xs:string" />
<xs:element name="licenseUrl" maxOccurs="1" minOccurs="0" type="xs:anyURI" />
<xs:element name="projectUrl" maxOccurs="1" minOccurs="0" type="xs:anyURI" />
<xs:element name="iconUrl" maxOccurs="1" minOccurs="0" type="xs:anyURI" />
<xs:element name="requireLicenseAcceptance" maxOccurs="1" minOccurs="0" type="xs:boolean" />
<xs:element name="description" maxOccurs="1" minOccurs="1" type="xs:string" />
<xs:element name="summary" maxOccurs="1" minOccurs="0" type="xs:string" />
<xs:element name="releaseNotes" maxOccurs="1" minOccurs="0" type="xs:string" />
<xs:element name="copyright" maxOccurs="1" minOccurs="0" type="xs:string" />
<xs:element name="language" maxOccurs="1" minOccurs="0" type="xs:string" default="en-US" />
<xs:element name="tags" maxOccurs="1" minOccurs="0" type="xs:string" />
<xs:element name="dependencies" maxOccurs="1" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="dependency" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="id" type="xs:string" use="required" />
<xs:attribute name="version" type="xs:string" use="optional" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="frameworkAssemblies" maxOccurs="1" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="frameworkAssembly" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="assemblyName" type="xs:string" use="required" />
<xs:attribute name="targetFramework" type="xs:string" use="optional" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="references" maxOccurs="1" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="reference" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="file" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:all>
</xs:complexType>
</xs:element>
<xs:element name="files" minOccurs="0" maxOccurs="1" nillable="true">
<xs:complexType>
<xs:sequence>
<xs:element name="file" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="src" use="required" type="xs:string" />
<xs:attribute name="target" use="optional" type="xs:string" />
<xs:attribute name="exclude" use="optional" type="xs:string" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

@ -1,186 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Publish" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- build targets -->
<Target Name="Clean" DependsOnTargets="_Clean" />
<Target Name="Build" DependsOnTargets="_Clean;_Prerequisites;_StampVersion;_GenerateSource;_Build" />
<Target Name="Label" DependsOnTargets="_HgLabel" />
<Target Name="Package" DependsOnTargets="_HgPack;_NugetPack" />
<Target Name="Prepare" DependsOnTargets="Clean;Build;Label;Package" />
<Target Name="PushAll" DependsOnTargets="_HgPush;_NugetPush" />
<Target Name="Publish" DependsOnTargets="Prepare;PushAll" />
<PropertyGroup>
<ProjectName>Protocol Buffers</ProjectName>
<VersionMajor>2</VersionMajor>
<VersionMinor>4</VersionMinor>
<VersionBuild>1</VersionBuild>
<VersionRevision></VersionRevision>
<VersionLabel></VersionLabel>
<PackagePrefix>protobuf-csharp-port-</PackagePrefix>
<PublishDebug>false</PublishDebug>
<GoogleUsername></GoogleUsername>
<GooglePassword></GooglePassword>
<!--Directory Paths-->
<ProjectDirectory>$(MSBuildProjectDirectory)\..</ProjectDirectory>
<BuildTempDirectory>$(ProjectDirectory)\build_temp</BuildTempDirectory>
<BuildOutputDirectory>$(ProjectDirectory)\build_output</BuildOutputDirectory>
<SourceDirectory>$(ProjectDirectory)\src</SourceDirectory>
<LibDirectory>$(ProjectDirectory)\lib</LibDirectory>
<!-- File Paths -->
<SigningKey>$(ProjectDirectory)\release-key\Google.ProtocolBuffers.snk</SigningKey>
<!--Tool Paths-->
<HgTool>hg.exe</HgTool>
<Python>C:\Python25\python.exe</Python>
<SnTool>$(registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.0A@InstallationFolder)Bin\sn.exe</SnTool>
<StampVer>$(LibDirectory)\StampVersion.exe</StampVer>
<ZipExePath>$(LibDirectory)\7-Zip 9.20\7za.exe</ZipExePath>
<NuGet>$(LibDirectory)\NuGet.exe</NuGet>
<ProtogenExePath>$(BuildOutputDirectory)\tools\protogen.exe</ProtogenExePath>
</PropertyGroup>
<!-- Import user settings -->
<Import Project="$(MSBuildProjectFullPath).user" Condition="Exists('$(MSBuildProjectFullPath).user')" />
<!-- Files -->
<ItemGroup>
</ItemGroup>
<!-- Tasks -->
<Target Name="_Prerequisites" DependsOnTargets="_CheckEnvironment;_ReadVersion" />
<Target Name="_Clean">
<MSBuild Properties="Configuration=Debug;" Targets="Clean" Projects="$(MSBuildProjectDirectory)\target.csproj" />
<MSBuild Properties="Configuration=Release;" Targets="Clean" Projects="$(MSBuildProjectDirectory)\target.csproj" />
<MakeDir Directories="$(BuildTempDirectory)" />
<MakeDir Directories="$(BuildOutputDirectory)" />
</Target>
<Target Name="_WriteUserConfig">
<ItemGroup>
<Lines Include="&lt;Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>" />
<Lines Include=" &lt;PropertyGroup>"/>
<Lines Include=" &lt;GoogleUsername> (Enter your google-code user/password here) &lt;/GoogleUsername>"/>
<Lines Include=" &lt;GooglePassword>&lt;/GooglePassword>"/>
<Lines Include=" &lt;/PropertyGroup>" />
<Lines Include="&lt;/Project>" />
</ItemGroup>
<WriteLinesToFile File="$(MSBuildProjectFullPath).user" Lines="@(Lines)" Overwrite="true" Condition="!Exists('$(MSBuildProjectFullPath).user')" />
<Exec Command="Notepad.exe $(MSBuildProjectFullPath).user" />
</Target>
<Target Name="_CheckEnvironment">
<!-- Require google credentials -->
<CallTarget Targets="_WriteUserConfig" Condition=" '$(GooglePassword)' == '' " />
<Error Text="Restart after you verify your credentials in $(MSBuildProjectFullPath).user" Condition=" '$(GooglePassword)' == '' " />
<!-- Require Win7.0A SDK to verify strong-name -->
<Error Text="Unable to locate Win7SDK Tools: $(SnTool)" Condition="!Exists($(SnTool))" />
<!-- Require Python 2.5 installed -->
<!-- Error Text="Unable to locate Python 2.5: $(Python)" Condition="!Exists($(Python))" / -->
<!-- Require production signing key -->
<Exec Command="$(HgTool) clone https://bitbucket.org/rknapp/protobuf-csharp-port-keyfile $(ProjectDirectory)\release-key" Condition="!Exists('$(SigningKey)')" />
<Error Text="Unable to locate release signing key: $(SigningKey)" Condition="!Exists($(SigningKey))" />
</Target>
<Target Name="_ReadVersion" Condition=" '$(VersionLabel)' == '' ">
<Exec Command="$(HgTool) log -l 1 --template &quot;{rev}&quot; > &quot;$(BuildTempDirectory)\revision.txt&quot;"></Exec>
<ReadLinesFromFile File="$(BuildTempDirectory)\revision.txt">
<Output TaskParameter="Lines" PropertyName="VersionRevision"/>
</ReadLinesFromFile>
<PropertyGroup>
<VersionLabel>$(VersionMajor).$(VersionMinor).$(VersionBuild).$(VersionRevision)</VersionLabel>
</PropertyGroup>
<Message Text="Building version $(VersionLabel)" Importance="high" />
</Target>
<Target Name="_StampVersion" DependsOnTargets="_Prerequisites">
<Exec Command="$(StampVer) /major:$(VersionMajor) /minor:$(VersionMinor) /build:$(VersionBuild) /revision:$(VersionRevision)" WorkingDirectory="$(SourceDirectory)" />
<Exec Command="FIND &quot;$(VersionLabel)&quot; ProtocolBuffers\Properties\AssemblyInfo.cs" WorkingDirectory="$(SourceDirectory)" />
</Target>
<Target Name="_GenerateSource" DependsOnTargets="_Prerequisites">
<MSBuild Properties="Configuration=Release;AssemblyOriginatorKeyFile=$(SigningKey)" Targets="GenerateProjects;BuildTools;GenerateSource" Projects="$(MSBuildProjectDirectory)\build.csproj" />
<Exec Command="&quot;$(SnTool)&quot; -T &quot;$(ProtogenExePath)&quot; > signkey.txt" WorkingDirectory="$(BuildTempDirectory)" />
<!-- Make sure we are signing with the correct key -->
<Exec Command="FIND &quot;55f7125234beb589&quot; signkey.txt" WorkingDirectory="$(BuildTempDirectory)" />
</Target>
<Target Name="_Build" DependsOnTargets="_Prerequisites">
<!-- Release Build -->
<MSBuild Properties="Configuration=Release;AssemblyOriginatorKeyFile=$(SigningKey)" Targets="_CompileAll" Projects="$(MSBuildProjectDirectory)\build.csproj" />
<MSBuild Properties="Configuration=Release;AssemblyOriginatorKeyFile=$(SigningKey);PackageName=$(PackagePrefix)$(VersionLabel)-release" Targets="GeneratePackage" Projects="$(MSBuildProjectDirectory)\build.csproj" />
<!-- Debug Build -->
<MSBuild Condition=" '$(PublishDebug)' == 'true' " Properties="Configuration=Debug;AssemblyOriginatorKeyFile=$(SigningKey)" Targets="_CompileAll" Projects="$(MSBuildProjectDirectory)\build.csproj" />
<MSBuild Condition=" '$(PublishDebug)' == 'true' " Properties="Configuration=Debug;AssemblyOriginatorKeyFile=$(SigningKey);PackageName=$(PackagePrefix)$(VersionLabel)-full" Targets="GeneratePackage" Projects="$(MSBuildProjectDirectory)\build.csproj" />
</Target>
<Target Name="_HgPack" DependsOnTargets="_Prerequisites">
<Exec Command="$(HgTool) archive $(BuildTempDirectory)\$(PackagePrefix)$(VersionLabel)-source.zip" WorkingDirectory="$(ProjectDirectory)" />
</Target>
<Target Name="_HgLabel" DependsOnTargets="_Prerequisites">
<Exec Command="$(HgTool) commit -m &quot;version $(VersionLabel)&quot;" WorkingDirectory="$(ProjectDirectory)" />
<Exec Command="$(HgTool) tag $(VersionLabel)" WorkingDirectory="$(ProjectDirectory)" />
</Target>
<Target Name="_HgPush" DependsOnTargets="_Prerequisites">
<Exec Command="$(HgTool) push" WorkingDirectory="$(ProjectDirectory)" />
</Target>
<Target Name="_PkgPush" DependsOnTargets="_Prerequisites">
<PropertyGroup>
<UploadPackage>$(Python) "$(MSBuildProjectDirectory)\googlecode_upload.py" --project protobuf-csharp-port --user "$(GoogleUsername)" --password "$(GooglePassword)"</UploadPackage>
<SourcePackage>$(BuildTempDirectory)\$(PackagePrefix)$(VersionLabel)-source.zip</SourcePackage>
<ReleasePackageBin>$(BuildTempDirectory)\$(PackagePrefix)$(VersionLabel)-release-binaries.zip</ReleasePackageBin>
<ReleasePackageSyb>$(BuildTempDirectory)\$(PackagePrefix)$(VersionLabel)-release-symbols.zip</ReleasePackageSyb>
<DebugPackageBin>$(BuildTempDirectory)\$(PackagePrefix)$(VersionLabel)-full-binaries.zip</DebugPackageBin>
<DebugPackageSyb>$(BuildTempDirectory)\$(PackagePrefix)$(VersionLabel)-full-symbols.zip</DebugPackageSyb>
</PropertyGroup>
<Error Condition="!Exists('$(SourcePackage)')" Text="File not found: $(SourcePackage)" />
<Error Condition="!Exists('$(ReleasePackageBin)')" Text="File not found: $(ReleasePackageBin)" />
<Error Condition="!Exists('$(ReleasePackageSyb)')" Text="File not found: $(ReleasePackageSyb)" />
<Error Condition="'$(PublishDebug)' == 'true' And !Exists('$(DebugPackageBin)')" Text="File not found: $(DebugPackageBin)" />
<Error Condition="'$(PublishDebug)' == 'true' And !Exists('$(DebugPackageSyb)')" Text="File not found: $(DebugPackageSyb)" />
<Exec WorkingDirectory="$(ProjectDirectory)"
Command="$(UploadPackage) --labels Type-Source,Featured --summary &quot;Version $(VersionLabel) source&quot; $(SourcePackage)" />
<Exec WorkingDirectory="$(ProjectDirectory)"
Command="$(UploadPackage) --labels Type-Executable,Featured --summary &quot;Version $(VersionLabel) release binaries only&quot; $(ReleasePackageBin)" />
<Exec WorkingDirectory="$(ProjectDirectory)"
Command="$(UploadPackage) --labels Type-Executable,Featured --summary &quot;Version $(VersionLabel) release binaries and symbols&quot; $(ReleasePackageSyb)" />
<Exec WorkingDirectory="$(ProjectDirectory)" Condition=" '$(PublishDebug)' == 'true' "
Command="$(UploadPackage) --labels Type-Executable,Featured --summary &quot;Version $(VersionLabel) all binaries&quot; $(DebugPackageBin)" />
<Exec WorkingDirectory="$(ProjectDirectory)" Condition=" '$(PublishDebug)' == 'true' "
Command="$(UploadPackage) --labels Type-Executable,Featured --summary &quot;Version $(VersionLabel) all binaries and symbols&quot; $(DebugPackageSyb)" />
</Target>
<Target Name="_NugetPack" DependsOnTargets="_Prerequisites">
<Exec WorkingDirectory="$(MSBuildProjectDirectory)"
Command="$(NuGet) update -self" />
<Exec WorkingDirectory="$(MSBuildProjectDirectory)"
Command="$(NuGet) pack Google.ProtocolBuffers.nuspec -Symbols -Version $(VersionLabel) -NoPackageAnalysis -OutputDirectory $(BuildTempDirectory)" />
<Exec WorkingDirectory="$(MSBuildProjectDirectory)"
Command="$(NuGet) pack Google.ProtocolBuffersLite.nuspec -Symbols -Version $(VersionLabel) -NoPackageAnalysis -OutputDirectory $(BuildTempDirectory)" />
</Target>
<Target Name="_NugetPush" DependsOnTargets="_Prerequisites">
<Exec WorkingDirectory="$(BuildTempDirectory)" Command="$(NuGet) push Google.ProtocolBuffers.$(VersionLabel).nupkg" ContinueOnError="true" />
<Exec WorkingDirectory="$(BuildTempDirectory)" Command="$(NuGet) push Google.ProtocolBuffersLite.$(VersionLabel).nupkg" ContinueOnError="true" />
<Exec WorkingDirectory="$(BuildTempDirectory)" Command="$(NuGet) push Google.ProtocolBuffers.$(VersionLabel).symbols.nupkg" ContinueOnError="true" />
<Exec WorkingDirectory="$(BuildTempDirectory)" Command="$(NuGet) push Google.ProtocolBuffersLite.$(VersionLabel).symbols.nupkg" ContinueOnError="true" />
</Target>
</Project>

@ -1,167 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- **********************************************************************************************
High-level Targets
*********************************************************************************************** -->
<Target Name="Clean" DependsOnTargets="_Clean" />
<Target Name="Build" DependsOnTargets="_Compile;_Test" />
<Target Name="Test" DependsOnTargets="_Test" />
<Target Name="Rebuild" DependsOnTargets="Clean;Build" />
<Target Name="Publish" DependsOnTargets="Clean;Build;_Publish" />
<!-- **********************************************************************************************
Properties
*********************************************************************************************** -->
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">Any CPU</Platform>
<TargetVersion Condition=" '$(TargetVersion)' == '' ">NET20</TargetVersion>
<BuildParams></BuildParams>
<!--Directory Paths-->
<ProjectDirectory>$(MSBuildProjectDirectory)\..</ProjectDirectory>
<SourceDirectory>$(ProjectDirectory)\src</SourceDirectory>
<LibDirectory>$(ProjectDirectory)\lib</LibDirectory>
<!--File Paths-->
<BuildTempDirectory>$(ProjectDirectory)\build_temp\$(Configuration)\$(TargetVersion)</BuildTempDirectory>
<BuildOutputDirectory>$(ProjectDirectory)\build_output\$(Configuration)\$(TargetVersion)</BuildOutputDirectory>
<SolutionFile>$(SourceDirectory)\ProtocolBuffersLibrary.$(TargetVersion).sln</SolutionFile>
<!--Tool Paths-->
<NUnitExePath>$(LibDirectory)\NUnit\tools\nunit-console.exe</NUnitExePath>
<StatLightExePath>$(LibDirectory)\StatLight\tools\StatLight.exe</StatLightExePath>
</PropertyGroup>
<!-- **********************************************************************************************
Target Versions
*********************************************************************************************** -->
<PropertyGroup Condition=" '$(TargetVersion)' == 'NET20' ">
<BuildTools>3.5</BuildTools>
<TestFramework>NUNIT</TestFramework>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetVersion)' == 'NET35' ">
<BuildTools>3.5</BuildTools>
<TestFramework>NUNIT</TestFramework>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetVersion)' == 'NET40' ">
<BuildTools>4.0</BuildTools>
<TestFramework>NUNIT</TestFramework>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetVersion)' == 'CF20' ">
<BuildTools>3.5</BuildTools>
<TestFramework>NONE</TestFramework>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetVersion)' == 'CF35' ">
<BuildTools>3.5</BuildTools>
<TestFramework>NONE</TestFramework>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetVersion)' == 'SL20' ">
<BuildTools>3.5</BuildTools>
<TestFramework>SILVERLIGHT</TestFramework>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetVersion)' == 'SL30' ">
<BuildTools>3.5</BuildTools>
<TestFramework>SILVERLIGHT</TestFramework>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetVersion)' == 'SL40' ">
<BuildTools>4.0</BuildTools>
<TestFramework>SILVERLIGHT</TestFramework>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetVersion)' == 'PL40' ">
<BuildTools>4.0</BuildTools>
<TestFramework>SILVERLIGHT</TestFramework>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<BuildOutputDirectory>$(ProjectDirectory)\build_output\$(Configuration)\portable-net40+sl4+sl5+wp7+wp8+win8</BuildOutputDirectory>
</PropertyGroup>
<!-- **********************************************************************************************
File Groups
*********************************************************************************************** -->
<ItemGroup>
<WorkingDirectories Include="$(BuildTempDirectory)" />
<WorkingDirectories Include="$(BuildOutputDirectory)" />
<TestContainer Include="$(SourceDirectory)\ProtocolBuffers.Test\bin\$(TargetVersion)\$(Configuration)\Google.ProtocolBuffers.Test.dll" />
<TestContainer Include="$(SourceDirectory)\ProtocolBuffersLite.Test\bin\$(TargetVersion)\$(Configuration)\Google.ProtocolBuffersLite.Test.dll" />
<TestContainer Include="$(SourceDirectory)\ProtocolBuffersLite.Test\bin\$(TargetVersion)\$(Configuration)\Google.ProtocolBuffersMixedLite.Test.dll" />
<StatLightTestContainer Include="$(SourceDirectory)\ProtocolBuffers.Test\bin\$(TargetVersion)\$(Configuration)\Google.ProtocolBuffers.Test.xap" />
<StatLightTestContainer Include="$(SourceDirectory)\ProtocolBuffersLite.Test\bin\$(TargetVersion)\$(Configuration)\Google.ProtocolBuffersLite.Test.xap" />
<StatLightTestContainer Include="$(SourceDirectory)\ProtocolBuffersLite.Test\bin\$(TargetVersion)\$(Configuration)\Google.ProtocolBuffersMixedLite.Test.xap" />
<PublishItem Include="$(SourceDirectory)\ProtocolBuffers\bin\$(TargetVersion)\$(Configuration)\Google.ProtocolBuffers.dll" />
<PublishItem Include="$(SourceDirectory)\ProtocolBuffers\bin\$(TargetVersion)\$(Configuration)\Google.ProtocolBuffers.pdb" />
<PublishItem Include="$(SourceDirectory)\ProtocolBuffers\bin\$(TargetVersion)\$(Configuration)\Google.ProtocolBuffers.xml" />
<PublishItem Include="$(SourceDirectory)\ProtocolBuffers\bin\$(TargetVersion)\$(Configuration)\Google.ProtocolBuffersLite.dll" />
<PublishItem Include="$(SourceDirectory)\ProtocolBuffers\bin\$(TargetVersion)\$(Configuration)\Google.ProtocolBuffersLite.pdb" />
<PublishItem Include="$(SourceDirectory)\ProtocolBuffers\bin\$(TargetVersion)\$(Configuration)\Google.ProtocolBuffersLite.xml" />
<PublishItem Include="$(SourceDirectory)\ProtocolBuffers.Serialization\bin\$(TargetVersion)\$(Configuration)\Google.ProtocolBuffers.Serialization.dll" />
<PublishItem Include="$(SourceDirectory)\ProtocolBuffers.Serialization\bin\$(TargetVersion)\$(Configuration)\Google.ProtocolBuffers.Serialization.pdb" />
<PublishItem Include="$(SourceDirectory)\ProtocolBuffers.Serialization\bin\$(TargetVersion)\$(Configuration)\Google.ProtocolBuffers.Serialization.xml" />
<PublishItem Include="$(SourceDirectory)\ProtocolBuffers.Serialization\bin\$(TargetVersion)\$(Configuration)\Google.ProtocolBuffersLite.Serialization.dll" />
<PublishItem Include="$(SourceDirectory)\ProtocolBuffers.Serialization\bin\$(TargetVersion)\$(Configuration)\Google.ProtocolBuffersLite.Serialization.pdb" />
<PublishItem Include="$(SourceDirectory)\ProtocolBuffers.Serialization\bin\$(TargetVersion)\$(Configuration)\Google.ProtocolBuffersLite.Serialization.xml" />
</ItemGroup>
<!-- **********************************************************************************************
Targets For Build
*********************************************************************************************** -->
<Target Name="_Configured">
<Message Text="Building $(TargetVersion) for configuration $(Configuration), platform $(Platform)" Importance="normal" />
<Error Text="Unknown or missing value for TargetVersion=[value]" Condition=" '$(BuildTools)' == '' " />
</Target>
<Target Name="_Clean" DependsOnTargets="_Configured">
<RemoveDir Directories="@(WorkingDirectories)" Condition="Exists(%(WorkingDirectories.Identity))" />
<MSBuild Targets="Clean" Projects="$(SolutionFile)" ToolsVersion="$(BuildTools)"
Properties="Configuration=$(Configuration);Platform=$(Platform);"
/>
</Target>
<Target Name="_Compile" DependsOnTargets="_Configured">
<MSBuild Targets="Build" Projects="$(SolutionFile)" ToolsVersion="$(BuildTools)"
Properties="Configuration=$(Configuration);Platform=$(Platform);$(BuildParams)"
/>
</Target>
<Target Name="_Publish" DependsOnTargets="_Configured">
<MakeDir Directories="$(BuildOutputDirectory)" />
<Copy SourceFiles="@(PublishItem)" DestinationFolder="$(BuildOutputDirectory)" />
</Target>
<!-- **********************************************************************************************
Targets For Test
*********************************************************************************************** -->
<Target Name="_Test" DependsOnTargets="_Configured">
<MakeDir Directories="$(BuildTempDirectory)" />
<CallTarget Targets="_RunNunit" Condition=" '$(TestFramework)'=='NUNIT' " />
<CallTarget Targets="_RunStatLight" Condition=" '$(TestFramework)'=='SILVERLIGHT' " />
</Target>
<Target Name="_RunNunit">
<Copy SourceFiles="$(LibDirectory)\NUnit-config\nunit-console.$(TargetFrameworkVersion).config" DestinationFiles="$(NUnitExePath).config" />
<Exec Command="&quot;$(NUnitExePath)&quot; /nologo /noshadow &quot;%(TestContainer.Identity)&quot; /xml:&quot;$(BuildTempDirectory)\%(TestContainer.Filename).xml&quot;" />
</Target>
<Target Name="_RunStatLight">
<Exec
Command="&quot;$(StatLightExePath)&quot; -x %(StatLightTestContainer.Identity) --ReportOutputFileType=NUnit --ReportOutputFile=$(BuildTempDirectory)\%(StatLightTestContainer.Filename).xml" />
</Target>
</Project>

@ -0,0 +1,13 @@
@rem Builds Google.Protobuf NuGet packages
@rem Adjust the location of nuget.exe
set NUGET=C:\nuget\nuget.exe
@rem Build src/Google.Protobuf.sln solution in Release configuration first.
%NUGET% pack src\Google.Protobuf\Google.Protobuf.nuspec -Symbols || goto :error
goto :EOF
:error
echo Failed!
exit /b %errorlevel%

@ -6,17 +6,12 @@ NUNIT_CONSOLE=nunit-console
# The rest you can leave intact # The rest you can leave intact
CONFIG=Release CONFIG=Release
KEYFILE=../keys/Google.ProtocolBuffers.snk # TODO(jtattermusch): signing!
SRC=$(dirname $0)/src SRC=$(dirname $0)/src
set -ex set -ex
echo Building the solution. echo Building the solution.
xbuild /p:Configuration=$CONFIG $SRC/ProtocolBuffers.sln xbuild /p:Configuration=$CONFIG $SRC/Google.Protobuf.sln
echo Running tests. echo Running tests.
$NUNIT_CONSOLE $SRC/ProtocolBuffers.Test/bin/$CONFIG/Google.ProtocolBuffers.Test.dll $NUNIT_CONSOLE $SRC/Google.Protobuf.Test/bin/$CONFIG/Google.Protobuf.Test.dll
$NUNIT_CONSOLE $SRC/ProtocolBuffersLite.Test/bin/$CONFIG/Google.ProtocolBuffersLite.Test.dll
$NUNIT_CONSOLE $SRC/ProtocolBuffersLite.Test/bin/$CONFIG/Google.ProtocolBuffersMixedLite.Test.dll

@ -23,10 +23,10 @@ cd $(dirname $0)/..
# Windows and Unix. # Windows and Unix.
if [ -z "$PROTOC" ]; then if [ -z "$PROTOC" ]; then
# TODO(jonskeet): Use an array and a for loop instead? # TODO(jonskeet): Use an array and a for loop instead?
if [ -x vsprojects/Debug/protoc.exe ]; then if [ -x cmake/build/Debug/protoc.exe ]; then
PROTOC=vsprojects/Debug/protoc.exe PROTOC=cmake/build/Debug/protoc.exe
elif [ -x vsprojects/Release/protoc.exe ]; then elif [ -x cmake/build/Release/protoc.exe ]; then
PROTOC=vsprojects/Release/protoc.exe PROTOC=cmake/build/Release/protoc.exe
elif [ -x src/protoc ]; then elif [ -x src/protoc ]; then
PROTOC=src/protoc PROTOC=src/protoc
else else
@ -38,56 +38,36 @@ fi
# Descriptor proto # Descriptor proto
# TODO(jonskeet): Remove fixup # TODO(jonskeet): Remove fixup
cp src/google/protobuf/descriptor.proto src/google/protobuf/descriptor_proto_file.proto cp src/google/protobuf/descriptor.proto src/google/protobuf/descriptor_proto_file.proto
$PROTOC -Isrc --csharp_out=csharp/src/ProtocolBuffers/DescriptorProtos \ $PROTOC -Isrc --csharp_out=csharp/src/Google.Protobuf/Reflection \
src/google/protobuf/descriptor_proto_file.proto src/google/protobuf/descriptor_proto_file.proto
rm src/google/protobuf/descriptor_proto_file.proto rm src/google/protobuf/descriptor_proto_file.proto
$PROTOC -Isrc --csharp_out=csharp/src/Google.Protobuf/WellKnownTypes \
src/google/protobuf/any.proto \
src/google/protobuf/api.proto \
src/google/protobuf/duration.proto \
src/google/protobuf/empty.proto \
src/google/protobuf/field_mask.proto \
src/google/protobuf/source_context.proto \
src/google/protobuf/struct.proto \
src/google/protobuf/timestamp.proto \
src/google/protobuf/type.proto \
src/google/protobuf/wrappers.proto
# ProtocolBuffers.Test protos $PROTOC -Isrc --csharp_out=csharp/src/Google.Protobuf.Test/TestProtos \
$PROTOC -Isrc --csharp_out=csharp/src/ProtocolBuffers.Test/TestProtos \ src/google/protobuf/map_unittest_proto3.proto \
src/google/protobuf/unittest.proto \ src/google/protobuf/unittest_proto3.proto \
src/google/protobuf/unittest_custom_options.proto \ src/google/protobuf/unittest_import_proto3.proto \
src/google/protobuf/unittest_drop_unknown_fields.proto \ src/google/protobuf/unittest_import_public_proto3.proto \
src/google/protobuf/unittest_enormous_descriptor.proto \ src/google/protobuf/unittest_well_known_types.proto
src/google/protobuf/unittest_import.proto \
src/google/protobuf/unittest_import_public.proto \
src/google/protobuf/unittest_mset.proto \
src/google/protobuf/unittest_optimize_for.proto \
src/google/protobuf/unittest_no_field_presence.proto \
src/google/protobuf/unknown_enum_test.proto
$PROTOC -Icsharp/protos/extest --csharp_out=csharp/src/ProtocolBuffers.Test/TestProtos \
csharp/protos/extest/unittest_extras_xmltest.proto \
csharp/protos/extest/unittest_issues.proto
$PROTOC -Ibenchmarks --csharp_out=csharp/src/ProtocolBuffers.Test/TestProtos \ $PROTOC -Icsharp/protos --csharp_out=csharp/src/Google.Protobuf.Test/TestProtos \
benchmarks/google_size.proto \ csharp/protos/unittest_issues.proto
benchmarks/google_speed.proto
# ProtocolBuffersLite.Test protos
$PROTOC -Isrc --csharp_out=csharp/src/ProtocolBuffersLite.Test/TestProtos \
src/google/protobuf/unittest.proto \
src/google/protobuf/unittest_import.proto \
src/google/protobuf/unittest_import_lite.proto \
src/google/protobuf/unittest_import_public.proto \
src/google/protobuf/unittest_import_public_lite.proto \
src/google/protobuf/unittest_lite.proto \
src/google/protobuf/unittest_lite_imports_nonlite.proto
$PROTOC -Icsharp/protos/extest --csharp_out=csharp/src/ProtocolBuffersLite.Test/TestProtos \
csharp/protos/extest/unittest_extras_full.proto \
csharp/protos/extest/unittest_extras_lite.proto
# TODO(jonskeet): Remove fixup; see issue #307
sed -i -e 's/RepeatedFieldsGenerator\.Group/RepeatedFieldsGenerator.Types.Group/g' \
csharp/src/ProtocolBuffers.Test/TestProtos/Unittest.cs \
csharp/src/ProtocolBuffersLite.Test/TestProtos/Unittest.cs \
csharp/src/ProtocolBuffersLite.Test/TestProtos/UnittestLite.cs
# TODO(jonskeet): Remove fixup
sed -i -e 's/DescriptorProtos\.Descriptor\./DescriptorProtos.DescriptorProtoFile./g' \
csharp/src/ProtocolBuffers.Test/TestProtos/UnittestCustomOptions.cs
# AddressBook sample protos # AddressBook sample protos
$PROTOC -Iexamples --csharp_out=csharp/src/AddressBook \ $PROTOC -Iexamples --csharp_out=csharp/src/AddressBook \
examples/addressbook.proto examples/addressbook.proto
$PROTOC -Iconformance --csharp_out=csharp/src/Google.Protobuf.Conformance \
conformance/conformance.proto

@ -0,0 +1,5 @@
Contents
--------
- Google.Protobuf.public.snk:
Public key to verify strong name of Google.Protobuf assemblies.

@ -1,13 +0,0 @@
@ECHO OFF
IF EXIST "C:\Program Files\Microsoft SDKs\Windows\v7.0\Bin\sn.exe" GOTO FOUND
goto USEPATH
:FOUND
"C:\Program Files\Microsoft SDKs\Windows\v7.0\Bin\sn.exe" -k %~dp0\Google.ProtocolBuffers.snk
GOTO EXIT
:USEPATH
sn.exe -k %~dp0\Google.ProtocolBuffers.snk
GOTO EXIT
:EXIT

@ -1,71 +0,0 @@
syntax = "proto2";
package protobuf_unittest_extra;
option csharp_namespace = "Google.ProtocolBuffers.TestProtos";
option optimize_for = CODE_SIZE;
option java_package = "com.google.protobuf";
message TestInteropPerson {
required string name = 1;
required int32 id = 2;
optional string email = 3;
repeated int32 codes = 10 [packed=true];
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber {
required string number = 1;
optional PhoneType type = 2 [default = HOME];
}
repeated PhoneNumber phone = 4;
repeated group Addresses = 5 {
required string address = 1;
optional string address2 = 2;
required string city = 3;
required string state = 4;
required fixed32 zip = 5;
}
extensions 100 to 199;
}
message TestInteropEmployeeId {
required string number = 1;
}
extend TestInteropPerson {
// Note: changed from required to optional, as required fields are not
// permitted in extensions. (The fact that this was allowed in protogen
// before was almost certainly a bug.)
optional TestInteropEmployeeId employee_id = 126;
}
message TestMissingFieldsA {
required string name = 1;
required int32 id = 2;
optional string email = 3;
message SubA {
required int32 count = 5;
repeated string values = 6;
}
optional SubA testA = 11;
}
message TestMissingFieldsB {
required string name = 1;
required int32 id = 2;
optional string website = 4;
message SubB {
repeated string values = 7;
}
optional SubB testB = 12;
}

@ -1,115 +0,0 @@
syntax = "proto2";
package protobuf_unittest_extra;
option csharp_namespace = "Google.ProtocolBuffers.TestProtos";
option optimize_for = LITE_RUNTIME;
option java_package = "com.google.protobuf";
message TestRequiredLite {
required int32 d = 1;
required ExtraEnum en = 2 [default = DEFAULT];
}
enum ExtraEnum {
DEFAULT = 10;
EXLITE_FOO = 7;
EXLITE_BAR = 8;
EXLITE_BAZ = 9;
}
message TestInteropPersonLite {
required string name = 1;
required int32 id = 2;
optional string email = 3;
repeated int32 codes = 10 [packed=true];
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber {
required string number = 1;
optional PhoneType type = 2 [default = HOME];
}
repeated PhoneNumber phone = 4;
repeated group Addresses = 5 {
required string address = 1;
optional string address2 = 2;
required string city = 3;
required string state = 4;
required fixed32 zip = 5;
}
extensions 100 to 199;
}
message TestInteropEmployeeIdLite {
required string number = 1;
}
extend TestInteropPersonLite {
// Note: changed from required to optional, as required fields are not
// permitted in extensions. (The fact that this was allowed in protogen
// before was almost certainly a bug.)
optional TestInteropEmployeeIdLite employee_id_lite = 126;
}
/* Removed from unittest_lite.proto and added back here */
message TestUnpackedExtensionsLite {
extensions 1 to max;
}
message TestUnpackedTypesLite {
repeated int32 unpacked_int32 = 90;
repeated int64 unpacked_int64 = 91;
repeated uint32 unpacked_uint32 = 92;
repeated uint64 unpacked_uint64 = 93;
repeated sint32 unpacked_sint32 = 94;
repeated sint64 unpacked_sint64 = 95;
repeated fixed32 unpacked_fixed32 = 96;
repeated fixed64 unpacked_fixed64 = 97;
repeated sfixed32 unpacked_sfixed32 = 98;
repeated sfixed64 unpacked_sfixed64 = 99;
repeated float unpacked_float = 100;
repeated double unpacked_double = 101;
repeated bool unpacked_bool = 102;
repeated UnpackedTypesForeignEnumLite unpacked_enum = 103;
}
extend TestUnpackedExtensionsLite {
repeated int32 unpacked_int32_extension_lite = 90;
repeated int64 unpacked_int64_extension_lite = 91;
repeated uint32 unpacked_uint32_extension_lite = 92;
repeated uint64 unpacked_uint64_extension_lite = 93;
repeated sint32 unpacked_sint32_extension_lite = 94;
repeated sint64 unpacked_sint64_extension_lite = 95;
repeated fixed32 unpacked_fixed32_extension_lite = 96;
repeated fixed64 unpacked_fixed64_extension_lite = 97;
repeated sfixed32 unpacked_sfixed32_extension_lite = 98;
repeated sfixed64 unpacked_sfixed64_extension_lite = 99;
repeated float unpacked_float_extension_lite = 100;
repeated double unpacked_double_extension_lite = 101;
repeated bool unpacked_bool_extension_lite = 102;
repeated UnpackedTypesForeignEnumLite unpacked_enum_extension_lite = 103;
}
enum UnpackedTypesForeignEnumLite {
FOREIGN_LITE_FOO = 4;
FOREIGN_LITE_BAR = 5;
FOREIGN_LITE_BAZ = 6;
}
message BucketOfBytes {
optional bytes value = 1;
}
message BucketOfBytesEx {
optional bytes value = 1;
optional bytes value2 = 255;
}

@ -1,53 +0,0 @@
syntax = "proto2";
option csharp_namespace = "Google.ProtocolBuffers.TestProtos";
package protobuf_unittest_extra;
option optimize_for = SPEED;
enum EnumOptions {
ONE = 0;
TWO = 1;
THREE = 2;
}
message TestXmlChild {
repeated EnumOptions options = 3;
optional bytes binary = 4;
}
message TestXmlNoFields {
}
message TestXmlRescursive {
optional TestXmlRescursive child = 1;
}
message TestXmlMessage {
optional int64 number = 6;
repeated int32 numbers = 2;
optional string text = 3;
repeated string textlines = 700;
optional bool valid = 5;
optional TestXmlChild child = 1;
repeated group Children = 401 {
repeated EnumOptions options = 3;
optional bytes binary = 4;
}
extensions 100 to 199;
}
message TestXmlExtension {
required int32 number = 1;
}
extend TestXmlMessage {
optional EnumOptions extension_enum = 101;
optional string extension_text = 102;
repeated int32 extension_number = 103 [packed = true];
optional TestXmlExtension extension_message = 199;
}

@ -1,141 +0,0 @@
syntax = "proto2";
// These proto descriptors have at one time been reported as an issue or defect.
// They are kept here to replicate the issue, and continue to verify the fix.
// Issue: Non-"Google.Protobuffers" namespace will ensure that protobuffer library types are qualified
option csharp_namespace = "UnitTest.Issues.TestProtos";
package unittest_issues;
option optimize_for = SPEED;
// The following is a representative set of features
/*
enum EnumOptions {
ONE = 0;
TWO = 1;
THREE = 2;
}
message TestBasicChild
{
repeated EnumOptions options = 3;
optional bytes binary = 4;
}
message TestBasicNoFields {
}
message TestBasicRescursive {
optional TestBasicRescursive child = 1;
}
message TestBasicMessage {
optional int64 number = 6;
repeated int32 numbers = 2;
optional string text = 3;
repeated string textlines = 700;
optional bool valid = 5;
optional TestBasicChild child = 1;
repeated group Children = 401
{
repeated EnumOptions options = 3;
optional bytes binary = 4;
}
extensions 100 to 199;
}
message TestBasicExtension {
required int32 number = 1;
}
extend TestBasicMessage {
optional EnumOptions extension_enum = 101;
optional string extension_text = 102;
repeated int32 extension_number = 103 [packed = true];
optional TestBasicExtension extension_message = 199;
}
// Issue for non-qualified type reference in new services generation
option (google.protobuf.csharp_file_options).service_generator_type = IRPCDISPATCH;
service TestGenericService {
rpc Foo(TestBasicNoFields) returns (TestBasicMessage);
rpc Bar(TestBasicNoFields) returns (TestBasicMessage);
}
*/
// Old issue 13: http://code.google.com/p/protobuf-csharp-port/issues/detail?id=13
// New issue 309: https://github.com/google/protobuf/issues/309
// message A {
// optional int32 _A = 1;
// }
// message B {
// optional int32 B_ = 1;
// }
//message AB {
// optional int32 a_b = 1;
//}
// Similar issue with numeric names
// Java code failed too, so probably best for this to be a restriction.
// See https://github.com/google/protobuf/issues/308
// message NumberField {
// optional int32 _01 = 1;
// }
// Issue 28: Circular message dependencies result in null defaults for DefaultInstance
message MyMessageAReferenceB {
required MyMessageBReferenceA value = 1;
}
message MyMessageBReferenceA {
required MyMessageAReferenceB value = 1;
}
// issue 19 - negative enum values
enum NegativeEnum {
FiveBelow = -5;
MinusOne = -1;
Zero = 0;
}
message NegativeEnumMessage {
optional NegativeEnum value = 1;
repeated NegativeEnum values = 2;
repeated NegativeEnum packed_values = 3 [packed=true];
}
// Issue 21: http://code.google.com/p/protobuf-csharp-port/issues/detail?id=21
// Decorate fields with [deprecated=true] as [System.Obsolete]
message DeprecatedChild {
}
enum DeprecatedEnum {
one = 1;
}
message DeprecatedFieldsMessage {
optional int32 PrimitiveValue = 1 [deprecated = true];
repeated int32 PrimitiveArray = 2 [deprecated = true];
optional DeprecatedChild MessageValue = 3 [deprecated = true];
repeated DeprecatedChild MessageArray = 4 [deprecated = true];
optional DeprecatedEnum EnumValue = 5 [deprecated = true];
repeated DeprecatedEnum EnumArray = 6 [deprecated = true];
}
// Issue 45: http://code.google.com/p/protobuf-csharp-port/issues/detail?id=45
message ItemField {
optional int32 item = 1;
}

@ -0,0 +1,119 @@
syntax = "proto3";
// These proto descriptors have at one time been reported as an issue or defect.
// They are kept here to replicate the issue, and continue to verify the fix.
// Issue: Non-"Google.Protobuffers" namespace will ensure that protobuffer library types are qualified
option csharp_namespace = "UnitTest.Issues.TestProtos";
package unittest_issues;
option optimize_for = SPEED;
// Issue 307: when generating doubly-nested types, any references
// should be of the form A.Types.B.Types.C.
message Issue307 {
message NestedOnce {
message NestedTwice {
}
}
}
// Old issue 13: http://code.google.com/p/protobuf-csharp-port/issues/detail?id=13
// New issue 309: https://github.com/google/protobuf/issues/309
// message A {
// optional int32 _A = 1;
// }
// message B {
// optional int32 B_ = 1;
// }
//message AB {
// optional int32 a_b = 1;
//}
// Similar issue with numeric names
// Java code failed too, so probably best for this to be a restriction.
// See https://github.com/google/protobuf/issues/308
// message NumberField {
// optional int32 _01 = 1;
// }
// issue 19 - negative enum values
enum NegativeEnum {
NEGATIVE_ENUM_ZERO = 0;
FiveBelow = -5;
MinusOne = -1;
}
message NegativeEnumMessage {
NegativeEnum value = 1;
repeated NegativeEnum values = 2 [packed = false];
repeated NegativeEnum packed_values = 3 [packed=true];
}
// Issue 21: http://code.google.com/p/protobuf-csharp-port/issues/detail?id=21
// Decorate fields with [deprecated=true] as [System.Obsolete]
message DeprecatedChild {
}
enum DeprecatedEnum {
DEPRECATED_ZERO = 0;
one = 1;
}
message DeprecatedFieldsMessage {
int32 PrimitiveValue = 1 [deprecated = true];
repeated int32 PrimitiveArray = 2 [deprecated = true];
DeprecatedChild MessageValue = 3 [deprecated = true];
repeated DeprecatedChild MessageArray = 4 [deprecated = true];
DeprecatedEnum EnumValue = 5 [deprecated = true];
repeated DeprecatedEnum EnumArray = 6 [deprecated = true];
}
// Issue 45: http://code.google.com/p/protobuf-csharp-port/issues/detail?id=45
message ItemField {
int32 item = 1;
}
message ReservedNames {
// Force a nested type called Types
message SomeNestedType {
}
int32 types = 1;
int32 descriptor = 2;
}
message TestJsonFieldOrdering {
// These fields are deliberately not declared in numeric
// order, and the oneof fields aren't contiguous either.
// This allows for reasonably robust tests of JSON output
// ordering.
// TestFieldOrderings in unittest_proto3.proto is similar,
// but doesn't include oneofs.
// TODO: Consider adding oneofs to TestFieldOrderings, although
// that will require fixing other tests in multiple platforms.
// Alternatively, consider just adding this to
// unittest_proto3.proto if multiple platforms want it.
int32 plain_int32 = 4;
oneof o1 {
string o1_string = 2;
int32 o1_int32 = 5;
}
string plain_string = 1;
oneof o2 {
int32 o2_int32 = 6;
string o2_string = 3;
}
}

@ -1,10 +1,7 @@
#region Copyright notice and license #region Copyright notice and license
// Protocol Buffers - Google's data interchange format // Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved. // Copyright 2008 Google Inc. All rights reserved.
// http://github.com/jskeet/dotnet-protobufs/ // https://developers.google.com/protocol-buffers/
// Original C++/Java/Python code:
// http://code.google.com/p/protobuf/
// //
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are // modification, are permitted provided that the following conditions are
@ -31,13 +28,12 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion #endregion
using System; using System;
using System.IO; using System.IO;
namespace Google.ProtocolBuffers.Examples.AddressBook namespace Google.Protobuf.Examples.AddressBook
{ {
internal class AddPerson internal class AddPerson
{ {
@ -46,7 +42,7 @@ namespace Google.ProtocolBuffers.Examples.AddressBook
/// </summary> /// </summary>
private static Person PromptForAddress(TextReader input, TextWriter output) private static Person PromptForAddress(TextReader input, TextWriter output)
{ {
Person.Builder person = Person.CreateBuilder(); Person person = new Person();
output.Write("Enter person ID: "); output.Write("Enter person ID: ");
person.Id = int.Parse(input.ReadLine()); person.Id = int.Parse(input.ReadLine());
@ -70,8 +66,7 @@ namespace Google.ProtocolBuffers.Examples.AddressBook
break; break;
} }
Person.Types.PhoneNumber.Builder phoneNumber = Person.Types.PhoneNumber phoneNumber = new Person.Types.PhoneNumber { Number = number };
Person.Types.PhoneNumber.CreateBuilder().SetNumber(number);
output.Write("Is this a mobile, home, or work phone? "); output.Write("Is this a mobile, home, or work phone? ");
String type = input.ReadLine(); String type = input.ReadLine();
@ -91,9 +86,9 @@ namespace Google.ProtocolBuffers.Examples.AddressBook
break; break;
} }
person.AddPhone(phoneNumber); person.Phones.Add(phoneNumber);
} }
return person.Build(); return person;
} }
/// <summary> /// <summary>
@ -108,27 +103,28 @@ namespace Google.ProtocolBuffers.Examples.AddressBook
return -1; return -1;
} }
AddressBook.Builder addressBook = AddressBook.CreateBuilder(); AddressBook addressBook;
if (File.Exists(args[0])) if (File.Exists(args[0]))
{ {
using (Stream file = File.OpenRead(args[0])) using (Stream file = File.OpenRead(args[0]))
{ {
addressBook.MergeFrom(file); addressBook = AddressBook.Parser.ParseFrom(file);
} }
} }
else else
{ {
Console.WriteLine("{0}: File not found. Creating a new file.", args[0]); Console.WriteLine("{0}: File not found. Creating a new file.", args[0]);
addressBook = new AddressBook();
} }
// Add an address. // Add an address.
addressBook.AddPerson(PromptForAddress(Console.In, Console.Out)); addressBook.People.Add(PromptForAddress(Console.In, Console.Out));
// Write the new address book back to disk. // Write the new address book back to disk.
using (Stream output = File.OpenWrite(args[0])) using (Stream output = File.OpenWrite(args[0]))
{ {
addressBook.Build().WriteTo(output); addressBook.WriteTo(output);
} }
return 0; return 0;
} }

@ -8,12 +8,13 @@
<ProjectGuid>{A31F5FB2-4FF3-432A-B35B-5CD203606311}</ProjectGuid> <ProjectGuid>{A31F5FB2-4FF3-432A-B35B-5CD203606311}</ProjectGuid>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder> <AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Google.ProtocolBuffers.Examples.AddressBook</RootNamespace> <RootNamespace>Google.Protobuf.Examples.AddressBook</RootNamespace>
<AssemblyName>AddressBook</AssemblyName> <AssemblyName>AddressBook</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion> <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<StartupObject>Google.ProtocolBuffers.Examples.AddressBook.Program</StartupObject> <StartupObject>Google.Protobuf.Examples.AddressBook.Program</StartupObject>
<TargetFrameworkProfile>Client</TargetFrameworkProfile> <TargetFrameworkProfile>
</TargetFrameworkProfile>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
@ -26,6 +27,7 @@
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<NoStdLib>true</NoStdLib> <NoStdLib>true</NoStdLib>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies> <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType> <DebugType>pdbonly</DebugType>
@ -37,6 +39,7 @@
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<NoStdLib>true</NoStdLib> <NoStdLib>true</NoStdLib>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies> <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="mscorlib" /> <Reference Include="mscorlib" />
@ -53,9 +56,9 @@
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\ProtocolBuffers\ProtocolBuffers.csproj"> <ProjectReference Include="..\Google.Protobuf\Google.Protobuf.csproj">
<Project>{6908BDCE-D925-43F3-94AC-A531E6DF2591}</Project> <Project>{6908BDCE-D925-43F3-94AC-A531E6DF2591}</Project>
<Name>ProtocolBuffers</Name> <Name>Google.Protobuf</Name>
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

File diff suppressed because it is too large Load Diff

@ -1,10 +1,7 @@
#region Copyright notice and license #region Copyright notice and license
// Protocol Buffers - Google's data interchange format // Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved. // Copyright 2008 Google Inc. All rights reserved.
// http://github.com/jskeet/dotnet-protobufs/ // https://developers.google.com/protocol-buffers/
// Original C++/Java/Python code:
// http://code.google.com/p/protobuf/
// //
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are // modification, are permitted provided that the following conditions are
@ -31,13 +28,12 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion #endregion
using System; using System;
using System.IO; using System.IO;
namespace Google.ProtocolBuffers.Examples.AddressBook namespace Google.Protobuf.Examples.AddressBook
{ {
internal class ListPeople internal class ListPeople
{ {
@ -46,16 +42,16 @@ namespace Google.ProtocolBuffers.Examples.AddressBook
/// </summary> /// </summary>
private static void Print(AddressBook addressBook) private static void Print(AddressBook addressBook)
{ {
foreach (Person person in addressBook.PersonList) foreach (Person person in addressBook.People)
{ {
Console.WriteLine("Person ID: {0}", person.Id); Console.WriteLine("Person ID: {0}", person.Id);
Console.WriteLine(" Name: {0}", person.Name); Console.WriteLine(" Name: {0}", person.Name);
if (person.HasEmail) if (person.Email != "")
{ {
Console.WriteLine(" E-mail address: {0}", person.Email); Console.WriteLine(" E-mail address: {0}", person.Email);
} }
foreach (Person.Types.PhoneNumber phoneNumber in person.PhoneList) foreach (Person.Types.PhoneNumber phoneNumber in person.Phones)
{ {
switch (phoneNumber.Type) switch (phoneNumber.Type)
{ {
@ -94,7 +90,7 @@ namespace Google.ProtocolBuffers.Examples.AddressBook
// Read the existing address book. // Read the existing address book.
using (Stream stream = File.OpenRead(args[0])) using (Stream stream = File.OpenRead(args[0]))
{ {
AddressBook addressBook = AddressBook.ParseFrom(stream); AddressBook addressBook = AddressBook.Parser.ParseFrom(stream);
Print(addressBook); Print(addressBook);
} }
return 0; return 0;

@ -1,10 +1,7 @@
#region Copyright notice and license #region Copyright notice and license
// Protocol Buffers - Google's data interchange format // Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved. // Copyright 2008 Google Inc. All rights reserved.
// http://github.com/jskeet/dotnet-protobufs/ // https://developers.google.com/protocol-buffers/
// Original C++/Java/Python code:
// http://code.google.com/p/protobuf/
// //
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are // modification, are permitted provided that the following conditions are
@ -31,12 +28,11 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion #endregion
using System; using System;
namespace Google.ProtocolBuffers.Examples.AddressBook namespace Google.Protobuf.Examples.AddressBook
{ {
/// <summary> /// <summary>
/// Entry point. Repeatedly prompts user for an action to take, delegating actual behaviour /// Entry point. Repeatedly prompts user for an action to take, delegating actual behaviour

@ -10,20 +10,9 @@ using System.Runtime.InteropServices;
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")] [assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AddressBook")] [assembly: AssemblyProduct("AddressBook")]
[assembly: AssemblyCopyright("Copyright © 2008")] [assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
// Version information for an assembly consists of the following four values: [assembly: AssemblyVersion("3.0.0.0")]
// [assembly: AssemblyFileVersion("3.0.0.0")]
// 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,44 +1,70 @@
using System; #region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2008 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
using System;
using System.IO; using System.IO;
namespace Google.ProtocolBuffers.Examples.AddressBook namespace Google.Protobuf.Examples.AddressBook
{ {
internal class SampleUsage internal class SampleUsage
{ {
private static void Main() private static void Main()
{ {
byte[] bytes; byte[] bytes;
//Create a builder to start building a message // Create a new person
Person.Builder newContact = Person.CreateBuilder(); Person person = new Person
//Set the primitive properties {
newContact.SetId(1) Id = 1,
.SetName("Foo") Name = "Foo",
.SetEmail("foo@bar"); Email = "foo@bar",
//Now add an item to a list (repeating) field Phones = { new Person.Types.PhoneNumber { Number = "555-1212" } }
newContact.AddPhone( };
//Create the child message inline
Person.Types.PhoneNumber.CreateBuilder().SetNumber("555-1212").Build()
);
//Now build the final message:
Person person = newContact.Build();
//The builder is no longer valid (at least not now, scheduled for 2.4):
newContact = null;
using (MemoryStream stream = new MemoryStream()) using (MemoryStream stream = new MemoryStream())
{ {
//Save the person to a stream // Save the person to a stream
person.WriteTo(stream); person.WriteTo(stream);
bytes = stream.ToArray(); bytes = stream.ToArray();
} }
//Create another builder, merge the byte[], and build the message: Person copy = Person.Parser.ParseFrom(bytes);
Person copy = Person.CreateBuilder().MergeFrom(bytes).Build();
//A more streamlined approach might look like this: // A more streamlined approach might look like this:
bytes = AddressBook.CreateBuilder().AddPerson(copy).Build().ToByteArray(); bytes = copy.ToByteArray();
//And read the address book back again // And read the address book back again
AddressBook restored = AddressBook.CreateBuilder().MergeFrom(bytes).Build(); AddressBook restored = AddressBook.Parser.ParseFrom(bytes);
//The message performs a deep-comparison on equality: // The message performs a deep-comparison on equality:
if (restored.PersonCount != 1 || !person.Equals(restored.PersonList[0])) if (restored.People.Count != 1 || !person.Equals(restored.People[0]))
{
throw new ApplicationException("There is a bad person in here!"); throw new ApplicationException("There is a bad person in here!");
}
} }
} }
} }

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

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

File diff suppressed because it is too large Load Diff

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

@ -0,0 +1,126 @@
#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
using Conformance;
using System;
using System.IO;
namespace Google.Protobuf.Conformance
{
/// <summary>
/// Conformance tests. The test runner will provide JSON or proto data on stdin,
/// and this program will produce its output on stdout.
/// </summary>
class Program
{
private static void Main(string[] args)
{
// This way we get the binary streams instead of readers/writers.
var input = new BinaryReader(Console.OpenStandardInput());
var output = new BinaryWriter(Console.OpenStandardOutput());
int count = 0;
while (RunTest(input, output))
{
count++;
}
Console.Error.WriteLine("Received EOF after {0} tests", count);
}
private static bool RunTest(BinaryReader input, BinaryWriter output)
{
int? size = ReadInt32(input);
if (size == null)
{
return false;
}
byte[] inputData = input.ReadBytes(size.Value);
if (inputData.Length != size.Value)
{
throw new EndOfStreamException("Read " + inputData.Length + " bytes of data when expecting " + size);
}
ConformanceRequest request = ConformanceRequest.Parser.ParseFrom(inputData);
ConformanceResponse response = PerformRequest(request);
byte[] outputData = response.ToByteArray();
output.Write(outputData.Length);
output.Write(outputData);
// Ready for another test...
return true;
}
private static ConformanceResponse PerformRequest(ConformanceRequest request)
{
TestAllTypes message;
switch (request.PayloadCase)
{
case ConformanceRequest.PayloadOneofCase.JsonPayload:
return new ConformanceResponse { Skipped = "JSON parsing not implemented in C# yet" };
case ConformanceRequest.PayloadOneofCase.ProtobufPayload:
try
{
message = TestAllTypes.Parser.ParseFrom(request.ProtobufPayload);
}
catch (InvalidProtocolBufferException e)
{
return new ConformanceResponse { ParseError = e.Message };
}
break;
default:
throw new Exception("Unsupported request payload: " + request.PayloadCase);
}
switch (request.RequestedOutputFormat)
{
case global::Conformance.WireFormat.JSON:
return new ConformanceResponse { JsonPayload = JsonFormatter.Default.Format(message) };
case global::Conformance.WireFormat.PROTOBUF:
return new ConformanceResponse { ProtobufPayload = message.ToByteString() };
default:
throw new Exception("Unsupported request output format: " + request.PayloadCase);
}
}
private static int? ReadInt32(BinaryReader input)
{
byte[] bytes = input.ReadBytes(4);
if (bytes.Length == 0)
{
// Cleanly reached the end of the stream
return null;
}
if (bytes.Length != 4)
{
throw new EndOfStreamException("Read " + bytes.Length + " bytes of size when expecting 4");
}
return bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24);
}
}
}

@ -1,65 +1,48 @@
// Protocol Buffers - Google's data interchange format #region Copyright notice and license
// Copyright 2008 Google Inc. All rights reserved. // Protocol Buffers - Google's data interchange format
// http://github.com/jskeet/dotnet-protobufs/ // Copyright 2015 Google Inc. All rights reserved.
// Original C++/Java/Python code: // https://developers.google.com/protocol-buffers/
// http://code.google.com/p/protobuf/ //
// // Redistribution and use in source and binary forms, with or without
// Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are
// modification, are permitted provided that the following conditions are // met:
// met: //
// // * Redistributions of source code must retain the above copyright
// * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer.
// notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above
// * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer
// copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the
// in the documentation and/or other materials provided with the // distribution.
// distribution. // * Neither the name of Google Inc. nor the names of its
// * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from
// contributors may be used to endorse or promote products derived from // this software without specific prior written permission.
// this software without specific prior written permission. //
// // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #endregion
using System;
using System.Reflection; using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices; // General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// General Information about an assembly is controlled through the following // associated with an assembly.
// set of attributes. Change these attribute values to modify the information [assembly: AssemblyTitle("Google.Protobuf.Conformance")]
// associated with an assembly. [assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyTitle("ProtocolBuffers")] [assembly: AssemblyCompany("")]
[assembly: AssemblyDescription("")] [assembly: AssemblyProduct("Google.Protobuf.Conformance")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyCompany("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyProduct("ProtocolBuffers")] [assembly: AssemblyCulture("")]
[assembly: AssemblyCopyright("Copyright © 2008")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyVersion("3.0.0.0")]
[assembly: AssemblyCulture("")] [assembly: AssemblyFileVersion("3.0.0.0")]
// 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")]
#if !NOFILEVERSION
[assembly: AssemblyFileVersion("2.4.1.555")]
#endif

@ -1,8 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup> <PropertyGroup>
<EnvironmentFlavor>CLIENTPROFILE</EnvironmentFlavor>
<EnvironmentTemplate>NET35</EnvironmentTemplate>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion> <ProductVersion>9.0.30729</ProductVersion>
@ -10,11 +8,12 @@
<ProjectGuid>{D7282E99-2DC3-405B-946F-177DB2FD2AE2}</ProjectGuid> <ProjectGuid>{D7282E99-2DC3-405B-946F-177DB2FD2AE2}</ProjectGuid>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder> <AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Google.ProtocolBuffers.ProtoDump</RootNamespace> <RootNamespace>Google.Protobuf.JsonDump</RootNamespace>
<AssemblyName>ProtoDump</AssemblyName> <AssemblyName>Google.Protobuf.JsonDump</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion> <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<TargetFrameworkProfile>Client</TargetFrameworkProfile> <TargetFrameworkProfile>
</TargetFrameworkProfile>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
@ -27,6 +26,7 @@
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<NoStdLib>true</NoStdLib> <NoStdLib>true</NoStdLib>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies> <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType> <DebugType>pdbonly</DebugType>
@ -38,6 +38,7 @@
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<NoStdLib>true</NoStdLib> <NoStdLib>true</NoStdLib>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies> <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="mscorlib" /> <Reference Include="mscorlib" />
@ -48,9 +49,9 @@
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\ProtocolBuffers\ProtocolBuffers.csproj"> <ProjectReference Include="..\Google.Protobuf\Google.Protobuf.csproj">
<Project>{6908BDCE-D925-43F3-94AC-A531E6DF2591}</Project> <Project>{6908BDCE-D925-43F3-94AC-A531E6DF2591}</Project>
<Name>ProtocolBuffers</Name> <Name>Google.Protobuf</Name>
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

@ -1,10 +1,7 @@
#region Copyright notice and license #region Copyright notice and license
// Protocol Buffers - Google's data interchange format // Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved. // Copyright 2008 Google Inc. All rights reserved.
// http://github.com/jskeet/dotnet-protobufs/ // https://developers.google.com/protocol-buffers/
// Original C++/Java/Python code:
// http://code.google.com/p/protobuf/
// //
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are // modification, are permitted provided that the following conditions are
@ -31,16 +28,15 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion #endregion
using System; using System;
using System.IO; using System.IO;
namespace Google.ProtocolBuffers.ProtoDump namespace Google.Protobuf.ProtoDump
{ {
/// <summary> /// <summary>
/// Small utility to load a binary message and dump it in text form /// Small utility to load a binary message and dump it in JSON format.
/// </summary> /// </summary>
internal class Program internal class Program
{ {
@ -48,41 +44,29 @@ namespace Google.ProtocolBuffers.ProtoDump
{ {
if (args.Length != 2) if (args.Length != 2)
{ {
Console.Error.WriteLine("Usage: ProtoDump <descriptor type name> <input data>"); Console.Error.WriteLine("Usage: Google.Protobuf.JsonDump <descriptor type name> <input data>");
Console.Error.WriteLine("The descriptor type name is the fully-qualified message name,"); Console.Error.WriteLine("The descriptor type name is the fully-qualified message name,");
Console.Error.WriteLine("including assembly e.g. ProjectNamespace.Message,Company.Project"); Console.Error.WriteLine("including assembly e.g. ProjectNamespace.Message,Company.Project");
return 1; return 1;
} }
IMessage defaultMessage; Type type = Type.GetType(args[0]);
try 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; return 1;
} }
try if (!typeof(IMessage).IsAssignableFrom(type))
{ {
IBuilder builder = defaultMessage.WeakCreateBuilderForType(); Console.Error.WriteLine("Type {0} doesn't implement IMessage.", args[0]);
if (builder == null) return 1;
{
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;
} }
catch (Exception e) IMessage message = (IMessage) Activator.CreateInstance(type);
using (var input = File.OpenRead(args[1]))
{ {
Console.Error.WriteLine("Error: {0}", e.Message); message.MergeFrom(input);
Console.Error.WriteLine();
Console.Error.WriteLine("Detailed exception information: {0}", e);
return 1;
} }
Console.WriteLine(message);
return 0;
} }
} }
} }

@ -11,20 +11,9 @@ using System.Runtime.InteropServices;
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")] [assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ProtoDump")] [assembly: AssemblyProduct("ProtoDump")]
[assembly: AssemblyCopyright("Copyright © 2009")] [assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
// Version information for an assembly consists of the following four values: [assembly: AssemblyVersion("3.0.0.0")]
// [assembly: AssemblyFileVersion("3.0.0.0")]
// 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,3 +1,3 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<configuration> <configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0,Profile=Client"/></startup></configuration> <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/></startup></configuration>

@ -1,10 +1,7 @@
#region Copyright notice and license #region Copyright notice and license
// Protocol Buffers - Google's data interchange format // Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved. // Copyright 2008 Google Inc. All rights reserved.
// http://github.com/jskeet/dotnet-protobufs/ // https://developers.google.com/protocol-buffers/
// Original C++/Java/Python code:
// http://code.google.com/p/protobuf/
// //
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are // modification, are permitted provided that the following conditions are
@ -31,17 +28,44 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion #endregion
using System; using System;
using System.Text; using System.Text;
using NUnit.Framework; using NUnit.Framework;
namespace Google.ProtocolBuffers namespace Google.Protobuf
{ {
public class ByteStringTest public class ByteStringTest
{ {
[Test]
public void Equality()
{
ByteString b1 = ByteString.CopyFrom(1, 2, 3);
ByteString b2 = ByteString.CopyFrom(1, 2, 3);
ByteString b3 = ByteString.CopyFrom(1, 2, 4);
ByteString b4 = ByteString.CopyFrom(1, 2, 3, 4);
EqualityTester.AssertEquality(b1, b1);
EqualityTester.AssertEquality(b1, b2);
EqualityTester.AssertInequality(b1, b3);
EqualityTester.AssertInequality(b1, b4);
EqualityTester.AssertInequality(b1, null);
#pragma warning disable 1718 // Deliberately calling ==(b1, b1) and !=(b1, b1)
Assert.IsTrue(b1 == b1);
Assert.IsTrue(b1 == b2);
Assert.IsFalse(b1 == b3);
Assert.IsFalse(b1 == b4);
Assert.IsFalse(b1 == null);
Assert.IsTrue((ByteString) null == null);
Assert.IsFalse(b1 != b1);
Assert.IsFalse(b1 != b2);
#pragma warning disable 1718
Assert.IsTrue(b1 != b3);
Assert.IsTrue(b1 != b4);
Assert.IsTrue(b1 != null);
Assert.IsFalse((ByteString) null != null);
}
[Test] [Test]
public void EmptyByteStringHasZeroSize() public void EmptyByteStringHasZeroSize()
{ {

@ -0,0 +1,53 @@
#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
using NUnit.Framework;
namespace Google.Protobuf
{
internal static class CodedInputStreamExtensions
{
public static void AssertNextTag(this CodedInputStream input, uint expectedTag)
{
uint tag = input.ReadTag();
Assert.AreEqual(expectedTag, tag);
}
public static T ReadMessage<T>(this CodedInputStream stream, MessageParser<T> parser)
where T : IMessage<T>
{
var message = parser.CreateTemplate();
stream.ReadMessage(message);
return message;
}
}
}

@ -1,10 +1,7 @@
#region Copyright notice and license #region Copyright notice and license
// Protocol Buffers - Google's data interchange format // Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved. // Copyright 2008 Google Inc. All rights reserved.
// http://github.com/jskeet/dotnet-protobufs/ // https://developers.google.com/protocol-buffers/
// Original C++/Java/Python code:
// http://code.google.com/p/protobuf/
// //
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are // modification, are permitted provided that the following conditions are
@ -31,17 +28,14 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion #endregion
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using Google.ProtocolBuffers.Descriptors; using Google.Protobuf.TestProtos;
using Google.ProtocolBuffers.TestProtos;
using NUnit.Framework; using NUnit.Framework;
namespace Google.ProtocolBuffers namespace Google.Protobuf
{ {
public class CodedInputStreamTest public class CodedInputStreamTest
{ {
@ -61,24 +55,24 @@ namespace Google.ProtocolBuffers
} }
/// <summary> /// <summary>
/// Parses the given bytes using ReadRawVarint32() and ReadRawVarint64() and /// Parses the given bytes using ReadRawVarint32() and ReadRawVarint64()
/// </summary> /// </summary>
private static void AssertReadVarint(byte[] data, ulong value) private static void AssertReadVarint(byte[] data, ulong value)
{ {
CodedInputStream input = CodedInputStream.CreateInstance(data); CodedInputStream input = new CodedInputStream(data);
Assert.AreEqual((uint) value, input.ReadRawVarint32()); Assert.AreEqual((uint) value, input.ReadRawVarint32());
input = CodedInputStream.CreateInstance(data); input = new CodedInputStream(data);
Assert.AreEqual(value, input.ReadRawVarint64()); Assert.AreEqual(value, input.ReadRawVarint64());
Assert.IsTrue(input.IsAtEnd); Assert.IsTrue(input.IsAtEnd);
// Try different block sizes. // Try different block sizes.
for (int bufferSize = 1; bufferSize <= 16; bufferSize *= 2) for (int bufferSize = 1; bufferSize <= 16; bufferSize *= 2)
{ {
input = CodedInputStream.CreateInstance(new SmallBlockInputStream(data, bufferSize)); input = new CodedInputStream(new SmallBlockInputStream(data, bufferSize));
Assert.AreEqual((uint) value, input.ReadRawVarint32()); Assert.AreEqual((uint) value, input.ReadRawVarint32());
input = CodedInputStream.CreateInstance(new SmallBlockInputStream(data, bufferSize)); input = new CodedInputStream(new SmallBlockInputStream(data, bufferSize));
Assert.AreEqual(value, input.ReadRawVarint64()); Assert.AreEqual(value, input.ReadRawVarint64());
Assert.IsTrue(input.IsAtEnd); Assert.IsTrue(input.IsAtEnd);
} }
@ -101,11 +95,11 @@ namespace Google.ProtocolBuffers
/// </summary> /// </summary>
private static void AssertReadVarintFailure(InvalidProtocolBufferException expected, byte[] data) private static void AssertReadVarintFailure(InvalidProtocolBufferException expected, byte[] data)
{ {
CodedInputStream input = CodedInputStream.CreateInstance(data); CodedInputStream input = new CodedInputStream(data);
var exception = Assert.Throws<InvalidProtocolBufferException>(() => input.ReadRawVarint32()); var exception = Assert.Throws<InvalidProtocolBufferException>(() => input.ReadRawVarint32());
Assert.AreEqual(expected.Message, exception.Message); Assert.AreEqual(expected.Message, exception.Message);
input = CodedInputStream.CreateInstance(data); input = new CodedInputStream(data);
exception = Assert.Throws<InvalidProtocolBufferException>(() => input.ReadRawVarint64()); exception = Assert.Throws<InvalidProtocolBufferException>(() => input.ReadRawVarint64());
Assert.AreEqual(expected.Message, exception.Message); Assert.AreEqual(expected.Message, exception.Message);
@ -158,14 +152,14 @@ namespace Google.ProtocolBuffers
/// </summary> /// </summary>
private static void AssertReadLittleEndian32(byte[] data, uint value) private static void AssertReadLittleEndian32(byte[] data, uint value)
{ {
CodedInputStream input = CodedInputStream.CreateInstance(data); CodedInputStream input = new CodedInputStream(data);
Assert.AreEqual(value, input.ReadRawLittleEndian32()); Assert.AreEqual(value, input.ReadRawLittleEndian32());
Assert.IsTrue(input.IsAtEnd); Assert.IsTrue(input.IsAtEnd);
// Try different block sizes. // Try different block sizes.
for (int blockSize = 1; blockSize <= 16; blockSize *= 2) for (int blockSize = 1; blockSize <= 16; blockSize *= 2)
{ {
input = CodedInputStream.CreateInstance( input = new CodedInputStream(
new SmallBlockInputStream(data, blockSize)); new SmallBlockInputStream(data, blockSize));
Assert.AreEqual(value, input.ReadRawLittleEndian32()); Assert.AreEqual(value, input.ReadRawLittleEndian32());
Assert.IsTrue(input.IsAtEnd); Assert.IsTrue(input.IsAtEnd);
@ -178,14 +172,14 @@ namespace Google.ProtocolBuffers
/// </summary> /// </summary>
private static void AssertReadLittleEndian64(byte[] data, ulong value) private static void AssertReadLittleEndian64(byte[] data, ulong value)
{ {
CodedInputStream input = CodedInputStream.CreateInstance(data); CodedInputStream input = new CodedInputStream(data);
Assert.AreEqual(value, input.ReadRawLittleEndian64()); Assert.AreEqual(value, input.ReadRawLittleEndian64());
Assert.IsTrue(input.IsAtEnd); Assert.IsTrue(input.IsAtEnd);
// Try different block sizes. // Try different block sizes.
for (int blockSize = 1; blockSize <= 16; blockSize *= 2) for (int blockSize = 1; blockSize <= 16; blockSize *= 2)
{ {
input = CodedInputStream.CreateInstance( input = new CodedInputStream(
new SmallBlockInputStream(data, blockSize)); new SmallBlockInputStream(data, blockSize));
Assert.AreEqual(value, input.ReadRawLittleEndian64()); Assert.AreEqual(value, input.ReadRawLittleEndian64());
Assert.IsTrue(input.IsAtEnd); Assert.IsTrue(input.IsAtEnd);
@ -231,66 +225,26 @@ namespace Google.ProtocolBuffers
Assert.AreEqual(0x7FFFFFFFFFFFFFFFL, CodedInputStream.DecodeZigZag64(0xFFFFFFFFFFFFFFFEL)); Assert.AreEqual(0x7FFFFFFFFFFFFFFFL, CodedInputStream.DecodeZigZag64(0xFFFFFFFFFFFFFFFEL));
Assert.AreEqual(unchecked((long) 0x8000000000000000L), CodedInputStream.DecodeZigZag64(0xFFFFFFFFFFFFFFFFL)); Assert.AreEqual(unchecked((long) 0x8000000000000000L), CodedInputStream.DecodeZigZag64(0xFFFFFFFFFFFFFFFFL));
} }
[Test] [Test]
public void ReadWholeMessage() public void ReadWholeMessage_VaryingBlockSizes()
{ {
TestAllTypes message = TestUtil.GetAllSet(); TestAllTypes message = SampleMessages.CreateFullTestAllTypes();
byte[] rawBytes = message.ToByteArray(); byte[] rawBytes = message.ToByteArray();
Assert.AreEqual(rawBytes.Length, message.SerializedSize); Assert.AreEqual(rawBytes.Length, message.CalculateSize());
TestAllTypes message2 = TestAllTypes.ParseFrom(rawBytes); TestAllTypes message2 = TestAllTypes.Parser.ParseFrom(rawBytes);
TestUtil.AssertAllFieldsSet(message2); Assert.AreEqual(message, message2);
// Try different block sizes. // Try different block sizes.
for (int blockSize = 1; blockSize < 256; blockSize *= 2) for (int blockSize = 1; blockSize < 256; blockSize *= 2)
{ {
message2 = TestAllTypes.ParseFrom(new SmallBlockInputStream(rawBytes, blockSize)); message2 = TestAllTypes.Parser.ParseFrom(new SmallBlockInputStream(rawBytes, blockSize));
TestUtil.AssertAllFieldsSet(message2); Assert.AreEqual(message, message2);
}
}
[Test]
public void SkipWholeMessage()
{
TestAllTypes message = TestUtil.GetAllSet();
byte[] rawBytes = message.ToByteArray();
// Create two parallel inputs. Parse one as unknown fields while using
// skipField() to skip each field on the other. Expect the same tags.
CodedInputStream input1 = CodedInputStream.CreateInstance(rawBytes);
CodedInputStream input2 = CodedInputStream.CreateInstance(rawBytes);
UnknownFieldSet.Builder unknownFields = UnknownFieldSet.CreateBuilder();
uint tag;
string name;
while (input1.ReadTag(out tag, out name))
{
uint tag2;
Assert.IsTrue(input2.ReadTag(out tag2, out name));
Assert.AreEqual(tag, tag2);
unknownFields.MergeFieldFrom(tag, input1);
input2.SkipField();
} }
} }
/// <summary>
/// Test that a bug in SkipRawBytes has been fixed: if the skip
/// skips exactly up to a limit, this should bnot break things
/// </summary>
[Test] [Test]
public void SkipRawBytesBug()
{
byte[] rawBytes = new byte[] {1, 2};
CodedInputStream input = CodedInputStream.CreateInstance(rawBytes);
int limit = input.PushLimit(1);
input.SkipRawBytes(1);
input.PopLimit(limit);
Assert.AreEqual(2, input.ReadRawByte());
}
public void ReadHugeBlob() public void ReadHugeBlob()
{ {
// Allocate and initialize a 1MB blob. // Allocate and initialize a 1MB blob.
@ -301,30 +255,21 @@ namespace Google.ProtocolBuffers
} }
// Make a message containing it. // Make a message containing it.
TestAllTypes.Builder builder = TestAllTypes.CreateBuilder(); var message = new TestAllTypes { SingleBytes = ByteString.CopyFrom(blob) };
TestUtil.SetAllFields(builder);
builder.SetOptionalBytes(ByteString.CopyFrom(blob));
TestAllTypes message = builder.Build();
// Serialize and parse it. Make sure to parse from an InputStream, not // Serialize and parse it. Make sure to parse from an InputStream, not
// directly from a ByteString, so that CodedInputStream uses buffered // directly from a ByteString, so that CodedInputStream uses buffered
// reading. // reading.
TestAllTypes message2 = TestAllTypes.ParseFrom(message.ToByteString().CreateCodedInput()); TestAllTypes message2 = TestAllTypes.Parser.ParseFrom(message.ToByteString());
Assert.AreEqual(message.OptionalBytes, message2.OptionalBytes); Assert.AreEqual(message, message2);
// Make sure all the other fields were parsed correctly.
TestAllTypes message3 = TestAllTypes.CreateBuilder(message2)
.SetOptionalBytes(TestUtil.GetAllSet().OptionalBytes)
.Build();
TestUtil.AssertAllFieldsSet(message3);
} }
[Test] [Test]
public void ReadMaliciouslyLargeBlob() public void ReadMaliciouslyLargeBlob()
{ {
MemoryStream ms = new MemoryStream(); MemoryStream ms = new MemoryStream();
CodedOutputStream output = CodedOutputStream.CreateInstance(ms); CodedOutputStream output = new CodedOutputStream(ms);
uint tag = WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited); uint tag = WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited);
output.WriteRawVarint32(tag); output.WriteRawVarint32(tag);
@ -333,27 +278,21 @@ namespace Google.ProtocolBuffers
output.Flush(); output.Flush();
ms.Position = 0; ms.Position = 0;
CodedInputStream input = CodedInputStream.CreateInstance(ms); CodedInputStream input = new CodedInputStream(ms);
uint testtag; Assert.AreEqual(tag, input.ReadTag());
string ignore;
Assert.IsTrue(input.ReadTag(out testtag, out ignore));
Assert.AreEqual(tag, testtag);
ByteString bytes = null; Assert.Throws<InvalidProtocolBufferException>(() => input.ReadBytes());
// TODO(jonskeet): Should this be ArgumentNullException instead?
Assert.Throws<InvalidProtocolBufferException>(() => input.ReadBytes(ref bytes));
} }
private static TestRecursiveMessage MakeRecursiveMessage(int depth) private static TestRecursiveMessage MakeRecursiveMessage(int depth)
{ {
if (depth == 0) if (depth == 0)
{ {
return TestRecursiveMessage.CreateBuilder().SetI(5).Build(); return new TestRecursiveMessage { I = 5 };
} }
else else
{ {
return TestRecursiveMessage.CreateBuilder() return new TestRecursiveMessage { A = MakeRecursiveMessage(depth - 1) };
.SetA(MakeRecursiveMessage(depth - 1)).Build();
} }
} }
@ -361,12 +300,12 @@ namespace Google.ProtocolBuffers
{ {
if (depth == 0) if (depth == 0)
{ {
Assert.IsFalse(message.HasA); Assert.IsNull(message.A);
Assert.AreEqual(5, message.I); Assert.AreEqual(5, message.I);
} }
else else
{ {
Assert.IsTrue(message.HasA); Assert.IsNotNull(message.A);
AssertMessageDepth(message.A, depth - 1); AssertMessageDepth(message.A, depth - 1);
} }
} }
@ -377,13 +316,12 @@ namespace Google.ProtocolBuffers
ByteString data64 = MakeRecursiveMessage(64).ToByteString(); ByteString data64 = MakeRecursiveMessage(64).ToByteString();
ByteString data65 = MakeRecursiveMessage(65).ToByteString(); ByteString data65 = MakeRecursiveMessage(65).ToByteString();
AssertMessageDepth(TestRecursiveMessage.ParseFrom(data64), 64); AssertMessageDepth(TestRecursiveMessage.Parser.ParseFrom(data64), 64);
Assert.Throws<InvalidProtocolBufferException>(() => TestRecursiveMessage.ParseFrom(data65)); Assert.Throws<InvalidProtocolBufferException>(() => TestRecursiveMessage.Parser.ParseFrom(data65));
CodedInputStream input = data64.CreateCodedInput(); CodedInputStream input = CodedInputStream.CreateWithLimits(new MemoryStream(data64.ToByteArray()), 1000000, 63);
input.SetRecursionLimit(8); Assert.Throws<InvalidProtocolBufferException>(() => TestRecursiveMessage.Parser.ParseFrom(input));
Assert.Throws<InvalidProtocolBufferException>(() => TestRecursiveMessage.ParseFrom(input));
} }
[Test] [Test]
@ -391,27 +329,9 @@ namespace Google.ProtocolBuffers
{ {
// Have to use a Stream rather than ByteString.CreateCodedInput as SizeLimit doesn't // Have to use a Stream rather than ByteString.CreateCodedInput as SizeLimit doesn't
// apply to the latter case. // apply to the latter case.
MemoryStream ms = new MemoryStream(TestUtil.GetAllSet().ToByteString().ToByteArray()); MemoryStream ms = new MemoryStream(SampleMessages.CreateFullTestAllTypes().ToByteArray());
CodedInputStream input = CodedInputStream.CreateInstance(ms); CodedInputStream input = CodedInputStream.CreateWithLimits(ms, 16, 100);
input.SetSizeLimit(16); Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseFrom(input));
Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.ParseFrom(input));
}
[Test]
public void ResetSizeCounter()
{
CodedInputStream input = CodedInputStream.CreateInstance(
new SmallBlockInputStream(new byte[256], 8));
input.SetSizeLimit(16);
input.ReadRawBytes(16);
Assert.Throws<InvalidProtocolBufferException>(() => input.ReadRawByte());
input.ResetSizeCounter();
input.ReadRawByte(); // No exception thrown.
Assert.Throws<InvalidProtocolBufferException>(() => input.ReadRawBytes(16));
} }
/// <summary> /// <summary>
@ -423,7 +343,7 @@ namespace Google.ProtocolBuffers
public void ReadInvalidUtf8() public void ReadInvalidUtf8()
{ {
MemoryStream ms = new MemoryStream(); MemoryStream ms = new MemoryStream();
CodedOutputStream output = CodedOutputStream.CreateInstance(ms); CodedOutputStream output = new CodedOutputStream(ms);
uint tag = WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited); uint tag = WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited);
output.WriteRawVarint32(tag); output.WriteRawVarint32(tag);
@ -432,15 +352,10 @@ namespace Google.ProtocolBuffers
output.Flush(); output.Flush();
ms.Position = 0; ms.Position = 0;
CodedInputStream input = CodedInputStream.CreateInstance(ms); CodedInputStream input = new CodedInputStream(ms);
uint testtag; Assert.AreEqual(tag, input.ReadTag());
string ignored; string text = input.ReadString();
Assert.IsTrue(input.ReadTag(out testtag, out ignored));
Assert.AreEqual(tag, testtag);
string text = null;
input.ReadString(ref text);
Assert.AreEqual('\ufffd', text[0]); Assert.AreEqual('\ufffd', text[0]);
} }
@ -465,105 +380,151 @@ namespace Google.ProtocolBuffers
} }
} }
enum TestNegEnum { None = 0, Value = -2 }
[Test] [Test]
public void TestNegativeEnum() public void TestNegativeEnum()
{ {
byte[] bytes = new byte[10] { 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01 }; byte[] bytes = { 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01 };
CodedInputStream input = CodedInputStream.CreateInstance(bytes); CodedInputStream input = new CodedInputStream(bytes);
object unk; Assert.AreEqual((int)SampleEnum.NegativeValue, input.ReadEnum());
TestNegEnum val = TestNegEnum.None;
Assert.IsTrue(input.ReadEnum(ref val, out unk));
Assert.IsTrue(input.IsAtEnd); Assert.IsTrue(input.IsAtEnd);
Assert.AreEqual(TestNegEnum.Value, val);
} }
//Issue 71: CodedInputStream.ReadBytes go to slow path unnecessarily
[Test] [Test]
public void TestNegativeEnumPackedArray() public void TestSlowPathAvoidance()
{ {
int arraySize = 1 + (10 * 5); using (var ms = new MemoryStream())
int msgSize = 1 + 1 + arraySize; {
byte[] bytes = new byte[msgSize]; CodedOutputStream output = new CodedOutputStream(ms);
CodedOutputStream output = CodedOutputStream.CreateInstance(bytes); output.WriteTag(1, WireFormat.WireType.LengthDelimited);
output.WritePackedInt32Array(8, "", arraySize, new int[] { 0, -1, -2, -3, -4, -5 }); output.WriteBytes(ByteString.CopyFrom(new byte[100]));
output.WriteTag(2, WireFormat.WireType.LengthDelimited);
Assert.AreEqual(0, output.SpaceLeft); output.WriteBytes(ByteString.CopyFrom(new byte[100]));
output.Flush();
CodedInputStream input = CodedInputStream.CreateInstance(bytes);
uint tag;
string name;
Assert.IsTrue(input.ReadTag(out tag, out name));
List<TestNegEnum> values = new List<TestNegEnum>(); ms.Position = 0;
ICollection<object> unk; CodedInputStream input = new CodedInputStream(ms, new byte[ms.Length / 2], 0, 0);
input.ReadEnumArray(tag, name, values, out unk);
Assert.AreEqual(2, values.Count); uint tag = input.ReadTag();
Assert.AreEqual(TestNegEnum.None, values[0]); Assert.AreEqual(1, WireFormat.GetTagFieldNumber(tag));
Assert.AreEqual(TestNegEnum.Value, values[1]); Assert.AreEqual(100, input.ReadBytes().Length);
Assert.NotNull(unk); tag = input.ReadTag();
Assert.AreEqual(4, unk.Count); Assert.AreEqual(2, WireFormat.GetTagFieldNumber(tag));
Assert.AreEqual(100, input.ReadBytes().Length);
}
} }
[Test] [Test]
public void TestNegativeEnumArray() public void Tag0Throws()
{ {
int arraySize = 1 + 1 + (11 * 5); var input = new CodedInputStream(new byte[] { 0 });
int msgSize = arraySize; Assert.Throws<InvalidProtocolBufferException>(() => input.ReadTag());
byte[] bytes = new byte[msgSize]; }
CodedOutputStream output = CodedOutputStream.CreateInstance(bytes);
output.WriteInt32Array(8, "", new int[] { 0, -1, -2, -3, -4, -5 });
Assert.AreEqual(0, output.SpaceLeft);
CodedInputStream input = CodedInputStream.CreateInstance(bytes); [Test]
uint tag; public void SkipGroup()
string name; {
Assert.IsTrue(input.ReadTag(out tag, out name)); // Create an output stream with a group in:
// Field 1: string "field 1"
// Field 2: group containing:
// Field 1: fixed int32 value 100
// Field 2: string "ignore me"
// Field 3: nested group containing
// Field 1: fixed int64 value 1000
// Field 3: string "field 3"
var stream = new MemoryStream();
var output = new CodedOutputStream(stream);
output.WriteTag(1, WireFormat.WireType.LengthDelimited);
output.WriteString("field 1");
// The outer group...
output.WriteTag(2, WireFormat.WireType.StartGroup);
output.WriteTag(1, WireFormat.WireType.Fixed32);
output.WriteFixed32(100);
output.WriteTag(2, WireFormat.WireType.LengthDelimited);
output.WriteString("ignore me");
// The nested group...
output.WriteTag(3, WireFormat.WireType.StartGroup);
output.WriteTag(1, WireFormat.WireType.Fixed64);
output.WriteFixed64(1000);
// Note: Not sure the field number is relevant for end group...
output.WriteTag(3, WireFormat.WireType.EndGroup);
// End the outer group
output.WriteTag(2, WireFormat.WireType.EndGroup);
output.WriteTag(3, WireFormat.WireType.LengthDelimited);
output.WriteString("field 3");
output.Flush();
stream.Position = 0;
// Now act like a generated client
var input = new CodedInputStream(stream);
Assert.AreEqual(WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited), input.ReadTag());
Assert.AreEqual("field 1", input.ReadString());
Assert.AreEqual(WireFormat.MakeTag(2, WireFormat.WireType.StartGroup), input.ReadTag());
input.SkipLastField(); // Should consume the whole group, including the nested one.
Assert.AreEqual(WireFormat.MakeTag(3, WireFormat.WireType.LengthDelimited), input.ReadTag());
Assert.AreEqual("field 3", input.ReadString());
}
List<TestNegEnum> values = new List<TestNegEnum>(); [Test]
ICollection<object> unk; public void EndOfStreamReachedWhileSkippingGroup()
input.ReadEnumArray(tag, name, values, out unk); {
var stream = new MemoryStream();
var output = new CodedOutputStream(stream);
output.WriteTag(1, WireFormat.WireType.StartGroup);
output.WriteTag(2, WireFormat.WireType.StartGroup);
output.WriteTag(2, WireFormat.WireType.EndGroup);
Assert.AreEqual(2, values.Count); output.Flush();
Assert.AreEqual(TestNegEnum.None, values[0]); stream.Position = 0;
Assert.AreEqual(TestNegEnum.Value, values[1]);
Assert.NotNull(unk); // Now act like a generated client
Assert.AreEqual(4, unk.Count); var input = new CodedInputStream(stream);
input.ReadTag();
Assert.Throws<InvalidProtocolBufferException>(() => input.SkipLastField());
} }
//Issue 71: CodedInputStream.ReadBytes go to slow path unnecessarily
[Test] [Test]
public void TestSlowPathAvoidance() public void RecursionLimitAppliedWhileSkippingGroup()
{ {
using (var ms = new MemoryStream()) var stream = new MemoryStream();
var output = new CodedOutputStream(stream);
for (int i = 0; i < CodedInputStream.DefaultRecursionLimit + 1; i++)
{ {
CodedOutputStream output = CodedOutputStream.CreateInstance(ms); output.WriteTag(1, WireFormat.WireType.StartGroup);
output.WriteField(FieldType.Bytes, 1, "bytes", ByteString.CopyFrom(new byte[100])); }
output.WriteField(FieldType.Bytes, 2, "bytes", ByteString.CopyFrom(new byte[100])); for (int i = 0; i < CodedInputStream.DefaultRecursionLimit + 1; i++)
output.Flush(); {
output.WriteTag(1, WireFormat.WireType.EndGroup);
ms.Position = 0; }
CodedInputStream input = CodedInputStream.CreateInstance(ms, new byte[ms.Length / 2]); output.Flush();
stream.Position = 0;
uint tag; // Now act like a generated client
string ignore; var input = new CodedInputStream(stream);
ByteString value; Assert.AreEqual(WireFormat.MakeTag(1, WireFormat.WireType.StartGroup), input.ReadTag());
Assert.Throws<InvalidProtocolBufferException>(() => input.SkipLastField());
}
Assert.IsTrue(input.ReadTag(out tag, out ignore)); [Test]
Assert.AreEqual(1, WireFormat.GetTagFieldNumber(tag)); public void Construction_Invalid()
value = ByteString.Empty; {
Assert.IsTrue(input.ReadBytes(ref value) && value.Length == 100); Assert.Throws<ArgumentNullException>(() => new CodedInputStream((byte[]) null));
Assert.Throws<ArgumentNullException>(() => new CodedInputStream(null, 0, 0));
Assert.Throws<ArgumentNullException>(() => new CodedInputStream((Stream) null));
Assert.Throws<ArgumentOutOfRangeException>(() => new CodedInputStream(new byte[10], 100, 0));
Assert.Throws<ArgumentOutOfRangeException>(() => new CodedInputStream(new byte[10], 5, 10));
}
Assert.IsTrue(input.ReadTag(out tag, out ignore)); [Test]
Assert.AreEqual(2, WireFormat.GetTagFieldNumber(tag)); public void CreateWithLimits_InvalidLimits()
value = ByteString.Empty; {
Assert.IsTrue(input.ReadBytes(ref value) && value.Length == 100); var stream = new MemoryStream();
} Assert.Throws<ArgumentOutOfRangeException>(() => CodedInputStream.CreateWithLimits(stream, 0, 1));
Assert.Throws<ArgumentOutOfRangeException>(() => CodedInputStream.CreateWithLimits(stream, 1, 0));
} }
} }
} }

@ -1,10 +1,7 @@
#region Copyright notice and license #region Copyright notice and license
// Protocol Buffers - Google's data interchange format // Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved. // Copyright 2008 Google Inc. All rights reserved.
// http://github.com/jskeet/dotnet-protobufs/ // https://developers.google.com/protocol-buffers/
// Original C++/Java/Python code:
// http://code.google.com/p/protobuf/
// //
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are // modification, are permitted provided that the following conditions are
@ -31,16 +28,14 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion #endregion
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using Google.ProtocolBuffers.TestProtos; using Google.Protobuf.TestProtos;
using NUnit.Framework; using NUnit.Framework;
namespace Google.ProtocolBuffers namespace Google.Protobuf
{ {
public class CodedOutputStreamTest public class CodedOutputStreamTest
{ {
@ -54,7 +49,7 @@ namespace Google.ProtocolBuffers
if ((value >> 32) == 0) if ((value >> 32) == 0)
{ {
MemoryStream rawOutput = new MemoryStream(); MemoryStream rawOutput = new MemoryStream();
CodedOutputStream output = CodedOutputStream.CreateInstance(rawOutput); CodedOutputStream output = new CodedOutputStream(rawOutput);
output.WriteRawVarint32((uint) value); output.WriteRawVarint32((uint) value);
output.Flush(); output.Flush();
Assert.AreEqual(data, rawOutput.ToArray()); Assert.AreEqual(data, rawOutput.ToArray());
@ -64,7 +59,7 @@ namespace Google.ProtocolBuffers
{ {
MemoryStream rawOutput = new MemoryStream(); MemoryStream rawOutput = new MemoryStream();
CodedOutputStream output = CodedOutputStream.CreateInstance(rawOutput); CodedOutputStream output = new CodedOutputStream(rawOutput);
output.WriteRawVarint64(value); output.WriteRawVarint64(value);
output.Flush(); output.Flush();
Assert.AreEqual(data, rawOutput.ToArray()); Assert.AreEqual(data, rawOutput.ToArray());
@ -81,7 +76,7 @@ namespace Google.ProtocolBuffers
{ {
MemoryStream rawOutput = new MemoryStream(); MemoryStream rawOutput = new MemoryStream();
CodedOutputStream output = CodedOutputStream output =
CodedOutputStream.CreateInstance(rawOutput, bufferSize); new CodedOutputStream(rawOutput, bufferSize);
output.WriteRawVarint32((uint) value); output.WriteRawVarint32((uint) value);
output.Flush(); output.Flush();
Assert.AreEqual(data, rawOutput.ToArray()); Assert.AreEqual(data, rawOutput.ToArray());
@ -89,7 +84,7 @@ namespace Google.ProtocolBuffers
{ {
MemoryStream rawOutput = new MemoryStream(); MemoryStream rawOutput = new MemoryStream();
CodedOutputStream output = CodedOutputStream.CreateInstance(rawOutput, bufferSize); CodedOutputStream output = new CodedOutputStream(rawOutput, bufferSize);
output.WriteRawVarint64(value); output.WriteRawVarint64(value);
output.Flush(); output.Flush();
Assert.AreEqual(data, rawOutput.ToArray()); Assert.AreEqual(data, rawOutput.ToArray());
@ -139,7 +134,7 @@ namespace Google.ProtocolBuffers
private static void AssertWriteLittleEndian32(byte[] data, uint value) private static void AssertWriteLittleEndian32(byte[] data, uint value)
{ {
MemoryStream rawOutput = new MemoryStream(); MemoryStream rawOutput = new MemoryStream();
CodedOutputStream output = CodedOutputStream.CreateInstance(rawOutput); CodedOutputStream output = new CodedOutputStream(rawOutput);
output.WriteRawLittleEndian32(value); output.WriteRawLittleEndian32(value);
output.Flush(); output.Flush();
Assert.AreEqual(data, rawOutput.ToArray()); Assert.AreEqual(data, rawOutput.ToArray());
@ -148,7 +143,7 @@ namespace Google.ProtocolBuffers
for (int bufferSize = 1; bufferSize <= 16; bufferSize *= 2) for (int bufferSize = 1; bufferSize <= 16; bufferSize *= 2)
{ {
rawOutput = new MemoryStream(); rawOutput = new MemoryStream();
output = CodedOutputStream.CreateInstance(rawOutput, bufferSize); output = new CodedOutputStream(rawOutput, bufferSize);
output.WriteRawLittleEndian32(value); output.WriteRawLittleEndian32(value);
output.Flush(); output.Flush();
Assert.AreEqual(data, rawOutput.ToArray()); Assert.AreEqual(data, rawOutput.ToArray());
@ -162,7 +157,7 @@ namespace Google.ProtocolBuffers
private static void AssertWriteLittleEndian64(byte[] data, ulong value) private static void AssertWriteLittleEndian64(byte[] data, ulong value)
{ {
MemoryStream rawOutput = new MemoryStream(); MemoryStream rawOutput = new MemoryStream();
CodedOutputStream output = CodedOutputStream.CreateInstance(rawOutput); CodedOutputStream output = new CodedOutputStream(rawOutput);
output.WriteRawLittleEndian64(value); output.WriteRawLittleEndian64(value);
output.Flush(); output.Flush();
Assert.AreEqual(data, rawOutput.ToArray()); Assert.AreEqual(data, rawOutput.ToArray());
@ -171,7 +166,7 @@ namespace Google.ProtocolBuffers
for (int blockSize = 1; blockSize <= 16; blockSize *= 2) for (int blockSize = 1; blockSize <= 16; blockSize *= 2)
{ {
rawOutput = new MemoryStream(); rawOutput = new MemoryStream();
output = CodedOutputStream.CreateInstance(rawOutput, blockSize); output = new CodedOutputStream(rawOutput, blockSize);
output.WriteRawLittleEndian64(value); output.WriteRawLittleEndian64(value);
output.Flush(); output.Flush();
Assert.AreEqual(data, rawOutput.ToArray()); Assert.AreEqual(data, rawOutput.ToArray());
@ -196,39 +191,23 @@ namespace Google.ProtocolBuffers
} }
[Test] [Test]
public void WriteWholeMessage() public void WriteWholeMessage_VaryingBlockSizes()
{ {
TestAllTypes message = TestUtil.GetAllSet(); TestAllTypes message = SampleMessages.CreateFullTestAllTypes();
byte[] rawBytes = message.ToByteArray(); byte[] rawBytes = message.ToByteArray();
TestUtil.AssertEqualBytes(TestUtil.GoldenMessage.ToByteArray(), rawBytes);
// Try different block sizes. // Try different block sizes.
for (int blockSize = 1; blockSize < 256; blockSize *= 2) for (int blockSize = 1; blockSize < 256; blockSize *= 2)
{ {
MemoryStream rawOutput = new MemoryStream(); MemoryStream rawOutput = new MemoryStream();
CodedOutputStream output = CodedOutputStream output = new CodedOutputStream(rawOutput, blockSize);
CodedOutputStream.CreateInstance(rawOutput, blockSize);
message.WriteTo(output); message.WriteTo(output);
output.Flush(); output.Flush();
TestUtil.AssertEqualBytes(rawBytes, rawOutput.ToArray()); Assert.AreEqual(rawBytes, rawOutput.ToArray());
} }
} }
/// <summary>
/// Tests writing a whole message with every packed field type. Ensures the
/// wire format of packed fields is compatible with C++.
/// </summary>
[Test]
public void WriteWholePackedFieldsMessage()
{
TestPackedTypes message = TestUtil.GetPackedSet();
byte[] rawBytes = message.ToByteArray();
TestUtil.AssertEqualBytes(TestUtil.GetGoldenPackedFieldsMessage().ToByteArray(),
rawBytes);
}
[Test] [Test]
public void EncodeZigZag32() public void EncodeZigZag32()
{ {
@ -293,80 +272,17 @@ namespace Google.ProtocolBuffers
[Test] [Test]
public void TestNegativeEnumNoTag() public void TestNegativeEnumNoTag()
{ {
Assert.AreEqual(10, CodedOutputStream.ComputeInt32SizeNoTag(-2)); Assert.AreEqual(10, CodedOutputStream.ComputeInt32Size(-2));
Assert.AreEqual(10, CodedOutputStream.ComputeEnumSizeNoTag(-2)); Assert.AreEqual(10, CodedOutputStream.ComputeEnumSize((int) SampleEnum.NegativeValue));
byte[] bytes = new byte[10]; byte[] bytes = new byte[10];
CodedOutputStream output = CodedOutputStream.CreateInstance(bytes); CodedOutputStream output = new CodedOutputStream(bytes);
output.WriteEnumNoTag(-2); output.WriteEnum((int) SampleEnum.NegativeValue);
Assert.AreEqual(0, output.SpaceLeft); Assert.AreEqual(0, output.SpaceLeft);
Assert.AreEqual("FE-FF-FF-FF-FF-FF-FF-FF-FF-01", BitConverter.ToString(bytes)); Assert.AreEqual("FE-FF-FF-FF-FF-FF-FF-FF-FF-01", BitConverter.ToString(bytes));
} }
[Test]
public void TestNegativeEnumWithTag()
{
Assert.AreEqual(11, CodedOutputStream.ComputeInt32Size(8, -2));
Assert.AreEqual(11, CodedOutputStream.ComputeEnumSize(8, -2));
byte[] bytes = new byte[11];
CodedOutputStream output = CodedOutputStream.CreateInstance(bytes);
output.WriteEnum(8, "", -2, -2);
Assert.AreEqual(0, output.SpaceLeft);
//fyi, 0x40 == 0x08 << 3 + 0, field num + wire format shift
Assert.AreEqual("40-FE-FF-FF-FF-FF-FF-FF-FF-FF-01", BitConverter.ToString(bytes));
}
[Test]
public void TestNegativeEnumArrayPacked()
{
int arraySize = 1 + (10 * 5);
int msgSize = 1 + 1 + arraySize;
byte[] bytes = new byte[msgSize];
CodedOutputStream output = CodedOutputStream.CreateInstance(bytes);
output.WritePackedEnumArray(8, "", arraySize, new int[] { 0, -1, -2, -3, -4, -5 });
Assert.AreEqual(0, output.SpaceLeft);
CodedInputStream input = CodedInputStream.CreateInstance(bytes);
uint tag;
string name;
Assert.IsTrue(input.ReadTag(out tag, out name));
List<int> values = new List<int>();
input.ReadInt32Array(tag, name, values);
Assert.AreEqual(6, values.Count);
for (int i = 0; i > -6; i--)
Assert.AreEqual(i, values[Math.Abs(i)]);
}
[Test]
public void TestNegativeEnumArray()
{
int arraySize = 1 + 1 + (11 * 5);
int msgSize = arraySize;
byte[] bytes = new byte[msgSize];
CodedOutputStream output = CodedOutputStream.CreateInstance(bytes);
output.WriteEnumArray(8, "", new int[] { 0, -1, -2, -3, -4, -5 });
Assert.AreEqual(0, output.SpaceLeft);
CodedInputStream input = CodedInputStream.CreateInstance(bytes);
uint tag;
string name;
Assert.IsTrue(input.ReadTag(out tag, out name));
List<int> values = new List<int>();
input.ReadInt32Array(tag, name, values);
Assert.AreEqual(6, values.Count);
for (int i = 0; i > -6; i--)
Assert.AreEqual(i, values[Math.Abs(i)]);
}
[Test] [Test]
public void TestCodedInputOutputPosition() public void TestCodedInputOutputPosition()
{ {
@ -377,92 +293,96 @@ namespace Google.ProtocolBuffers
byte[] child = new byte[120]; byte[] child = new byte[120];
{ {
MemoryStream ms = new MemoryStream(child); MemoryStream ms = new MemoryStream(child);
CodedOutputStream cout = CodedOutputStream.CreateInstance(ms, 20); CodedOutputStream cout = new CodedOutputStream(ms, 20);
// Field 11: numeric value: 500 // Field 11: numeric value: 500
cout.WriteTag(11, WireFormat.WireType.Varint); cout.WriteTag(11, WireFormat.WireType.Varint);
Assert.AreEqual(1, cout.Position); Assert.AreEqual(1, cout.Position);
cout.WriteInt32NoTag(500); cout.WriteInt32(500);
Assert.AreEqual(3, cout.Position); Assert.AreEqual(3, cout.Position);
//Field 12: length delimited 120 bytes //Field 12: length delimited 120 bytes
cout.WriteTag(12, WireFormat.WireType.LengthDelimited); cout.WriteTag(12, WireFormat.WireType.LengthDelimited);
Assert.AreEqual(4, cout.Position); Assert.AreEqual(4, cout.Position);
cout.WriteBytesNoTag(ByteString.CopyFrom(content)); cout.WriteBytes(ByteString.CopyFrom(content));
Assert.AreEqual(115, cout.Position); Assert.AreEqual(115, cout.Position);
// Field 13: fixed numeric value: 501 // Field 13: fixed numeric value: 501
cout.WriteTag(13, WireFormat.WireType.Fixed32); cout.WriteTag(13, WireFormat.WireType.Fixed32);
Assert.AreEqual(116, cout.Position); Assert.AreEqual(116, cout.Position);
cout.WriteSFixed32NoTag(501); cout.WriteSFixed32(501);
Assert.AreEqual(120, cout.Position); Assert.AreEqual(120, cout.Position);
cout.Flush(); cout.Flush();
} }
byte[] bytes = new byte[130]; byte[] bytes = new byte[130];
{ {
CodedOutputStream cout = CodedOutputStream.CreateInstance(bytes); CodedOutputStream cout = new CodedOutputStream(bytes);
// Field 1: numeric value: 500 // Field 1: numeric value: 500
cout.WriteTag(1, WireFormat.WireType.Varint); cout.WriteTag(1, WireFormat.WireType.Varint);
Assert.AreEqual(1, cout.Position); Assert.AreEqual(1, cout.Position);
cout.WriteInt32NoTag(500); cout.WriteInt32(500);
Assert.AreEqual(3, cout.Position); Assert.AreEqual(3, cout.Position);
//Field 2: length delimited 120 bytes //Field 2: length delimited 120 bytes
cout.WriteTag(2, WireFormat.WireType.LengthDelimited); cout.WriteTag(2, WireFormat.WireType.LengthDelimited);
Assert.AreEqual(4, cout.Position); Assert.AreEqual(4, cout.Position);
cout.WriteBytesNoTag(ByteString.CopyFrom(child)); cout.WriteBytes(ByteString.CopyFrom(child));
Assert.AreEqual(125, cout.Position); Assert.AreEqual(125, cout.Position);
// Field 3: fixed numeric value: 500 // Field 3: fixed numeric value: 500
cout.WriteTag(3, WireFormat.WireType.Fixed32); cout.WriteTag(3, WireFormat.WireType.Fixed32);
Assert.AreEqual(126, cout.Position); Assert.AreEqual(126, cout.Position);
cout.WriteSFixed32NoTag(501); cout.WriteSFixed32(501);
Assert.AreEqual(130, cout.Position); Assert.AreEqual(130, cout.Position);
cout.Flush(); cout.Flush();
} }
//Now test Input stream: // Now test Input stream:
{ {
CodedInputStream cin = CodedInputStream.CreateInstance(new MemoryStream(bytes), new byte[50]); CodedInputStream cin = new CodedInputStream(new MemoryStream(bytes), new byte[50], 0, 0);
uint tag;
int intValue = 0;
string ignore;
Assert.AreEqual(0, cin.Position); Assert.AreEqual(0, cin.Position);
// Field 1: // Field 1:
Assert.IsTrue(cin.ReadTag(out tag, out ignore) && tag >> 3 == 1); uint tag = cin.ReadTag();
Assert.AreEqual(1, tag >> 3);
Assert.AreEqual(1, cin.Position); Assert.AreEqual(1, cin.Position);
Assert.IsTrue(cin.ReadInt32(ref intValue) && intValue == 500); Assert.AreEqual(500, cin.ReadInt32());
Assert.AreEqual(3, cin.Position); Assert.AreEqual(3, cin.Position);
//Field 2: //Field 2:
Assert.IsTrue(cin.ReadTag(out tag, out ignore) && tag >> 3 == 2); tag = cin.ReadTag();
Assert.AreEqual(2, tag >> 3);
Assert.AreEqual(4, cin.Position); Assert.AreEqual(4, cin.Position);
uint childlen = cin.ReadRawVarint32(); int childlen = cin.ReadLength();
Assert.AreEqual(120u, childlen); Assert.AreEqual(120, childlen);
Assert.AreEqual(5, cin.Position); Assert.AreEqual(5, cin.Position);
int oldlimit = cin.PushLimit((int)childlen); int oldlimit = cin.PushLimit((int)childlen);
Assert.AreEqual(5, cin.Position); Assert.AreEqual(5, cin.Position);
// Now we are reading child message // Now we are reading child message
{ {
// Field 11: numeric value: 500 // Field 11: numeric value: 500
Assert.IsTrue(cin.ReadTag(out tag, out ignore) && tag >> 3 == 11); tag = cin.ReadTag();
Assert.AreEqual(11, tag >> 3);
Assert.AreEqual(6, cin.Position); Assert.AreEqual(6, cin.Position);
Assert.IsTrue(cin.ReadInt32(ref intValue) && intValue == 500); Assert.AreEqual(500, cin.ReadInt32());
Assert.AreEqual(8, cin.Position); Assert.AreEqual(8, cin.Position);
//Field 12: length delimited 120 bytes //Field 12: length delimited 120 bytes
Assert.IsTrue(cin.ReadTag(out tag, out ignore) && tag >> 3 == 12); tag = cin.ReadTag();
Assert.AreEqual(12, tag >> 3);
Assert.AreEqual(9, cin.Position); Assert.AreEqual(9, cin.Position);
ByteString bstr = null; ByteString bstr = cin.ReadBytes();
Assert.IsTrue(cin.ReadBytes(ref bstr) && bstr.Length == 110 && bstr.ToByteArray()[109] == 109); Assert.AreEqual(110, bstr.Length);
Assert.AreEqual((byte) 109, bstr[109]);
Assert.AreEqual(120, cin.Position); Assert.AreEqual(120, cin.Position);
// Field 13: fixed numeric value: 501 // Field 13: fixed numeric value: 501
Assert.IsTrue(cin.ReadTag(out tag, out ignore) && tag >> 3 == 13); tag = cin.ReadTag();
Assert.AreEqual(13, tag >> 3);
// ROK - Previously broken here, this returned 126 failing to account for bufferSizeAfterLimit // ROK - Previously broken here, this returned 126 failing to account for bufferSizeAfterLimit
Assert.AreEqual(121, cin.Position); Assert.AreEqual(121, cin.Position);
Assert.IsTrue(cin.ReadSFixed32(ref intValue) && intValue == 501); Assert.AreEqual(501, cin.ReadSFixed32());
Assert.AreEqual(125, cin.Position); Assert.AreEqual(125, cin.Position);
Assert.IsTrue(cin.IsAtEnd); Assert.IsTrue(cin.IsAtEnd);
} }
cin.PopLimit(oldlimit); cin.PopLimit(oldlimit);
Assert.AreEqual(125, cin.Position); Assert.AreEqual(125, cin.Position);
// Field 3: fixed numeric value: 501 // Field 3: fixed numeric value: 501
Assert.IsTrue(cin.ReadTag(out tag, out ignore) && tag >> 3 == 3); tag = cin.ReadTag();
Assert.AreEqual(3, tag >> 3);
Assert.AreEqual(126, cin.Position); Assert.AreEqual(126, cin.Position);
Assert.IsTrue(cin.ReadSFixed32(ref intValue) && intValue == 501); Assert.AreEqual(501, cin.ReadSFixed32());
Assert.AreEqual(130, cin.Position); Assert.AreEqual(130, cin.Position);
Assert.IsTrue(cin.IsAtEnd); Assert.IsTrue(cin.IsAtEnd);
} }

@ -0,0 +1,570 @@
#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
using System;
using System.Collections.Generic;
using Google.Protobuf.TestProtos;
using NUnit.Framework;
using System.Collections;
using System.Linq;
namespace Google.Protobuf.Collections
{
/// <summary>
/// Tests for MapField which aren't reliant on the encoded format -
/// tests for serialization/deserialization are part of GeneratedMessageTest.
/// </summary>
public class MapFieldTest
{
[Test]
public void Clone_ClonesMessages()
{
var message = new ForeignMessage { C = 20 };
var map = new MapField<string, ForeignMessage> { { "x", message } };
var clone = map.Clone();
map["x"].C = 30;
Assert.AreEqual(20, clone["x"].C);
}
[Test]
public void NullValues()
{
TestNullValues<int?>(0);
TestNullValues("");
TestNullValues(new TestAllTypes());
}
private void TestNullValues<T>(T nonNullValue)
{
var map = new MapField<int, T>(false);
var nullValue = (T) (object) null;
Assert.Throws<ArgumentNullException>(() => map.Add(0, nullValue));
Assert.Throws<ArgumentNullException>(() => map[0] = nullValue);
map.Add(1, nonNullValue);
map[1] = nonNullValue;
// Doesn't throw...
map = new MapField<int, T>(true);
map.Add(0, nullValue);
map[0] = nullValue;
map.Add(1, nonNullValue);
map[1] = nonNullValue;
}
[Test]
public void Add_ForbidsNullKeys()
{
var map = new MapField<string, ForeignMessage>();
Assert.Throws<ArgumentNullException>(() => map.Add(null, new ForeignMessage()));
}
[Test]
public void Indexer_ForbidsNullKeys()
{
var map = new MapField<string, ForeignMessage>();
Assert.Throws<ArgumentNullException>(() => map[null] = new ForeignMessage());
}
[Test]
public void AddPreservesInsertionOrder()
{
var map = new MapField<string, string>();
map.Add("a", "v1");
map.Add("b", "v2");
map.Add("c", "v3");
map.Remove("b");
map.Add("d", "v4");
CollectionAssert.AreEqual(new[] { "a", "c", "d" }, map.Keys);
CollectionAssert.AreEqual(new[] { "v1", "v3", "v4" }, map.Values);
}
[Test]
public void EqualityIsOrderInsensitive()
{
var map1 = new MapField<string, string>();
map1.Add("a", "v1");
map1.Add("b", "v2");
var map2 = new MapField<string, string>();
map2.Add("b", "v2");
map2.Add("a", "v1");
EqualityTester.AssertEquality(map1, map2);
}
[Test]
public void EqualityIsKeySensitive()
{
var map1 = new MapField<string, string>();
map1.Add("first key", "v1");
map1.Add("second key", "v2");
var map2 = new MapField<string, string>();
map2.Add("third key", "v1");
map2.Add("fourth key", "v2");
EqualityTester.AssertInequality(map1, map2);
}
[Test]
public void Equality_Simple()
{
var map = new MapField<string, string>();
EqualityTester.AssertEquality(map, map);
EqualityTester.AssertInequality(map, null);
Assert.IsFalse(map.Equals(new object()));
}
[Test]
public void EqualityIsValueSensitive()
{
// Note: Without some care, it's a little easier than one might
// hope to see hash collisions, but only in some environments...
var map1 = new MapField<string, string>();
map1.Add("a", "first value");
map1.Add("b", "second value");
var map2 = new MapField<string, string>();
map2.Add("a", "third value");
map2.Add("b", "fourth value");
EqualityTester.AssertInequality(map1, map2);
}
[Test]
public void EqualityHandlesNullValues()
{
var map1 = new MapField<string, ForeignMessage>();
map1.Add("a", new ForeignMessage { C = 10 });
map1.Add("b", null);
var map2 = new MapField<string, ForeignMessage>();
map2.Add("a", new ForeignMessage { C = 10 });
map2.Add("b", null);
EqualityTester.AssertEquality(map1, map2);
// Check the null value isn't ignored entirely...
Assert.IsTrue(map1.Remove("b"));
EqualityTester.AssertInequality(map1, map2);
map1.Add("b", new ForeignMessage());
EqualityTester.AssertInequality(map1, map2);
map1["b"] = null;
EqualityTester.AssertEquality(map1, map2);
}
[Test]
public void Add_Dictionary()
{
var map1 = new MapField<string, string>
{
{ "x", "y" },
{ "a", "b" }
};
var map2 = new MapField<string, string>
{
{ "before", "" },
map1,
{ "after", "" }
};
var expected = new MapField<string, string>
{
{ "before", "" },
{ "x", "y" },
{ "a", "b" },
{ "after", "" }
};
Assert.AreEqual(expected, map2);
CollectionAssert.AreEqual(new[] { "before", "x", "a", "after" }, map2.Keys);
}
// General IDictionary<TKey, TValue> behavior tests
[Test]
public void Add_KeyAlreadyExists()
{
var map = new MapField<string, string>();
map.Add("foo", "bar");
Assert.Throws<ArgumentException>(() => map.Add("foo", "baz"));
}
[Test]
public void Add_Pair()
{
var map = new MapField<string, string>();
ICollection<KeyValuePair<string, string>> collection = map;
collection.Add(NewKeyValuePair("x", "y"));
Assert.AreEqual("y", map["x"]);
Assert.Throws<ArgumentException>(() => collection.Add(NewKeyValuePair("x", "z")));
}
[Test]
public void Contains_Pair()
{
var map = new MapField<string, string> { { "x", "y" } };
ICollection<KeyValuePair<string, string>> collection = map;
Assert.IsTrue(collection.Contains(NewKeyValuePair("x", "y")));
Assert.IsFalse(collection.Contains(NewKeyValuePair("x", "z")));
Assert.IsFalse(collection.Contains(NewKeyValuePair("z", "y")));
}
[Test]
public void Remove_Key()
{
var map = new MapField<string, string>();
map.Add("foo", "bar");
Assert.AreEqual(1, map.Count);
Assert.IsFalse(map.Remove("missing"));
Assert.AreEqual(1, map.Count);
Assert.IsTrue(map.Remove("foo"));
Assert.AreEqual(0, map.Count);
Assert.Throws<ArgumentNullException>(() => map.Remove(null));
}
[Test]
public void Remove_Pair()
{
var map = new MapField<string, string>();
map.Add("foo", "bar");
ICollection<KeyValuePair<string, string>> collection = map;
Assert.AreEqual(1, map.Count);
Assert.IsFalse(collection.Remove(NewKeyValuePair("wrong key", "bar")));
Assert.AreEqual(1, map.Count);
Assert.IsFalse(collection.Remove(NewKeyValuePair("foo", "wrong value")));
Assert.AreEqual(1, map.Count);
Assert.IsTrue(collection.Remove(NewKeyValuePair("foo", "bar")));
Assert.AreEqual(0, map.Count);
Assert.Throws<ArgumentException>(() => collection.Remove(new KeyValuePair<string, string>(null, "")));
}
[Test]
public void CopyTo_Pair()
{
var map = new MapField<string, string>();
map.Add("foo", "bar");
ICollection<KeyValuePair<string, string>> collection = map;
KeyValuePair<string, string>[] array = new KeyValuePair<string, string>[3];
collection.CopyTo(array, 1);
Assert.AreEqual(NewKeyValuePair("foo", "bar"), array[1]);
}
[Test]
public void Clear()
{
var map = new MapField<string, string> { { "x", "y" } };
Assert.AreEqual(1, map.Count);
map.Clear();
Assert.AreEqual(0, map.Count);
map.Add("x", "y");
Assert.AreEqual(1, map.Count);
}
[Test]
public void Indexer_Get()
{
var map = new MapField<string, string> { { "x", "y" } };
Assert.AreEqual("y", map["x"]);
Assert.Throws<KeyNotFoundException>(() => { var ignored = map["z"]; });
}
[Test]
public void Indexer_Set()
{
var map = new MapField<string, string>();
map["x"] = "y";
Assert.AreEqual("y", map["x"]);
map["x"] = "z"; // This won't throw, unlike Add.
Assert.AreEqual("z", map["x"]);
}
[Test]
public void GetEnumerator_NonGeneric()
{
IEnumerable map = new MapField<string, string> { { "x", "y" } };
CollectionAssert.AreEqual(new[] { new KeyValuePair<string, string>("x", "y") },
map.Cast<object>().ToList());
}
// Test for the explicitly-implemented non-generic IDictionary interface
[Test]
public void IDictionary_GetEnumerator()
{
IDictionary map = new MapField<string, string> { { "x", "y" } };
var enumerator = map.GetEnumerator();
// Commented assertions show an ideal situation - it looks like
// the LinkedList enumerator doesn't throw when you ask for the current entry
// at an inappropriate time; fixing this would be more work than it's worth.
// Assert.Throws<InvalidOperationException>(() => enumerator.Current.GetHashCode());
Assert.IsTrue(enumerator.MoveNext());
Assert.AreEqual("x", enumerator.Key);
Assert.AreEqual("y", enumerator.Value);
Assert.AreEqual(new DictionaryEntry("x", "y"), enumerator.Current);
Assert.AreEqual(new DictionaryEntry("x", "y"), enumerator.Entry);
Assert.IsFalse(enumerator.MoveNext());
// Assert.Throws<InvalidOperationException>(() => enumerator.Current.GetHashCode());
enumerator.Reset();
// Assert.Throws<InvalidOperationException>(() => enumerator.Current.GetHashCode());
Assert.IsTrue(enumerator.MoveNext());
Assert.AreEqual("x", enumerator.Key); // Assume the rest are okay
}
[Test]
public void IDictionary_Add()
{
var map = new MapField<string, string> { { "x", "y" } };
IDictionary dictionary = map;
dictionary.Add("a", "b");
Assert.AreEqual("b", map["a"]);
Assert.Throws<ArgumentException>(() => dictionary.Add("a", "duplicate"));
Assert.Throws<InvalidCastException>(() => dictionary.Add(new object(), "key is bad"));
Assert.Throws<InvalidCastException>(() => dictionary.Add("value is bad", new object()));
}
[Test]
public void IDictionary_Contains()
{
var map = new MapField<string, string> { { "x", "y" } };
IDictionary dictionary = map;
Assert.IsFalse(dictionary.Contains("a"));
Assert.IsFalse(dictionary.Contains(5));
// Surprising, but IDictionary.Contains is only about keys.
Assert.IsFalse(dictionary.Contains(new DictionaryEntry("x", "y")));
Assert.IsTrue(dictionary.Contains("x"));
}
[Test]
public void IDictionary_Remove()
{
var map = new MapField<string, string> { { "x", "y" } };
IDictionary dictionary = map;
dictionary.Remove("a");
Assert.AreEqual(1, dictionary.Count);
dictionary.Remove(5);
Assert.AreEqual(1, dictionary.Count);
dictionary.Remove(new DictionaryEntry("x", "y"));
Assert.AreEqual(1, dictionary.Count);
dictionary.Remove("x");
Assert.AreEqual(0, dictionary.Count);
Assert.Throws<ArgumentNullException>(() => dictionary.Remove(null));
}
[Test]
public void IDictionary_CopyTo()
{
var map = new MapField<string, string> { { "x", "y" } };
IDictionary dictionary = map;
var array = new DictionaryEntry[3];
dictionary.CopyTo(array, 1);
CollectionAssert.AreEqual(new[] { default(DictionaryEntry), new DictionaryEntry("x", "y"), default(DictionaryEntry) },
array);
var objectArray = new object[3];
dictionary.CopyTo(objectArray, 1);
CollectionAssert.AreEqual(new object[] { null, new DictionaryEntry("x", "y"), null },
objectArray);
}
[Test]
public void IDictionary_IsFixedSize()
{
var map = new MapField<string, string> { { "x", "y" } };
IDictionary dictionary = map;
Assert.IsFalse(dictionary.IsFixedSize);
}
[Test]
public void IDictionary_Keys()
{
IDictionary dictionary = new MapField<string, string> { { "x", "y" } };
CollectionAssert.AreEqual(new[] { "x" }, dictionary.Keys);
}
[Test]
public void IDictionary_Values()
{
IDictionary dictionary = new MapField<string, string> { { "x", "y" } };
CollectionAssert.AreEqual(new[] { "y" }, dictionary.Values);
}
[Test]
public void IDictionary_IsSynchronized()
{
IDictionary dictionary = new MapField<string, string> { { "x", "y" } };
Assert.IsFalse(dictionary.IsSynchronized);
}
[Test]
public void IDictionary_SyncRoot()
{
IDictionary dictionary = new MapField<string, string> { { "x", "y" } };
Assert.AreSame(dictionary, dictionary.SyncRoot);
}
[Test]
public void IDictionary_Indexer_Get()
{
IDictionary dictionary = new MapField<string, string> { { "x", "y" } };
Assert.AreEqual("y", dictionary["x"]);
Assert.IsNull(dictionary["a"]);
Assert.IsNull(dictionary[5]);
Assert.Throws<ArgumentNullException>(() => dictionary[null].GetHashCode());
}
[Test]
public void IDictionary_Indexer_Set()
{
var map = new MapField<string, string> { { "x", "y" } };
IDictionary dictionary = map;
map["a"] = "b";
Assert.AreEqual("b", map["a"]);
map["a"] = "c";
Assert.AreEqual("c", map["a"]);
Assert.Throws<InvalidCastException>(() => dictionary[5] = "x");
Assert.Throws<InvalidCastException>(() => dictionary["x"] = 5);
Assert.Throws<ArgumentNullException>(() => dictionary[null] = "z");
Assert.Throws<ArgumentNullException>(() => dictionary["x"] = null);
}
[Test]
public void AllowNullValues_Property()
{
// Non-message reference type values are non-nullable by default, but can be overridden
Assert.IsFalse(new MapField<int, string>().AllowsNullValues);
Assert.IsFalse(new MapField<int, string>(false).AllowsNullValues);
Assert.IsTrue(new MapField<int, string>(true).AllowsNullValues);
// Non-nullable value type values are never nullable
Assert.IsFalse(new MapField<int, int>().AllowsNullValues);
Assert.IsFalse(new MapField<int, int>(false).AllowsNullValues);
Assert.Throws<ArgumentException>(() => new MapField<int, int>(true));
// Message type values are nullable by default, but can be overridden
Assert.IsTrue(new MapField<int, TestAllTypes>().AllowsNullValues);
Assert.IsFalse(new MapField<int, TestAllTypes>(false).AllowsNullValues);
Assert.IsTrue(new MapField<int, TestAllTypes>(true).AllowsNullValues);
// Nullable value type values are nullable by default, but can be overridden
Assert.IsTrue(new MapField<int, int?>().AllowsNullValues);
Assert.IsFalse(new MapField<int, int?>(false).AllowsNullValues);
Assert.IsTrue(new MapField<int, int?>(true).AllowsNullValues);
}
[Test]
public void KeysReturnsLiveView()
{
var map = new MapField<string, string>();
var keys = map.Keys;
CollectionAssert.AreEqual(new string[0], keys);
map["foo"] = "bar";
map["x"] = "y";
CollectionAssert.AreEqual(new[] { "foo", "x" }, keys);
}
[Test]
public void ValuesReturnsLiveView()
{
var map = new MapField<string, string>();
var values = map.Values;
CollectionAssert.AreEqual(new string[0], values);
map["foo"] = "bar";
map["x"] = "y";
CollectionAssert.AreEqual(new[] { "bar", "y" }, values);
}
// Just test keys - we know the implementation is the same for values
[Test]
public void ViewsAreReadOnly()
{
var map = new MapField<string, string>();
var keys = map.Keys;
Assert.IsTrue(keys.IsReadOnly);
Assert.Throws<NotSupportedException>(() => keys.Clear());
Assert.Throws<NotSupportedException>(() => keys.Remove("a"));
Assert.Throws<NotSupportedException>(() => keys.Add("a"));
}
// Just test keys - we know the implementation is the same for values
[Test]
public void ViewCopyTo()
{
var map = new MapField<string, string> { { "foo", "bar" }, { "x", "y" } };
var keys = map.Keys;
var array = new string[4];
Assert.Throws<ArgumentException>(() => keys.CopyTo(array, 3));
Assert.Throws<ArgumentOutOfRangeException>(() => keys.CopyTo(array, -1));
keys.CopyTo(array, 1);
CollectionAssert.AreEqual(new[] { null, "foo", "x", null }, array);
}
// Just test keys - we know the implementation is the same for values
[Test]
public void NonGenericViewCopyTo()
{
IDictionary map = new MapField<string, string> { { "foo", "bar" }, { "x", "y" } };
ICollection keys = map.Keys;
// Note the use of the Array type here rather than string[]
Array array = new string[4];
Assert.Throws<ArgumentException>(() => keys.CopyTo(array, 3));
Assert.Throws<ArgumentOutOfRangeException>(() => keys.CopyTo(array, -1));
keys.CopyTo(array, 1);
CollectionAssert.AreEqual(new[] { null, "foo", "x", null }, array);
}
[Test]
public void KeysContains()
{
var map = new MapField<string, string> { { "foo", "bar" }, { "x", "y" } };
var keys = map.Keys;
Assert.IsTrue(keys.Contains("foo"));
Assert.IsFalse(keys.Contains("bar")); // It's a value!
Assert.IsFalse(keys.Contains("1"));
// Keys can't be null, so we should prevent contains check
Assert.Throws<ArgumentNullException>(() => keys.Contains(null));
}
[Test]
public void ValuesContains()
{
var map = new MapField<string, string> { { "foo", "bar" }, { "x", "y" } };
var values = map.Values;
Assert.IsTrue(values.Contains("bar"));
Assert.IsFalse(values.Contains("foo")); // It's a key!
Assert.IsFalse(values.Contains("1"));
// Values can be null, so this makes sense
Assert.IsFalse(values.Contains(null));
}
private static KeyValuePair<TKey, TValue> NewKeyValuePair<TKey, TValue>(TKey key, TValue value)
{
return new KeyValuePair<TKey, TValue>(key, value);
}
}
}

@ -0,0 +1,603 @@
#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
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Google.Protobuf.TestProtos;
using NUnit.Framework;
namespace Google.Protobuf.Collections
{
public class RepeatedFieldTest
{
[Test]
public void NullValuesRejected()
{
var list = new RepeatedField<string>();
Assert.Throws<ArgumentNullException>(() => list.Add((string)null));
Assert.Throws<ArgumentNullException>(() => list.Add((IEnumerable<string>)null));
Assert.Throws<ArgumentNullException>(() => list.Add((RepeatedField<string>)null));
Assert.Throws<ArgumentNullException>(() => list.Contains(null));
Assert.Throws<ArgumentNullException>(() => list.IndexOf(null));
}
[Test]
public void Add_SingleItem()
{
var list = new RepeatedField<string>();
list.Add("foo");
Assert.AreEqual(1, list.Count);
Assert.AreEqual("foo", list[0]);
}
[Test]
public void Add_Sequence()
{
var list = new RepeatedField<string>();
list.Add(new[] { "foo", "bar" });
Assert.AreEqual(2, list.Count);
Assert.AreEqual("foo", list[0]);
Assert.AreEqual("bar", list[1]);
}
[Test]
public void Add_RepeatedField()
{
var list = new RepeatedField<string> { "original" };
list.Add(new RepeatedField<string> { "foo", "bar" });
Assert.AreEqual(3, list.Count);
Assert.AreEqual("original", list[0]);
Assert.AreEqual("foo", list[1]);
Assert.AreEqual("bar", list[2]);
}
[Test]
public void RemoveAt_Valid()
{
var list = new RepeatedField<string> { "first", "second", "third" };
list.RemoveAt(1);
CollectionAssert.AreEqual(new[] { "first", "third" }, list);
// Just check that these don't throw...
list.RemoveAt(list.Count - 1); // Now the count will be 1...
list.RemoveAt(0);
Assert.AreEqual(0, list.Count);
}
[Test]
public void RemoveAt_Invalid()
{
var list = new RepeatedField<string> { "first", "second", "third" };
Assert.Throws<ArgumentOutOfRangeException>(() => list.RemoveAt(-1));
Assert.Throws<ArgumentOutOfRangeException>(() => list.RemoveAt(3));
}
[Test]
public void Insert_Valid()
{
var list = new RepeatedField<string> { "first", "second" };
list.Insert(1, "middle");
CollectionAssert.AreEqual(new[] { "first", "middle", "second" }, list);
list.Insert(3, "end");
CollectionAssert.AreEqual(new[] { "first", "middle", "second", "end" }, list);
list.Insert(0, "start");
CollectionAssert.AreEqual(new[] { "start", "first", "middle", "second", "end" }, list);
}
[Test]
public void Insert_Invalid()
{
var list = new RepeatedField<string> { "first", "second" };
Assert.Throws<ArgumentOutOfRangeException>(() => list.Insert(-1, "foo"));
Assert.Throws<ArgumentOutOfRangeException>(() => list.Insert(3, "foo"));
Assert.Throws<ArgumentNullException>(() => list.Insert(0, null));
}
[Test]
public void Equals_RepeatedField()
{
var list = new RepeatedField<string> { "first", "second" };
Assert.IsFalse(list.Equals((RepeatedField<string>) null));
Assert.IsTrue(list.Equals(list));
Assert.IsFalse(list.Equals(new RepeatedField<string> { "first", "third" }));
Assert.IsFalse(list.Equals(new RepeatedField<string> { "first" }));
Assert.IsTrue(list.Equals(new RepeatedField<string> { "first", "second" }));
}
[Test]
public void Equals_Object()
{
var list = new RepeatedField<string> { "first", "second" };
Assert.IsFalse(list.Equals((object) null));
Assert.IsTrue(list.Equals((object) list));
Assert.IsFalse(list.Equals((object) new RepeatedField<string> { "first", "third" }));
Assert.IsFalse(list.Equals((object) new RepeatedField<string> { "first" }));
Assert.IsTrue(list.Equals((object) new RepeatedField<string> { "first", "second" }));
Assert.IsFalse(list.Equals(new object()));
}
[Test]
public void GetEnumerator_GenericInterface()
{
IEnumerable<string> list = new RepeatedField<string> { "first", "second" };
// Select gets rid of the optimizations in ToList...
CollectionAssert.AreEqual(new[] { "first", "second" }, list.Select(x => x).ToList());
}
[Test]
public void GetEnumerator_NonGenericInterface()
{
IEnumerable list = new RepeatedField<string> { "first", "second" };
CollectionAssert.AreEqual(new[] { "first", "second" }, list.Cast<object>().ToList());
}
[Test]
public void CopyTo()
{
var list = new RepeatedField<string> { "first", "second" };
string[] stringArray = new string[4];
list.CopyTo(stringArray, 1);
CollectionAssert.AreEqual(new[] { null, "first", "second", null }, stringArray);
}
[Test]
public void Indexer_Get()
{
var list = new RepeatedField<string> { "first", "second" };
Assert.AreEqual("first", list[0]);
Assert.AreEqual("second", list[1]);
Assert.Throws<ArgumentOutOfRangeException>(() => list[-1].GetHashCode());
Assert.Throws<ArgumentOutOfRangeException>(() => list[2].GetHashCode());
}
[Test]
public void Indexer_Set()
{
var list = new RepeatedField<string> { "first", "second" };
list[0] = "changed";
Assert.AreEqual("changed", list[0]);
Assert.Throws<ArgumentNullException>(() => list[0] = null);
Assert.Throws<ArgumentOutOfRangeException>(() => list[-1] = "bad");
Assert.Throws<ArgumentOutOfRangeException>(() => list[2] = "bad");
}
[Test]
public void Clone_ReturnsMutable()
{
var list = new RepeatedField<int> { 0 };
var clone = list.Clone();
clone[0] = 1;
}
[Test]
public void Enumerator()
{
var list = new RepeatedField<string> { "first", "second" };
using (var enumerator = list.GetEnumerator())
{
Assert.IsTrue(enumerator.MoveNext());
Assert.AreEqual("first", enumerator.Current);
Assert.IsTrue(enumerator.MoveNext());
Assert.AreEqual("second", enumerator.Current);
Assert.IsFalse(enumerator.MoveNext());
Assert.IsFalse(enumerator.MoveNext());
}
}
[Test]
public void AddEntriesFrom_PackedInt32()
{
uint packedTag = WireFormat.MakeTag(10, WireFormat.WireType.LengthDelimited);
var stream = new MemoryStream();
var output = new CodedOutputStream(stream);
var length = CodedOutputStream.ComputeInt32Size(10)
+ CodedOutputStream.ComputeInt32Size(999)
+ CodedOutputStream.ComputeInt32Size(-1000);
output.WriteTag(packedTag);
output.WriteRawVarint32((uint) length);
output.WriteInt32(10);
output.WriteInt32(999);
output.WriteInt32(-1000);
output.Flush();
stream.Position = 0;
// Deliberately "expecting" a non-packed tag, but we detect that the data is
// actually packed.
uint nonPackedTag = WireFormat.MakeTag(10, WireFormat.WireType.LengthDelimited);
var field = new RepeatedField<int>();
var input = new CodedInputStream(stream);
input.AssertNextTag(packedTag);
field.AddEntriesFrom(input, FieldCodec.ForInt32(nonPackedTag));
CollectionAssert.AreEqual(new[] { 10, 999, -1000 }, field);
Assert.IsTrue(input.IsAtEnd);
}
[Test]
public void AddEntriesFrom_NonPackedInt32()
{
uint nonPackedTag = WireFormat.MakeTag(10, WireFormat.WireType.Varint);
var stream = new MemoryStream();
var output = new CodedOutputStream(stream);
output.WriteTag(nonPackedTag);
output.WriteInt32(10);
output.WriteTag(nonPackedTag);
output.WriteInt32(999);
output.WriteTag(nonPackedTag);
output.WriteInt32(-1000); // Just for variety...
output.Flush();
stream.Position = 0;
// Deliberately "expecting" a packed tag, but we detect that the data is
// actually not packed.
uint packedTag = WireFormat.MakeTag(10, WireFormat.WireType.LengthDelimited);
var field = new RepeatedField<int>();
var input = new CodedInputStream(stream);
input.AssertNextTag(nonPackedTag);
field.AddEntriesFrom(input, FieldCodec.ForInt32(packedTag));
CollectionAssert.AreEqual(new[] { 10, 999, -1000 }, field);
Assert.IsTrue(input.IsAtEnd);
}
[Test]
public void AddEntriesFrom_String()
{
uint tag = WireFormat.MakeTag(10, WireFormat.WireType.LengthDelimited);
var stream = new MemoryStream();
var output = new CodedOutputStream(stream);
output.WriteTag(tag);
output.WriteString("Foo");
output.WriteTag(tag);
output.WriteString("");
output.WriteTag(tag);
output.WriteString("Bar");
output.Flush();
stream.Position = 0;
var field = new RepeatedField<string>();
var input = new CodedInputStream(stream);
input.AssertNextTag(tag);
field.AddEntriesFrom(input, FieldCodec.ForString(tag));
CollectionAssert.AreEqual(new[] { "Foo", "", "Bar" }, field);
Assert.IsTrue(input.IsAtEnd);
}
[Test]
public void AddEntriesFrom_Message()
{
var message1 = new ForeignMessage { C = 2000 };
var message2 = new ForeignMessage { C = -250 };
uint tag = WireFormat.MakeTag(10, WireFormat.WireType.LengthDelimited);
var stream = new MemoryStream();
var output = new CodedOutputStream(stream);
output.WriteTag(tag);
output.WriteMessage(message1);
output.WriteTag(tag);
output.WriteMessage(message2);
output.Flush();
stream.Position = 0;
var field = new RepeatedField<ForeignMessage>();
var input = new CodedInputStream(stream);
input.AssertNextTag(tag);
field.AddEntriesFrom(input, FieldCodec.ForMessage(tag, ForeignMessage.Parser));
CollectionAssert.AreEqual(new[] { message1, message2}, field);
Assert.IsTrue(input.IsAtEnd);
}
[Test]
public void WriteTo_PackedInt32()
{
uint tag = WireFormat.MakeTag(10, WireFormat.WireType.LengthDelimited);
var field = new RepeatedField<int> { 10, 1000, 1000000 };
var stream = new MemoryStream();
var output = new CodedOutputStream(stream);
field.WriteTo(output, FieldCodec.ForInt32(tag));
output.Flush();
stream.Position = 0;
var input = new CodedInputStream(stream);
input.AssertNextTag(tag);
var length = input.ReadLength();
Assert.AreEqual(10, input.ReadInt32());
Assert.AreEqual(1000, input.ReadInt32());
Assert.AreEqual(1000000, input.ReadInt32());
Assert.IsTrue(input.IsAtEnd);
Assert.AreEqual(1 + CodedOutputStream.ComputeLengthSize(length) + length, stream.Length);
}
[Test]
public void WriteTo_NonPackedInt32()
{
uint tag = WireFormat.MakeTag(10, WireFormat.WireType.Varint);
var field = new RepeatedField<int> { 10, 1000, 1000000};
var stream = new MemoryStream();
var output = new CodedOutputStream(stream);
field.WriteTo(output, FieldCodec.ForInt32(tag));
output.Flush();
stream.Position = 0;
var input = new CodedInputStream(stream);
input.AssertNextTag(tag);
Assert.AreEqual(10, input.ReadInt32());
input.AssertNextTag(tag);
Assert.AreEqual(1000, input.ReadInt32());
input.AssertNextTag(tag);
Assert.AreEqual(1000000, input.ReadInt32());
Assert.IsTrue(input.IsAtEnd);
}
[Test]
public void WriteTo_String()
{
uint tag = WireFormat.MakeTag(10, WireFormat.WireType.LengthDelimited);
var field = new RepeatedField<string> { "Foo", "", "Bar" };
var stream = new MemoryStream();
var output = new CodedOutputStream(stream);
field.WriteTo(output, FieldCodec.ForString(tag));
output.Flush();
stream.Position = 0;
var input = new CodedInputStream(stream);
input.AssertNextTag(tag);
Assert.AreEqual("Foo", input.ReadString());
input.AssertNextTag(tag);
Assert.AreEqual("", input.ReadString());
input.AssertNextTag(tag);
Assert.AreEqual("Bar", input.ReadString());
Assert.IsTrue(input.IsAtEnd);
}
[Test]
public void WriteTo_Message()
{
var message1 = new ForeignMessage { C = 20 };
var message2 = new ForeignMessage { C = 25 };
uint tag = WireFormat.MakeTag(10, WireFormat.WireType.LengthDelimited);
var field = new RepeatedField<ForeignMessage> { message1, message2 };
var stream = new MemoryStream();
var output = new CodedOutputStream(stream);
field.WriteTo(output, FieldCodec.ForMessage(tag, ForeignMessage.Parser));
output.Flush();
stream.Position = 0;
var input = new CodedInputStream(stream);
input.AssertNextTag(tag);
Assert.AreEqual(message1, input.ReadMessage(ForeignMessage.Parser));
input.AssertNextTag(tag);
Assert.AreEqual(message2, input.ReadMessage(ForeignMessage.Parser));
Assert.IsTrue(input.IsAtEnd);
}
[Test]
public void CalculateSize_VariableSizeNonPacked()
{
var list = new RepeatedField<int> { 1, 500, 1 };
var tag = WireFormat.MakeTag(1, WireFormat.WireType.Varint);
// 2 bytes for the first entry, 3 bytes for the second, 2 bytes for the third
Assert.AreEqual(7, list.CalculateSize(FieldCodec.ForInt32(tag)));
}
[Test]
public void CalculateSize_FixedSizeNonPacked()
{
var list = new RepeatedField<int> { 1, 500, 1 };
var tag = WireFormat.MakeTag(1, WireFormat.WireType.Fixed32);
// 5 bytes for the each entry
Assert.AreEqual(15, list.CalculateSize(FieldCodec.ForSFixed32(tag)));
}
[Test]
public void CalculateSize_VariableSizePacked()
{
var list = new RepeatedField<int> { 1, 500, 1};
var tag = WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited);
// 1 byte for the tag, 1 byte for the length,
// 1 byte for the first entry, 2 bytes for the second, 1 byte for the third
Assert.AreEqual(6, list.CalculateSize(FieldCodec.ForInt32(tag)));
}
[Test]
public void CalculateSize_FixedSizePacked()
{
var list = new RepeatedField<int> { 1, 500, 1 };
var tag = WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited);
// 1 byte for the tag, 1 byte for the length, 4 bytes per entry
Assert.AreEqual(14, list.CalculateSize(FieldCodec.ForSFixed32(tag)));
}
[Test]
public void TestNegativeEnumArray()
{
int arraySize = 1 + 1 + (11 * 5);
int msgSize = arraySize;
byte[] bytes = new byte[msgSize];
CodedOutputStream output = new CodedOutputStream(bytes);
uint tag = WireFormat.MakeTag(8, WireFormat.WireType.Varint);
for (int i = 0; i >= -5; i--)
{
output.WriteTag(tag);
output.WriteEnum(i);
}
Assert.AreEqual(0, output.SpaceLeft);
CodedInputStream input = new CodedInputStream(bytes);
tag = input.ReadTag();
RepeatedField<SampleEnum> values = new RepeatedField<SampleEnum>();
values.AddEntriesFrom(input, FieldCodec.ForEnum(tag, x => (int)x, x => (SampleEnum)x));
Assert.AreEqual(6, values.Count);
Assert.AreEqual(SampleEnum.None, values[0]);
Assert.AreEqual(((SampleEnum)(-1)), values[1]);
Assert.AreEqual(SampleEnum.NegativeValue, values[2]);
Assert.AreEqual(((SampleEnum)(-3)), values[3]);
Assert.AreEqual(((SampleEnum)(-4)), values[4]);
Assert.AreEqual(((SampleEnum)(-5)), values[5]);
}
[Test]
public void TestNegativeEnumPackedArray()
{
int arraySize = 1 + (10 * 5);
int msgSize = 1 + 1 + arraySize;
byte[] bytes = new byte[msgSize];
CodedOutputStream output = new CodedOutputStream(bytes);
// Length-delimited to show we want the packed representation
uint tag = WireFormat.MakeTag(8, WireFormat.WireType.LengthDelimited);
output.WriteTag(tag);
int size = 0;
for (int i = 0; i >= -5; i--)
{
size += CodedOutputStream.ComputeEnumSize(i);
}
output.WriteRawVarint32((uint)size);
for (int i = 0; i >= -5; i--)
{
output.WriteEnum(i);
}
Assert.AreEqual(0, output.SpaceLeft);
CodedInputStream input = new CodedInputStream(bytes);
tag = input.ReadTag();
RepeatedField<SampleEnum> values = new RepeatedField<SampleEnum>();
values.AddEntriesFrom(input, FieldCodec.ForEnum(tag, x => (int)x, x => (SampleEnum)x));
Assert.AreEqual(6, values.Count);
Assert.AreEqual(SampleEnum.None, values[0]);
Assert.AreEqual(((SampleEnum)(-1)), values[1]);
Assert.AreEqual(SampleEnum.NegativeValue, values[2]);
Assert.AreEqual(((SampleEnum)(-3)), values[3]);
Assert.AreEqual(((SampleEnum)(-4)), values[4]);
Assert.AreEqual(((SampleEnum)(-5)), values[5]);
}
// Fairly perfunctory tests for the non-generic IList implementation
[Test]
public void IList_Indexer()
{
var field = new RepeatedField<string> { "first", "second" };
IList list = field;
Assert.AreEqual("first", list[0]);
list[1] = "changed";
Assert.AreEqual("changed", field[1]);
}
[Test]
public void IList_Contains()
{
IList list = new RepeatedField<string> { "first", "second" };
Assert.IsTrue(list.Contains("second"));
Assert.IsFalse(list.Contains("third"));
Assert.IsFalse(list.Contains(new object()));
}
[Test]
public void IList_Add()
{
IList list = new RepeatedField<string> { "first", "second" };
list.Add("third");
CollectionAssert.AreEqual(new[] { "first", "second", "third" }, list);
}
[Test]
public void IList_Remove()
{
IList list = new RepeatedField<string> { "first", "second" };
list.Remove("third"); // No-op, no exception
list.Remove(new object()); // No-op, no exception
list.Remove("first");
CollectionAssert.AreEqual(new[] { "second" }, list);
}
[Test]
public void IList_IsFixedSize()
{
var field = new RepeatedField<string> { "first", "second" };
IList list = field;
Assert.IsFalse(list.IsFixedSize);
}
[Test]
public void IList_IndexOf()
{
IList list = new RepeatedField<string> { "first", "second" };
Assert.AreEqual(1, list.IndexOf("second"));
Assert.AreEqual(-1, list.IndexOf("third"));
Assert.AreEqual(-1, list.IndexOf(new object()));
}
[Test]
public void IList_SyncRoot()
{
IList list = new RepeatedField<string> { "first", "second" };
Assert.AreSame(list, list.SyncRoot);
}
[Test]
public void IList_CopyTo()
{
IList list = new RepeatedField<string> { "first", "second" };
string[] stringArray = new string[4];
list.CopyTo(stringArray, 1);
CollectionAssert.AreEqual(new[] { null, "first", "second", null }, stringArray);
object[] objectArray = new object[4];
list.CopyTo(objectArray, 1);
CollectionAssert.AreEqual(new[] { null, "first", "second", null }, objectArray);
Assert.Throws<ArrayTypeMismatchException>(() => list.CopyTo(new StringBuilder[4], 1));
Assert.Throws<ArrayTypeMismatchException>(() => list.CopyTo(new int[4], 1));
}
[Test]
public void IList_IsSynchronized()
{
IList list = new RepeatedField<string> { "first", "second" };
Assert.IsFalse(list.IsSynchronized);
}
[Test]
public void IList_Insert()
{
IList list = new RepeatedField<string> { "first", "second" };
list.Insert(1, "middle");
CollectionAssert.AreEqual(new[] { "first", "middle", "second" }, list);
}
}
}

@ -0,0 +1,98 @@
#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
using NUnit.Framework;
using System.Reflection;
namespace Google.Protobuf.Compatibility
{
public class PropertyInfoExtensionsTest
{
public string PublicReadWrite { get; set; }
private string PrivateReadWrite { get; set; }
public string PublicReadPrivateWrite { get; private set; }
public string PrivateReadPublicWrite { private get; set; }
public string PublicReadOnly { get { return null; } }
private string PrivateReadOnly { get { return null; } }
public string PublicWriteOnly { set { } }
private string PrivateWriteOnly { set { } }
[Test]
[TestCase("PublicReadWrite")]
[TestCase("PublicReadPrivateWrite")]
[TestCase("PublicReadOnly")]
public void GetGetMethod_Success(string name)
{
var propertyInfo = typeof(PropertyInfoExtensionsTest)
.GetProperty(name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
Assert.IsNotNull(PropertyInfoExtensions.GetGetMethod(propertyInfo));
}
[Test]
[TestCase("PrivateReadWrite")]
[TestCase("PrivateReadPublicWrite")]
[TestCase("PrivateReadOnly")]
[TestCase("PublicWriteOnly")]
[TestCase("PrivateWriteOnly")]
public void GetGetMethod_NoAccessibleGetter(string name)
{
var propertyInfo = typeof(PropertyInfoExtensionsTest)
.GetProperty(name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
Assert.IsNull(PropertyInfoExtensions.GetGetMethod(propertyInfo));
}
[Test]
[TestCase("PublicReadWrite")]
[TestCase("PrivateReadPublicWrite")]
[TestCase("PublicWriteOnly")]
public void GetSetMethod_Success(string name)
{
var propertyInfo = typeof(PropertyInfoExtensionsTest)
.GetProperty(name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
Assert.IsNotNull(PropertyInfoExtensions.GetSetMethod(propertyInfo));
}
[Test]
[TestCase("PublicReadPrivateWrite")]
[TestCase("PrivateReadWrite")]
[TestCase("PrivateReadOnly")]
[TestCase("PublicReadOnly")]
[TestCase("PrivateWriteOnly")]
public void GetSetMethod_NoAccessibleGetter(string name)
{
var propertyInfo = typeof(PropertyInfoExtensionsTest)
.GetProperty(name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
Assert.IsNull(PropertyInfoExtensions.GetSetMethod(propertyInfo));
}
}
}

@ -0,0 +1,133 @@
#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
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Reflection;
namespace Google.Protobuf.Compatibility
{
public class TypeExtensionsTest
{
public class DerivedList : List<string> { }
public string PublicProperty { get; set; }
private string PrivateProperty { get; set; }
public void PublicMethod()
{
}
private void PrivateMethod()
{
}
[Test]
[TestCase(typeof(int), true)]
[TestCase(typeof(int?), true)]
[TestCase(typeof(Nullable<>), true)]
[TestCase(typeof(WireFormat.WireType), true)]
[TestCase(typeof(string), false)]
[TestCase(typeof(object), false)]
[TestCase(typeof(Enum), false)]
[TestCase(typeof(ValueType), false)]
[TestCase(typeof(TypeExtensionsTest), false)]
[TestCase(typeof(Action), false)]
[TestCase(typeof(Action<>), false)]
[TestCase(typeof(IDisposable), false)]
public void IsValueType(Type type, bool expected)
{
Assert.AreEqual(expected, TypeExtensions.IsValueType(type));
}
[Test]
[TestCase(typeof(object), typeof(string), true)]
[TestCase(typeof(object), typeof(int), true)]
[TestCase(typeof(string), typeof(string), true)]
[TestCase(typeof(string), typeof(object), false)]
[TestCase(typeof(string), typeof(int), false)]
[TestCase(typeof(int), typeof(int), true)]
[TestCase(typeof(ValueType), typeof(int), true)]
[TestCase(typeof(long), typeof(int), false)] //
public void IsAssignableFrom(Type target, Type argument, bool expected)
{
Assert.AreEqual(expected, TypeExtensions.IsAssignableFrom(target, argument));
}
[Test]
[TestCase(typeof(DerivedList), "Count")] // Go up the type hierarchy
[TestCase(typeof(List<string>), "Count")]
[TestCase(typeof(List<>), "Count")]
[TestCase(typeof(TypeExtensionsTest), "PublicProperty")]
public void GetProperty_Success(Type type, string name)
{
var property = TypeExtensions.GetProperty(type, name);
Assert.IsNotNull(property);
Assert.AreEqual(name, property.Name);
}
[Test]
[TestCase(typeof(TypeExtensionsTest), "PrivateProperty")]
[TestCase(typeof(TypeExtensionsTest), "Garbage")]
public void GetProperty_NoSuchProperty(Type type, string name)
{
var property = TypeExtensions.GetProperty(type, name);
Assert.IsNull(property);
}
[Test]
[TestCase(typeof(DerivedList), "RemoveAt")] // Go up the type hierarchy
[TestCase(typeof(List<>), "RemoveAt")]
[TestCase(typeof(TypeExtensionsTest), "PublicMethod")]
public void GetMethod_Success(Type type, string name)
{
var method = TypeExtensions.GetMethod(type, name);
Assert.IsNotNull(method);
Assert.AreEqual(name, method.Name);
}
[Test]
[TestCase(typeof(TypeExtensionsTest), "PrivateMethod")]
[TestCase(typeof(TypeExtensionsTest), "GarbageMethod")]
public void GetMethod_NoSuchMethod(Type type, string name)
{
var method = TypeExtensions.GetMethod(type, name);
Assert.IsNull(method);
}
[Test]
[TestCase(typeof(List<string>), "IndexOf")]
public void GetMethod_Ambiguous(Type type, string name)
{
Assert.Throws<AmbiguousMatchException>(() => TypeExtensions.GetMethod(type, name));
}
}
}

@ -0,0 +1,55 @@
#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
using System;
using System.Reflection;
using Google.Protobuf.TestProtos;
using NUnit.Framework;
namespace Google.Protobuf
{
public class DeprecatedMemberTest
{
private static void AssertIsDeprecated(MemberInfo member)
{
Assert.NotNull(member);
Assert.IsTrue(member.IsDefined(typeof(ObsoleteAttribute), false), "Member not obsolete: " + member);
}
[Test]
public void TestDepreatedPrimitiveValue()
{
AssertIsDeprecated(typeof(TestDeprecatedFields).GetProperty("DeprecatedInt32"));
}
}
}

@ -0,0 +1,64 @@
#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
using System;
using NUnit.Framework;
namespace Google.Protobuf
{
/// <summary>
/// Helper methods when testing equality. NUnit's Assert.AreEqual and
/// Assert.AreNotEqual methods try to be clever with collections, which can
/// be annoying...
/// </summary>
internal static class EqualityTester
{
public static void AssertEquality<T>(T first, T second) where T : IEquatable<T>
{
Assert.IsTrue(first.Equals(second));
Assert.IsTrue(first.Equals((object) second));
Assert.AreEqual(first.GetHashCode(), second.GetHashCode());
}
public static void AssertInequality<T>(T first, T second) where T : IEquatable<T>
{
Assert.IsFalse(first.Equals(second));
Assert.IsFalse(first.Equals((object) second));
// While this isn't a requirement, the chances of this test failing due to
// coincidence rather than a bug are very small.
if (first != null && second != null)
{
Assert.AreNotEqual(first.GetHashCode(), second.GetHashCode());
}
}
}
}

@ -0,0 +1,195 @@
#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
using System.Collections.Generic;
using System.IO;
using Google.Protobuf.TestProtos;
using NUnit.Framework;
namespace Google.Protobuf
{
public class FieldCodecTest
{
#pragma warning disable 0414 // Used by tests via reflection - do not remove!
private static readonly List<ICodecTestData> Codecs = new List<ICodecTestData>
{
new FieldCodecTestData<bool>(FieldCodec.ForBool(100), true, "Bool"),
new FieldCodecTestData<string>(FieldCodec.ForString(100), "sample", "String"),
new FieldCodecTestData<ByteString>(FieldCodec.ForBytes(100), ByteString.CopyFrom(1, 2, 3), "Bytes"),
new FieldCodecTestData<int>(FieldCodec.ForInt32(100), -1000, "Int32"),
new FieldCodecTestData<int>(FieldCodec.ForSInt32(100), -1000, "SInt32"),
new FieldCodecTestData<int>(FieldCodec.ForSFixed32(100), -1000, "SFixed32"),
new FieldCodecTestData<uint>(FieldCodec.ForUInt32(100), 1234, "UInt32"),
new FieldCodecTestData<uint>(FieldCodec.ForFixed32(100), 1234, "Fixed32"),
new FieldCodecTestData<long>(FieldCodec.ForInt64(100), -1000, "Int64"),
new FieldCodecTestData<long>(FieldCodec.ForSInt64(100), -1000, "SInt64"),
new FieldCodecTestData<long>(FieldCodec.ForSFixed64(100), -1000, "SFixed64"),
new FieldCodecTestData<ulong>(FieldCodec.ForUInt64(100), 1234, "UInt64"),
new FieldCodecTestData<ulong>(FieldCodec.ForFixed64(100), 1234, "Fixed64"),
new FieldCodecTestData<float>(FieldCodec.ForFloat(100), 1234.5f, "Float"),
new FieldCodecTestData<double>(FieldCodec.ForDouble(100), 1234567890.5d, "Double"),
new FieldCodecTestData<ForeignEnum>(
FieldCodec.ForEnum(100, t => (int) t, t => (ForeignEnum) t), ForeignEnum.FOREIGN_BAZ, "Enum"),
new FieldCodecTestData<ForeignMessage>(
FieldCodec.ForMessage(100, ForeignMessage.Parser), new ForeignMessage { C = 10 }, "Message"),
};
#pragma warning restore 0414
[Test, TestCaseSource("Codecs")]
public void RoundTripWithTag(ICodecTestData codec)
{
codec.TestRoundTripWithTag();
}
[Test, TestCaseSource("Codecs")]
public void RoundTripRaw(ICodecTestData codec)
{
codec.TestRoundTripRaw();
}
[Test, TestCaseSource("Codecs")]
public void CalculateSize(ICodecTestData codec)
{
codec.TestCalculateSizeWithTag();
}
[Test, TestCaseSource("Codecs")]
public void DefaultValue(ICodecTestData codec)
{
codec.TestDefaultValue();
}
[Test, TestCaseSource("Codecs")]
public void FixedSize(ICodecTestData codec)
{
codec.TestFixedSize();
}
// This is ugly, but it means we can have a non-generic interface.
// It feels like NUnit should support this better, but I don't know
// of any better ways right now.
public interface ICodecTestData
{
void TestRoundTripRaw();
void TestRoundTripWithTag();
void TestCalculateSizeWithTag();
void TestDefaultValue();
void TestFixedSize();
}
public class FieldCodecTestData<T> : ICodecTestData
{
private readonly FieldCodec<T> codec;
private readonly T sampleValue;
private readonly string name;
public FieldCodecTestData(FieldCodec<T> codec, T sampleValue, string name)
{
this.codec = codec;
this.sampleValue = sampleValue;
this.name = name;
}
public void TestRoundTripRaw()
{
var stream = new MemoryStream();
var codedOutput = new CodedOutputStream(stream);
codec.ValueWriter(codedOutput, sampleValue);
codedOutput.Flush();
stream.Position = 0;
var codedInput = new CodedInputStream(stream);
Assert.AreEqual(sampleValue, codec.ValueReader(codedInput));
Assert.IsTrue(codedInput.IsAtEnd);
}
public void TestRoundTripWithTag()
{
var stream = new MemoryStream();
var codedOutput = new CodedOutputStream(stream);
codec.WriteTagAndValue(codedOutput, sampleValue);
codedOutput.Flush();
stream.Position = 0;
var codedInput = new CodedInputStream(stream);
codedInput.AssertNextTag(codec.Tag);
Assert.AreEqual(sampleValue, codec.Read(codedInput));
Assert.IsTrue(codedInput.IsAtEnd);
}
public void TestCalculateSizeWithTag()
{
var stream = new MemoryStream();
var codedOutput = new CodedOutputStream(stream);
codec.WriteTagAndValue(codedOutput, sampleValue);
codedOutput.Flush();
Assert.AreEqual(stream.Position, codec.CalculateSizeWithTag(sampleValue));
}
public void TestDefaultValue()
{
// WriteTagAndValue ignores default values
var stream = new MemoryStream();
var codedOutput = new CodedOutputStream(stream);
codec.WriteTagAndValue(codedOutput, codec.DefaultValue);
codedOutput.Flush();
Assert.AreEqual(0, stream.Position);
Assert.AreEqual(0, codec.CalculateSizeWithTag(codec.DefaultValue));
if (typeof(T).IsValueType)
{
Assert.AreEqual(default(T), codec.DefaultValue);
}
// The plain ValueWriter/ValueReader delegates don't.
if (codec.DefaultValue != null) // This part isn't appropriate for message types.
{
codedOutput = new CodedOutputStream(stream);
codec.ValueWriter(codedOutput, codec.DefaultValue);
codedOutput.Flush();
Assert.AreNotEqual(0, stream.Position);
Assert.AreEqual(stream.Position, codec.ValueSizeCalculator(codec.DefaultValue));
stream.Position = 0;
var codedInput = new CodedInputStream(stream);
Assert.AreEqual(codec.DefaultValue, codec.ValueReader(codedInput));
}
}
public void TestFixedSize()
{
Assert.AreEqual(name.Contains("Fixed"), codec.FixedSize != 0);
}
public override string ToString()
{
return name;
}
}
}
}

@ -0,0 +1,655 @@
#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
using System;
using System.IO;
using Google.Protobuf.TestProtos;
using NUnit.Framework;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Google.Protobuf.WellKnownTypes;
namespace Google.Protobuf
{
/// <summary>
/// Tests around the generated TestAllTypes message.
/// </summary>
public class GeneratedMessageTest
{
[Test]
public void EmptyMessageFieldDistinctFromMissingMessageField()
{
// This demonstrates what we're really interested in...
var message1 = new TestAllTypes { SingleForeignMessage = new ForeignMessage() };
var message2 = new TestAllTypes(); // SingleForeignMessage is null
EqualityTester.AssertInequality(message1, message2);
}
[Test]
public void DefaultValues()
{
// Single fields
var message = new TestAllTypes();
Assert.AreEqual(false, message.SingleBool);
Assert.AreEqual(ByteString.Empty, message.SingleBytes);
Assert.AreEqual(0.0, message.SingleDouble);
Assert.AreEqual(0, message.SingleFixed32);
Assert.AreEqual(0L, message.SingleFixed64);
Assert.AreEqual(0.0f, message.SingleFloat);
Assert.AreEqual(ForeignEnum.FOREIGN_UNSPECIFIED, message.SingleForeignEnum);
Assert.IsNull(message.SingleForeignMessage);
Assert.AreEqual(ImportEnum.IMPORT_ENUM_UNSPECIFIED, message.SingleImportEnum);
Assert.IsNull(message.SingleImportMessage);
Assert.AreEqual(0, message.SingleInt32);
Assert.AreEqual(0L, message.SingleInt64);
Assert.AreEqual(TestAllTypes.Types.NestedEnum.NESTED_ENUM_UNSPECIFIED, message.SingleNestedEnum);
Assert.IsNull(message.SingleNestedMessage);
Assert.IsNull(message.SinglePublicImportMessage);
Assert.AreEqual(0, message.SingleSfixed32);
Assert.AreEqual(0L, message.SingleSfixed64);
Assert.AreEqual(0, message.SingleSint32);
Assert.AreEqual(0L, message.SingleSint64);
Assert.AreEqual("", message.SingleString);
Assert.AreEqual(0U, message.SingleUint32);
Assert.AreEqual(0UL, message.SingleUint64);
// Repeated fields
Assert.AreEqual(0, message.RepeatedBool.Count);
Assert.AreEqual(0, message.RepeatedBytes.Count);
Assert.AreEqual(0, message.RepeatedDouble.Count);
Assert.AreEqual(0, message.RepeatedFixed32.Count);
Assert.AreEqual(0, message.RepeatedFixed64.Count);
Assert.AreEqual(0, message.RepeatedFloat.Count);
Assert.AreEqual(0, message.RepeatedForeignEnum.Count);
Assert.AreEqual(0, message.RepeatedForeignMessage.Count);
Assert.AreEqual(0, message.RepeatedImportEnum.Count);
Assert.AreEqual(0, message.RepeatedImportMessage.Count);
Assert.AreEqual(0, message.RepeatedNestedEnum.Count);
Assert.AreEqual(0, message.RepeatedNestedMessage.Count);
Assert.AreEqual(0, message.RepeatedPublicImportMessage.Count);
Assert.AreEqual(0, message.RepeatedSfixed32.Count);
Assert.AreEqual(0, message.RepeatedSfixed64.Count);
Assert.AreEqual(0, message.RepeatedSint32.Count);
Assert.AreEqual(0, message.RepeatedSint64.Count);
Assert.AreEqual(0, message.RepeatedString.Count);
Assert.AreEqual(0, message.RepeatedUint32.Count);
Assert.AreEqual(0, message.RepeatedUint64.Count);
// Oneof fields
Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.None, message.OneofFieldCase);
Assert.AreEqual(0, message.OneofUint32);
Assert.AreEqual("", message.OneofString);
Assert.AreEqual(ByteString.Empty, message.OneofBytes);
Assert.IsNull(message.OneofNestedMessage);
}
[Test]
public void NullStringAndBytesRejected()
{
var message = new TestAllTypes();
Assert.Throws<ArgumentNullException>(() => message.SingleString = null);
Assert.Throws<ArgumentNullException>(() => message.OneofString = null);
Assert.Throws<ArgumentNullException>(() => message.SingleBytes = null);
Assert.Throws<ArgumentNullException>(() => message.OneofBytes = null);
}
[Test]
public void RoundTrip_Empty()
{
var message = new TestAllTypes();
// Without setting any values, there's nothing to write.
byte[] bytes = message.ToByteArray();
Assert.AreEqual(0, bytes.Length);
TestAllTypes parsed = TestAllTypes.Parser.ParseFrom(bytes);
Assert.AreEqual(message, parsed);
}
[Test]
public void RoundTrip_SingleValues()
{
var message = new TestAllTypes
{
SingleBool = true,
SingleBytes = ByteString.CopyFrom(1, 2, 3, 4),
SingleDouble = 23.5,
SingleFixed32 = 23,
SingleFixed64 = 1234567890123,
SingleFloat = 12.25f,
SingleForeignEnum = ForeignEnum.FOREIGN_BAR,
SingleForeignMessage = new ForeignMessage { C = 10 },
SingleImportEnum = ImportEnum.IMPORT_BAZ,
SingleImportMessage = new ImportMessage { D = 20 },
SingleInt32 = 100,
SingleInt64 = 3210987654321,
SingleNestedEnum = TestAllTypes.Types.NestedEnum.FOO,
SingleNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 35 },
SinglePublicImportMessage = new PublicImportMessage { E = 54 },
SingleSfixed32 = -123,
SingleSfixed64 = -12345678901234,
SingleSint32 = -456,
SingleSint64 = -12345678901235,
SingleString = "test",
SingleUint32 = uint.MaxValue,
SingleUint64 = ulong.MaxValue
};
byte[] bytes = message.ToByteArray();
TestAllTypes parsed = TestAllTypes.Parser.ParseFrom(bytes);
Assert.AreEqual(message, parsed);
}
[Test]
public void RoundTrip_RepeatedValues()
{
var message = new TestAllTypes
{
RepeatedBool = { true, false },
RepeatedBytes = { ByteString.CopyFrom(1, 2, 3, 4), ByteString.CopyFrom(5, 6) },
RepeatedDouble = { -12.25, 23.5 },
RepeatedFixed32 = { uint.MaxValue, 23 },
RepeatedFixed64 = { ulong.MaxValue, 1234567890123 },
RepeatedFloat = { 100f, 12.25f },
RepeatedForeignEnum = { ForeignEnum.FOREIGN_FOO, ForeignEnum.FOREIGN_BAR },
RepeatedForeignMessage = { new ForeignMessage(), new ForeignMessage { C = 10 } },
RepeatedImportEnum = { ImportEnum.IMPORT_BAZ, ImportEnum.IMPORT_ENUM_UNSPECIFIED },
RepeatedImportMessage = { new ImportMessage { D = 20 }, new ImportMessage { D = 25 } },
RepeatedInt32 = { 100, 200 },
RepeatedInt64 = { 3210987654321, long.MaxValue },
RepeatedNestedEnum = { TestAllTypes.Types.NestedEnum.FOO, TestAllTypes.Types.NestedEnum.NEG },
RepeatedNestedMessage = { new TestAllTypes.Types.NestedMessage { Bb = 35 }, new TestAllTypes.Types.NestedMessage { Bb = 10 } },
RepeatedPublicImportMessage = { new PublicImportMessage { E = 54 }, new PublicImportMessage { E = -1 } },
RepeatedSfixed32 = { -123, 123 },
RepeatedSfixed64 = { -12345678901234, 12345678901234 },
RepeatedSint32 = { -456, 100 },
RepeatedSint64 = { -12345678901235, 123 },
RepeatedString = { "foo", "bar" },
RepeatedUint32 = { uint.MaxValue, uint.MinValue },
RepeatedUint64 = { ulong.MaxValue, uint.MinValue }
};
byte[] bytes = message.ToByteArray();
TestAllTypes parsed = TestAllTypes.Parser.ParseFrom(bytes);
Assert.AreEqual(message, parsed);
}
// Note that not every map within map_unittest_proto3 is used. They all go through very
// similar code paths. The fact that all maps are present is validation that we have codecs
// for every type.
[Test]
public void RoundTrip_Maps()
{
var message = new TestMap
{
MapBoolBool = {
{ false, true },
{ true, false }
},
MapInt32Bytes = {
{ 5, ByteString.CopyFrom(6, 7, 8) },
{ 25, ByteString.CopyFrom(1, 2, 3, 4, 5) },
{ 10, ByteString.Empty }
},
MapInt32ForeignMessage = {
{ 0, new ForeignMessage { C = 10 } },
{ 5, null },
},
MapInt32Enum = {
{ 1, MapEnum.MAP_ENUM_BAR },
{ 2000, MapEnum.MAP_ENUM_FOO }
}
};
byte[] bytes = message.ToByteArray();
TestMap parsed = TestMap.Parser.ParseFrom(bytes);
Assert.AreEqual(message, parsed);
}
[Test]
public void MapWithEmptyEntry()
{
var message = new TestMap
{
MapInt32Bytes = { { 0, ByteString.Empty } }
};
byte[] bytes = message.ToByteArray();
Assert.AreEqual(2, bytes.Length); // Tag for field entry (1 byte), length of entry (0; 1 byte)
var parsed = TestMap.Parser.ParseFrom(bytes);
Assert.AreEqual(1, parsed.MapInt32Bytes.Count);
Assert.AreEqual(ByteString.Empty, parsed.MapInt32Bytes[0]);
}
[Test]
public void MapWithOnlyValue()
{
// Hand-craft the stream to contain a single entry with just a value.
var memoryStream = new MemoryStream();
var output = new CodedOutputStream(memoryStream);
output.WriteTag(TestMap.MapInt32ForeignMessageFieldNumber, WireFormat.WireType.LengthDelimited);
var nestedMessage = new ForeignMessage { C = 20 };
// Size of the entry (tag, size written by WriteMessage, data written by WriteMessage)
output.WriteLength(2 + nestedMessage.CalculateSize());
output.WriteTag(2, WireFormat.WireType.LengthDelimited);
output.WriteMessage(nestedMessage);
output.Flush();
var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
Assert.AreEqual(nestedMessage, parsed.MapInt32ForeignMessage[0]);
}
[Test]
public void MapIgnoresExtraFieldsWithinEntryMessages()
{
// Hand-craft the stream to contain a single entry with three fields
var memoryStream = new MemoryStream();
var output = new CodedOutputStream(memoryStream);
output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
var key = 10; // Field 1
var value = 20; // Field 2
var extra = 30; // Field 3
// Each field can be represented in a single byte, with a single byte tag.
// Total message size: 6 bytes.
output.WriteLength(6);
output.WriteTag(1, WireFormat.WireType.Varint);
output.WriteInt32(key);
output.WriteTag(2, WireFormat.WireType.Varint);
output.WriteInt32(value);
output.WriteTag(3, WireFormat.WireType.Varint);
output.WriteInt32(extra);
output.Flush();
var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
Assert.AreEqual(value, parsed.MapInt32Int32[key]);
}
[Test]
public void MapFieldOrderIsIrrelevant()
{
var memoryStream = new MemoryStream();
var output = new CodedOutputStream(memoryStream);
output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
var key = 10;
var value = 20;
// Each field can be represented in a single byte, with a single byte tag.
// Total message size: 4 bytes.
output.WriteLength(4);
output.WriteTag(2, WireFormat.WireType.Varint);
output.WriteInt32(value);
output.WriteTag(1, WireFormat.WireType.Varint);
output.WriteInt32(key);
output.Flush();
var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
Assert.AreEqual(value, parsed.MapInt32Int32[key]);
}
[Test]
public void MapNonContiguousEntries()
{
var memoryStream = new MemoryStream();
var output = new CodedOutputStream(memoryStream);
// Message structure:
// Entry for MapInt32Int32
// Entry for MapStringString
// Entry for MapInt32Int32
// First entry
var key1 = 10;
var value1 = 20;
output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
output.WriteLength(4);
output.WriteTag(1, WireFormat.WireType.Varint);
output.WriteInt32(key1);
output.WriteTag(2, WireFormat.WireType.Varint);
output.WriteInt32(value1);
// Second entry
var key2 = "a";
var value2 = "b";
output.WriteTag(TestMap.MapStringStringFieldNumber, WireFormat.WireType.LengthDelimited);
output.WriteLength(6); // 3 bytes per entry: tag, size, character
output.WriteTag(1, WireFormat.WireType.LengthDelimited);
output.WriteString(key2);
output.WriteTag(2, WireFormat.WireType.LengthDelimited);
output.WriteString(value2);
// Third entry
var key3 = 15;
var value3 = 25;
output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
output.WriteLength(4);
output.WriteTag(1, WireFormat.WireType.Varint);
output.WriteInt32(key3);
output.WriteTag(2, WireFormat.WireType.Varint);
output.WriteInt32(value3);
output.Flush();
var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
var expected = new TestMap
{
MapInt32Int32 = { { key1, value1 }, { key3, value3 } },
MapStringString = { { key2, value2 } }
};
Assert.AreEqual(expected, parsed);
}
[Test]
public void DuplicateKeys_LastEntryWins()
{
var memoryStream = new MemoryStream();
var output = new CodedOutputStream(memoryStream);
var key = 10;
var value1 = 20;
var value2 = 30;
// First entry
output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
output.WriteLength(4);
output.WriteTag(1, WireFormat.WireType.Varint);
output.WriteInt32(key);
output.WriteTag(2, WireFormat.WireType.Varint);
output.WriteInt32(value1);
// Second entry - same key, different value
output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
output.WriteLength(4);
output.WriteTag(1, WireFormat.WireType.Varint);
output.WriteInt32(key);
output.WriteTag(2, WireFormat.WireType.Varint);
output.WriteInt32(value2);
output.Flush();
var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
Assert.AreEqual(value2, parsed.MapInt32Int32[key]);
}
[Test]
public void CloneSingleNonMessageValues()
{
var original = new TestAllTypes
{
SingleBool = true,
SingleBytes = ByteString.CopyFrom(1, 2, 3, 4),
SingleDouble = 23.5,
SingleFixed32 = 23,
SingleFixed64 = 1234567890123,
SingleFloat = 12.25f,
SingleInt32 = 100,
SingleInt64 = 3210987654321,
SingleNestedEnum = TestAllTypes.Types.NestedEnum.FOO,
SingleSfixed32 = -123,
SingleSfixed64 = -12345678901234,
SingleSint32 = -456,
SingleSint64 = -12345678901235,
SingleString = "test",
SingleUint32 = uint.MaxValue,
SingleUint64 = ulong.MaxValue
};
var clone = original.Clone();
Assert.AreNotSame(original, clone);
Assert.AreEqual(original, clone);
// Just as a single example
clone.SingleInt32 = 150;
Assert.AreNotEqual(original, clone);
}
[Test]
public void CloneRepeatedNonMessageValues()
{
var original = new TestAllTypes
{
RepeatedBool = { true, false },
RepeatedBytes = { ByteString.CopyFrom(1, 2, 3, 4), ByteString.CopyFrom(5, 6) },
RepeatedDouble = { -12.25, 23.5 },
RepeatedFixed32 = { uint.MaxValue, 23 },
RepeatedFixed64 = { ulong.MaxValue, 1234567890123 },
RepeatedFloat = { 100f, 12.25f },
RepeatedInt32 = { 100, 200 },
RepeatedInt64 = { 3210987654321, long.MaxValue },
RepeatedNestedEnum = { TestAllTypes.Types.NestedEnum.FOO, TestAllTypes.Types.NestedEnum.NEG },
RepeatedSfixed32 = { -123, 123 },
RepeatedSfixed64 = { -12345678901234, 12345678901234 },
RepeatedSint32 = { -456, 100 },
RepeatedSint64 = { -12345678901235, 123 },
RepeatedString = { "foo", "bar" },
RepeatedUint32 = { uint.MaxValue, uint.MinValue },
RepeatedUint64 = { ulong.MaxValue, uint.MinValue }
};
var clone = original.Clone();
Assert.AreNotSame(original, clone);
Assert.AreEqual(original, clone);
// Just as a single example
clone.RepeatedDouble.Add(25.5);
Assert.AreNotEqual(original, clone);
}
[Test]
public void CloneSingleMessageField()
{
var original = new TestAllTypes
{
SingleNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 20 }
};
var clone = original.Clone();
Assert.AreNotSame(original, clone);
Assert.AreNotSame(original.SingleNestedMessage, clone.SingleNestedMessage);
Assert.AreEqual(original, clone);
clone.SingleNestedMessage.Bb = 30;
Assert.AreNotEqual(original, clone);
}
[Test]
public void CloneRepeatedMessageField()
{
var original = new TestAllTypes
{
RepeatedNestedMessage = { new TestAllTypes.Types.NestedMessage { Bb = 20 } }
};
var clone = original.Clone();
Assert.AreNotSame(original, clone);
Assert.AreNotSame(original.RepeatedNestedMessage, clone.RepeatedNestedMessage);
Assert.AreNotSame(original.RepeatedNestedMessage[0], clone.RepeatedNestedMessage[0]);
Assert.AreEqual(original, clone);
clone.RepeatedNestedMessage[0].Bb = 30;
Assert.AreNotEqual(original, clone);
}
[Test]
public void CloneOneofField()
{
var original = new TestAllTypes
{
OneofNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 20 }
};
var clone = original.Clone();
Assert.AreNotSame(original, clone);
Assert.AreEqual(original, clone);
// We should have cloned the message
original.OneofNestedMessage.Bb = 30;
Assert.AreNotEqual(original, clone);
}
[Test]
public void OneofProperties()
{
// Switch the oneof case between each of the different options, and check everything behaves
// as expected in each case.
var message = new TestAllTypes();
Assert.AreEqual("", message.OneofString);
Assert.AreEqual(0, message.OneofUint32);
Assert.AreEqual(ByteString.Empty, message.OneofBytes);
Assert.IsNull(message.OneofNestedMessage);
Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.None, message.OneofFieldCase);
message.OneofString = "sample";
Assert.AreEqual("sample", message.OneofString);
Assert.AreEqual(0, message.OneofUint32);
Assert.AreEqual(ByteString.Empty, message.OneofBytes);
Assert.IsNull(message.OneofNestedMessage);
Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofString, message.OneofFieldCase);
var bytes = ByteString.CopyFrom(1, 2, 3);
message.OneofBytes = bytes;
Assert.AreEqual("", message.OneofString);
Assert.AreEqual(0, message.OneofUint32);
Assert.AreEqual(bytes, message.OneofBytes);
Assert.IsNull(message.OneofNestedMessage);
Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofBytes, message.OneofFieldCase);
message.OneofUint32 = 20;
Assert.AreEqual("", message.OneofString);
Assert.AreEqual(20, message.OneofUint32);
Assert.AreEqual(ByteString.Empty, message.OneofBytes);
Assert.IsNull(message.OneofNestedMessage);
Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofUint32, message.OneofFieldCase);
var nestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 25 };
message.OneofNestedMessage = nestedMessage;
Assert.AreEqual("", message.OneofString);
Assert.AreEqual(0, message.OneofUint32);
Assert.AreEqual(ByteString.Empty, message.OneofBytes);
Assert.AreEqual(nestedMessage, message.OneofNestedMessage);
Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofNestedMessage, message.OneofFieldCase);
message.ClearOneofField();
Assert.AreEqual("", message.OneofString);
Assert.AreEqual(0, message.OneofUint32);
Assert.AreEqual(ByteString.Empty, message.OneofBytes);
Assert.IsNull(message.OneofNestedMessage);
Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.None, message.OneofFieldCase);
}
[Test]
public void OneofSerialization_NonDefaultValue()
{
var message = new TestAllTypes();
message.OneofString = "this would take a bit of space";
message.OneofUint32 = 10;
var bytes = message.ToByteArray();
Assert.AreEqual(3, bytes.Length); // 2 bytes for the tag + 1 for the value - no string!
var message2 = TestAllTypes.Parser.ParseFrom(bytes);
Assert.AreEqual(message, message2);
Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofUint32, message2.OneofFieldCase);
}
[Test]
public void OneofSerialization_DefaultValue()
{
var message = new TestAllTypes();
message.OneofString = "this would take a bit of space";
message.OneofUint32 = 0; // This is the default value for UInt32; normally wouldn't be serialized
var bytes = message.ToByteArray();
Assert.AreEqual(3, bytes.Length); // 2 bytes for the tag + 1 for the value - it's still serialized
var message2 = TestAllTypes.Parser.ParseFrom(bytes);
Assert.AreEqual(message, message2);
Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofUint32, message2.OneofFieldCase);
}
[Test]
public void IgnoreUnknownFields_RealDataStillRead()
{
var message = SampleMessages.CreateFullTestAllTypes();
var stream = new MemoryStream();
var output = new CodedOutputStream(stream);
var unusedFieldNumber = 23456;
Assert.IsFalse(TestAllTypes.Descriptor.Fields.InDeclarationOrder().Select(x => x.FieldNumber).Contains(unusedFieldNumber));
output.WriteTag(unusedFieldNumber, WireFormat.WireType.LengthDelimited);
output.WriteString("ignore me");
message.WriteTo(output);
output.Flush();
stream.Position = 0;
var parsed = TestAllTypes.Parser.ParseFrom(stream);
Assert.AreEqual(message, parsed);
}
[Test]
public void IgnoreUnknownFields_AllTypes()
{
// Simple way of ensuring we can skip all kinds of fields.
var data = SampleMessages.CreateFullTestAllTypes().ToByteArray();
var empty = Empty.Parser.ParseFrom(data);
Assert.AreEqual(new Empty(), empty);
}
// This was originally seen as a conformance test failure.
[Test]
public void TruncatedMessageFieldThrows()
{
// 130, 3 is the message tag
// 1 is the data length - but there's no data.
var data = new byte[] { 130, 3, 1 };
Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseFrom(data));
}
/// <summary>
/// Demonstrates current behaviour with an extraneous end group tag - see issue 688
/// for details; we may want to change this.
/// </summary>
[Test]
public void ExtraEndGroupSkipped()
{
var message = SampleMessages.CreateFullTestAllTypes();
var stream = new MemoryStream();
var output = new CodedOutputStream(stream);
output.WriteTag(100, WireFormat.WireType.EndGroup);
output.WriteTag(TestAllTypes.SingleFixed32FieldNumber, WireFormat.WireType.Fixed32);
output.WriteFixed32(123);
output.Flush();
stream.Position = 0;
var parsed = TestAllTypes.Parser.ParseFrom(stream);
Assert.AreEqual(new TestAllTypes { SingleFixed32 = 123 }, parsed);
}
}
}

@ -5,15 +5,13 @@
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion> <ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion> <SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{EE01ED24-3750-4567-9A23-1DB676A15610}</ProjectGuid> <ProjectGuid>{DD01ED24-3750-4567-9A23-1DB676A15610}</ProjectGuid>
<OutputType>Library</OutputType> <OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder> <AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Google.ProtocolBuffers</RootNamespace> <RootNamespace>Google.Protobuf</RootNamespace>
<AssemblyName>Google.ProtocolBuffersLite.Test</AssemblyName> <AssemblyName>Google.Protobuf.Test</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion> <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>..\..\keys\Google.ProtocolBuffers.snk</AssemblyOriginatorKeyFile>
<OldToolsVersion>3.5</OldToolsVersion> <OldToolsVersion>3.5</OldToolsVersion>
<TargetFrameworkProfile> <TargetFrameworkProfile>
</TargetFrameworkProfile> </TargetFrameworkProfile>
@ -45,6 +43,20 @@
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies> <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
<Prefer32Bit>false</Prefer32Bit> <Prefer32Bit>false</Prefer32Bit>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseSigned|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\ReleaseSigned</OutputPath>
<IntermediateOutputPath>obj\ReleaseSigned\</IntermediateOutputPath>
<DefineConstants>TRACE;$(EnvironmentFlavor);$(EnvironmentTemplate)</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<NoStdLib>true</NoStdLib>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
<Prefer32Bit>false</Prefer32Bit>
<SignAssembly>True</SignAssembly>
<AssemblyOriginatorKeyFile>C:\keys\Google.Protobuf.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="mscorlib" /> <Reference Include="mscorlib" />
<Reference Include="nunit.core, Version=2.6.4.14350, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL"> <Reference Include="nunit.core, Version=2.6.4.14350, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
@ -71,37 +83,49 @@
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="..\ProtocolBuffers.Test\Properties\AssemblyInfo.cs"> <Compile Include="ByteStringTest.cs" />
<Link>Properties\AssemblyInfo.cs</Link> <Compile Include="CodedInputStreamExtensions.cs" />
</Compile> <Compile Include="CodedInputStreamTest.cs" />
<Compile Include="AbstractBuilderLiteTest.cs" /> <Compile Include="CodedOutputStreamTest.cs" />
<Compile Include="AbstractMessageLiteTest.cs" /> <Compile Include="Compatibility\PropertyInfoExtensionsTest.cs" />
<Compile Include="ExtendableBuilderLiteTest.cs" /> <Compile Include="Compatibility\TypeExtensionsTest.cs" />
<Compile Include="ExtendableMessageLiteTest.cs" /> <Compile Include="EqualityTester.cs" />
<Compile Include="LiteTest.cs" /> <Compile Include="FieldCodecTest.cs" />
<Compile Include="TestLiteByApi.cs" /> <Compile Include="GeneratedMessageTest.cs" />
<Compile Include="TestProtos\UnittestExtrasLite.cs" /> <Compile Include="Collections\MapFieldTest.cs" />
<Compile Include="TestProtos\UnittestImportLite.cs" /> <Compile Include="Collections\RepeatedFieldTest.cs" />
<Compile Include="TestProtos\UnittestImportPublicLite.cs" /> <Compile Include="JsonFormatterTest.cs" />
<Compile Include="TestProtos\UnittestLite.cs" /> <Compile Include="Reflection\DescriptorsTest.cs" />
<Compile Include="Reflection\FieldAccessTest.cs" />
<Compile Include="SampleEnum.cs" />
<Compile Include="SampleMessages.cs" />
<Compile Include="TestProtos\MapUnittestProto3.cs" />
<Compile Include="TestProtos\UnittestImportProto3.cs" />
<Compile Include="TestProtos\UnittestImportPublicProto3.cs" />
<Compile Include="TestProtos\UnittestIssues.cs" />
<Compile Include="TestProtos\UnittestProto3.cs" />
<Compile Include="DeprecatedMemberTest.cs" />
<Compile Include="IssuesTest.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TestCornerCases.cs" />
<Compile Include="TestProtos\UnittestWellKnownTypes.cs" />
<Compile Include="WellKnownTypes\DurationTest.cs" />
<Compile Include="WellKnownTypes\TimestampTest.cs" />
<Compile Include="WellKnownTypes\WrappersTest.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\ProtocolBuffers.Serialization\ProtocolBuffersLite.Serialization.csproj"> <ProjectReference Include="..\Google.Protobuf\Google.Protobuf.csproj">
<Project>{E067A59D-9D0A-4A1F-92B1-38E4457241D1}</Project> <Project>{6908BDCE-D925-43F3-94AC-A531E6DF2591}</Project>
<Name>ProtocolBuffersLite.Serialization</Name> <Name>Google.Protobuf</Name>
</ProjectReference>
<ProjectReference Include="..\ProtocolBuffers\ProtocolBuffersLite.csproj">
<Project>{6969BDCE-D925-43F3-94AC-A531E6DF2591}</Project>
<Name>ProtocolBuffersLite</Name>
<Private>True</Private>
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> <None Include="packages.config" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="packages.config" /> <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup> </ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- 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. Other similar extension points exist, see Microsoft.Common.targets.

@ -1,10 +1,7 @@
#region Copyright notice and license #region Copyright notice and license
// Protocol Buffers - Google's data interchange format // Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved. // Copyright 2008 Google Inc. All rights reserved.
// http://github.com/jskeet/dotnet-protobufs/ // https://developers.google.com/protocol-buffers/
// Original C++/Java/Python code:
// http://code.google.com/p/protobuf/
// //
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are // modification, are permitted provided that the following conditions are
@ -31,16 +28,14 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion #endregion
using Google.Protobuf.Reflection;
using Google.ProtocolBuffers.Descriptors;
using UnitTest.Issues.TestProtos; using UnitTest.Issues.TestProtos;
using NUnit.Framework; using NUnit.Framework;
namespace Google.ProtocolBuffers namespace Google.Protobuf
{ {
/// <summary> /// <summary>
/// Tests for issues which aren't easily compartmentalized into other unit tests. /// Tests for issues which aren't easily compartmentalized into other unit tests.
@ -51,10 +46,18 @@ namespace Google.ProtocolBuffers
[Test] [Test]
public void FieldCalledItem() public void FieldCalledItem()
{ {
ItemField message = new ItemField.Builder { Item = 3 }.Build(); ItemField message = new ItemField { Item = 3 };
FieldDescriptor field = ItemField.Descriptor.FindFieldByName("item"); FieldDescriptor field = ItemField.Descriptor.FindFieldByName("item");
Assert.NotNull(field); Assert.NotNull(field);
Assert.AreEqual(3, (int)message[field]); Assert.AreEqual(3, (int)field.Accessor.GetValue(message));
}
[Test]
public void ReservedNames()
{
var message = new ReservedNames { Types_ = 10, Descriptor_ = 20 };
// Underscores aren't reflected in the JSON.
Assert.AreEqual("{ \"types\": 10, \"descriptor\": 20 }", message.ToString());
} }
} }
} }

@ -0,0 +1,419 @@
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2008 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
using System;
using Google.Protobuf.TestProtos;
using NUnit.Framework;
using UnitTest.Issues.TestProtos;
using Google.Protobuf.WellKnownTypes;
namespace Google.Protobuf
{
/// <summary>
/// Tests for the JSON formatter. Note that in these tests, double quotes are replaced with apostrophes
/// for the sake of readability (embedding \" everywhere is painful). See the AssertJson method for details.
/// </summary>
public class JsonFormatterTest
{
[Test]
public void DefaultValues_WhenOmitted()
{
var formatter = new JsonFormatter(new JsonFormatter.Settings(formatDefaultValues: false));
AssertJson("{ }", formatter.Format(new ForeignMessage()));
AssertJson("{ }", formatter.Format(new TestAllTypes()));
AssertJson("{ }", formatter.Format(new TestMap()));
}
[Test]
public void DefaultValues_WhenIncluded()
{
var formatter = new JsonFormatter(new JsonFormatter.Settings(formatDefaultValues: true));
AssertJson("{ 'c': 0 }", formatter.Format(new ForeignMessage()));
}
[Test]
public void AllSingleFields()
{
var message = new TestAllTypes
{
SingleBool = true,
SingleBytes = ByteString.CopyFrom(1, 2, 3, 4),
SingleDouble = 23.5,
SingleFixed32 = 23,
SingleFixed64 = 1234567890123,
SingleFloat = 12.25f,
SingleForeignEnum = ForeignEnum.FOREIGN_BAR,
SingleForeignMessage = new ForeignMessage { C = 10 },
SingleImportEnum = ImportEnum.IMPORT_BAZ,
SingleImportMessage = new ImportMessage { D = 20 },
SingleInt32 = 100,
SingleInt64 = 3210987654321,
SingleNestedEnum = TestAllTypes.Types.NestedEnum.FOO,
SingleNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 35 },
SinglePublicImportMessage = new PublicImportMessage { E = 54 },
SingleSfixed32 = -123,
SingleSfixed64 = -12345678901234,
SingleSint32 = -456,
SingleSint64 = -12345678901235,
SingleString = "test\twith\ttabs",
SingleUint32 = uint.MaxValue,
SingleUint64 = ulong.MaxValue,
};
var actualText = JsonFormatter.Default.Format(message);
// Fields in numeric order
var expectedText = "{ " +
"'singleInt32': 100, " +
"'singleInt64': '3210987654321', " +
"'singleUint32': 4294967295, " +
"'singleUint64': '18446744073709551615', " +
"'singleSint32': -456, " +
"'singleSint64': '-12345678901235', " +
"'singleFixed32': 23, " +
"'singleFixed64': '1234567890123', " +
"'singleSfixed32': -123, " +
"'singleSfixed64': '-12345678901234', " +
"'singleFloat': 12.25, " +
"'singleDouble': 23.5, " +
"'singleBool': true, " +
"'singleString': 'test\\twith\\ttabs', " +
"'singleBytes': 'AQIDBA==', " +
"'singleNestedMessage': { 'bb': 35 }, " +
"'singleForeignMessage': { 'c': 10 }, " +
"'singleImportMessage': { 'd': 20 }, " +
"'singleNestedEnum': 'FOO', " +
"'singleForeignEnum': 'FOREIGN_BAR', " +
"'singleImportEnum': 'IMPORT_BAZ', " +
"'singlePublicImportMessage': { 'e': 54 }" +
" }";
AssertJson(expectedText, actualText);
}
[Test]
public void RepeatedField()
{
AssertJson("{ 'repeatedInt32': [ 1, 2, 3, 4, 5 ] }",
JsonFormatter.Default.Format(new TestAllTypes { RepeatedInt32 = { 1, 2, 3, 4, 5 } }));
}
[Test]
public void MapField_StringString()
{
AssertJson("{ 'mapStringString': { 'with spaces': 'bar', 'a': 'b' } }",
JsonFormatter.Default.Format(new TestMap { MapStringString = { { "with spaces", "bar" }, { "a", "b" } } }));
}
[Test]
public void MapField_Int32Int32()
{
// The keys are quoted, but the values aren't.
AssertJson("{ 'mapInt32Int32': { '0': 1, '2': 3 } }",
JsonFormatter.Default.Format(new TestMap { MapInt32Int32 = { { 0, 1 }, { 2, 3 } } }));
}
[Test]
public void MapField_BoolBool()
{
// The keys are quoted, but the values aren't.
AssertJson("{ 'mapBoolBool': { 'false': true, 'true': false } }",
JsonFormatter.Default.Format(new TestMap { MapBoolBool = { { false, true }, { true, false } } }));
}
[TestCase(1.0, "1")]
[TestCase(double.NaN, "'NaN'")]
[TestCase(double.PositiveInfinity, "'Infinity'")]
[TestCase(double.NegativeInfinity, "'-Infinity'")]
public void DoubleRepresentations(double value, string expectedValueText)
{
var message = new TestAllTypes { SingleDouble = value };
string actualText = JsonFormatter.Default.Format(message);
string expectedText = "{ 'singleDouble': " + expectedValueText + " }";
AssertJson(expectedText, actualText);
}
[Test]
public void UnknownEnumValueOmitted_SingleField()
{
var message = new TestAllTypes { SingleForeignEnum = (ForeignEnum) 100 };
AssertJson("{ }", JsonFormatter.Default.Format(message));
}
[Test]
public void UnknownEnumValueOmitted_RepeatedField()
{
var message = new TestAllTypes { RepeatedForeignEnum = { ForeignEnum.FOREIGN_BAZ, (ForeignEnum) 100, ForeignEnum.FOREIGN_FOO } };
AssertJson("{ 'repeatedForeignEnum': [ 'FOREIGN_BAZ', 'FOREIGN_FOO' ] }", JsonFormatter.Default.Format(message));
}
[Test]
public void UnknownEnumValueOmitted_MapField()
{
// This matches the C++ behaviour.
var message = new TestMap { MapInt32Enum = { { 1, MapEnum.MAP_ENUM_FOO }, { 2, (MapEnum) 100 }, { 3, MapEnum.MAP_ENUM_BAR } } };
AssertJson("{ 'mapInt32Enum': { '1': 'MAP_ENUM_FOO', '3': 'MAP_ENUM_BAR' } }", JsonFormatter.Default.Format(message));
}
[Test]
public void UnknownEnumValueOmitted_RepeatedField_AllEntriesUnknown()
{
// *Maybe* we should hold off on writing the "[" until we find that we've got at least one value to write...
// but this is what happens at the moment, and it doesn't seem too awful.
var message = new TestAllTypes { RepeatedForeignEnum = { (ForeignEnum) 200, (ForeignEnum) 100 } };
AssertJson("{ 'repeatedForeignEnum': [ ] }", JsonFormatter.Default.Format(message));
}
[Test]
public void NullValueForMessage()
{
var message = new TestMap { MapInt32ForeignMessage = { { 10, null } } };
AssertJson("{ 'mapInt32ForeignMessage': { '10': null } }", JsonFormatter.Default.Format(message));
}
[Test]
[TestCase("a\u17b4b", "a\\u17b4b")] // Explicit
[TestCase("a\u0601b", "a\\u0601b")] // Ranged
[TestCase("a\u0605b", "a\u0605b")] // Passthrough (note lack of double backslash...)
public void SimpleNonAscii(string text, string encoded)
{
var message = new TestAllTypes { SingleString = text };
AssertJson("{ 'singleString': '" + encoded + "' }", JsonFormatter.Default.Format(message));
}
[Test]
public void SurrogatePairEscaping()
{
var message = new TestAllTypes { SingleString = "a\uD801\uDC01b" };
AssertJson("{ 'singleString': 'a\\ud801\\udc01b' }", JsonFormatter.Default.Format(message));
}
[Test]
public void InvalidSurrogatePairsFail()
{
// Note: don't use TestCase for these, as the strings can't be reliably represented
// See http://codeblog.jonskeet.uk/2014/11/07/when-is-a-string-not-a-string/
// Lone low surrogate
var message = new TestAllTypes { SingleString = "a\uDC01b" };
Assert.Throws<ArgumentException>(() => JsonFormatter.Default.Format(message));
// Lone high surrogate
message = new TestAllTypes { SingleString = "a\uD801b" };
Assert.Throws<ArgumentException>(() => JsonFormatter.Default.Format(message));
}
[Test]
[TestCase("foo_bar", "fooBar")]
[TestCase("bananaBanana", "bananaBanana")]
[TestCase("BANANABanana", "bananaBanana")]
public void ToCamelCase(string original, string expected)
{
Assert.AreEqual(expected, JsonFormatter.ToCamelCase(original));
}
[Test]
[TestCase(null, "{ }")]
[TestCase("x", "{ 'fooString': 'x' }")]
[TestCase("", "{ 'fooString': '' }")]
public void Oneof(string fooStringValue, string expectedJson)
{
var message = new TestOneof();
if (fooStringValue != null)
{
message.FooString = fooStringValue;
}
// We should get the same result both with and without "format default values".
var formatter = new JsonFormatter(new JsonFormatter.Settings(false));
AssertJson(expectedJson, formatter.Format(message));
formatter = new JsonFormatter(new JsonFormatter.Settings(true));
AssertJson(expectedJson, formatter.Format(message));
}
[Test]
public void WrapperFormatting_Single()
{
// Just a few examples, handling both classes and value types, and
// default vs non-default values
var message = new TestWellKnownTypes
{
Int64Field = 10,
Int32Field = 0,
BytesField = ByteString.FromBase64("ABCD"),
StringField = ""
};
var expectedJson = "{ 'int64Field': '10', 'int32Field': 0, 'stringField': '', 'bytesField': 'ABCD' }";
AssertJson(expectedJson, JsonFormatter.Default.Format(message));
}
[Test]
public void WrapperFormatting_IncludeNull()
{
// The actual JSON here is very large because there are lots of fields. Just test a couple of them.
var message = new TestWellKnownTypes { Int32Field = 10 };
var formatter = new JsonFormatter(new JsonFormatter.Settings(true));
var actualJson = formatter.Format(message);
Assert.IsTrue(actualJson.Contains("\"int64Field\": null"));
Assert.IsFalse(actualJson.Contains("\"int32Field\": null"));
}
[Test]
public void OutputIsInNumericFieldOrder_NoDefaults()
{
var formatter = new JsonFormatter(new JsonFormatter.Settings(false));
var message = new TestJsonFieldOrdering { PlainString = "p1", PlainInt32 = 2 };
AssertJson("{ 'plainString': 'p1', 'plainInt32': 2 }", formatter.Format(message));
message = new TestJsonFieldOrdering { O1Int32 = 5, O2String = "o2", PlainInt32 = 10, PlainString = "plain" };
AssertJson("{ 'plainString': 'plain', 'o2String': 'o2', 'plainInt32': 10, 'o1Int32': 5 }", formatter.Format(message));
message = new TestJsonFieldOrdering { O1String = "", O2Int32 = 0, PlainInt32 = 10, PlainString = "plain" };
AssertJson("{ 'plainString': 'plain', 'o1String': '', 'plainInt32': 10, 'o2Int32': 0 }", formatter.Format(message));
}
[Test]
public void OutputIsInNumericFieldOrder_WithDefaults()
{
var formatter = new JsonFormatter(new JsonFormatter.Settings(true));
var message = new TestJsonFieldOrdering();
AssertJson("{ 'plainString': '', 'plainInt32': 0 }", formatter.Format(message));
message = new TestJsonFieldOrdering { O1Int32 = 5, O2String = "o2", PlainInt32 = 10, PlainString = "plain" };
AssertJson("{ 'plainString': 'plain', 'o2String': 'o2', 'plainInt32': 10, 'o1Int32': 5 }", formatter.Format(message));
message = new TestJsonFieldOrdering { O1String = "", O2Int32 = 0, PlainInt32 = 10, PlainString = "plain" };
AssertJson("{ 'plainString': 'plain', 'o1String': '', 'plainInt32': 10, 'o2Int32': 0 }", formatter.Format(message));
}
[Test]
public void TimestampStandalone()
{
Assert.AreEqual("1970-01-01T00:00:00Z", new Timestamp().ToString());
Assert.AreEqual("1970-01-01T00:00:00.100Z", new Timestamp { Nanos = 100000000 }.ToString());
Assert.AreEqual("1970-01-01T00:00:00.120Z", new Timestamp { Nanos = 120000000 }.ToString());
Assert.AreEqual("1970-01-01T00:00:00.123Z", new Timestamp { Nanos = 123000000 }.ToString());
Assert.AreEqual("1970-01-01T00:00:00.123400Z", new Timestamp { Nanos = 123400000 }.ToString());
Assert.AreEqual("1970-01-01T00:00:00.123450Z", new Timestamp { Nanos = 123450000 }.ToString());
Assert.AreEqual("1970-01-01T00:00:00.123456Z", new Timestamp { Nanos = 123456000 }.ToString());
Assert.AreEqual("1970-01-01T00:00:00.123456700Z", new Timestamp { Nanos = 123456700 }.ToString());
Assert.AreEqual("1970-01-01T00:00:00.123456780Z", new Timestamp { Nanos = 123456780 }.ToString());
Assert.AreEqual("1970-01-01T00:00:00.123456789Z", new Timestamp { Nanos = 123456789 }.ToString());
// One before and one after the Unix epoch
Assert.AreEqual("1673-06-19T12:34:56Z",
new DateTime(1673, 6, 19, 12, 34, 56, DateTimeKind.Utc).ToTimestamp().ToString());
Assert.AreEqual("2015-07-31T10:29:34Z",
new DateTime(2015, 7, 31, 10, 29, 34, DateTimeKind.Utc).ToTimestamp().ToString());
}
[Test]
public void TimestampField()
{
var message = new TestWellKnownTypes { TimestampField = new Timestamp() };
AssertJson("{ 'timestampField': '1970-01-01T00:00:00Z' }", JsonFormatter.Default.Format(message));
}
[Test]
[TestCase(0, 0, "0s")]
[TestCase(1, 0, "1s")]
[TestCase(-1, 0, "-1s")]
[TestCase(0, 100000000, "0.100s")]
[TestCase(0, 120000000, "0.120s")]
[TestCase(0, 123000000, "0.123s")]
[TestCase(0, 123400000, "0.123400s")]
[TestCase(0, 123450000, "0.123450s")]
[TestCase(0, 123456000, "0.123456s")]
[TestCase(0, 123456700, "0.123456700s")]
[TestCase(0, 123456780, "0.123456780s")]
[TestCase(0, 123456789, "0.123456789s")]
[TestCase(0, -100000000, "-0.100s")]
[TestCase(1, 100000000, "1.100s")]
[TestCase(-1, -100000000, "-1.100s")]
// Non-normalized examples
[TestCase(1, 2123456789, "3.123456789s")]
[TestCase(1, -100000000, "0.900s")]
public void DurationStandalone(long seconds, int nanoseconds, string expected)
{
Assert.AreEqual(expected, new Duration { Seconds = seconds, Nanos = nanoseconds }.ToString());
}
[Test]
public void DurationField()
{
var message = new TestWellKnownTypes { DurationField = new Duration() };
AssertJson("{ 'durationField': '0s' }", JsonFormatter.Default.Format(message));
}
[Test]
public void StructSample()
{
var message = new Struct
{
Fields =
{
{ "a", new Value { NullValue = new NullValue() } },
{ "b", new Value { BoolValue = false } },
{ "c", new Value { NumberValue = 10.5 } },
{ "d", new Value { StringValue = "text" } },
{ "e", new Value { ListValue = new ListValue { Values = { new Value { StringValue = "t1" }, new Value { NumberValue = 5 } } } } },
{ "f", new Value { StructValue = new Struct { Fields = { { "nested", new Value { StringValue = "value" } } } } } }
}
};
AssertJson("{ 'a': null, 'b': false, 'c': 10.5, 'd': 'text', 'e': [ 't1', 5 ], 'f': { 'nested': 'value' } }", message.ToString());
}
[Test]
public void FieldMaskStandalone()
{
var fieldMask = new FieldMask { Paths = { "", "single", "with_underscore", "nested.field.name", "nested..double_dot" } };
Assert.AreEqual(",single,withUnderscore,nested.field.name,nested..doubleDot", fieldMask.ToString());
// Invalid, but we shouldn't create broken JSON...
fieldMask = new FieldMask { Paths = { "x\\y" } };
Assert.AreEqual(@"x\\y", fieldMask.ToString());
}
[Test]
public void FieldMaskField()
{
var message = new TestWellKnownTypes { FieldMaskField = new FieldMask { Paths = { "user.display_name", "photo" } } };
AssertJson("{ 'fieldMaskField': 'user.displayName,photo' }", JsonFormatter.Default.Format(message));
}
/// <summary>
/// Checks that the actual JSON is the same as the expected JSON - but after replacing
/// all apostrophes in the expected JSON with double quotes. This basically makes the tests easier
/// to read.
/// </summary>
private static void AssertJson(string expectedJsonWithApostrophes, string actualJson)
{
var expectedJson = expectedJsonWithApostrophes.Replace("'", "\"");
Assert.AreEqual(expectedJson, actualJson);
}
}
}

@ -0,0 +1,20 @@
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("Google.Protobuf.Test")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Google.Protobuf.Test")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: AssemblyVersion("3.0.0.0")]
[assembly: AssemblyFileVersion("3.0.0.0")]

@ -1,286 +1,262 @@
#region Copyright notice and license #region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Protocol Buffers - Google's data interchange format // Copyright 2008 Google Inc. All rights reserved.
// Copyright 2008 Google Inc. All rights reserved. // https://developers.google.com/protocol-buffers/
// http://github.com/jskeet/dotnet-protobufs/ //
// Original C++/Java/Python code: // Redistribution and use in source and binary forms, with or without
// http://code.google.com/p/protobuf/ // modification, are permitted provided that the following conditions are
// // met:
// Redistribution and use in source and binary forms, with or without //
// modification, are permitted provided that the following conditions are // * Redistributions of source code must retain the above copyright
// met: // notice, this list of conditions and the following disclaimer.
// // * Redistributions in binary form must reproduce the above
// * Redistributions of source code must retain the above copyright // copyright notice, this list of conditions and the following disclaimer
// notice, this list of conditions and the following disclaimer. // in the documentation and/or other materials provided with the
// * Redistributions in binary form must reproduce the above // distribution.
// copyright notice, this list of conditions and the following disclaimer // * Neither the name of Google Inc. nor the names of its
// in the documentation and/or other materials provided with the // contributors may be used to endorse or promote products derived from
// distribution. // this software without specific prior written permission.
// * Neither the name of Google Inc. nor the names of its //
// contributors may be used to endorse or promote products derived from // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// this software without specific prior written permission. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT #endregion
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using System.Linq;
using Google.Protobuf.TestProtos;
#endregion using NUnit.Framework;
using UnitTest.Issues.TestProtos;
using Google.ProtocolBuffers.Descriptors;
using Google.ProtocolBuffers.TestProtos; namespace Google.Protobuf.Reflection
using NUnit.Framework; {
/// <summary>
namespace Google.ProtocolBuffers /// Tests for descriptors. (Not in its own namespace or broken up into individual classes as the
{ /// size doesn't warrant it. On the other hand, this makes me feel a bit dirty...)
/// <summary> /// </summary>
/// Tests for descriptors. (Not in its own namespace or broken up into individual classes as the public class DescriptorsTest
/// size doesn't warrant it. On the other hand, this makes me feel a bit dirty...) {
/// </summary> [Test]
public class DescriptorsTest public void FileDescriptor()
{ {
[Test] FileDescriptor file = UnittestProto3.Descriptor;
public void FileDescriptor()
{ Assert.AreEqual("google/protobuf/unittest_proto3.proto", file.Name);
FileDescriptor file = Unittest.Descriptor; Assert.AreEqual("protobuf_unittest", file.Package);
Assert.AreEqual("google/protobuf/unittest.proto", file.Name); Assert.AreEqual("UnittestProto", file.Proto.Options.JavaOuterClassname);
Assert.AreEqual("protobuf_unittest", file.Package); Assert.AreEqual("google/protobuf/unittest_proto3.proto", file.Proto.Name);
Assert.AreEqual("UnittestProto", file.Options.JavaOuterClassname); // unittest.proto doesn't have any public imports, but unittest_import.proto does.
Assert.AreEqual("google/protobuf/unittest.proto", file.Proto.Name); Assert.AreEqual(0, file.PublicDependencies.Count);
Assert.AreEqual(1, UnittestImportProto3.Descriptor.PublicDependencies.Count);
// unittest.proto doesn't have any public imports, but unittest_import.proto does. Assert.AreEqual(UnittestImportPublicProto3.Descriptor, UnittestImportProto3.Descriptor.PublicDependencies[0]);
Assert.AreEqual(0, file.PublicDependencies.Count);
Assert.AreEqual(1, UnittestImport.Descriptor.PublicDependencies.Count); Assert.AreEqual(1, file.Dependencies.Count);
Assert.AreEqual(UnittestImportPublic.Descriptor, UnittestImport.Descriptor.PublicDependencies[0]); Assert.AreEqual(UnittestImportProto3.Descriptor, file.Dependencies[0]);
Assert.AreEqual(1, file.Dependencies.Count); MessageDescriptor messageType = TestAllTypes.Descriptor;
Assert.AreEqual(UnittestImport.Descriptor, file.Dependencies[0]); Assert.AreSame(typeof(TestAllTypes), messageType.GeneratedType);
Assert.AreEqual(messageType, file.MessageTypes[0]);
MessageDescriptor messageType = TestAllTypes.Descriptor; Assert.AreEqual(messageType, file.FindTypeByName<MessageDescriptor>("TestAllTypes"));
Assert.AreEqual(messageType, file.MessageTypes[0]); Assert.Null(file.FindTypeByName<MessageDescriptor>("NoSuchType"));
Assert.AreEqual(messageType, file.FindTypeByName<MessageDescriptor>("TestAllTypes")); Assert.Null(file.FindTypeByName<MessageDescriptor>("protobuf_unittest.TestAllTypes"));
Assert.Null(file.FindTypeByName<MessageDescriptor>("NoSuchType")); for (int i = 0; i < file.MessageTypes.Count; i++)
Assert.Null(file.FindTypeByName<MessageDescriptor>("protobuf_unittest.TestAllTypes")); {
for (int i = 0; i < file.MessageTypes.Count; i++) Assert.AreEqual(i, file.MessageTypes[i].Index);
{ }
Assert.AreEqual(i, file.MessageTypes[i].Index);
} Assert.AreEqual(file.EnumTypes[0], file.FindTypeByName<EnumDescriptor>("ForeignEnum"));
Assert.Null(file.FindTypeByName<EnumDescriptor>("NoSuchType"));
Assert.AreEqual(file.EnumTypes[0], file.FindTypeByName<EnumDescriptor>("ForeignEnum")); Assert.Null(file.FindTypeByName<EnumDescriptor>("protobuf_unittest.ForeignEnum"));
Assert.Null(file.FindTypeByName<EnumDescriptor>("NoSuchType")); Assert.AreEqual(1, UnittestImportProto3.Descriptor.EnumTypes.Count);
Assert.Null(file.FindTypeByName<EnumDescriptor>("protobuf_unittest.ForeignEnum")); Assert.AreEqual("ImportEnum", UnittestImportProto3.Descriptor.EnumTypes[0].Name);
Assert.AreEqual(1, UnittestImport.Descriptor.EnumTypes.Count); for (int i = 0; i < file.EnumTypes.Count; i++)
Assert.AreEqual("ImportEnum", UnittestImport.Descriptor.EnumTypes[0].Name); {
for (int i = 0; i < file.EnumTypes.Count; i++) Assert.AreEqual(i, file.EnumTypes[i].Index);
{ }
Assert.AreEqual(i, file.EnumTypes[i].Index);
} Assert.AreEqual(10, file.SerializedData[0]);
}
FieldDescriptor extension = Unittest.OptionalInt32Extension.Descriptor;
Assert.AreEqual(extension, file.Extensions[0]); [Test]
Assert.AreEqual(extension, file.FindTypeByName<FieldDescriptor>("optional_int32_extension")); public void MessageDescriptor()
Assert.Null(file.FindTypeByName<FieldDescriptor>("no_such_ext")); {
Assert.Null(file.FindTypeByName<FieldDescriptor>("protobuf_unittest.optional_int32_extension")); MessageDescriptor messageType = TestAllTypes.Descriptor;
Assert.AreEqual(0, UnittestImport.Descriptor.Extensions.Count); MessageDescriptor nestedType = TestAllTypes.Types.NestedMessage.Descriptor;
for (int i = 0; i < file.Extensions.Count; i++)
{ Assert.AreEqual("TestAllTypes", messageType.Name);
Assert.AreEqual(i, file.Extensions[i].Index); Assert.AreEqual("protobuf_unittest.TestAllTypes", messageType.FullName);
} Assert.AreEqual(UnittestProto3.Descriptor, messageType.File);
} Assert.IsNull(messageType.ContainingType);
Assert.IsNull(messageType.Proto.Options);
[Test]
public void MessageDescriptor() Assert.AreEqual("TestAllTypes", messageType.Name);
{
MessageDescriptor messageType = TestAllTypes.Descriptor; Assert.AreEqual("NestedMessage", nestedType.Name);
MessageDescriptor nestedType = TestAllTypes.Types.NestedMessage.Descriptor; Assert.AreEqual("protobuf_unittest.TestAllTypes.NestedMessage", nestedType.FullName);
Assert.AreEqual(UnittestProto3.Descriptor, nestedType.File);
Assert.AreEqual("TestAllTypes", messageType.Name); Assert.AreEqual(messageType, nestedType.ContainingType);
Assert.AreEqual("protobuf_unittest.TestAllTypes", messageType.FullName);
Assert.AreEqual(Unittest.Descriptor, messageType.File); FieldDescriptor field = messageType.Fields.InDeclarationOrder()[0];
Assert.Null(messageType.ContainingType); Assert.AreEqual("single_int32", field.Name);
Assert.AreEqual(DescriptorProtos.MessageOptions.DefaultInstance, messageType.Options); Assert.AreEqual(field, messageType.FindDescriptor<FieldDescriptor>("single_int32"));
Assert.AreEqual("TestAllTypes", messageType.Proto.Name); Assert.Null(messageType.FindDescriptor<FieldDescriptor>("no_such_field"));
Assert.AreEqual(field, messageType.FindFieldByNumber(1));
Assert.AreEqual("NestedMessage", nestedType.Name); Assert.Null(messageType.FindFieldByNumber(571283));
Assert.AreEqual("protobuf_unittest.TestAllTypes.NestedMessage", nestedType.FullName); var fieldsInDeclarationOrder = messageType.Fields.InDeclarationOrder();
Assert.AreEqual(Unittest.Descriptor, nestedType.File); for (int i = 0; i < fieldsInDeclarationOrder.Count; i++)
Assert.AreEqual(messageType, nestedType.ContainingType); {
Assert.AreEqual(i, fieldsInDeclarationOrder[i].Index);
FieldDescriptor field = messageType.Fields[0]; }
Assert.AreEqual("optional_int32", field.Name);
Assert.AreEqual(field, messageType.FindDescriptor<FieldDescriptor>("optional_int32")); Assert.AreEqual(nestedType, messageType.NestedTypes[0]);
Assert.Null(messageType.FindDescriptor<FieldDescriptor>("no_such_field")); Assert.AreEqual(nestedType, messageType.FindDescriptor<MessageDescriptor>("NestedMessage"));
Assert.AreEqual(field, messageType.FindFieldByNumber(1)); Assert.Null(messageType.FindDescriptor<MessageDescriptor>("NoSuchType"));
Assert.Null(messageType.FindFieldByNumber(571283)); for (int i = 0; i < messageType.NestedTypes.Count; i++)
for (int i = 0; i < messageType.Fields.Count; i++) {
{ Assert.AreEqual(i, messageType.NestedTypes[i].Index);
Assert.AreEqual(i, messageType.Fields[i].Index); }
}
Assert.AreEqual(messageType.EnumTypes[0], messageType.FindDescriptor<EnumDescriptor>("NestedEnum"));
Assert.AreEqual(nestedType, messageType.NestedTypes[0]); Assert.Null(messageType.FindDescriptor<EnumDescriptor>("NoSuchType"));
Assert.AreEqual(nestedType, messageType.FindDescriptor<MessageDescriptor>("NestedMessage")); for (int i = 0; i < messageType.EnumTypes.Count; i++)
Assert.Null(messageType.FindDescriptor<MessageDescriptor>("NoSuchType")); {
for (int i = 0; i < messageType.NestedTypes.Count; i++) Assert.AreEqual(i, messageType.EnumTypes[i].Index);
{ }
Assert.AreEqual(i, messageType.NestedTypes[i].Index); }
}
[Test]
Assert.AreEqual(messageType.EnumTypes[0], messageType.FindDescriptor<EnumDescriptor>("NestedEnum")); public void FieldDescriptor()
Assert.Null(messageType.FindDescriptor<EnumDescriptor>("NoSuchType")); {
for (int i = 0; i < messageType.EnumTypes.Count; i++) MessageDescriptor messageType = TestAllTypes.Descriptor;
{ FieldDescriptor primitiveField = messageType.FindDescriptor<FieldDescriptor>("single_int32");
Assert.AreEqual(i, messageType.EnumTypes[i].Index); FieldDescriptor enumField = messageType.FindDescriptor<FieldDescriptor>("single_nested_enum");
} FieldDescriptor messageField = messageType.FindDescriptor<FieldDescriptor>("single_foreign_message");
}
Assert.AreEqual("single_int32", primitiveField.Name);
[Test] Assert.AreEqual("protobuf_unittest.TestAllTypes.single_int32",
public void FieldDescriptor() primitiveField.FullName);
{ Assert.AreEqual(1, primitiveField.FieldNumber);
MessageDescriptor messageType = TestAllTypes.Descriptor; Assert.AreEqual(messageType, primitiveField.ContainingType);
FieldDescriptor primitiveField = messageType.FindDescriptor<FieldDescriptor>("optional_int32"); Assert.AreEqual(UnittestProto3.Descriptor, primitiveField.File);
FieldDescriptor enumField = messageType.FindDescriptor<FieldDescriptor>("optional_nested_enum"); Assert.AreEqual(FieldType.Int32, primitiveField.FieldType);
FieldDescriptor messageField = messageType.FindDescriptor<FieldDescriptor>("optional_foreign_message"); Assert.IsNull(primitiveField.Proto.Options);
FieldDescriptor cordField = messageType.FindDescriptor<FieldDescriptor>("optional_cord");
FieldDescriptor extension = Unittest.OptionalInt32Extension.Descriptor; Assert.AreEqual("single_nested_enum", enumField.Name);
FieldDescriptor nestedExtension = TestRequired.Single.Descriptor; Assert.AreEqual(FieldType.Enum, enumField.FieldType);
// Assert.AreEqual(TestAllTypes.Types.NestedEnum.DescriptorProtoFile, enumField.EnumType);
Assert.AreEqual("optional_int32", primitiveField.Name);
Assert.AreEqual("protobuf_unittest.TestAllTypes.optional_int32", Assert.AreEqual("single_foreign_message", messageField.Name);
primitiveField.FullName); Assert.AreEqual(FieldType.Message, messageField.FieldType);
Assert.AreEqual(1, primitiveField.FieldNumber); Assert.AreEqual(ForeignMessage.Descriptor, messageField.MessageType);
Assert.AreEqual(messageType, primitiveField.ContainingType); }
Assert.AreEqual(Unittest.Descriptor, primitiveField.File);
Assert.AreEqual(FieldType.Int32, primitiveField.FieldType); [Test]
Assert.AreEqual(MappedType.Int32, primitiveField.MappedType); public void FieldDescriptorLabel()
Assert.AreEqual(DescriptorProtos.FieldOptions.DefaultInstance, primitiveField.Options); {
Assert.IsFalse(primitiveField.IsExtension); FieldDescriptor singleField =
Assert.AreEqual("optional_int32", primitiveField.Proto.Name); TestAllTypes.Descriptor.FindDescriptor<FieldDescriptor>("single_int32");
FieldDescriptor repeatedField =
Assert.AreEqual("optional_nested_enum", enumField.Name); TestAllTypes.Descriptor.FindDescriptor<FieldDescriptor>("repeated_int32");
Assert.AreEqual(FieldType.Enum, enumField.FieldType);
Assert.AreEqual(MappedType.Enum, enumField.MappedType); Assert.IsFalse(singleField.IsRepeated);
// Assert.AreEqual(TestAllTypes.Types.NestedEnum.DescriptorProtoFile, enumField.EnumType); Assert.IsTrue(repeatedField.IsRepeated);
}
Assert.AreEqual("optional_foreign_message", messageField.Name);
Assert.AreEqual(FieldType.Message, messageField.FieldType); [Test]
Assert.AreEqual(MappedType.Message, messageField.MappedType); public void EnumDescriptor()
Assert.AreEqual(ForeignMessage.Descriptor, messageField.MessageType); {
// Note: this test is a bit different to the Java version because there's no static way of getting to the descriptor
Assert.AreEqual("optional_cord", cordField.Name); EnumDescriptor enumType = UnittestProto3.Descriptor.FindTypeByName<EnumDescriptor>("ForeignEnum");
Assert.AreEqual(FieldType.String, cordField.FieldType); EnumDescriptor nestedType = TestAllTypes.Descriptor.FindDescriptor<EnumDescriptor>("NestedEnum");
Assert.AreEqual(MappedType.String, cordField.MappedType);
Assert.AreEqual(DescriptorProtos.FieldOptions.Types.CType.CORD, cordField.Options.Ctype); Assert.AreEqual("ForeignEnum", enumType.Name);
Assert.AreEqual("protobuf_unittest.ForeignEnum", enumType.FullName);
Assert.AreEqual("optional_int32_extension", extension.Name); Assert.AreEqual(UnittestProto3.Descriptor, enumType.File);
Assert.AreEqual("protobuf_unittest.optional_int32_extension", extension.FullName); Assert.Null(enumType.ContainingType);
Assert.AreEqual(1, extension.FieldNumber); Assert.Null(enumType.Proto.Options);
Assert.AreEqual(TestAllExtensions.Descriptor, extension.ContainingType);
Assert.AreEqual(Unittest.Descriptor, extension.File); Assert.AreEqual("NestedEnum", nestedType.Name);
Assert.AreEqual(FieldType.Int32, extension.FieldType); Assert.AreEqual("protobuf_unittest.TestAllTypes.NestedEnum",
Assert.AreEqual(MappedType.Int32, extension.MappedType); nestedType.FullName);
Assert.AreEqual(DescriptorProtos.FieldOptions.DefaultInstance, Assert.AreEqual(UnittestProto3.Descriptor, nestedType.File);
extension.Options); Assert.AreEqual(TestAllTypes.Descriptor, nestedType.ContainingType);
Assert.IsTrue(extension.IsExtension);
Assert.AreEqual(null, extension.ExtensionScope); EnumValueDescriptor value = enumType.FindValueByName("FOREIGN_FOO");
Assert.AreEqual("optional_int32_extension", extension.Proto.Name); Assert.AreEqual(value, enumType.Values[1]);
Assert.AreEqual("FOREIGN_FOO", value.Name);
Assert.AreEqual("single", nestedExtension.Name); Assert.AreEqual(4, value.Number);
Assert.AreEqual("protobuf_unittest.TestRequired.single", Assert.AreEqual((int) ForeignEnum.FOREIGN_FOO, value.Number);
nestedExtension.FullName); Assert.AreEqual(value, enumType.FindValueByNumber(4));
Assert.AreEqual(TestRequired.Descriptor, Assert.Null(enumType.FindValueByName("NO_SUCH_VALUE"));
nestedExtension.ExtensionScope); for (int i = 0; i < enumType.Values.Count; i++)
} {
Assert.AreEqual(i, enumType.Values[i].Index);
[Test] }
public void FieldDescriptorLabel() }
{
FieldDescriptor requiredField = [Test]
TestRequired.Descriptor.FindDescriptor<FieldDescriptor>("a"); public void OneofDescriptor()
FieldDescriptor optionalField = {
TestAllTypes.Descriptor.FindDescriptor<FieldDescriptor>("optional_int32"); OneofDescriptor descriptor = TestAllTypes.Descriptor.FindDescriptor<OneofDescriptor>("oneof_field");
FieldDescriptor repeatedField = Assert.AreEqual("oneof_field", descriptor.Name);
TestAllTypes.Descriptor.FindDescriptor<FieldDescriptor>("repeated_int32"); Assert.AreEqual("protobuf_unittest.TestAllTypes.oneof_field", descriptor.FullName);
Assert.IsTrue(requiredField.IsRequired); var expectedFields = new[] {
Assert.IsFalse(requiredField.IsRepeated); TestAllTypes.OneofBytesFieldNumber,
Assert.IsFalse(optionalField.IsRequired); TestAllTypes.OneofNestedMessageFieldNumber,
Assert.IsFalse(optionalField.IsRepeated); TestAllTypes.OneofStringFieldNumber,
Assert.IsFalse(repeatedField.IsRequired); TestAllTypes.OneofUint32FieldNumber }
Assert.IsTrue(repeatedField.IsRepeated); .Select(fieldNumber => TestAllTypes.Descriptor.FindFieldByNumber(fieldNumber))
} .ToList();
[Test] foreach (var field in expectedFields)
public void FieldDescriptorDefault() {
{ Assert.AreSame(descriptor, field.ContainingOneof);
MessageDescriptor d = TestAllTypes.Descriptor; }
Assert.IsFalse(d.FindDescriptor<FieldDescriptor>("optional_int32").HasDefaultValue);
Assert.AreEqual(0, d.FindDescriptor<FieldDescriptor>("optional_int32").DefaultValue); CollectionAssert.AreEquivalent(expectedFields, descriptor.Fields);
Assert.IsTrue(d.FindDescriptor<FieldDescriptor>("default_int32").HasDefaultValue); }
Assert.AreEqual(41, d.FindDescriptor<FieldDescriptor>("default_int32").DefaultValue);
[Test]
d = TestExtremeDefaultValues.Descriptor; public void ConstructionWithoutGeneratedCodeInfo()
Assert.AreEqual(TestExtremeDefaultValues.DefaultInstance.EscapedBytes, {
d.FindDescriptor<FieldDescriptor>("escaped_bytes").DefaultValue); var data = UnittestIssues.Descriptor.Proto.ToByteArray();
var newDescriptor = Google.Protobuf.Reflection.FileDescriptor.InternalBuildGeneratedFileFrom(data, new Reflection.FileDescriptor[] { }, null);
Assert.AreEqual(uint.MaxValue, d.FindDescriptor<FieldDescriptor>("large_uint32").DefaultValue);
Assert.AreEqual(ulong.MaxValue, d.FindDescriptor<FieldDescriptor>("large_uint64").DefaultValue); // We should still be able to get at a field...
} var messageDescriptor = newDescriptor.FindTypeByName<MessageDescriptor>("ItemField");
[Test] var fieldDescriptor = messageDescriptor.FindFieldByName("item");
public void EnumDescriptor() // But there shouldn't be an accessor (or a generated type for the message)
{ Assert.IsNull(fieldDescriptor.Accessor);
// Note: this test is a bit different to the Java version because there's no static way of getting to the descriptor Assert.IsNull(messageDescriptor.GeneratedType);
EnumDescriptor enumType = Unittest.Descriptor.FindTypeByName<EnumDescriptor>("ForeignEnum"); }
EnumDescriptor nestedType = TestAllTypes.Descriptor.FindDescriptor<EnumDescriptor>("NestedEnum");
// From TestFieldOrdering:
Assert.AreEqual("ForeignEnum", enumType.Name); // string my_string = 11;
Assert.AreEqual("protobuf_unittest.ForeignEnum", enumType.FullName); // int64 my_int = 1;
Assert.AreEqual(Unittest.Descriptor, enumType.File); // float my_float = 101;
Assert.Null(enumType.ContainingType); // NestedMessage single_nested_message = 200;
Assert.AreEqual(DescriptorProtos.EnumOptions.DefaultInstance, [Test]
enumType.Options); public void FieldListOrderings()
{
Assert.AreEqual("NestedEnum", nestedType.Name); var fields = TestFieldOrderings.Descriptor.Fields;
Assert.AreEqual("protobuf_unittest.TestAllTypes.NestedEnum", Assert.AreEqual(new[] { 11, 1, 101, 200 }, fields.InDeclarationOrder().Select(x => x.FieldNumber));
nestedType.FullName); Assert.AreEqual(new[] { 1, 11, 101, 200 }, fields.InFieldNumberOrder().Select(x => x.FieldNumber));
Assert.AreEqual(Unittest.Descriptor, nestedType.File); }
Assert.AreEqual(TestAllTypes.Descriptor, nestedType.ContainingType);
EnumValueDescriptor value = enumType.FindValueByName("FOREIGN_FOO"); [Test]
Assert.AreEqual(value, enumType.Values[0]); public void DescriptorProtoFileDescriptor()
Assert.AreEqual("FOREIGN_FOO", value.Name); {
Assert.AreEqual(4, value.Number); var descriptor = Google.Protobuf.Reflection.FileDescriptor.DescriptorProtoFileDescriptor;
Assert.AreEqual((int) ForeignEnum.FOREIGN_FOO, value.Number); }
Assert.AreEqual(value, enumType.FindValueByNumber(4)); }
Assert.Null(enumType.FindValueByName("NO_SUCH_VALUE")); }
for (int i = 0; i < enumType.Values.Count; i++)
{
Assert.AreEqual(i, enumType.Values[i].Index);
}
}
[Test]
public void CustomOptions()
{
MessageDescriptor descriptor = TestMessageWithCustomOptions.Descriptor;
Assert.IsTrue(descriptor.Options.HasExtension(UnittestCustomOptions.MessageOpt1));
Assert.AreEqual(-56, descriptor.Options.GetExtension(UnittestCustomOptions.MessageOpt1));
FieldDescriptor field = descriptor.FindFieldByName("field1");
Assert.NotNull(field);
Assert.IsTrue(field.Options.HasExtension(UnittestCustomOptions.FieldOpt1));
Assert.AreEqual(8765432109uL, field.Options.GetExtension(UnittestCustomOptions.FieldOpt1));
}
}
}

@ -0,0 +1,218 @@
#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
using Google.Protobuf.TestProtos;
using NUnit.Framework;
using System;
using System.Collections;
using System.Collections.Generic;
namespace Google.Protobuf.Reflection
{
public class FieldAccessTest
{
[Test]
public void GetValue()
{
var message = SampleMessages.CreateFullTestAllTypes();
var fields = TestAllTypes.Descriptor.Fields;
Assert.AreEqual(message.SingleBool, fields[TestAllTypes.SingleBoolFieldNumber].Accessor.GetValue(message));
Assert.AreEqual(message.SingleBytes, fields[TestAllTypes.SingleBytesFieldNumber].Accessor.GetValue(message));
Assert.AreEqual(message.SingleDouble, fields[TestAllTypes.SingleDoubleFieldNumber].Accessor.GetValue(message));
Assert.AreEqual(message.SingleFixed32, fields[TestAllTypes.SingleFixed32FieldNumber].Accessor.GetValue(message));
Assert.AreEqual(message.SingleFixed64, fields[TestAllTypes.SingleFixed64FieldNumber].Accessor.GetValue(message));
Assert.AreEqual(message.SingleFloat, fields[TestAllTypes.SingleFloatFieldNumber].Accessor.GetValue(message));
Assert.AreEqual(message.SingleForeignEnum, fields[TestAllTypes.SingleForeignEnumFieldNumber].Accessor.GetValue(message));
Assert.AreEqual(message.SingleForeignMessage, fields[TestAllTypes.SingleForeignMessageFieldNumber].Accessor.GetValue(message));
Assert.AreEqual(message.SingleImportEnum, fields[TestAllTypes.SingleImportEnumFieldNumber].Accessor.GetValue(message));
Assert.AreEqual(message.SingleImportMessage, fields[TestAllTypes.SingleImportMessageFieldNumber].Accessor.GetValue(message));
Assert.AreEqual(message.SingleInt32, fields[TestAllTypes.SingleInt32FieldNumber].Accessor.GetValue(message));
Assert.AreEqual(message.SingleInt64, fields[TestAllTypes.SingleInt64FieldNumber].Accessor.GetValue(message));
Assert.AreEqual(message.SingleNestedEnum, fields[TestAllTypes.SingleNestedEnumFieldNumber].Accessor.GetValue(message));
Assert.AreEqual(message.SingleNestedMessage, fields[TestAllTypes.SingleNestedMessageFieldNumber].Accessor.GetValue(message));
Assert.AreEqual(message.SinglePublicImportMessage, fields[TestAllTypes.SinglePublicImportMessageFieldNumber].Accessor.GetValue(message));
Assert.AreEqual(message.SingleSint32, fields[TestAllTypes.SingleSint32FieldNumber].Accessor.GetValue(message));
Assert.AreEqual(message.SingleSint64, fields[TestAllTypes.SingleSint64FieldNumber].Accessor.GetValue(message));
Assert.AreEqual(message.SingleString, fields[TestAllTypes.SingleStringFieldNumber].Accessor.GetValue(message));
Assert.AreEqual(message.SingleSfixed32, fields[TestAllTypes.SingleSfixed32FieldNumber].Accessor.GetValue(message));
Assert.AreEqual(message.SingleSfixed64, fields[TestAllTypes.SingleSfixed64FieldNumber].Accessor.GetValue(message));
Assert.AreEqual(message.SingleUint32, fields[TestAllTypes.SingleUint32FieldNumber].Accessor.GetValue(message));
Assert.AreEqual(message.SingleUint64, fields[TestAllTypes.SingleUint64FieldNumber].Accessor.GetValue(message));
Assert.AreEqual(message.OneofBytes, fields[TestAllTypes.OneofBytesFieldNumber].Accessor.GetValue(message));
Assert.AreEqual(message.OneofString, fields[TestAllTypes.OneofStringFieldNumber].Accessor.GetValue(message));
Assert.AreEqual(message.OneofNestedMessage, fields[TestAllTypes.OneofNestedMessageFieldNumber].Accessor.GetValue(message));
Assert.AreEqual(message.OneofUint32, fields[TestAllTypes.OneofUint32FieldNumber].Accessor.GetValue(message));
// Just one example for repeated fields - they're all just returning the list
var list = (IList) fields[TestAllTypes.RepeatedInt32FieldNumber].Accessor.GetValue(message);
Assert.AreEqual(message.RepeatedInt32, list);
Assert.AreEqual(message.RepeatedInt32[0], list[0]); // Just in case there was any doubt...
// Just a single map field, for the same reason
var mapMessage = new TestMap { MapStringString = { { "key1", "value1" }, { "key2", "value2" } } };
fields = TestMap.Descriptor.Fields;
var dictionary = (IDictionary) fields[TestMap.MapStringStringFieldNumber].Accessor.GetValue(mapMessage);
Assert.AreEqual(mapMessage.MapStringString, dictionary);
Assert.AreEqual("value1", dictionary["key1"]);
}
[Test]
public void Clear()
{
var message = SampleMessages.CreateFullTestAllTypes();
var fields = TestAllTypes.Descriptor.Fields;
fields[TestAllTypes.SingleBoolFieldNumber].Accessor.Clear(message);
fields[TestAllTypes.SingleInt32FieldNumber].Accessor.Clear(message);
fields[TestAllTypes.SingleStringFieldNumber].Accessor.Clear(message);
fields[TestAllTypes.SingleBytesFieldNumber].Accessor.Clear(message);
fields[TestAllTypes.SingleForeignEnumFieldNumber].Accessor.Clear(message);
fields[TestAllTypes.SingleForeignMessageFieldNumber].Accessor.Clear(message);
fields[TestAllTypes.RepeatedDoubleFieldNumber].Accessor.Clear(message);
var expected = new TestAllTypes(SampleMessages.CreateFullTestAllTypes())
{
SingleBool = false,
SingleInt32 = 0,
SingleString = "",
SingleBytes = ByteString.Empty,
SingleForeignEnum = 0,
SingleForeignMessage = null,
};
expected.RepeatedDouble.Clear();
Assert.AreEqual(expected, message);
// Separately, maps.
var mapMessage = new TestMap { MapStringString = { { "key1", "value1" }, { "key2", "value2" } } };
fields = TestMap.Descriptor.Fields;
fields[TestMap.MapStringStringFieldNumber].Accessor.Clear(mapMessage);
Assert.AreEqual(0, mapMessage.MapStringString.Count);
}
[Test]
public void SetValue_SingleFields()
{
// Just a sample (primitives, messages, enums, strings, byte strings)
var message = SampleMessages.CreateFullTestAllTypes();
var fields = TestAllTypes.Descriptor.Fields;
fields[TestAllTypes.SingleBoolFieldNumber].Accessor.SetValue(message, false);
fields[TestAllTypes.SingleInt32FieldNumber].Accessor.SetValue(message, 500);
fields[TestAllTypes.SingleStringFieldNumber].Accessor.SetValue(message, "It's a string");
fields[TestAllTypes.SingleBytesFieldNumber].Accessor.SetValue(message, ByteString.CopyFrom(99, 98, 97));
fields[TestAllTypes.SingleForeignEnumFieldNumber].Accessor.SetValue(message, ForeignEnum.FOREIGN_FOO);
fields[TestAllTypes.SingleForeignMessageFieldNumber].Accessor.SetValue(message, new ForeignMessage { C = 12345 });
fields[TestAllTypes.SingleDoubleFieldNumber].Accessor.SetValue(message, 20150701.5);
var expected = new TestAllTypes(SampleMessages.CreateFullTestAllTypes())
{
SingleBool = false,
SingleInt32 = 500,
SingleString = "It's a string",
SingleBytes = ByteString.CopyFrom(99, 98, 97),
SingleForeignEnum = ForeignEnum.FOREIGN_FOO,
SingleForeignMessage = new ForeignMessage { C = 12345 },
SingleDouble = 20150701.5
};
Assert.AreEqual(expected, message);
}
[Test]
public void SetValue_SingleFields_WrongType()
{
IMessage message = SampleMessages.CreateFullTestAllTypes();
var fields = message.Descriptor.Fields;
Assert.Throws<InvalidCastException>(() => fields[TestAllTypes.SingleBoolFieldNumber].Accessor.SetValue(message, "This isn't a bool"));
}
[Test]
public void SetValue_MapFields()
{
IMessage message = new TestMap();
var fields = message.Descriptor.Fields;
Assert.Throws<InvalidOperationException>(() => fields[TestMap.MapStringStringFieldNumber].Accessor.SetValue(message, new Dictionary<string, string>()));
}
[Test]
public void SetValue_RepeatedFields()
{
IMessage message = SampleMessages.CreateFullTestAllTypes();
var fields = message.Descriptor.Fields;
Assert.Throws<InvalidOperationException>(() => fields[TestAllTypes.RepeatedDoubleFieldNumber].Accessor.SetValue(message, new double[10]));
}
[Test]
public void GetValue_IncorrectType()
{
IMessage message = SampleMessages.CreateFullTestAllTypes();
var fields = message.Descriptor.Fields;
Assert.Throws<InvalidCastException>(() => fields[TestAllTypes.SingleBoolFieldNumber].Accessor.GetValue(new TestMap()));
}
[Test]
public void Oneof()
{
var message = new TestAllTypes();
var descriptor = TestAllTypes.Descriptor;
Assert.AreEqual(1, descriptor.Oneofs.Count);
var oneof = descriptor.Oneofs[0];
Assert.AreEqual("oneof_field", oneof.Name);
Assert.IsNull(oneof.Accessor.GetCaseFieldDescriptor(message));
message.OneofString = "foo";
Assert.AreSame(descriptor.Fields[TestAllTypes.OneofStringFieldNumber], oneof.Accessor.GetCaseFieldDescriptor(message));
message.OneofUint32 = 10;
Assert.AreSame(descriptor.Fields[TestAllTypes.OneofUint32FieldNumber], oneof.Accessor.GetCaseFieldDescriptor(message));
oneof.Accessor.Clear(message);
Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.None, message.OneofFieldCase);
}
[Test]
public void FieldDescriptor_ByName()
{
var descriptor = TestAllTypes.Descriptor;
Assert.AreSame(
descriptor.Fields[TestAllTypes.SingleBoolFieldNumber],
descriptor.Fields["single_bool"]);
}
[Test]
public void FieldDescriptor_NotFound()
{
var descriptor = TestAllTypes.Descriptor;
Assert.Throws<KeyNotFoundException>(() => descriptor.Fields[999999].ToString());
Assert.Throws<KeyNotFoundException>(() => descriptor.Fields["not found"].ToString());
}
}
}

@ -0,0 +1,42 @@
#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
namespace Google.Protobuf
{
// Just a sample enum with positive and negative values to be used in tests.
internal enum SampleEnum
{
NegativeValue = -2,
None = 0,
PositiveValue = 3
}
}

@ -0,0 +1,99 @@
#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
using System;
using Google.Protobuf.TestProtos;
namespace Google.Protobuf
{
/// <summary>
/// Helper methods to create sample instances of types generated from unit test messages.
/// </summary>
public class SampleMessages
{
/// <summary>
/// Creates a new sample TestAllTypes message with all fields populated.
/// The "oneof" field is populated with the string property (OneofString).
/// </summary>
public static TestAllTypes CreateFullTestAllTypes()
{
return new TestAllTypes
{
SingleBool = true,
SingleBytes = ByteString.CopyFrom(1, 2, 3, 4),
SingleDouble = 23.5,
SingleFixed32 = 23,
SingleFixed64 = 1234567890123,
SingleFloat = 12.25f,
SingleForeignEnum = ForeignEnum.FOREIGN_BAR,
SingleForeignMessage = new ForeignMessage { C = 10 },
SingleImportEnum = ImportEnum.IMPORT_BAZ,
SingleImportMessage = new ImportMessage { D = 20 },
SingleInt32 = 100,
SingleInt64 = 3210987654321,
SingleNestedEnum = TestAllTypes.Types.NestedEnum.FOO,
SingleNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 35 },
SinglePublicImportMessage = new PublicImportMessage { E = 54 },
SingleSfixed32 = -123,
SingleSfixed64 = -12345678901234,
SingleSint32 = -456,
SingleSint64 = -12345678901235,
SingleString = "test",
SingleUint32 = UInt32.MaxValue,
SingleUint64 = UInt64.MaxValue,
RepeatedBool = { true, false },
RepeatedBytes = { ByteString.CopyFrom(1, 2, 3, 4), ByteString.CopyFrom(5, 6), ByteString.CopyFrom(new byte[1000]) },
RepeatedDouble = { -12.25, 23.5 },
RepeatedFixed32 = { UInt32.MaxValue, 23 },
RepeatedFixed64 = { UInt64.MaxValue, 1234567890123 },
RepeatedFloat = { 100f, 12.25f },
RepeatedForeignEnum = { ForeignEnum.FOREIGN_FOO, ForeignEnum.FOREIGN_BAR },
RepeatedForeignMessage = { new ForeignMessage(), new ForeignMessage { C = 10 } },
RepeatedImportEnum = { ImportEnum.IMPORT_BAZ, ImportEnum.IMPORT_ENUM_UNSPECIFIED },
RepeatedImportMessage = { new ImportMessage { D = 20 }, new ImportMessage { D = 25 } },
RepeatedInt32 = { 100, 200 },
RepeatedInt64 = { 3210987654321, Int64.MaxValue },
RepeatedNestedEnum = { TestAllTypes.Types.NestedEnum.FOO, TestAllTypes.Types.NestedEnum.NEG },
RepeatedNestedMessage = { new TestAllTypes.Types.NestedMessage { Bb = 35 }, new TestAllTypes.Types.NestedMessage { Bb = 10 } },
RepeatedPublicImportMessage = { new PublicImportMessage { E = 54 }, new PublicImportMessage { E = -1 } },
RepeatedSfixed32 = { -123, 123 },
RepeatedSfixed64 = { -12345678901234, 12345678901234 },
RepeatedSint32 = { -456, 100 },
RepeatedSint64 = { -12345678901235, 123 },
RepeatedString = { "foo", "bar" },
RepeatedUint32 = { UInt32.MaxValue, UInt32.MinValue },
RepeatedUint64 = { UInt64.MaxValue, UInt32.MinValue },
OneofString = "Oneof string"
};
}
}
}

@ -0,0 +1,62 @@
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2008 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
using UnitTest.Issues.TestProtos;
using NUnit.Framework;
namespace Google.Protobuf
{
public class TestCornerCases
{
[Test]
public void TestRoundTripNegativeEnums()
{
NegativeEnumMessage msg = new NegativeEnumMessage
{
Value = NegativeEnum.MinusOne,
Values = { NegativeEnum.NEGATIVE_ENUM_ZERO, NegativeEnum.MinusOne, NegativeEnum.FiveBelow },
PackedValues = { NegativeEnum.NEGATIVE_ENUM_ZERO, NegativeEnum.MinusOne, NegativeEnum.FiveBelow }
};
Assert.AreEqual(58, msg.CalculateSize());
byte[] bytes = new byte[58];
CodedOutputStream output = new CodedOutputStream(bytes);
msg.WriteTo(output);
Assert.AreEqual(0, output.SpaceLeft);
NegativeEnumMessage copy = NegativeEnumMessage.Parser.ParseFrom(bytes);
Assert.AreEqual(msg, copy);
}
}
}

@ -0,0 +1,158 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: google/protobuf/unittest_import_proto3.proto
#pragma warning disable 1591, 0612, 3021
#region Designer generated code
using pb = global::Google.Protobuf;
using pbc = global::Google.Protobuf.Collections;
using pbr = global::Google.Protobuf.Reflection;
using scg = global::System.Collections.Generic;
namespace Google.Protobuf.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public static partial class UnittestImportProto3 {
#region Descriptor
public static pbr::FileDescriptor Descriptor {
get { return descriptor; }
}
private static pbr::FileDescriptor descriptor;
static UnittestImportProto3() {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
"Cixnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0X3Byb3RvMy5wcm90",
"bxIYcHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0GjNnb29nbGUvcHJvdG9idWYv",
"dW5pdHRlc3RfaW1wb3J0X3B1YmxpY19wcm90bzMucHJvdG8iGgoNSW1wb3J0",
"TWVzc2FnZRIJCgFkGAEgASgFKlkKCkltcG9ydEVudW0SGwoXSU1QT1JUX0VO",
"VU1fVU5TUEVDSUZJRUQQABIOCgpJTVBPUlRfRk9PEAcSDgoKSU1QT1JUX0JB",
"UhAIEg4KCklNUE9SVF9CQVoQCUI8Chhjb20uZ29vZ2xlLnByb3RvYnVmLnRl",
"c3RIAfgBAaoCGkdvb2dsZS5Qcm90b2J1Zi5UZXN0UHJvdG9zUABiBnByb3Rv",
"Mw=="));
descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
new pbr::FileDescriptor[] { global::Google.Protobuf.TestProtos.UnittestImportPublicProto3.Descriptor, },
new pbr::GeneratedCodeInfo(new[] {typeof(global::Google.Protobuf.TestProtos.ImportEnum), }, new pbr::GeneratedCodeInfo[] {
new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.ImportMessage), new[]{ "D" }, null, null, null)
}));
}
#endregion
}
#region Enums
public enum ImportEnum {
IMPORT_ENUM_UNSPECIFIED = 0,
IMPORT_FOO = 7,
IMPORT_BAR = 8,
IMPORT_BAZ = 9,
}
#endregion
#region Messages
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class ImportMessage : pb::IMessage<ImportMessage> {
private static readonly pb::MessageParser<ImportMessage> _parser = new pb::MessageParser<ImportMessage>(() => new ImportMessage());
public static pb::MessageParser<ImportMessage> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestImportProto3.Descriptor.MessageTypes[0]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
public ImportMessage() {
OnConstruction();
}
partial void OnConstruction();
public ImportMessage(ImportMessage other) : this() {
d_ = other.d_;
}
public ImportMessage Clone() {
return new ImportMessage(this);
}
public const int DFieldNumber = 1;
private int d_;
public int D {
get { return d_; }
set {
d_ = value;
}
}
public override bool Equals(object other) {
return Equals(other as ImportMessage);
}
public bool Equals(ImportMessage other) {
if (ReferenceEquals(other, null)) {
return false;
}
if (ReferenceEquals(other, this)) {
return true;
}
if (D != other.D) return false;
return true;
}
public override int GetHashCode() {
int hash = 1;
if (D != 0) hash ^= D.GetHashCode();
return hash;
}
public override string ToString() {
return pb::JsonFormatter.Default.Format(this);
}
public void WriteTo(pb::CodedOutputStream output) {
if (D != 0) {
output.WriteRawTag(8);
output.WriteInt32(D);
}
}
public int CalculateSize() {
int size = 0;
if (D != 0) {
size += 1 + pb::CodedOutputStream.ComputeInt32Size(D);
}
return size;
}
public void MergeFrom(ImportMessage other) {
if (other == null) {
return;
}
if (other.D != 0) {
D = other.D;
}
}
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
input.SkipLastField();
break;
case 8: {
D = input.ReadInt32();
break;
}
}
}
}
}
#endregion
}
#endregion Designer generated code

@ -0,0 +1,144 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: google/protobuf/unittest_import_public_proto3.proto
#pragma warning disable 1591, 0612, 3021
#region Designer generated code
using pb = global::Google.Protobuf;
using pbc = global::Google.Protobuf.Collections;
using pbr = global::Google.Protobuf.Reflection;
using scg = global::System.Collections.Generic;
namespace Google.Protobuf.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public static partial class UnittestImportPublicProto3 {
#region Descriptor
public static pbr::FileDescriptor Descriptor {
get { return descriptor; }
}
private static pbr::FileDescriptor descriptor;
static UnittestImportPublicProto3() {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
"CjNnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0X3B1YmxpY19wcm90",
"bzMucHJvdG8SGHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydCIgChNQdWJsaWNJ",
"bXBvcnRNZXNzYWdlEgkKAWUYASABKAVCNwoYY29tLmdvb2dsZS5wcm90b2J1",
"Zi50ZXN0qgIaR29vZ2xlLlByb3RvYnVmLlRlc3RQcm90b3NiBnByb3RvMw=="));
descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.PublicImportMessage), new[]{ "E" }, null, null, null)
}));
}
#endregion
}
#region Messages
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class PublicImportMessage : pb::IMessage<PublicImportMessage> {
private static readonly pb::MessageParser<PublicImportMessage> _parser = new pb::MessageParser<PublicImportMessage>(() => new PublicImportMessage());
public static pb::MessageParser<PublicImportMessage> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestImportPublicProto3.Descriptor.MessageTypes[0]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
public PublicImportMessage() {
OnConstruction();
}
partial void OnConstruction();
public PublicImportMessage(PublicImportMessage other) : this() {
e_ = other.e_;
}
public PublicImportMessage Clone() {
return new PublicImportMessage(this);
}
public const int EFieldNumber = 1;
private int e_;
public int E {
get { return e_; }
set {
e_ = value;
}
}
public override bool Equals(object other) {
return Equals(other as PublicImportMessage);
}
public bool Equals(PublicImportMessage other) {
if (ReferenceEquals(other, null)) {
return false;
}
if (ReferenceEquals(other, this)) {
return true;
}
if (E != other.E) return false;
return true;
}
public override int GetHashCode() {
int hash = 1;
if (E != 0) hash ^= E.GetHashCode();
return hash;
}
public override string ToString() {
return pb::JsonFormatter.Default.Format(this);
}
public void WriteTo(pb::CodedOutputStream output) {
if (E != 0) {
output.WriteRawTag(8);
output.WriteInt32(E);
}
}
public int CalculateSize() {
int size = 0;
if (E != 0) {
size += 1 + pb::CodedOutputStream.ComputeInt32Size(E);
}
return size;
}
public void MergeFrom(PublicImportMessage other) {
if (other == null) {
return;
}
if (other.E != 0) {
E = other.E;
}
}
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
input.SkipLastField();
break;
case 8: {
E = input.ReadInt32();
break;
}
}
}
}
}
#endregion
}
#endregion Designer generated code

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,104 @@
#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
using NUnit.Framework;
using System;
namespace Google.Protobuf.WellKnownTypes
{
public class DurationTest
{
[Test]
public void ToTimeSpan()
{
Assert.AreEqual(TimeSpan.FromSeconds(1), new Duration { Seconds = 1 }.ToTimeSpan());
Assert.AreEqual(TimeSpan.FromSeconds(-1), new Duration { Seconds = -1 }.ToTimeSpan());
Assert.AreEqual(TimeSpan.FromMilliseconds(1), new Duration { Nanos = 1000000 }.ToTimeSpan());
Assert.AreEqual(TimeSpan.FromMilliseconds(-1), new Duration { Nanos = -1000000 }.ToTimeSpan());
Assert.AreEqual(TimeSpan.FromTicks(1), new Duration { Nanos = 100 }.ToTimeSpan());
Assert.AreEqual(TimeSpan.FromTicks(-1), new Duration { Nanos = -100 }.ToTimeSpan());
// Rounding is towards 0
Assert.AreEqual(TimeSpan.FromTicks(2), new Duration { Nanos = 250 }.ToTimeSpan());
Assert.AreEqual(TimeSpan.FromTicks(-2), new Duration { Nanos = -250 }.ToTimeSpan());
// Non-normalized durations
Assert.AreEqual(TimeSpan.FromSeconds(3), new Duration { Seconds = 1, Nanos = 2 * Duration.NanosecondsPerSecond }.ToTimeSpan());
Assert.AreEqual(TimeSpan.FromSeconds(1), new Duration { Seconds = 3, Nanos = -2 * Duration.NanosecondsPerSecond }.ToTimeSpan());
Assert.AreEqual(TimeSpan.FromSeconds(-1), new Duration { Seconds = 1, Nanos = -2 * Duration.NanosecondsPerSecond }.ToTimeSpan());
}
[Test]
public void Addition()
{
Assert.AreEqual(new Duration { Seconds = 2, Nanos = 100000000 },
new Duration { Seconds = 1, Nanos = 600000000 } + new Duration { Nanos = 500000000 });
Assert.AreEqual(new Duration { Seconds = -2, Nanos = -100000000 },
new Duration { Seconds = -1, Nanos = -600000000 } + new Duration { Nanos = -500000000 });
Assert.AreEqual(new Duration { Seconds = 1, Nanos = 100000000 },
new Duration { Seconds = 1, Nanos = 600000000 } + new Duration { Nanos = -500000000 });
// Non-normalized durations, or non-normalized intermediate results
Assert.AreEqual(new Duration { Seconds = 1 },
new Duration { Seconds = 1, Nanos = -500000000 } + new Duration { Nanos = 500000000 });
Assert.AreEqual(new Duration { Nanos = -900000000 },
new Duration { Seconds = -1, Nanos = -100000000 } + new Duration { Nanos = 200000000 });
Assert.AreEqual(new Duration { Nanos = 900000000 },
new Duration { Seconds = 1, Nanos = 100000000 } + new Duration { Nanos = -200000000 });
}
[Test]
public void Subtraction()
{
Assert.AreEqual(new Duration { Seconds = 1, Nanos = 100000000 },
new Duration { Seconds = 1, Nanos = 600000000 } - new Duration { Nanos = 500000000 });
Assert.AreEqual(new Duration { Seconds = -1, Nanos = -100000000 },
new Duration { Seconds = -1, Nanos = -600000000 } - new Duration { Nanos = -500000000 });
Assert.AreEqual(new Duration { Seconds = 2, Nanos = 100000000 },
new Duration { Seconds = 1, Nanos = 600000000 } - new Duration { Nanos = -500000000 });
// Non-normalized durations
Assert.AreEqual(new Duration(),
new Duration { Seconds = 1, Nanos = -500000000 } - new Duration { Nanos = 500000000 });
Assert.AreEqual(new Duration { Seconds = 1 },
new Duration { Nanos = 2000000000 } - new Duration { Nanos = 1000000000 });
}
[Test]
public void FromTimeSpan()
{
Assert.AreEqual(new Duration { Seconds = 1 }, Duration.FromTimeSpan(TimeSpan.FromSeconds(1)));
Assert.AreEqual(new Duration { Nanos = Duration.NanosecondsPerTick }, Duration.FromTimeSpan(TimeSpan.FromTicks(1)));
}
}
}

@ -0,0 +1,84 @@
#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
using NUnit.Framework;
using System;
namespace Google.Protobuf.WellKnownTypes
{
public class TimestampTest
{
[Test]
public void FromAndToDateTime()
{
DateTime utcMin = DateTime.SpecifyKind(DateTime.MinValue, DateTimeKind.Utc);
DateTime utcMax = DateTime.SpecifyKind(DateTime.MaxValue, DateTimeKind.Utc);
AssertRoundtrip(new Timestamp { Seconds = -62135596800 }, utcMin);
AssertRoundtrip(new Timestamp { Seconds = 253402300799, Nanos = 999999900 }, utcMax);
AssertRoundtrip(new Timestamp(), new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc));
AssertRoundtrip(new Timestamp { Nanos = 1000000}, new DateTime(1970, 1, 1, 0, 0, 0, 1, DateTimeKind.Utc));
AssertRoundtrip(new Timestamp { Seconds = -1, Nanos = 999000000 }, new DateTime(1969, 12, 31, 23, 59, 59, 999, DateTimeKind.Utc));
AssertRoundtrip(new Timestamp { Seconds = 3600 }, new DateTime(1970, 1, 1, 1, 0, 0, DateTimeKind.Utc));
AssertRoundtrip(new Timestamp { Seconds = -3600 }, new DateTime(1969, 12, 31, 23, 0, 0, DateTimeKind.Utc));
}
[Test]
public void ToDateTimeTruncation()
{
var t1 = new Timestamp { Seconds = 1, Nanos = 1000000 + Duration.NanosecondsPerTick - 1 };
Assert.AreEqual(new DateTime(1970, 1, 1, 0, 0, 1, DateTimeKind.Utc).AddMilliseconds(1), t1.ToDateTime());
var t2 = new Timestamp { Seconds = -1, Nanos = 1000000 + Duration.NanosecondsPerTick - 1 };
Assert.AreEqual(new DateTime(1969, 12, 31, 23, 59, 59).AddMilliseconds(1), t2.ToDateTime());
}
private static void AssertRoundtrip(Timestamp timestamp, DateTime dateTime)
{
Assert.AreEqual(timestamp, Timestamp.FromDateTime(dateTime));
Assert.AreEqual(dateTime, timestamp.ToDateTime());
Assert.AreEqual(DateTimeKind.Utc, timestamp.ToDateTime().Kind);
}
[Test]
public void Arithmetic()
{
Timestamp t1 = new Timestamp { Seconds = 10000, Nanos = 5000 };
Timestamp t2 = new Timestamp { Seconds = 8000, Nanos = 10000 };
Duration difference = new Duration { Seconds = 1999, Nanos = Duration.NanosecondsPerSecond - 5000 };
Assert.AreEqual(difference, t1 - t2);
Assert.AreEqual(-difference, t2 - t1);
Assert.AreEqual(t1, t2 + difference);
Assert.AreEqual(t2, t1 - difference);
}
}
}

@ -0,0 +1,349 @@
#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
using System;
using Google.Protobuf.TestProtos;
using NUnit.Framework;
using System.Collections;
using System.IO;
namespace Google.Protobuf.WellKnownTypes
{
public class WrappersTest
{
[Test]
public void NullIsDefault()
{
var message = new TestWellKnownTypes();
Assert.IsNull(message.StringField);
Assert.IsNull(message.BytesField);
Assert.IsNull(message.BoolField);
Assert.IsNull(message.FloatField);
Assert.IsNull(message.DoubleField);
Assert.IsNull(message.Int32Field);
Assert.IsNull(message.Int64Field);
Assert.IsNull(message.Uint32Field);
Assert.IsNull(message.Uint64Field);
}
[Test]
public void NonDefaultSingleValues()
{
var message = new TestWellKnownTypes
{
StringField = "x",
BytesField = ByteString.CopyFrom(1, 2, 3),
BoolField = true,
FloatField = 12.5f,
DoubleField = 12.25d,
Int32Field = 1,
Int64Field = 2,
Uint32Field = 3,
Uint64Field = 4
};
var bytes = message.ToByteArray();
var parsed = TestWellKnownTypes.Parser.ParseFrom(bytes);
Assert.AreEqual("x", parsed.StringField);
Assert.AreEqual(ByteString.CopyFrom(1, 2, 3), parsed.BytesField);
Assert.AreEqual(true, parsed.BoolField);
Assert.AreEqual(12.5f, parsed.FloatField);
Assert.AreEqual(12.25d, parsed.DoubleField);
Assert.AreEqual(1, parsed.Int32Field);
Assert.AreEqual(2L, parsed.Int64Field);
Assert.AreEqual(3U, parsed.Uint32Field);
Assert.AreEqual(4UL, parsed.Uint64Field);
}
[Test]
public void NonNullDefaultIsPreservedThroughSerialization()
{
var message = new TestWellKnownTypes
{
StringField = "",
BytesField = ByteString.Empty,
BoolField = false,
FloatField = 0f,
DoubleField = 0d,
Int32Field = 0,
Int64Field = 0,
Uint32Field = 0,
Uint64Field = 0
};
var bytes = message.ToByteArray();
var parsed = TestWellKnownTypes.Parser.ParseFrom(bytes);
Assert.AreEqual("", parsed.StringField);
Assert.AreEqual(ByteString.Empty, parsed.BytesField);
Assert.AreEqual(false, parsed.BoolField);
Assert.AreEqual(0f, parsed.FloatField);
Assert.AreEqual(0d, parsed.DoubleField);
Assert.AreEqual(0, parsed.Int32Field);
Assert.AreEqual(0L, parsed.Int64Field);
Assert.AreEqual(0U, parsed.Uint32Field);
Assert.AreEqual(0UL, parsed.Uint64Field);
}
[Test]
public void RepeatedWrappersProhibitNullItems()
{
var message = new RepeatedWellKnownTypes();
Assert.Throws<ArgumentNullException>(() => message.BoolField.Add((bool?) null));
Assert.Throws<ArgumentNullException>(() => message.Int32Field.Add((int?) null));
Assert.Throws<ArgumentNullException>(() => message.StringField.Add((string) null));
Assert.Throws<ArgumentNullException>(() => message.BytesField.Add((ByteString) null));
}
[Test]
public void RepeatedWrappersSerializeDeserialize()
{
var message = new RepeatedWellKnownTypes
{
BoolField = { true, false },
BytesField = { ByteString.CopyFrom(1, 2, 3), ByteString.CopyFrom(4, 5, 6), ByteString.Empty },
DoubleField = { 12.5, -1.5, 0d },
FloatField = { 123.25f, -20f, 0f },
Int32Field = { int.MaxValue, int.MinValue, 0 },
Int64Field = { long.MaxValue, long.MinValue, 0L },
StringField = { "First", "Second", "" },
Uint32Field = { uint.MaxValue, uint.MinValue, 0U },
Uint64Field = { ulong.MaxValue, ulong.MinValue, 0UL },
};
var bytes = message.ToByteArray();
var parsed = RepeatedWellKnownTypes.Parser.ParseFrom(bytes);
Assert.AreEqual(message, parsed);
// Just to test a single value for sanity...
Assert.AreEqual("Second", message.StringField[1]);
}
[Test]
public void MapWrappersSerializeDeserialize()
{
var message = new MapWellKnownTypes
{
BoolField = { { 10, false }, { 20, true } },
BytesField = {
{ -1, ByteString.CopyFrom(1, 2, 3) },
{ 10, ByteString.CopyFrom(4, 5, 6) },
{ 1000, ByteString.Empty },
{ 10000, null }
},
DoubleField = { { 1, 12.5 }, { 10, -1.5 }, { 20, 0d } },
FloatField = { { 2, 123.25f }, { 3, -20f }, { 4, 0f } },
Int32Field = { { 5, int.MaxValue }, { 6, int.MinValue }, { 7, 0 } },
Int64Field = { { 8, long.MaxValue }, { 9, long.MinValue }, { 10, 0L } },
StringField = { { 11, "First" }, { 12, "Second" }, { 13, "" }, { 14, null } },
Uint32Field = { { 15, uint.MaxValue }, { 16, uint.MinValue }, { 17, 0U } },
Uint64Field = { { 18, ulong.MaxValue }, { 19, ulong.MinValue }, { 20, 0UL } },
};
var bytes = message.ToByteArray();
var parsed = MapWellKnownTypes.Parser.ParseFrom(bytes);
Assert.AreEqual(message, parsed);
// Just to test a single value for sanity...
Assert.AreEqual("Second", message.StringField[12]);
}
[Test]
public void Reflection_SingleValues()
{
var message = new TestWellKnownTypes
{
StringField = "x",
BytesField = ByteString.CopyFrom(1, 2, 3),
BoolField = true,
FloatField = 12.5f,
DoubleField = 12.25d,
Int32Field = 1,
Int64Field = 2,
Uint32Field = 3,
Uint64Field = 4
};
var fields = TestWellKnownTypes.Descriptor.Fields;
Assert.AreEqual("x", fields[TestWellKnownTypes.StringFieldFieldNumber].Accessor.GetValue(message));
Assert.AreEqual(ByteString.CopyFrom(1, 2, 3), fields[TestWellKnownTypes.BytesFieldFieldNumber].Accessor.GetValue(message));
Assert.AreEqual(true, fields[TestWellKnownTypes.BoolFieldFieldNumber].Accessor.GetValue(message));
Assert.AreEqual(12.5f, fields[TestWellKnownTypes.FloatFieldFieldNumber].Accessor.GetValue(message));
Assert.AreEqual(12.25d, fields[TestWellKnownTypes.DoubleFieldFieldNumber].Accessor.GetValue(message));
Assert.AreEqual(1, fields[TestWellKnownTypes.Int32FieldFieldNumber].Accessor.GetValue(message));
Assert.AreEqual(2L, fields[TestWellKnownTypes.Int64FieldFieldNumber].Accessor.GetValue(message));
Assert.AreEqual(3U, fields[TestWellKnownTypes.Uint32FieldFieldNumber].Accessor.GetValue(message));
Assert.AreEqual(4UL, fields[TestWellKnownTypes.Uint64FieldFieldNumber].Accessor.GetValue(message));
// And a couple of null fields...
message.StringField = null;
message.FloatField = null;
Assert.IsNull(fields[TestWellKnownTypes.StringFieldFieldNumber].Accessor.GetValue(message));
Assert.IsNull(fields[TestWellKnownTypes.FloatFieldFieldNumber].Accessor.GetValue(message));
}
[Test]
public void Reflection_RepeatedFields()
{
// Just a single example... note that we can't have a null value here
var message = new RepeatedWellKnownTypes { Int32Field = { 1, 2 } };
var fields = RepeatedWellKnownTypes.Descriptor.Fields;
var list = (IList) fields[RepeatedWellKnownTypes.Int32FieldFieldNumber].Accessor.GetValue(message);
CollectionAssert.AreEqual(new[] { 1, 2 }, list);
}
[Test]
public void Reflection_MapFields()
{
// Just a single example... note that we can't have a null value here
var message = new MapWellKnownTypes { Int32Field = { { 1, 2 }, { 3, null } } };
var fields = MapWellKnownTypes.Descriptor.Fields;
var dictionary = (IDictionary) fields[MapWellKnownTypes.Int32FieldFieldNumber].Accessor.GetValue(message);
Assert.AreEqual(2, dictionary[1]);
Assert.IsNull(dictionary[3]);
Assert.IsTrue(dictionary.Contains(3));
}
[Test]
public void Oneof()
{
var message = new OneofWellKnownTypes { EmptyField = new Empty() };
// Start off with a non-wrapper
Assert.AreEqual(OneofWellKnownTypes.OneofFieldOneofCase.EmptyField, message.OneofFieldCase);
AssertOneofRoundTrip(message);
message.StringField = "foo";
Assert.AreEqual(OneofWellKnownTypes.OneofFieldOneofCase.StringField, message.OneofFieldCase);
AssertOneofRoundTrip(message);
message.StringField = "foo";
Assert.AreEqual(OneofWellKnownTypes.OneofFieldOneofCase.StringField, message.OneofFieldCase);
AssertOneofRoundTrip(message);
message.DoubleField = 0.0f;
Assert.AreEqual(OneofWellKnownTypes.OneofFieldOneofCase.DoubleField, message.OneofFieldCase);
AssertOneofRoundTrip(message);
message.DoubleField = 1.0f;
Assert.AreEqual(OneofWellKnownTypes.OneofFieldOneofCase.DoubleField, message.OneofFieldCase);
AssertOneofRoundTrip(message);
message.ClearOneofField();
Assert.AreEqual(OneofWellKnownTypes.OneofFieldOneofCase.None, message.OneofFieldCase);
AssertOneofRoundTrip(message);
}
private void AssertOneofRoundTrip(OneofWellKnownTypes message)
{
// Normal roundtrip, but explicitly checking the case...
var bytes = message.ToByteArray();
var parsed = OneofWellKnownTypes.Parser.ParseFrom(bytes);
Assert.AreEqual(message, parsed);
Assert.AreEqual(message.OneofFieldCase, parsed.OneofFieldCase);
}
[Test]
[TestCase("x", "y", "y")]
[TestCase("x", "", "x")]
[TestCase("x", null, "x")]
[TestCase("", "y", "y")]
[TestCase("", "", "")]
[TestCase("", null, "")]
[TestCase(null, "y", "y")]
[TestCase(null, "", "")]
[TestCase(null, null, null)]
public void Merging(string original, string merged, string expected)
{
var originalMessage = new TestWellKnownTypes { StringField = original };
var mergingMessage = new TestWellKnownTypes { StringField = merged };
originalMessage.MergeFrom(mergingMessage);
Assert.AreEqual(expected, originalMessage.StringField);
// Try it using MergeFrom(CodedInputStream) too...
originalMessage = new TestWellKnownTypes { StringField = original };
originalMessage.MergeFrom(mergingMessage.ToByteArray());
Assert.AreEqual(expected, originalMessage.StringField);
}
// Merging is odd with wrapper types, due to the way that default values aren't emitted in
// the binary stream. In fact we cheat a little bit - a message with an explicitly present default
// value will have that default value ignored.
[Test]
public void MergingCornerCase()
{
var message = new TestWellKnownTypes { Int32Field = 5 };
// Create a byte array which has the data of an Int32Value explicitly containing a value of 0.
// This wouldn't normally happen.
byte[] bytes;
var wrapperTag = WireFormat.MakeTag(TestWellKnownTypes.Int32FieldFieldNumber, WireFormat.WireType.LengthDelimited);
var valueTag = WireFormat.MakeTag(Int32Value.ValueFieldNumber, WireFormat.WireType.Varint);
using (var stream = new MemoryStream())
{
var coded = new CodedOutputStream(stream);
coded.WriteTag(wrapperTag);
coded.WriteLength(2); // valueTag + a value 0, each one byte
coded.WriteTag(valueTag);
coded.WriteInt32(0);
coded.Flush();
bytes = stream.ToArray();
}
message.MergeFrom(bytes);
// A normal implementation would have 0 now, as the explicit default would have been overwritten the 5.
Assert.AreEqual(5, message.Int32Field);
}
[Test]
public void UnknownFieldInWrapper()
{
var stream = new MemoryStream();
var output = new CodedOutputStream(stream);
var wrapperTag = WireFormat.MakeTag(TestWellKnownTypes.Int32FieldFieldNumber, WireFormat.WireType.LengthDelimited);
var unknownTag = WireFormat.MakeTag(15, WireFormat.WireType.Varint);
var valueTag = WireFormat.MakeTag(Int32Value.ValueFieldNumber, WireFormat.WireType.Varint);
output.WriteTag(wrapperTag);
output.WriteLength(4); // unknownTag + value 5 + valueType + value 6, each 1 byte
output.WriteTag(unknownTag);
output.WriteInt32((int) valueTag); // Sneakily "pretend" it's a tag when it's really a value
output.WriteTag(valueTag);
output.WriteInt32(6);
output.Flush();
stream.Position = 0;
var message = TestWellKnownTypes.Parser.ParseFrom(stream);
Assert.AreEqual(6, message.Int32Field);
}
}
}

@ -0,0 +1,56 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.31101.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Google.Protobuf", "Google.Protobuf\Google.Protobuf.csproj", "{6908BDCE-D925-43F3-94AC-A531E6DF2591}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Google.Protobuf.Test", "Google.Protobuf.Test\Google.Protobuf.Test.csproj", "{DD01ED24-3750-4567-9A23-1DB676A15610}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AddressBook", "AddressBook\AddressBook.csproj", "{A31F5FB2-4FF3-432A-B35B-5CD203606311}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Google.Protobuf.JsonDump", "Google.Protobuf.JsonDump\Google.Protobuf.JsonDump.csproj", "{D7282E99-2DC3-405B-946F-177DB2FD2AE2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Google.Protobuf.Conformance", "Google.Protobuf.Conformance\Google.Protobuf.Conformance.csproj", "{0607D1B8-80D6-4B35-9857-1263C1B32B94}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
ReleaseSigned|Any CPU = ReleaseSigned|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{6908BDCE-D925-43F3-94AC-A531E6DF2591}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6908BDCE-D925-43F3-94AC-A531E6DF2591}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6908BDCE-D925-43F3-94AC-A531E6DF2591}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6908BDCE-D925-43F3-94AC-A531E6DF2591}.Release|Any CPU.Build.0 = Release|Any CPU
{6908BDCE-D925-43F3-94AC-A531E6DF2591}.ReleaseSigned|Any CPU.ActiveCfg = ReleaseSigned|Any CPU
{6908BDCE-D925-43F3-94AC-A531E6DF2591}.ReleaseSigned|Any CPU.Build.0 = ReleaseSigned|Any CPU
{DD01ED24-3750-4567-9A23-1DB676A15610}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DD01ED24-3750-4567-9A23-1DB676A15610}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DD01ED24-3750-4567-9A23-1DB676A15610}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DD01ED24-3750-4567-9A23-1DB676A15610}.Release|Any CPU.Build.0 = Release|Any CPU
{DD01ED24-3750-4567-9A23-1DB676A15610}.ReleaseSigned|Any CPU.ActiveCfg = ReleaseSigned|Any CPU
{DD01ED24-3750-4567-9A23-1DB676A15610}.ReleaseSigned|Any CPU.Build.0 = ReleaseSigned|Any CPU
{A31F5FB2-4FF3-432A-B35B-5CD203606311}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A31F5FB2-4FF3-432A-B35B-5CD203606311}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A31F5FB2-4FF3-432A-B35B-5CD203606311}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A31F5FB2-4FF3-432A-B35B-5CD203606311}.Release|Any CPU.Build.0 = Release|Any CPU
{A31F5FB2-4FF3-432A-B35B-5CD203606311}.ReleaseSigned|Any CPU.ActiveCfg = Release|Any CPU
{A31F5FB2-4FF3-432A-B35B-5CD203606311}.ReleaseSigned|Any CPU.Build.0 = Release|Any CPU
{D7282E99-2DC3-405B-946F-177DB2FD2AE2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{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
{D7282E99-2DC3-405B-946F-177DB2FD2AE2}.ReleaseSigned|Any CPU.ActiveCfg = Release|Any CPU
{D7282E99-2DC3-405B-946F-177DB2FD2AE2}.ReleaseSigned|Any CPU.Build.0 = Release|Any CPU
{0607D1B8-80D6-4B35-9857-1263C1B32B94}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0607D1B8-80D6-4B35-9857-1263C1B32B94}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0607D1B8-80D6-4B35-9857-1263C1B32B94}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0607D1B8-80D6-4B35-9857-1263C1B32B94}.Release|Any CPU.Build.0 = Release|Any CPU
{0607D1B8-80D6-4B35-9857-1263C1B32B94}.ReleaseSigned|Any CPU.ActiveCfg = Release|Any CPU
{0607D1B8-80D6-4B35-9857-1263C1B32B94}.ReleaseSigned|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

@ -1,10 +1,7 @@
#region Copyright notice and license #region Copyright notice and license
// Protocol Buffers - Google's data interchange format // Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved. // Copyright 2008 Google Inc. All rights reserved.
// http://github.com/jskeet/dotnet-protobufs/ // https://developers.google.com/protocol-buffers/
// Original C++/Java/Python code:
// http://code.google.com/p/protobuf/
// //
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are // modification, are permitted provided that the following conditions are
@ -31,12 +28,11 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion #endregion
using System; using System;
namespace Google.ProtocolBuffers namespace Google.Protobuf
{ {
/// <summary> /// <summary>
/// Provides a utility routine to copy small arrays much more quickly than Buffer.BlockCopy /// Provides a utility routine to copy small arrays much more quickly than Buffer.BlockCopy
@ -51,7 +47,7 @@ namespace Google.ProtocolBuffers
/// <summary> /// <summary>
/// Determines which copy routine to use based on the number of bytes to be copied. /// Determines which copy routine to use based on the number of bytes to be copied.
/// </summary> /// </summary>
public static void Copy(byte[] src, int srcOffset, byte[] dst, int dstOffset, int count) internal static void Copy(byte[] src, int srcOffset, byte[] dst, int dstOffset, int count)
{ {
if (count > CopyThreshold) if (count > CopyThreshold)
{ {
@ -59,31 +55,22 @@ namespace Google.ProtocolBuffers
} }
else else
{ {
ByteCopy(src, srcOffset, dst, dstOffset, count); int stop = srcOffset + count;
} for (int i = srcOffset; i < stop; i++)
} {
dst[dstOffset++] = src[i];
/// <summary> }
/// Copy the bytes provided with a for loop, faster when there are only a few bytes to copy
/// </summary>
public static void ByteCopy(byte[] src, int srcOffset, byte[] dst, int dstOffset, int count)
{
int stop = srcOffset + count;
for (int i = srcOffset; i < stop; i++)
{
dst[dstOffset++] = src[i];
} }
} }
/// <summary> /// <summary>
/// Reverses the order of bytes in the array /// Reverses the order of bytes in the array
/// </summary> /// </summary>
public static void Reverse(byte[] bytes) internal static void Reverse(byte[] bytes)
{ {
byte temp;
for (int first = 0, last = bytes.Length - 1; first < last; first++, last--) for (int first = 0, last = bytes.Length - 1; first < last; first++, last--)
{ {
temp = bytes[first]; byte temp = bytes[first];
bytes[first] = bytes[last]; bytes[first] = bytes[last];
bytes[last] = temp; bytes[last] = temp;
} }

@ -1,10 +1,7 @@
#region Copyright notice and license #region Copyright notice and license
// Protocol Buffers - Google's data interchange format // Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved. // Copyright 2008 Google Inc. All rights reserved.
// http://github.com/jskeet/dotnet-protobufs/ // https://developers.google.com/protocol-buffers/
// Original C++/Java/Python code:
// http://code.google.com/p/protobuf/
// //
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are // modification, are permitted provided that the following conditions are
@ -31,7 +28,6 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion #endregion
using System; using System;
@ -40,11 +36,10 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using System.Text; using System.Text;
namespace Google.ProtocolBuffers namespace Google.Protobuf
{ {
/// <summary> /// <summary>
/// Immutable array of bytes. /// Immutable array of bytes.
/// TODO(jonskeet): Implement the common collection interfaces?
/// </summary> /// </summary>
public sealed class ByteString : IEnumerable<byte>, IEquatable<ByteString> public sealed class ByteString : IEnumerable<byte>, IEquatable<ByteString>
{ {
@ -109,23 +104,35 @@ namespace Google.ProtocolBuffers
get { return bytes.Length; } get { return bytes.Length; }
} }
/// <summary>
/// Returns <c>true</c> if this byte string is empty, <c>false</c> otherwise.
/// </summary>
public bool IsEmpty public bool IsEmpty
{ {
get { return Length == 0; } get { return Length == 0; }
} }
/// <summary>
/// Converts this <see cref="ByteString"/> into a byte array.
/// </summary>
/// <remarks>The data is copied - changes to the returned array will not be reflected in this <c>ByteString</c>.</remarks>
/// <returns>A byte array with the same data as this <c>ByteString</c>.</returns>
public byte[] ToByteArray() public byte[] ToByteArray()
{ {
return (byte[]) bytes.Clone(); return (byte[]) bytes.Clone();
} }
/// <summary>
/// Converts this <see cref="ByteString"/> into a standard base64 representation.
/// </summary>
/// <returns>A base64 representation of this <c>ByteString</c>.</returns>
public string ToBase64() public string ToBase64()
{ {
return Convert.ToBase64String(bytes); return Convert.ToBase64String(bytes);
} }
/// <summary> /// <summary>
/// Constructs a ByteString from the Base64 Encoded String. /// Constructs a <see cref="ByteString" /> from the Base64 Encoded String.
/// </summary> /// </summary>
public static ByteString FromBase64(string bytes) public static ByteString FromBase64(string bytes)
{ {
@ -135,17 +142,19 @@ namespace Google.ProtocolBuffers
} }
/// <summary> /// <summary>
/// Constructs a ByteString from the given array. The contents /// Constructs a <see cref="ByteString" /> from the given array. The contents
/// are copied, so further modifications to the array will not /// are copied, so further modifications to the array will not
/// be reflected in the returned ByteString. /// be reflected in the returned ByteString.
/// This method can also be invoked in <c>ByteString.CopyFrom(0xaa, 0xbb, ...)</c> form
/// which is primarily useful for testing.
/// </summary> /// </summary>
public static ByteString CopyFrom(byte[] bytes) public static ByteString CopyFrom(params byte[] bytes)
{ {
return new ByteString((byte[]) bytes.Clone()); return new ByteString((byte[]) bytes.Clone());
} }
/// <summary> /// <summary>
/// Constructs a ByteString from a portion of a byte array. /// Constructs a <see cref="ByteString" /> from a portion of a byte array.
/// </summary> /// </summary>
public static ByteString CopyFrom(byte[] bytes, int offset, int count) public static ByteString CopyFrom(byte[] bytes, int offset, int count)
{ {
@ -155,7 +164,7 @@ namespace Google.ProtocolBuffers
} }
/// <summary> /// <summary>
/// Creates a new ByteString by encoding the specified text with /// Creates a new <see cref="ByteString" /> by encoding the specified text with
/// the given encoding. /// the given encoding.
/// </summary> /// </summary>
public static ByteString CopyFrom(string text, Encoding encoding) public static ByteString CopyFrom(string text, Encoding encoding)
@ -164,7 +173,7 @@ namespace Google.ProtocolBuffers
} }
/// <summary> /// <summary>
/// Creates a new ByteString by encoding the specified text in UTF-8. /// Creates a new <see cref="ByteString" /> by encoding the specified text in UTF-8.
/// </summary> /// </summary>
public static ByteString CopyFromUtf8(string text) public static ByteString CopyFromUtf8(string text)
{ {
@ -179,21 +188,46 @@ namespace Google.ProtocolBuffers
get { return bytes[index]; } get { return bytes[index]; }
} }
/// <summary>
/// Converts this <see cref="ByteString"/> into a string by applying the given encoding.
/// </summary>
/// <remarks>
/// This method should only be used to convert binary data which was the result of encoding
/// text with the given encoding.
/// </remarks>
/// <param name="encoding">The encoding to use to decode the binary data into text.</param>
/// <returns>The result of decoding the binary data with the given decoding.</returns>
public string ToString(Encoding encoding) public string ToString(Encoding encoding)
{ {
return encoding.GetString(bytes, 0, bytes.Length); return encoding.GetString(bytes, 0, bytes.Length);
} }
/// <summary>
/// Converts this <see cref="ByteString"/> into a string by applying the UTF-8 encoding.
/// </summary>
/// <remarks>
/// This method should only be used to convert binary data which was the result of encoding
/// text with UTF-8.
/// </remarks>
/// <returns>The result of decoding the binary data with the given decoding.</returns>
public string ToStringUtf8() public string ToStringUtf8()
{ {
return ToString(Encoding.UTF8); return ToString(Encoding.UTF8);
} }
/// <summary>
/// Returns an iterator over the bytes in this <see cref="ByteString"/>.
/// </summary>
/// <returns>An iterator over the bytes in this object.</returns>
public IEnumerator<byte> GetEnumerator() public IEnumerator<byte> GetEnumerator()
{ {
return ((IEnumerable<byte>) bytes).GetEnumerator(); return ((IEnumerable<byte>) bytes).GetEnumerator();
} }
/// <summary>
/// Returns an iterator over the bytes in this <see cref="ByteString"/>.
/// </summary>
/// <returns>An iterator over the bytes in this object.</returns>
IEnumerator IEnumerable.GetEnumerator() IEnumerator IEnumerable.GetEnumerator()
{ {
return GetEnumerator(); return GetEnumerator();
@ -205,40 +239,32 @@ namespace Google.ProtocolBuffers
public CodedInputStream CreateCodedInput() public CodedInputStream CreateCodedInput()
{ {
// We trust CodedInputStream not to reveal the provided byte array or modify it // We trust CodedInputStream not to reveal the provided byte array or modify it
return CodedInputStream.CreateInstance(bytes); return new CodedInputStream(bytes);
} }
// TODO(jonskeet): CopyTo if it turns out to be required /// <summary>
/// Compares two byte strings for equality.
public override bool Equals(object obj) /// </summary>
/// <param name="lhs">The first byte string to compare.</param>
/// <param name="rhs">The second byte string to compare.</param>
/// <returns><c>true</c> if the byte strings are equal; false otherwise.</returns>
public static bool operator ==(ByteString lhs, ByteString rhs)
{ {
ByteString other = obj as ByteString; if (ReferenceEquals(lhs, rhs))
if (obj == null)
{ {
return false; return true;
} }
return Equals(other); if (ReferenceEquals(lhs, null) || ReferenceEquals(rhs, null))
}
public override int GetHashCode()
{
int ret = 23;
foreach (byte b in bytes)
{ {
ret = (ret << 8) | b; return false;
} }
return ret; if (lhs.bytes.Length != rhs.bytes.Length)
}
public bool Equals(ByteString other)
{
if (other.bytes.Length != bytes.Length)
{ {
return false; return false;
} }
for (int i = 0; i < bytes.Length; i++) for (int i = 0; i < lhs.Length; i++)
{ {
if (other.bytes[i] != bytes[i]) if (rhs.bytes[i] != lhs.bytes[i])
{ {
return false; return false;
} }
@ -247,35 +273,49 @@ namespace Google.ProtocolBuffers
} }
/// <summary> /// <summary>
/// Builder for ByteStrings which allows them to be created without extra /// Compares two byte strings for inequality.
/// copying being involved. This has to be a nested type in order to have access
/// to the private ByteString constructor.
/// </summary> /// </summary>
internal sealed class CodedBuilder /// <param name="lhs">The first byte string to compare.</param>
/// <param name="rhs">The second byte string to compare.</param>
/// <returns><c>false</c> if the byte strings are equal; true otherwise.</returns>
public static bool operator !=(ByteString lhs, ByteString rhs)
{ {
private readonly CodedOutputStream output; return !(lhs == rhs);
private readonly byte[] buffer; }
internal CodedBuilder(int size) /// <summary>
{ /// Compares this byte string with another object.
buffer = new byte[size]; /// </summary>
output = CodedOutputStream.CreateInstance(buffer); /// <param name="obj">The object to compare this with.</param>
} /// <returns><c>true</c> if <paramref name="obj"/> refers to an equal <see cref="ByteString"/>; <c>false</c> otherwise.</returns>
public override bool Equals(object obj)
{
return this == (obj as ByteString);
}
internal ByteString Build() /// <summary>
/// Returns a hash code for this object. Two equal byte strings
/// will return the same hash code.
/// </summary>
/// <returns>A hash code for this object.</returns>
public override int GetHashCode()
{
int ret = 23;
foreach (byte b in bytes)
{ {
output.CheckNoSpaceLeft(); ret = (ret << 8) | b;
// We can be confident that the CodedOutputStream will not modify the
// underlying bytes anymore because it already wrote all of them. So,
// no need to make a copy.
return new ByteString(buffer);
} }
return ret;
}
internal CodedOutputStream CodedOutput /// <summary>
{ /// Compares this byte string with another.
get { return output; } /// </summary>
} /// <param name="other">The <see cref="ByteString"/> to compare this with.</param>
/// <returns><c>true</c> if <paramref name="other"/> refers to an equal byte string; <c>false</c> otherwise.</returns>
public bool Equals(ByteString other)
{
return this == other;
} }
/// <summary> /// <summary>

File diff suppressed because it is too large Load Diff

@ -0,0 +1,304 @@
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2008 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
using System;
namespace Google.Protobuf
{
// This part of CodedOutputStream provides all the static entry points that are used
// by generated code and internally to compute the size of messages prior to being
// written to an instance of CodedOutputStream.
public sealed partial class CodedOutputStream
{
private const int LittleEndian64Size = 8;
private const int LittleEndian32Size = 4;
/// <summary>
/// Computes the number of bytes that would be needed to encode a
/// double field, including the tag.
/// </summary>
public static int ComputeDoubleSize(double value)
{
return LittleEndian64Size;
}
/// <summary>
/// Computes the number of bytes that would be needed to encode a
/// float field, including the tag.
/// </summary>
public static int ComputeFloatSize(float value)
{
return LittleEndian32Size;
}
/// <summary>
/// Computes the number of bytes that would be needed to encode a
/// uint64 field, including the tag.
/// </summary>
public static int ComputeUInt64Size(ulong value)
{
return ComputeRawVarint64Size(value);
}
/// <summary>
/// Computes the number of bytes that would be needed to encode an
/// int64 field, including the tag.
/// </summary>
public static int ComputeInt64Size(long value)
{
return ComputeRawVarint64Size((ulong) value);
}
/// <summary>
/// Computes the number of bytes that would be needed to encode an
/// int32 field, including the tag.
/// </summary>
public static int ComputeInt32Size(int value)
{
if (value >= 0)
{
return ComputeRawVarint32Size((uint) value);
}
else
{
// Must sign-extend.
return 10;
}
}
/// <summary>
/// Computes the number of bytes that would be needed to encode a
/// fixed64 field, including the tag.
/// </summary>
public static int ComputeFixed64Size(ulong value)
{
return LittleEndian64Size;
}
/// <summary>
/// Computes the number of bytes that would be needed to encode a
/// fixed32 field, including the tag.
/// </summary>
public static int ComputeFixed32Size(uint value)
{
return LittleEndian32Size;
}
/// <summary>
/// Computes the number of bytes that would be needed to encode a
/// bool field, including the tag.
/// </summary>
public static int ComputeBoolSize(bool value)
{
return 1;
}
/// <summary>
/// Computes the number of bytes that would be needed to encode a
/// string field, including the tag.
/// </summary>
public static int ComputeStringSize(String value)
{
int byteArraySize = Utf8Encoding.GetByteCount(value);
return ComputeLengthSize(byteArraySize) + byteArraySize;
}
/// <summary>
/// Computes the number of bytes that would be needed to encode a
/// group field, including the tag.
/// </summary>
public static int ComputeGroupSize(IMessage value)
{
return value.CalculateSize();
}
/// <summary>
/// Computes the number of bytes that would be needed to encode an
/// embedded message field, including the tag.
/// </summary>
public static int ComputeMessageSize(IMessage value)
{
int size = value.CalculateSize();
return ComputeLengthSize(size) + size;
}
/// <summary>
/// Computes the number of bytes that would be needed to encode a
/// bytes field, including the tag.
/// </summary>
public static int ComputeBytesSize(ByteString value)
{
return ComputeLengthSize(value.Length) + value.Length;
}
/// <summary>
/// Computes the number of bytes that would be needed to encode a
/// uint32 field, including the tag.
/// </summary>
public static int ComputeUInt32Size(uint value)
{
return ComputeRawVarint32Size(value);
}
/// <summary>
/// Computes the number of bytes that would be needed to encode a
/// enum field, including the tag. The caller is responsible for
/// converting the enum value to its numeric value.
/// </summary>
public static int ComputeEnumSize(int value)
{
// Currently just a pass-through, but it's nice to separate it logically.
return ComputeInt32Size(value);
}
/// <summary>
/// Computes the number of bytes that would be needed to encode an
/// sfixed32 field, including the tag.
/// </summary>
public static int ComputeSFixed32Size(int value)
{
return LittleEndian32Size;
}
/// <summary>
/// Computes the number of bytes that would be needed to encode an
/// sfixed64 field, including the tag.
/// </summary>
public static int ComputeSFixed64Size(long value)
{
return LittleEndian64Size;
}
/// <summary>
/// Computes the number of bytes that would be needed to encode an
/// sint32 field, including the tag.
/// </summary>
public static int ComputeSInt32Size(int value)
{
return ComputeRawVarint32Size(EncodeZigZag32(value));
}
/// <summary>
/// Computes the number of bytes that would be needed to encode an
/// sint64 field, including the tag.
/// </summary>
public static int ComputeSInt64Size(long value)
{
return ComputeRawVarint64Size(EncodeZigZag64(value));
}
/// <summary>
/// Computes the number of bytes that would be needed to encode a length,
/// as written by <see cref="WriteLength"/>.
/// </summary>
public static int ComputeLengthSize(int length)
{
return ComputeRawVarint32Size((uint) length);
}
/// <summary>
/// Computes the number of bytes that would be needed to encode a varint.
/// </summary>
public static int ComputeRawVarint32Size(uint value)
{
if ((value & (0xffffffff << 7)) == 0)
{
return 1;
}
if ((value & (0xffffffff << 14)) == 0)
{
return 2;
}
if ((value & (0xffffffff << 21)) == 0)
{
return 3;
}
if ((value & (0xffffffff << 28)) == 0)
{
return 4;
}
return 5;
}
/// <summary>
/// Computes the number of bytes that would be needed to encode a varint.
/// </summary>
public static int ComputeRawVarint64Size(ulong value)
{
if ((value & (0xffffffffffffffffL << 7)) == 0)
{
return 1;
}
if ((value & (0xffffffffffffffffL << 14)) == 0)
{
return 2;
}
if ((value & (0xffffffffffffffffL << 21)) == 0)
{
return 3;
}
if ((value & (0xffffffffffffffffL << 28)) == 0)
{
return 4;
}
if ((value & (0xffffffffffffffffL << 35)) == 0)
{
return 5;
}
if ((value & (0xffffffffffffffffL << 42)) == 0)
{
return 6;
}
if ((value & (0xffffffffffffffffL << 49)) == 0)
{
return 7;
}
if ((value & (0xffffffffffffffffL << 56)) == 0)
{
return 8;
}
if ((value & (0xffffffffffffffffL << 63)) == 0)
{
return 9;
}
return 10;
}
/// <summary>
/// Computes the number of bytes that would be needed to encode a tag.
/// </summary>
public static int ComputeTagSize(int fieldNumber)
{
return ComputeRawVarint32Size(WireFormat.MakeTag(fieldNumber, 0));
}
}
}

@ -0,0 +1,708 @@
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2008 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
using Google.Protobuf.Collections;
using System;
using System.IO;
using System.Text;
namespace Google.Protobuf
{
/// <summary>
/// Encodes and writes protocol message fields.
/// </summary>
/// <remarks>
/// <para>
/// This class is generally used by generated code to write appropriate
/// primitives to the stream. It effectively encapsulates the lowest
/// levels of protocol buffer format. Unlike some other implementations,
/// this does not include combined "write tag and value" methods. Generated
/// code knows the exact byte representations of the tags they're going to write,
/// so there's no need to re-encode them each time. Manually-written code calling
/// this class should just call one of the <c>WriteTag</c> overloads before each value.
/// </para>
/// <para>
/// Repeated fields and map fields are not handled by this class; use <c>RepeatedField&lt;T&gt;</c>
/// and <c>MapField&lt;TKey, TValue&gt;</c> to serialize such fields.
/// </para>
/// </remarks>
public sealed partial class CodedOutputStream
{
// "Local" copy of Encoding.UTF8, for efficiency. (Yes, it makes a difference.)
internal static readonly Encoding Utf8Encoding = Encoding.UTF8;
/// <summary>
/// The buffer size used by CreateInstance(Stream).
/// </summary>
public static readonly int DefaultBufferSize = 4096;
private readonly byte[] buffer;
private readonly int limit;
private int position;
private readonly Stream output;
#region Construction
/// <summary>
/// Creates a new CodedOutputStream that writes directly to the given
/// byte array. If more bytes are written than fit in the array,
/// OutOfSpaceException will be thrown.
/// </summary>
public CodedOutputStream(byte[] flatArray) : this(flatArray, 0, flatArray.Length)
{
}
/// <summary>
/// Creates a new CodedOutputStream that writes directly to the given
/// byte array slice. If more bytes are written than fit in the array,
/// OutOfSpaceException will be thrown.
/// </summary>
private CodedOutputStream(byte[] buffer, int offset, int length)
{
this.output = null;
this.buffer = buffer;
this.position = offset;
this.limit = offset + length;
}
private CodedOutputStream(Stream output, byte[] buffer)
{
this.output = output;
this.buffer = buffer;
this.position = 0;
this.limit = buffer.Length;
}
/// <summary>
/// Creates a new CodedOutputStream which write to the given stream.
/// </summary>
public CodedOutputStream(Stream output) : this(output, DefaultBufferSize)
{
}
/// <summary>
/// Creates a new CodedOutputStream which write to the given stream and uses
/// the specified buffer size.
/// </summary>
public CodedOutputStream(Stream output, int bufferSize) : this(output, new byte[bufferSize])
{
}
#endregion
/// <summary>
/// Returns the current position in the stream, or the position in the output buffer
/// </summary>
public long Position
{
get
{
if (output != null)
{
return output.Position + position;
}
return position;
}
}
#region Writing of values (not including tags)
/// <summary>
/// Writes a double field value, without a tag, to the stream.
/// </summary>
/// <param name="value">The value to write</param>
public void WriteDouble(double value)
{
WriteRawLittleEndian64((ulong)BitConverter.DoubleToInt64Bits(value));
}
/// <summary>
/// Writes a float field value, without a tag, to the stream.
/// </summary>
/// <param name="value">The value to write</param>
public void WriteFloat(float value)
{
byte[] rawBytes = BitConverter.GetBytes(value);
if (!BitConverter.IsLittleEndian)
{
ByteArray.Reverse(rawBytes);
}
if (limit - position >= 4)
{
buffer[position++] = rawBytes[0];
buffer[position++] = rawBytes[1];
buffer[position++] = rawBytes[2];
buffer[position++] = rawBytes[3];
}
else
{
WriteRawBytes(rawBytes, 0, 4);
}
}
/// <summary>
/// Writes a uint64 field value, without a tag, to the stream.
/// </summary>
/// <param name="value">The value to write</param>
public void WriteUInt64(ulong value)
{
WriteRawVarint64(value);
}
/// <summary>
/// Writes an int64 field value, without a tag, to the stream.
/// </summary>
/// <param name="value">The value to write</param>
public void WriteInt64(long value)
{
WriteRawVarint64((ulong) value);
}
/// <summary>
/// Writes an int32 field value, without a tag, to the stream.
/// </summary>
/// <param name="value">The value to write</param>
public void WriteInt32(int value)
{
if (value >= 0)
{
WriteRawVarint32((uint) value);
}
else
{
// Must sign-extend.
WriteRawVarint64((ulong) value);
}
}
/// <summary>
/// Writes a fixed64 field value, without a tag, to the stream.
/// </summary>
/// <param name="value">The value to write</param>
public void WriteFixed64(ulong value)
{
WriteRawLittleEndian64(value);
}
/// <summary>
/// Writes a fixed32 field value, without a tag, to the stream.
/// </summary>
/// <param name="value">The value to write</param>
public void WriteFixed32(uint value)
{
WriteRawLittleEndian32(value);
}
/// <summary>
/// Writes a bool field value, without a tag, to the stream.
/// </summary>
/// <param name="value">The value to write</param>
public void WriteBool(bool value)
{
WriteRawByte(value ? (byte) 1 : (byte) 0);
}
/// <summary>
/// Writes a string field value, without a tag, to the stream.
/// The data is length-prefixed.
/// </summary>
/// <param name="value">The value to write</param>
public void WriteString(string value)
{
// Optimise the case where we have enough space to write
// the string directly to the buffer, which should be common.
int length = Utf8Encoding.GetByteCount(value);
WriteLength(length);
if (limit - position >= length)
{
if (length == value.Length) // Must be all ASCII...
{
for (int i = 0; i < length; i++)
{
buffer[position + i] = (byte)value[i];
}
}
else
{
Utf8Encoding.GetBytes(value, 0, value.Length, buffer, position);
}
position += length;
}
else
{
byte[] bytes = Utf8Encoding.GetBytes(value);
WriteRawBytes(bytes);
}
}
/// <summary>
/// Writes a message, without a tag, to the stream.
/// The data is length-prefixed.
/// </summary>
/// <param name="value">The value to write</param>
public void WriteMessage(IMessage value)
{
WriteLength(value.CalculateSize());
value.WriteTo(this);
}
/// <summary>
/// Write a byte string, without a tag, to the stream.
/// The data is length-prefixed.
/// </summary>
/// <param name="value">The value to write</param>
public void WriteBytes(ByteString value)
{
WriteLength(value.Length);
value.WriteRawBytesTo(this);
}
/// <summary>
/// Writes a uint32 value, without a tag, to the stream.
/// </summary>
/// <param name="value">The value to write</param>
public void WriteUInt32(uint value)
{
WriteRawVarint32(value);
}
/// <summary>
/// Writes an enum value, without a tag, to the stream.
/// </summary>
/// <param name="value">The value to write</param>
public void WriteEnum(int value)
{
WriteInt32(value);
}
/// <summary>
/// Writes an sfixed32 value, without a tag, to the stream.
/// </summary>
/// <param name="value">The value to write.</param>
public void WriteSFixed32(int value)
{
WriteRawLittleEndian32((uint) value);
}
/// <summary>
/// Writes an sfixed64 value, without a tag, to the stream.
/// </summary>
/// <param name="value">The value to write</param>
public void WriteSFixed64(long value)
{
WriteRawLittleEndian64((ulong) value);
}
/// <summary>
/// Writes an sint32 value, without a tag, to the stream.
/// </summary>
/// <param name="value">The value to write</param>
public void WriteSInt32(int value)
{
WriteRawVarint32(EncodeZigZag32(value));
}
/// <summary>
/// Writes an sint64 value, without a tag, to the stream.
/// </summary>
/// <param name="value">The value to write</param>
public void WriteSInt64(long value)
{
WriteRawVarint64(EncodeZigZag64(value));
}
/// <summary>
/// Writes a length (in bytes) for length-delimited data.
/// </summary>
/// <remarks>
/// This method simply writes a rawint, but exists for clarity in calling code.
/// </remarks>
/// <param name="length">Length value, in bytes.</param>
public void WriteLength(int length)
{
WriteRawVarint32((uint) length);
}
#endregion
#region Raw tag writing
/// <summary>
/// Encodes and writes a tag.
/// </summary>
/// <param name="fieldNumber">The number of the field to write the tag for</param>
/// <param name="type">The wire format type of the tag to write</param>
public void WriteTag(int fieldNumber, WireFormat.WireType type)
{
WriteRawVarint32(WireFormat.MakeTag(fieldNumber, type));
}
/// <summary>
/// Writes an already-encoded tag.
/// </summary>
/// <param name="tag">The encoded tag</param>
public void WriteTag(uint tag)
{
WriteRawVarint32(tag);
}
/// <summary>
/// Writes the given single-byte tag directly to the stream.
/// </summary>
/// <param name="b1">The encoded tag</param>
public void WriteRawTag(byte b1)
{
WriteRawByte(b1);
}
/// <summary>
/// Writes the given two-byte tag directly to the stream.
/// </summary>
/// <param name="b1">The first byte of the encoded tag</param>
/// <param name="b2">The second byte of the encoded tag</param>
public void WriteRawTag(byte b1, byte b2)
{
WriteRawByte(b1);
WriteRawByte(b2);
}
/// <summary>
/// Writes the given three-byte tag directly to the stream.
/// </summary>
/// <param name="b1">The first byte of the encoded tag</param>
/// <param name="b2">The second byte of the encoded tag</param>
/// <param name="b3">The third byte of the encoded tag</param>
public void WriteRawTag(byte b1, byte b2, byte b3)
{
WriteRawByte(b1);
WriteRawByte(b2);
WriteRawByte(b3);
}
/// <summary>
/// Writes the given four-byte tag directly to the stream.
/// </summary>
/// <param name="b1">The first byte of the encoded tag</param>
/// <param name="b2">The second byte of the encoded tag</param>
/// <param name="b3">The third byte of the encoded tag</param>
/// <param name="b4">The fourth byte of the encoded tag</param>
public void WriteRawTag(byte b1, byte b2, byte b3, byte b4)
{
WriteRawByte(b1);
WriteRawByte(b2);
WriteRawByte(b3);
WriteRawByte(b4);
}
/// <summary>
/// Writes the given five-byte tag directly to the stream.
/// </summary>
/// <param name="b1">The first byte of the encoded tag</param>
/// <param name="b2">The second byte of the encoded tag</param>
/// <param name="b3">The third byte of the encoded tag</param>
/// <param name="b4">The fourth byte of the encoded tag</param>
/// <param name="b5">The fifth byte of the encoded tag</param>
public void WriteRawTag(byte b1, byte b2, byte b3, byte b4, byte b5)
{
WriteRawByte(b1);
WriteRawByte(b2);
WriteRawByte(b3);
WriteRawByte(b4);
WriteRawByte(b5);
}
#endregion
#region Underlying writing primitives
/// <summary>
/// Writes a 32 bit value as a varint. The fast route is taken when
/// there's enough buffer space left to whizz through without checking
/// for each byte; otherwise, we resort to calling WriteRawByte each time.
/// </summary>
internal void WriteRawVarint32(uint value)
{
// Optimize for the common case of a single byte value
if (value < 128 && position < limit)
{
buffer[position++] = (byte)value;
return;
}
while (value > 127 && position < limit)
{
buffer[position++] = (byte) ((value & 0x7F) | 0x80);
value >>= 7;
}
while (value > 127)
{
WriteRawByte((byte) ((value & 0x7F) | 0x80));
value >>= 7;
}
if (position < limit)
{
buffer[position++] = (byte) value;
}
else
{
WriteRawByte((byte) value);
}
}
internal void WriteRawVarint64(ulong value)
{
while (value > 127 && position < limit)
{
buffer[position++] = (byte) ((value & 0x7F) | 0x80);
value >>= 7;
}
while (value > 127)
{
WriteRawByte((byte) ((value & 0x7F) | 0x80));
value >>= 7;
}
if (position < limit)
{
buffer[position++] = (byte) value;
}
else
{
WriteRawByte((byte) value);
}
}
internal void WriteRawLittleEndian32(uint value)
{
if (position + 4 > limit)
{
WriteRawByte((byte) value);
WriteRawByte((byte) (value >> 8));
WriteRawByte((byte) (value >> 16));
WriteRawByte((byte) (value >> 24));
}
else
{
buffer[position++] = ((byte) value);
buffer[position++] = ((byte) (value >> 8));
buffer[position++] = ((byte) (value >> 16));
buffer[position++] = ((byte) (value >> 24));
}
}
internal void WriteRawLittleEndian64(ulong value)
{
if (position + 8 > limit)
{
WriteRawByte((byte) value);
WriteRawByte((byte) (value >> 8));
WriteRawByte((byte) (value >> 16));
WriteRawByte((byte) (value >> 24));
WriteRawByte((byte) (value >> 32));
WriteRawByte((byte) (value >> 40));
WriteRawByte((byte) (value >> 48));
WriteRawByte((byte) (value >> 56));
}
else
{
buffer[position++] = ((byte) value);
buffer[position++] = ((byte) (value >> 8));
buffer[position++] = ((byte) (value >> 16));
buffer[position++] = ((byte) (value >> 24));
buffer[position++] = ((byte) (value >> 32));
buffer[position++] = ((byte) (value >> 40));
buffer[position++] = ((byte) (value >> 48));
buffer[position++] = ((byte) (value >> 56));
}
}
internal void WriteRawByte(byte value)
{
if (position == limit)
{
RefreshBuffer();
}
buffer[position++] = value;
}
internal void WriteRawByte(uint value)
{
WriteRawByte((byte) value);
}
/// <summary>
/// Writes out an array of bytes.
/// </summary>
internal void WriteRawBytes(byte[] value)
{
WriteRawBytes(value, 0, value.Length);
}
/// <summary>
/// Writes out part of an array of bytes.
/// </summary>
internal void WriteRawBytes(byte[] value, int offset, int length)
{
if (limit - position >= length)
{
ByteArray.Copy(value, offset, buffer, position, length);
// We have room in the current buffer.
position += length;
}
else
{
// Write extends past current buffer. Fill the rest of this buffer and
// flush.
int bytesWritten = limit - position;
ByteArray.Copy(value, offset, buffer, position, bytesWritten);
offset += bytesWritten;
length -= bytesWritten;
position = limit;
RefreshBuffer();
// Now deal with the rest.
// Since we have an output stream, this is our buffer
// and buffer offset == 0
if (length <= limit)
{
// Fits in new buffer.
ByteArray.Copy(value, offset, buffer, 0, length);
position = length;
}
else
{
// Write is very big. Let's do it all at once.
output.Write(value, offset, length);
}
}
}
#endregion
/// <summary>
/// Encode a 32-bit value with ZigZag encoding.
/// </summary>
/// <remarks>
/// ZigZag encodes signed integers into values that can be efficiently
/// encoded with varint. (Otherwise, negative values must be
/// sign-extended to 64 bits to be varint encoded, thus always taking
/// 10 bytes on the wire.)
/// </remarks>
internal static uint EncodeZigZag32(int n)
{
// Note: the right-shift must be arithmetic
return (uint) ((n << 1) ^ (n >> 31));
}
/// <summary>
/// Encode a 64-bit value with ZigZag encoding.
/// </summary>
/// <remarks>
/// ZigZag encodes signed integers into values that can be efficiently
/// encoded with varint. (Otherwise, negative values must be
/// sign-extended to 64 bits to be varint encoded, thus always taking
/// 10 bytes on the wire.)
/// </remarks>
internal static ulong EncodeZigZag64(long n)
{
return (ulong) ((n << 1) ^ (n >> 63));
}
private void RefreshBuffer()
{
if (output == null)
{
// We're writing to a single buffer.
throw new OutOfSpaceException();
}
// Since we have an output stream, this is our buffer
// and buffer offset == 0
output.Write(buffer, 0, position);
position = 0;
}
/// <summary>
/// Indicates that a CodedOutputStream wrapping a flat byte array
/// ran out of space.
/// </summary>
public sealed class OutOfSpaceException : IOException
{
internal OutOfSpaceException()
: base("CodedOutputStream was writing to a flat byte array and ran out of space.")
{
}
}
/// <summary>
/// Flushes any buffered data to the underlying stream (if there is one).
/// </summary>
public void Flush()
{
if (output != null)
{
RefreshBuffer();
}
}
/// <summary>
/// Verifies that SpaceLeft returns zero. It's common to create a byte array
/// that is exactly big enough to hold a message, then write to it with
/// a CodedOutputStream. Calling CheckNoSpaceLeft after writing verifies that
/// the message was actually as big as expected, which can help bugs.
/// </summary>
public void CheckNoSpaceLeft()
{
if (SpaceLeft != 0)
{
throw new InvalidOperationException("Did not write as much data as expected.");
}
}
/// <summary>
/// If writing to a flat array, returns the space left in the array. Otherwise,
/// throws an InvalidOperationException.
/// </summary>
public int SpaceLeft
{
get
{
if (output == null)
{
return limit - position;
}
else
{
throw new InvalidOperationException(
"SpaceLeft can only be called on CodedOutputStreams that are " +
"writing to a flat array.");
}
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save