Merge branch 'main' into remove-class-aliases

This commit is contained in:
Brent Shaffer 2022-04-19 13:25:15 -05:00 committed by GitHub
commit 37f464590c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
516 changed files with 30214 additions and 24288 deletions

View File

@ -1,4 +1,5 @@
# These are fetched as external repositories.
third_party/abseil-cpp
third_party/benchmark
third_party/googletest
_build/

View File

@ -16,7 +16,7 @@ Stack Overflow is also a useful if unofficial resource https://stackoverflow.com
-->
**What version of protobuf and what language are you using?**
Version: master/v3.6.0/v3.5.0 etc.
Version: main/v3.6.0/v3.5.0 etc.
Language: C++/Java/Python/C#/Ruby/PHP/Objective-C/Javascript
**What operating system (Linux, Windows, ...) and version?**

View File

@ -13,4 +13,4 @@ jobs:
with:
check_filenames: true
skip: ./.git,./conformance/third_party,*.snk,*.pb,*.pb.cc,*.pb.h,./src/google/protobuf/testdata,./objectivec/Tests,./python/compatibility_tests/v2.5.0/tests/google/protobuf/internal,./.github/workflows/codespell.yml
ignore_words_list: "alow,alse,ba,cleare,copyable,cloneable,dedup,dur,errorprone,files',fo,fundementals,hel,importd,inout,leapyear,nd,nin,ois,ons,parseable,process',te,testof,ue,unparseable,wasn,wee,gae,keyserver,objext,od,optin,sur"
ignore_words_list: "alow,alse,ba,cleare,copyable,cloneable,dedup,dur,errorprone,files',fo,fundementals,hel,importd,inout,leapyear,nd,nin,ois,ons,parseable,process',te,testof,ue,unparseable,wasn,wee,gae,keyserver,objext,od,optin,streem,sur"

43
.github/workflows/php-ext.yml vendored Normal file
View File

@ -0,0 +1,43 @@
name: PHP extension
on:
- push
- pull_request
jobs:
build-php:
name: Build PHP extension
runs-on: ubuntu-latest
container: ${{ matrix.php-image }}
strategy:
matrix:
php-image:
- php:7.4-cli
- php:8.1-cli
steps:
- name: Install git
run: |
apt-get update -q
apt-get install -qy --no-install-recommends git
- name: Checkout
uses: actions/checkout@v3
with:
submodules: recursive
- name: Prepare source code
run: |
rm -rf "$GITHUB_WORKSPACE/php/ext/google/protobuf/third_party"
cp -r "$GITHUB_WORKSPACE/third_party" "$GITHUB_WORKSPACE/php/ext/google/protobuf"
cp "$GITHUB_WORKSPACE/LICENSE" "$GITHUB_WORKSPACE/php/ext/google/protobuf"
- name: Create package
run: |
cd /tmp
rm -rf protobuf-*.tgz
pecl package "$GITHUB_WORKSPACE/php/ext/google/protobuf/package.xml"
- name: Compile extension
run: |
cd /tmp
MAKE="make -j$(nproc)" pecl install protobuf-*.tgz
- name: Enable extension
run: docker-php-ext-enable protobuf
- name: Inspect extension
run: php --ri protobuf

6
.gitignore vendored
View File

@ -46,7 +46,7 @@ src/.libs
any_test.pb.*
map*unittest.pb.*
unittest*.pb.*
cpp_test*.pb.*
src/google/protobuf/compiler/cpp/test*.pb.*
src/google/protobuf/util/**/*.pb.cc
src/google/protobuf/util/**/*.pb.h
@ -89,6 +89,10 @@ java/**/*.iml
# Windows native output.
cmake/build
build_msvc
# Directories suggested by cmake/README.md
/debug/
/solution/
/release/
# NuGet packages: we want the repository configuration, but not the
# packages themselves.

4
.gitmodules vendored
View File

@ -5,3 +5,7 @@
path = third_party/googletest
url = https://github.com/google/googletest.git
ignore = dirty
[submodule "third_party/abseil-cpp"]
path = third_party/abseil-cpp
url = https://github.com/abseil/abseil-cpp.git
branch = lts_2021_11_02

117
BUILD
View File

@ -159,6 +159,7 @@ cc_library(
"src/google/protobuf/any_lite.cc",
"src/google/protobuf/arena.cc",
"src/google/protobuf/arenastring.cc",
"src/google/protobuf/arenaz_sampler.cc",
"src/google/protobuf/extension_set.cc",
"src/google/protobuf/generated_enum_util.cc",
"src/google/protobuf/generated_message_tctable_lite.cc",
@ -419,21 +420,21 @@ cc_library(
# AUTOGEN(protoc_lib_srcs)
"src/google/protobuf/compiler/code_generator.cc",
"src/google/protobuf/compiler/command_line_interface.cc",
"src/google/protobuf/compiler/cpp/cpp_enum.cc",
"src/google/protobuf/compiler/cpp/cpp_enum_field.cc",
"src/google/protobuf/compiler/cpp/cpp_extension.cc",
"src/google/protobuf/compiler/cpp/cpp_field.cc",
"src/google/protobuf/compiler/cpp/cpp_file.cc",
"src/google/protobuf/compiler/cpp/cpp_generator.cc",
"src/google/protobuf/compiler/cpp/cpp_helpers.cc",
"src/google/protobuf/compiler/cpp/cpp_map_field.cc",
"src/google/protobuf/compiler/cpp/cpp_message.cc",
"src/google/protobuf/compiler/cpp/cpp_message_field.cc",
"src/google/protobuf/compiler/cpp/cpp_padding_optimizer.cc",
"src/google/protobuf/compiler/cpp/cpp_parse_function_generator.cc",
"src/google/protobuf/compiler/cpp/cpp_primitive_field.cc",
"src/google/protobuf/compiler/cpp/cpp_service.cc",
"src/google/protobuf/compiler/cpp/cpp_string_field.cc",
"src/google/protobuf/compiler/cpp/enum.cc",
"src/google/protobuf/compiler/cpp/enum_field.cc",
"src/google/protobuf/compiler/cpp/extension.cc",
"src/google/protobuf/compiler/cpp/field.cc",
"src/google/protobuf/compiler/cpp/file.cc",
"src/google/protobuf/compiler/cpp/generator.cc",
"src/google/protobuf/compiler/cpp/helpers.cc",
"src/google/protobuf/compiler/cpp/map_field.cc",
"src/google/protobuf/compiler/cpp/message.cc",
"src/google/protobuf/compiler/cpp/message_field.cc",
"src/google/protobuf/compiler/cpp/padding_optimizer.cc",
"src/google/protobuf/compiler/cpp/parse_function_generator.cc",
"src/google/protobuf/compiler/cpp/primitive_field.cc",
"src/google/protobuf/compiler/cpp/service.cc",
"src/google/protobuf/compiler/cpp/string_field.cc",
"src/google/protobuf/compiler/csharp/csharp_doc_comment.cc",
"src/google/protobuf/compiler/csharp/csharp_enum.cc",
"src/google/protobuf/compiler/csharp/csharp_enum_field.cc",
@ -450,35 +451,35 @@ cc_library(
"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_wrapper_field.cc",
"src/google/protobuf/compiler/java/java_context.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_field.cc",
"src/google/protobuf/compiler/java/java_enum_field_lite.cc",
"src/google/protobuf/compiler/java/java_enum_lite.cc",
"src/google/protobuf/compiler/java/java_extension.cc",
"src/google/protobuf/compiler/java/java_extension_lite.cc",
"src/google/protobuf/compiler/java/java_field.cc",
"src/google/protobuf/compiler/java/java_file.cc",
"src/google/protobuf/compiler/java/java_generator.cc",
"src/google/protobuf/compiler/java/java_generator_factory.cc",
"src/google/protobuf/compiler/java/java_helpers.cc",
"src/google/protobuf/compiler/java/java_kotlin_generator.cc",
"src/google/protobuf/compiler/java/java_map_field.cc",
"src/google/protobuf/compiler/java/java_map_field_lite.cc",
"src/google/protobuf/compiler/java/java_message.cc",
"src/google/protobuf/compiler/java/java_message_builder.cc",
"src/google/protobuf/compiler/java/java_message_builder_lite.cc",
"src/google/protobuf/compiler/java/java_message_field.cc",
"src/google/protobuf/compiler/java/java_message_field_lite.cc",
"src/google/protobuf/compiler/java/java_message_lite.cc",
"src/google/protobuf/compiler/java/java_name_resolver.cc",
"src/google/protobuf/compiler/java/java_primitive_field.cc",
"src/google/protobuf/compiler/java/java_primitive_field_lite.cc",
"src/google/protobuf/compiler/java/java_service.cc",
"src/google/protobuf/compiler/java/java_shared_code_generator.cc",
"src/google/protobuf/compiler/java/java_string_field.cc",
"src/google/protobuf/compiler/java/java_string_field_lite.cc",
"src/google/protobuf/compiler/java/context.cc",
"src/google/protobuf/compiler/java/doc_comment.cc",
"src/google/protobuf/compiler/java/enum.cc",
"src/google/protobuf/compiler/java/enum_field.cc",
"src/google/protobuf/compiler/java/enum_field_lite.cc",
"src/google/protobuf/compiler/java/enum_lite.cc",
"src/google/protobuf/compiler/java/extension.cc",
"src/google/protobuf/compiler/java/extension_lite.cc",
"src/google/protobuf/compiler/java/field.cc",
"src/google/protobuf/compiler/java/file.cc",
"src/google/protobuf/compiler/java/generator.cc",
"src/google/protobuf/compiler/java/generator_factory.cc",
"src/google/protobuf/compiler/java/helpers.cc",
"src/google/protobuf/compiler/java/kotlin_generator.cc",
"src/google/protobuf/compiler/java/map_field.cc",
"src/google/protobuf/compiler/java/map_field_lite.cc",
"src/google/protobuf/compiler/java/message.cc",
"src/google/protobuf/compiler/java/message_builder.cc",
"src/google/protobuf/compiler/java/message_builder_lite.cc",
"src/google/protobuf/compiler/java/message_field.cc",
"src/google/protobuf/compiler/java/message_field_lite.cc",
"src/google/protobuf/compiler/java/message_lite.cc",
"src/google/protobuf/compiler/java/name_resolver.cc",
"src/google/protobuf/compiler/java/primitive_field.cc",
"src/google/protobuf/compiler/java/primitive_field_lite.cc",
"src/google/protobuf/compiler/java/service.cc",
"src/google/protobuf/compiler/java/shared_code_generator.cc",
"src/google/protobuf/compiler/java/string_field.cc",
"src/google/protobuf/compiler/java/string_field_lite.cc",
"src/google/protobuf/compiler/js/js_generator.cc",
"src/google/protobuf/compiler/js/well_known_types_embed.cc",
"src/google/protobuf/compiler/objectivec/objectivec_enum.cc",
@ -496,9 +497,9 @@ cc_library(
"src/google/protobuf/compiler/php/php_generator.cc",
"src/google/protobuf/compiler/plugin.cc",
"src/google/protobuf/compiler/plugin.pb.cc",
"src/google/protobuf/compiler/python/python_generator.cc",
"src/google/protobuf/compiler/python/python_helpers.cc",
"src/google/protobuf/compiler/python/python_pyi_generator.cc",
"src/google/protobuf/compiler/python/generator.cc",
"src/google/protobuf/compiler/python/helpers.cc",
"src/google/protobuf/compiler/python/pyi_generator.cc",
"src/google/protobuf/compiler/ruby/ruby_generator.cc",
"src/google/protobuf/compiler/subprocess.cc",
"src/google/protobuf/compiler/zip_writer.cc",
@ -605,8 +606,8 @@ LITE_TEST_PROTOS = ["src/" + s for s in RELATIVE_LITE_TEST_PROTOS]
RELATIVE_TEST_PROTOS = [
# AUTOGEN(test_protos)
"google/protobuf/any_test.proto",
"google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto",
"google/protobuf/compiler/cpp/cpp_test_large_enum_value.proto",
"google/protobuf/compiler/cpp/test_bad_identifiers.proto",
"google/protobuf/compiler/cpp/test_large_enum_value.proto",
"google/protobuf/map_proto2_unittest.proto",
"google/protobuf/map_unittest.proto",
"google/protobuf/unittest.proto",
@ -765,23 +766,24 @@ cc_test(
"src/google/protobuf/any_test.cc",
"src/google/protobuf/arena_unittest.cc",
"src/google/protobuf/arenastring_unittest.cc",
"src/google/protobuf/arenaz_sampler_test.cc",
"src/google/protobuf/compiler/annotation_test_util.cc",
"src/google/protobuf/compiler/command_line_interface_unittest.cc",
"src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc",
"src/google/protobuf/compiler/cpp/cpp_move_unittest.cc",
"src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc",
"src/google/protobuf/compiler/cpp/cpp_unittest.cc",
"src/google/protobuf/compiler/cpp/cpp_unittest.inc",
"src/google/protobuf/compiler/cpp/bootstrap_unittest.cc",
"src/google/protobuf/compiler/cpp/metadata_test.cc",
"src/google/protobuf/compiler/cpp/move_unittest.cc",
"src/google/protobuf/compiler/cpp/plugin_unittest.cc",
"src/google/protobuf/compiler/cpp/unittest.cc",
"src/google/protobuf/compiler/cpp/unittest.inc",
"src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc",
"src/google/protobuf/compiler/csharp/csharp_generator_unittest.cc",
"src/google/protobuf/compiler/importer_unittest.cc",
"src/google/protobuf/compiler/java/java_doc_comment_unittest.cc",
"src/google/protobuf/compiler/java/java_plugin_unittest.cc",
"src/google/protobuf/compiler/java/doc_comment_unittest.cc",
"src/google/protobuf/compiler/java/plugin_unittest.cc",
"src/google/protobuf/compiler/mock_code_generator.cc",
"src/google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc",
"src/google/protobuf/compiler/parser_unittest.cc",
"src/google/protobuf/compiler/python/python_plugin_unittest.cc",
"src/google/protobuf/compiler/python/plugin_unittest.cc",
"src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc",
"src/google/protobuf/descriptor_database_unittest.cc",
"src/google/protobuf/descriptor_unittest.cc",
@ -789,6 +791,7 @@ cc_test(
"src/google/protobuf/dynamic_message_unittest.cc",
"src/google/protobuf/extension_set_unittest.cc",
"src/google/protobuf/generated_message_reflection_unittest.cc",
"src/google/protobuf/generated_message_tctable_lite_test.cc",
"src/google/protobuf/inlined_string_field_unittest.cc",
"src/google/protobuf/io/coded_stream_unittest.cc",
"src/google/protobuf/io/io_win32_unittest.cc",

View File

@ -1,9 +1,39 @@
2022-04-05 version 3.20.1 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
PHP
* Fix building packaged PHP extension (#9727)
Other
* Fix versioning issues in 3.20.0
Unreleased Changes
C++
* Refactor generated message class layout
* Optimize tokenizer ParseInteger by removing division
* Reserve exactly the right amount of capacity in ExtensionSet::MergeFrom
Compiler
* Protoc outputs the list of suggested field numbers when invalid field
numbers are specified in the .proto file.
Java
* 6x speedup in ArrayEncoder.writeUInt32NotTag
Python
* Added UnknownFieldSet(message) for pure Python. The old
message.UnknownFields() will be deprecated after UnknownFieldSet(message) is
added for cpp extension.
2022-03-04 version 3.20.0 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
Ruby
* Dropped Ruby 2.3 and 2.4 support for CI and releases. (#9311)
* Message.decode/encode: Add max_recursion_depth option (#9218)
* Rename max_recursion_depth to recursion_limit (#9486)
* Added Ruby 3.1 support for CI and releases (#9566).
* Message.decode/encode: Add recursion_limit option (#9218/#9486)
* Allocate with xrealloc()/xfree() so message allocation is visible to the
Ruby GC. In certain tests this leads to much lower memory usage due to more
frequent GC runs (#9586).
* Fix conversion of singleton classes in Ruby (#9342)
* Suppress warning for intentional circular require (#9556)
* JSON will now output shorter strings for double and float fields when possible

View File

@ -162,6 +162,15 @@ file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/cmaketest.map)
find_package(Threads REQUIRED)
# We can install dependencies from submodules if we're running
# CMake v3.13 or newer.
if(CMAKE_VERSION VERSION_LESS 3.13)
set(_protobuf_INSTALL_SUPPORTED_FROM_MODULE OFF)
else()
set(_protobuf_INSTALL_SUPPORTED_FROM_MODULE ON)
endif()
set(_protobuf_FIND_ZLIB)
if (protobuf_WITH_ZLIB)
find_package(ZLIB)
@ -301,6 +310,10 @@ if (protobuf_UNICODE)
add_definitions(-DUNICODE -D_UNICODE)
endif (protobuf_UNICODE)
set(protobuf_ABSL_PROVIDER "module" CACHE STRING "Provider of absl library")
set_property(CACHE protobuf_ABSL_PROVIDER PROPERTY STRINGS "module" "package")
include(${protobuf_SOURCE_DIR}/cmake/abseil-cpp.cmake)
include(${protobuf_SOURCE_DIR}/cmake/libprotobuf-lite.cmake)
include(${protobuf_SOURCE_DIR}/cmake/libprotobuf.cmake)
if (protobuf_BUILD_LIBPROTOC)

View File

@ -53,11 +53,11 @@ conforming.
## Contributing Process
Most pull requests should go to the master branch and the change will be
Most pull requests should go to the main branch and the change will be
included in the next major/minor version release (e.g., 3.6.0 release). If you
need to include a bug fix in a patch release (e.g., 3.5.2), make sure its
already merged to master, and then create a pull request cherry-picking the
commits from master branch to the release branch (e.g., branch 3.5.x).
already merged to main, and then create a pull request cherry-picking the
commits from main branch to the release branch (e.g., branch 3.5.x).
For each pull request, a protobuf team member will be assigned to review the
pull request. For minor cleanups, the pull request may be merged right away
@ -96,9 +96,9 @@ the final release.
of inactivity.
* Maintain clean commit history and use meaningful commit messages. PRs with
messy commit history are difficult to review and won't be merged. Use rebase
-i upstream/master to curate your commit history and/or to bring in latest
changes from master (but avoid rebasing in the middle of a code review).
* Keep your PR up to date with upstream/master (if there are merge conflicts,
-i upstream/main to curate your commit history and/or to bring in latest
changes from main (but avoid rebasing in the middle of a code review).
* Keep your PR up to date with upstream/main (if there are merge conflicts,
we can't really merge your change).
* All tests need to be passing before your change can be merged. We recommend
you run tests locally before creating your PR to catch breakages early on.

View File

@ -50,6 +50,7 @@ pkgconfig_DATA = protobuf.pc protobuf-lite.pc
csharp_EXTRA_DIST= \
global.json \
csharp/.editorconfig \
csharp/.gitignore \
csharp/CHANGES.txt \
csharp/Google.Protobuf.Tools.targets \
@ -1114,6 +1115,8 @@ python_EXTRA_DIST= \
python/google/protobuf/pyext/repeated_scalar_container.h \
python/google/protobuf/pyext/safe_numerics.h \
python/google/protobuf/pyext/scoped_pyobject_ptr.h \
python/google/protobuf/pyext/unknown_field_set.cc \
python/google/protobuf/pyext/unknown_field_set.h \
python/google/protobuf/python_protobuf.h \
python/google/protobuf/reflection.py \
python/google/protobuf/service.py \
@ -1121,6 +1124,7 @@ python_EXTRA_DIST= \
python/google/protobuf/symbol_database.py \
python/google/protobuf/text_encoding.py \
python/google/protobuf/text_format.py \
python/google/protobuf/unknown_fields.py \
python/google/protobuf/util/__init__.py \
python/release.sh \
python/mox.py \
@ -1399,6 +1403,7 @@ EXTRA_DIST = $(@DIST_LANG@_EXTRA_DIST) \
BUILD \
WORKSPACE \
CMakeLists.txt \
cmake/abseil-cpp.cmake \
cmake/CMakeLists.txt \
cmake/README.md \
cmake/conformance.cmake \

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'Protobuf-C++'
s.version = '3.20.0-rc1'
s.version = '3.20.1-rc1'
s.summary = 'Protocol Buffers v3 runtime library for C++.'
s.homepage = 'https://github.com/google/protobuf'
s.license = 'BSD-3-Clause'

View File

@ -5,7 +5,7 @@
# dependent projects use the :git notation to refer to the library.
Pod::Spec.new do |s|
s.name = 'Protobuf'
s.version = '3.20.0-rc1'
s.version = '3.20.1-rc1'
s.summary = 'Protocol Buffers v.3 runtime library for Objective-C.'
s.homepage = 'https://github.com/protocolbuffers/protobuf'
s.license = 'BSD-3-Clause'

View File

@ -38,7 +38,7 @@ page, check out the maven repo here:
[https://repo1.maven.org/maven2/com/google/protobuf/protoc/](https://repo1.maven.org/maven2/com/google/protobuf/protoc/)
These pre-built binaries are only provided for released versions. If you want
to use the github master version at HEAD, or you need to modify protobuf code,
to use the github main version at HEAD, or you need to modify protobuf code,
or you are using C++, it's recommended to build your own protoc binary from
source.

View File

@ -5,7 +5,7 @@ This directory contains benchmarking schemas and data sets that you
can use to test a variety of performance scenarios against your
protobuf language runtime. If you are looking for performance
numbers of officially supported languages, see [Protobuf Performance](
https://github.com/protocolbuffers/protobuf/blob/master/docs/performance.md).
https://github.com/protocolbuffers/protobuf/blob/main/docs/performance.md).
## Prerequisite
@ -61,7 +61,7 @@ PHP benchmark's requirement is the same as PHP protobuf's requirements. The benc
include PHP protobuf's src and build the c extension if required.
### Node.js
Node.js benchmark need [node](https://nodejs.org/en/)(higher than V6) and [npm](https://www.npmjs.com/) package manager installed. This benchmark is using the [benchmark](https://www.npmjs.com/package/benchmark) framework to test, which needn't to manually install. And another prerequisite is [protobuf js](https://github.com/protocolbuffers/protobuf/tree/master/js), which needn't to manually install either
Node.js benchmark need [node](https://nodejs.org/en/)(higher than V6) and [npm](https://www.npmjs.com/) package manager installed. This benchmark is using the [benchmark](https://www.npmjs.com/package/benchmark) framework to test, which needn't to manually install. And another prerequisite is [protobuf js](https://github.com/protocolbuffers/protobuf/tree/main/js), which needn't to manually install either
### C#
The C# benchmark code is built as part of the main Google.Protobuf
@ -69,18 +69,6 @@ solution. It requires the .NET Core SDK, and depends on
[BenchmarkDotNet](https://github.com/dotnet/BenchmarkDotNet), which
will be downloaded automatically.
### Big data
There's some optional big testing data which is not included in the directory
initially, you need to run the following command to download the testing data:
```
$ ./download_data.sh
```
After doing this the big data file will automatically generated in the
benchmark directory.
## Run instructions
To run all the benchmark dataset:

View File

@ -59,7 +59,7 @@ Or you can use git to clone from protobuf git repository.
C:\Path\to> mkdir src & cd src
C:\Path\to\src> git clone -b [release_tag] https://github.com/protocolbuffers/protobuf.git
Where *[release_tag]* is a git tag like *v3.0.0-beta-1* or a branch name like *master*
Where *[release_tag]* is a git tag like *v3.0.0-beta-1* or a branch name like *main*
if you want to get the latest code.
Go to the project folder:

28
cmake/abseil-cpp.cmake Normal file
View File

@ -0,0 +1,28 @@
if(protobuf_ABSL_PROVIDER STREQUAL "module")
if(NOT ABSL_ROOT_DIR)
set(ABSL_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/abseil-cpp)
endif()
if(EXISTS "${ABSL_ROOT_DIR}/CMakeLists.txt")
if(protobuf_INSTALL)
# When protobuf_INSTALL is enabled and Abseil will be built as a module,
# Abseil will be installed along with protobuf for convenience.
set(ABSL_ENABLE_INSTALL ON)
endif()
add_subdirectory(${ABSL_ROOT_DIR} third_party/abseil-cpp)
else()
message(WARNING "protobuf_ABSL_PROVIDER is \"module\" but ABSL_ROOT_DIR is wrong")
endif()
if(protobuf_INSTALL AND NOT _protobuf_INSTALL_SUPPORTED_FROM_MODULE)
message(WARNING "protobuf_INSTALL will be forced to FALSE because protobuf_ABSL_PROVIDER is \"module\" and CMake version (${CMAKE_VERSION}) is less than 3.13.")
set(protobuf_INSTALL FALSE)
endif()
elseif(protobuf_ABSL_PROVIDER STREQUAL "package")
# Use "CONFIG" as there is no built-in cmake module for absl.
find_package(absl REQUIRED CONFIG)
endif()
set(_protobuf_FIND_ABSL "if(NOT TARGET absl::strings)\n find_package(absl CONFIG)\nendif()")
set(protobuf_ABSL_USED_TARGETS
absl::strings
absl::strings_internal
)

View File

@ -13,131 +13,130 @@ mkdir include\google\protobuf\compiler\ruby
mkdir include\google\protobuf\io
mkdir include\google\protobuf\stubs
mkdir include\google\protobuf\util
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\any.h" include\google\protobuf\any.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\any.pb.h" include\google\protobuf\any.pb.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\api.pb.h" include\google\protobuf\api.pb.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\arena.h" include\google\protobuf\arena.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\arena_impl.h" include\google\protobuf\arena_impl.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\arenastring.h" include\google\protobuf\arenastring.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\arenaz_sampler.h" include\google\protobuf\arenaz_sampler.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\compiler\code_generator.h" include\google\protobuf\compiler\code_generator.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_file.h" include\google\protobuf\compiler\cpp\cpp_file.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_helpers.h" include\google\protobuf\compiler\cpp\cpp_helpers.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\compiler\cpp\cpp_names.h" include\google\protobuf\compiler\cpp\cpp_names.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\compiler\csharp\csharp_doc_comment.h" include\google\protobuf\compiler\csharp\csharp_doc_comment.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\csharp\csharp_options.h" include\google\protobuf\compiler\csharp\csharp_options.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_kotlin_generator.h" include\google\protobuf\compiler\java\java_kotlin_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\js\js_generator.h" include\google\protobuf\compiler\js\js_generator.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\compiler\objectivec\objectivec_generator.h" include\google\protobuf\compiler\objectivec\objectivec_generator.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\compiler\objectivec\objectivec_helpers.h" include\google\protobuf\compiler\objectivec\objectivec_helpers.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\compiler\parser.h" include\google\protobuf\compiler\parser.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\compiler\php\php_generator.h" include\google\protobuf\compiler\php\php_generator.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\compiler\plugin.h" include\google\protobuf\compiler\plugin.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\compiler\plugin.pb.h" include\google\protobuf\compiler\plugin.pb.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\compiler\python\python_generator.h" include\google\protobuf\compiler\python\python_generator.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\compiler\python\python_pyi_generator.h" include\google\protobuf\compiler\python\python_pyi_generator.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\compiler\python\python_helpers.h" include\google\protobuf\compiler\python\python_helpers.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\compiler\ruby\ruby_generator.h" include\google\protobuf\compiler\ruby\ruby_generator.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\descriptor.h" include\google\protobuf\descriptor.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\descriptor.pb.h" include\google\protobuf\descriptor.pb.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\descriptor_database.h" include\google\protobuf\descriptor_database.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\duration.pb.h" include\google\protobuf\duration.pb.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\dynamic_message.h" include\google\protobuf\dynamic_message.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\empty.pb.h" include\google\protobuf\empty.pb.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\explicitly_constructed.h" include\google\protobuf\explicitly_constructed.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\extension_set.h" include\google\protobuf\extension_set.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\extension_set_inl.h" include\google\protobuf\extension_set_inl.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\field_access_listener.h" include\google\protobuf\field_access_listener.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\field_mask.pb.h" include\google\protobuf\field_mask.pb.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\generated_enum_reflection.h" include\google\protobuf\generated_enum_reflection.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\generated_enum_util.h" include\google\protobuf\generated_enum_util.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\generated_message_bases.h" include\google\protobuf\generated_message_bases.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\generated_message_reflection.h" include\google\protobuf\generated_message_reflection.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\generated_message_tctable_decl.h" include\google\protobuf\generated_message_tctable_decl.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\generated_message_tctable_impl.h" include\google\protobuf\generated_message_tctable_impl.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\generated_message_util.h" include\google\protobuf\generated_message_util.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\has_bits.h" include\google\protobuf\has_bits.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\implicit_weak_message.h" include\google\protobuf\implicit_weak_message.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\inlined_string_field.h" include\google\protobuf\inlined_string_field.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\io\coded_stream.h" include\google\protobuf\io\coded_stream.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\io\gzip_stream.h" include\google\protobuf\io\gzip_stream.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\io\io_win32.h" include\google\protobuf\io\io_win32.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\io\printer.h" include\google\protobuf\io\printer.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\io\strtod.h" include\google\protobuf\io\strtod.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\io\tokenizer.h" include\google\protobuf\io\tokenizer.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\io\zero_copy_stream.h" include\google\protobuf\io\zero_copy_stream.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\io\zero_copy_stream_impl.h" include\google\protobuf\io\zero_copy_stream_impl.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\io\zero_copy_stream_impl_lite.h" include\google\protobuf\io\zero_copy_stream_impl_lite.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\map.h" include\google\protobuf\map.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\map_entry.h" include\google\protobuf\map_entry.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\map_entry_lite.h" include\google\protobuf\map_entry_lite.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\map_field.h" include\google\protobuf\map_field.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\map_field_inl.h" include\google\protobuf\map_field_inl.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\map_field_lite.h" include\google\protobuf\map_field_lite.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\map_type_handler.h" include\google\protobuf\map_type_handler.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\message.h" include\google\protobuf\message.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\message_lite.h" include\google\protobuf\message_lite.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\metadata.h" include\google\protobuf\metadata.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\metadata_lite.h" include\google\protobuf\metadata_lite.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\parse_context.h" include\google\protobuf\parse_context.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\port.h" include\google\protobuf\port.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\port_def.inc" include\google\protobuf\port_def.inc
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\port_undef.inc" include\google\protobuf\port_undef.inc
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\reflection.h" include\google\protobuf\reflection.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\reflection_ops.h" include\google\protobuf\reflection_ops.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\repeated_field.h" include\google\protobuf\repeated_field.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\repeated_ptr_field.h" include\google\protobuf\repeated_ptr_field.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\service.h" include\google\protobuf\service.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\source_context.pb.h" include\google\protobuf\source_context.pb.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\struct.pb.h" include\google\protobuf\struct.pb.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\stubs\bytestream.h" include\google\protobuf\stubs\bytestream.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\stubs\callback.h" include\google\protobuf\stubs\callback.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\stubs\casts.h" include\google\protobuf\stubs\casts.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\stubs\common.h" include\google\protobuf\stubs\common.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\stubs\hash.h" include\google\protobuf\stubs\hash.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\stubs\logging.h" include\google\protobuf\stubs\logging.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\stubs\macros.h" include\google\protobuf\stubs\macros.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\stubs\map_util.h" include\google\protobuf\stubs\map_util.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\stubs\mutex.h" include\google\protobuf\stubs\mutex.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\stubs\once.h" include\google\protobuf\stubs\once.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\stubs\platform_macros.h" include\google\protobuf\stubs\platform_macros.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\stubs\port.h" include\google\protobuf\stubs\port.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\stubs\status.h" include\google\protobuf\stubs\status.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\stubs\stl_util.h" include\google\protobuf\stubs\stl_util.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\stubs\stringpiece.h" include\google\protobuf\stubs\stringpiece.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\stubs\strutil.h" include\google\protobuf\stubs\strutil.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\stubs\template_util.h" include\google\protobuf\stubs\template_util.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\text_format.h" include\google\protobuf\text_format.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\timestamp.pb.h" include\google\protobuf\timestamp.pb.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\type.pb.h" include\google\protobuf\type.pb.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\unknown_field_set.h" include\google\protobuf\unknown_field_set.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\util\delimited_message_util.h" include\google\protobuf\util\delimited_message_util.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\util\field_comparator.h" include\google\protobuf\util\field_comparator.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\util\field_mask_util.h" include\google\protobuf\util\field_mask_util.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\util\json_util.h" include\google\protobuf\util\json_util.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\util\message_differencer.h" include\google\protobuf\util\message_differencer.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\util\time_util.h" include\google\protobuf\util\time_util.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\util\type_resolver.h" include\google\protobuf\util\type_resolver.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\util\type_resolver_util.h" include\google\protobuf\util\type_resolver_util.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\wire_format.h" include\google\protobuf\wire_format.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\wire_format_lite.h" include\google\protobuf\wire_format_lite.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\wrappers.pb.h" include\google\protobuf\wrappers.pb.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\any.proto" include\google\protobuf\any.proto
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\api.proto" include\google\protobuf\api.proto
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\compiler\plugin.proto" include\google\protobuf\compiler\plugin.proto
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\descriptor.proto" include\google\protobuf\descriptor.proto
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\duration.proto" include\google\protobuf\duration.proto
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\empty.proto" include\google\protobuf\empty.proto
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\field_mask.proto" include\google\protobuf\field_mask.proto
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\source_context.proto" include\google\protobuf\source_context.proto
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\struct.proto" include\google\protobuf\struct.proto
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\timestamp.proto" include\google\protobuf\timestamp.proto
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\type.proto" include\google\protobuf\type.proto
copy "${PROTOBUF_SOURCE_WIN32_PATH}\src\google\protobuf\wrappers.proto" include\google\protobuf\wrappers.proto
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\any.h" include\google\protobuf\any.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\any.pb.h" include\google\protobuf\any.pb.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\api.pb.h" include\google\protobuf\api.pb.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\arena.h" include\google\protobuf\arena.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\arena_impl.h" include\google\protobuf\arena_impl.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\arenastring.h" include\google\protobuf\arenastring.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\arenaz_sampler.h" include\google\protobuf\arenaz_sampler.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\code_generator.h" include\google\protobuf\compiler\code_generator.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\file.h" include\google\protobuf\compiler\cpp\file.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\cpp\generator.h" include\google\protobuf\compiler\cpp\generator.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\cpp\helpers.h" include\google\protobuf\compiler\cpp\helpers.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\cpp\names.h" include\google\protobuf\compiler\cpp\names.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\csharp\csharp_doc_comment.h" include\google\protobuf\compiler\csharp\csharp_doc_comment.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\csharp\csharp_options.h" include\google\protobuf\compiler\csharp\csharp_options.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\generator.h" include\google\protobuf\compiler\java\generator.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\java\kotlin_generator.h" include\google\protobuf\compiler\java\kotlin_generator.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\java\names.h" include\google\protobuf\compiler\java\names.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\js\js_generator.h" include\google\protobuf\compiler\js\js_generator.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\objectivec\objectivec_generator.h" include\google\protobuf\compiler\objectivec\objectivec_generator.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\objectivec\objectivec_helpers.h" include\google\protobuf\compiler\objectivec\objectivec_helpers.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\parser.h" include\google\protobuf\compiler\parser.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\php\php_generator.h" include\google\protobuf\compiler\php\php_generator.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\plugin.h" include\google\protobuf\compiler\plugin.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\plugin.pb.h" include\google\protobuf\compiler\plugin.pb.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\python\generator.h" include\google\protobuf\compiler\python\generator.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\python\pyi_generator.h" include\google\protobuf\compiler\python\pyi_generator.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\ruby\ruby_generator.h" include\google\protobuf\compiler\ruby\ruby_generator.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\descriptor.h" include\google\protobuf\descriptor.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\descriptor.pb.h" include\google\protobuf\descriptor.pb.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\descriptor_database.h" include\google\protobuf\descriptor_database.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\duration.pb.h" include\google\protobuf\duration.pb.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\dynamic_message.h" include\google\protobuf\dynamic_message.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\empty.pb.h" include\google\protobuf\empty.pb.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\explicitly_constructed.h" include\google\protobuf\explicitly_constructed.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\extension_set.h" include\google\protobuf\extension_set.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\extension_set_inl.h" include\google\protobuf\extension_set_inl.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\field_access_listener.h" include\google\protobuf\field_access_listener.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\field_mask.pb.h" include\google\protobuf\field_mask.pb.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_enum_reflection.h" include\google\protobuf\generated_enum_reflection.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_enum_util.h" include\google\protobuf\generated_enum_util.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_bases.h" include\google\protobuf\generated_message_bases.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_reflection.h" include\google\protobuf\generated_message_reflection.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_tctable_decl.h" include\google\protobuf\generated_message_tctable_decl.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_tctable_impl.h" include\google\protobuf\generated_message_tctable_impl.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_util.h" include\google\protobuf\generated_message_util.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\has_bits.h" include\google\protobuf\has_bits.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\implicit_weak_message.h" include\google\protobuf\implicit_weak_message.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\inlined_string_field.h" include\google\protobuf\inlined_string_field.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\coded_stream.h" include\google\protobuf\io\coded_stream.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\gzip_stream.h" include\google\protobuf\io\gzip_stream.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\io_win32.h" include\google\protobuf\io\io_win32.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\printer.h" include\google\protobuf\io\printer.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\strtod.h" include\google\protobuf\io\strtod.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\tokenizer.h" include\google\protobuf\io\tokenizer.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\zero_copy_stream.h" include\google\protobuf\io\zero_copy_stream.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\zero_copy_stream_impl.h" include\google\protobuf\io\zero_copy_stream_impl.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\zero_copy_stream_impl_lite.h" include\google\protobuf\io\zero_copy_stream_impl_lite.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\map.h" include\google\protobuf\map.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\map_entry.h" include\google\protobuf\map_entry.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\map_entry_lite.h" include\google\protobuf\map_entry_lite.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\map_field.h" include\google\protobuf\map_field.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\map_field_inl.h" include\google\protobuf\map_field_inl.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\map_field_lite.h" include\google\protobuf\map_field_lite.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\map_type_handler.h" include\google\protobuf\map_type_handler.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\message.h" include\google\protobuf\message.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\message_lite.h" include\google\protobuf\message_lite.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\metadata.h" include\google\protobuf\metadata.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\metadata_lite.h" include\google\protobuf\metadata_lite.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\parse_context.h" include\google\protobuf\parse_context.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\port.h" include\google\protobuf\port.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\port_def.inc" include\google\protobuf\port_def.inc
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\port_undef.inc" include\google\protobuf\port_undef.inc
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\reflection.h" include\google\protobuf\reflection.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\reflection_ops.h" include\google\protobuf\reflection_ops.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\repeated_field.h" include\google\protobuf\repeated_field.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\repeated_ptr_field.h" include\google\protobuf\repeated_ptr_field.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\service.h" include\google\protobuf\service.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\source_context.pb.h" include\google\protobuf\source_context.pb.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\struct.pb.h" include\google\protobuf\struct.pb.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\bytestream.h" include\google\protobuf\stubs\bytestream.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\callback.h" include\google\protobuf\stubs\callback.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\casts.h" include\google\protobuf\stubs\casts.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\common.h" include\google\protobuf\stubs\common.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\hash.h" include\google\protobuf\stubs\hash.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\logging.h" include\google\protobuf\stubs\logging.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\macros.h" include\google\protobuf\stubs\macros.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\map_util.h" include\google\protobuf\stubs\map_util.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\mutex.h" include\google\protobuf\stubs\mutex.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\once.h" include\google\protobuf\stubs\once.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\platform_macros.h" include\google\protobuf\stubs\platform_macros.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\port.h" include\google\protobuf\stubs\port.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\status.h" include\google\protobuf\stubs\status.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\stl_util.h" include\google\protobuf\stubs\stl_util.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\stringpiece.h" include\google\protobuf\stubs\stringpiece.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\strutil.h" include\google\protobuf\stubs\strutil.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\template_util.h" include\google\protobuf\stubs\template_util.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\text_format.h" include\google\protobuf\text_format.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\timestamp.pb.h" include\google\protobuf\timestamp.pb.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\type.pb.h" include\google\protobuf\type.pb.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\unknown_field_set.h" include\google\protobuf\unknown_field_set.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\delimited_message_util.h" include\google\protobuf\util\delimited_message_util.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\field_comparator.h" include\google\protobuf\util\field_comparator.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\field_mask_util.h" include\google\protobuf\util\field_mask_util.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\json_util.h" include\google\protobuf\util\json_util.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\message_differencer.h" include\google\protobuf\util\message_differencer.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\time_util.h" include\google\protobuf\util\time_util.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\type_resolver.h" include\google\protobuf\util\type_resolver.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\type_resolver_util.h" include\google\protobuf\util\type_resolver_util.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\wire_format.h" include\google\protobuf\wire_format.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\wire_format_lite.h" include\google\protobuf\wire_format_lite.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\wrappers.pb.h" include\google\protobuf\wrappers.pb.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\any.proto" include\google\protobuf\any.proto
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\api.proto" include\google\protobuf\api.proto
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\plugin.proto" include\google\protobuf\compiler\plugin.proto
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\descriptor.proto" include\google\protobuf\descriptor.proto
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\duration.proto" include\google\protobuf\duration.proto
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\empty.proto" include\google\protobuf\empty.proto
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\field_mask.proto" include\google\protobuf\field_mask.proto
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\source_context.proto" include\google\protobuf\source_context.proto
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\struct.proto" include\google\protobuf\struct.proto
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\timestamp.proto" include\google\protobuf\timestamp.proto
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\type.proto" include\google\protobuf\type.proto
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\wrappers.proto" include\google\protobuf\wrappers.proto

View File

@ -39,6 +39,7 @@ set(libprotobuf_lite_includes
${protobuf_SOURCE_DIR}/src/google/protobuf/arena_impl.h
${protobuf_SOURCE_DIR}/src/google/protobuf/arenastring.h
${protobuf_SOURCE_DIR}/src/google/protobuf/arenaz_sampler.h
${protobuf_SOURCE_DIR}/src/google/protobuf/endian.h
${protobuf_SOURCE_DIR}/src/google/protobuf/explicitly_constructed.h
${protobuf_SOURCE_DIR}/src/google/protobuf/extension_set.h
${protobuf_SOURCE_DIR}/src/google/protobuf/extension_set_inl.h
@ -103,6 +104,9 @@ if(protobuf_HAVE_LD_VERSION_SCRIPT)
LINK_DEPENDS ${protobuf_SOURCE_DIR}/src/libprotobuf-lite.map)
endif()
target_link_libraries(libprotobuf-lite PRIVATE ${CMAKE_THREAD_LIBS_INIT})
target_include_directories(libprotobuf-lite
PRIVATE ${ABSL_ROOT_DIR}
)
if(protobuf_LINK_LIBATOMIC)
target_link_libraries(libprotobuf-lite PRIVATE atomic)
endif()

View File

@ -20,7 +20,6 @@ set(libprotobuf_files
${protobuf_SOURCE_DIR}/src/google/protobuf/io/tokenizer.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/map_field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/message.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/reflection_internal.h
${protobuf_SOURCE_DIR}/src/google/protobuf/reflection_ops.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/service.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/source_context.pb.cc
@ -79,6 +78,7 @@ set(libprotobuf_includes
${protobuf_SOURCE_DIR}/src/google/protobuf/message.h
${protobuf_SOURCE_DIR}/src/google/protobuf/metadata.h
${protobuf_SOURCE_DIR}/src/google/protobuf/reflection.h
${protobuf_SOURCE_DIR}/src/google/protobuf/reflection_internal.h
${protobuf_SOURCE_DIR}/src/google/protobuf/reflection_ops.h
${protobuf_SOURCE_DIR}/src/google/protobuf/service.h
${protobuf_SOURCE_DIR}/src/google/protobuf/source_context.pb.h
@ -117,6 +117,9 @@ if(protobuf_HAVE_LD_VERSION_SCRIPT)
LINK_DEPENDS ${protobuf_SOURCE_DIR}/src/libprotobuf.map)
endif()
target_link_libraries(libprotobuf PRIVATE ${CMAKE_THREAD_LIBS_INIT})
target_include_directories(libprotobuf
PRIVATE ${ABSL_ROOT_DIR}
)
if(protobuf_WITH_ZLIB)
target_link_libraries(libprotobuf PRIVATE ${ZLIB_LIBRARIES})
endif()

View File

@ -1,21 +1,21 @@
set(libprotoc_files
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/code_generator.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/command_line_interface.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/cpp_enum.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/cpp_extension.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/cpp_field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/cpp_file.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/cpp_generator.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/cpp_helpers.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/cpp_map_field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/cpp_message.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/cpp_message_field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/cpp_service.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/cpp_string_field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/enum.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/enum_field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/extension.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/file.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/generator.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/helpers.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/map_field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/message.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/message_field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/padding_optimizer.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/parse_function_generator.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/primitive_field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/service.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/string_field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_doc_comment.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_enum.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_enum_field.cc
@ -32,94 +32,81 @@ 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_source_generator_base.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_doc_comment.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/java_enum.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/java_enum_field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/java_enum_field.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/java_enum_field_lite.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/java_enum_lite.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/java_extension.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/java_extension_lite.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/java_field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/java_file.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/java_generator.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/java_generator_factory.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/java_helpers.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/java_kotlin_generator.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/java_map_field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/java_map_field_lite.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/java_message.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/java_message_builder.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/java_message_builder_lite.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/java_message_field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/java_message_field_lite.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/java_message_lite.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/java_name_resolver.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/java_primitive_field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/java_primitive_field_lite.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/java_service.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/java_shared_code_generator.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/java_string_field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/java_string_field_lite.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/context.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/doc_comment.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/enum.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/enum_field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/enum_field_lite.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/enum_lite.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/extension.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/extension_lite.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/file.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/generator.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/generator_factory.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/helpers.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/kotlin_generator.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/map_field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/map_field_lite.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/message.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/message_builder.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/message_builder_lite.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/message_field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/message_field_lite.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/message_lite.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/name_resolver.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/primitive_field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/primitive_field_lite.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/service.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/shared_code_generator.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/string_field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/string_field_lite.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/js/js_generator.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/js/well_known_types_embed.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_enum.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_enum.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_extension.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_extension.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_field.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_file.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_file.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_generator.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_map_field.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_message.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_message.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_message_field.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_nsobject_methods.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_oneof.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_oneof.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/php/php_generator.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/plugin.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/plugin.pb.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/python/python_generator.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/python/python_helpers.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/python/python_pyi_generator.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/python/generator.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/python/helpers.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/python/pyi_generator.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/ruby/ruby_generator.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/subprocess.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/zip_writer.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/zip_writer.h
)
set(libprotoc_headers
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/code_generator.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/command_line_interface.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/cpp_file.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/cpp_generator.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/cpp_helpers.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/cpp_names.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/file.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/generator.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/helpers.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/names.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_doc_comment.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_generator.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_names.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_options.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/java_generator.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/java_kotlin_generator.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/java_names.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/generator.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/kotlin_generator.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/names.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/js/js_generator.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_generator.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_helpers.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/php/php_generator.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/plugin.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/python/python_generator.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/python/python_pyi_generator.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/python/generator.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/python/pyi_generator.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/ruby/ruby_generator.h
)
@ -141,6 +128,9 @@ if(protobuf_HAVE_LD_VERSION_SCRIPT)
LINK_DEPENDS ${protobuf_SOURCE_DIR}/src/libprotoc.map)
endif()
target_link_libraries(libprotoc PRIVATE libprotobuf)
target_include_directories(libprotoc
PRIVATE ${ABSL_ROOT_DIR}
)
if(protobuf_BUILD_SHARED_LIBS)
target_compile_definitions(libprotoc
PUBLIC PROTOBUF_USE_DLLS

View File

@ -3,6 +3,7 @@ include("${CMAKE_CURRENT_LIST_DIR}/protobuf-options.cmake")
# Depend packages
@_protobuf_FIND_ZLIB@
@_protobuf_FIND_ABSL@
# Imported targets
include("${CMAKE_CURRENT_LIST_DIR}/protobuf-targets.cmake")

View File

@ -9,7 +9,11 @@ set(protoc_rc_files
endif()
add_executable(protoc ${protoc_files} ${protoc_rc_files})
target_link_libraries(protoc libprotoc libprotobuf)
target_link_libraries(protoc
libprotoc
libprotobuf
${protobuf_ABSL_USED_TARGETS}
)
add_executable(protobuf::protoc ALIAS protoc)
set_target_properties(protoc PROPERTIES

View File

@ -1,5 +1,7 @@
option(protobuf_USE_EXTERNAL_GTEST "Use external Google Test (i.e. not the one in third_party/googletest)" OFF)
option(protobuf_TEST_XML_OUTDIR "Output directory for XML logs from tests." "")
option(protobuf_ABSOLUTE_TEST_PLUGIN_PATH
"Using absolute test_plugin path in tests" ON)
mark_as_advanced(protobuf_ABSOLUTE_TEST_PLUGIN_PATH)
@ -19,6 +21,7 @@ else()
set(googlemock_source_dir "${protobuf_SOURCE_DIR}/third_party/googletest/googlemock")
set(googletest_source_dir "${protobuf_SOURCE_DIR}/third_party/googletest/googletest")
include_directories(
${ABSL_ROOT_DIR}
${googlemock_source_dir}
${googletest_source_dir}
${googletest_source_dir}/include
@ -46,8 +49,8 @@ set(lite_test_protos
set(tests_protos
google/protobuf/any_test.proto
google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto
google/protobuf/compiler/cpp/cpp_test_large_enum_value.proto
google/protobuf/compiler/cpp/test_bad_identifiers.proto
google/protobuf/compiler/cpp/test_large_enum_value.proto
google/protobuf/map_proto2_unittest.proto
google/protobuf/map_unittest.proto
google/protobuf/unittest.proto
@ -93,7 +96,7 @@ set(tests_protos
)
macro(compile_proto_file filename)
get_filename_component(dirname ${filename} DIRECTORY)
get_filename_component(dirname ${filename} PATH)
get_filename_component(basename ${filename} NAME_WE)
add_custom_command(
OUTPUT ${protobuf_SOURCE_DIR}/src/${dirname}/${basename}.pb.cc
@ -127,6 +130,10 @@ set(common_lite_test_files
${protobuf_SOURCE_DIR}/src/google/protobuf/test_util_lite.cc
)
add_library(protobuf-lite-test-common STATIC
${common_lite_test_files} ${lite_test_proto_files})
target_link_libraries(protobuf-lite-test-common libprotobuf-lite GTest::gmock)
set(common_test_files
${common_lite_test_files}
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/mock_code_generator.cc
@ -137,6 +144,10 @@ set(common_test_files
${protobuf_SOURCE_DIR}/src/google/protobuf/testing/googletest.cc
)
add_library(protobuf-test-common STATIC
${common_test_files} ${tests_proto_files})
target_link_libraries(protobuf-test-common libprotobuf GTest::gmock)
set(tests_files
${protobuf_SOURCE_DIR}/src/google/protobuf/any_test.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/arena_unittest.cc
@ -145,20 +156,21 @@ set(tests_files
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/annotation_test_util.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/annotation_test_util.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/command_line_interface_unittest.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/cpp_move_unittest.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/cpp_unittest.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/cpp_unittest.inc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/bootstrap_unittest.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/message_size_unittest.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/metadata_test.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/move_unittest.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/plugin_unittest.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/unittest.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/unittest.inc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_generator_unittest.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/importer_unittest.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/java_doc_comment_unittest.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/java_plugin_unittest.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/doc_comment_unittest.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/plugin_unittest.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/parser_unittest.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/python/python_plugin_unittest.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/python/plugin_unittest.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/descriptor_database_unittest.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/descriptor_unittest.cc
@ -233,13 +245,27 @@ if(MINGW)
endif()
add_executable(tests ${tests_files} ${common_test_files} ${tests_proto_files} ${lite_test_proto_files})
if(protobuf_TEST_XML_OUTDIR)
if(NOT "${protobuf_TEST_XML_OUTDIR}" MATCHES "[/\\]$")
string(APPEND protobuf_TEST_XML_OUTDIR "/")
endif()
set(protobuf_GTEST_ARGS "--gtest_output=xml:${protobuf_TEST_XML_OUTDIR}")
endif()
add_executable(tests ${tests_files})
if (MSVC)
target_compile_options(tests PRIVATE
/wd4146 # unary minus operator applied to unsigned type, result still unsigned
)
endif()
target_link_libraries(tests libprotoc libprotobuf GTest::gmock_main)
target_link_libraries(tests
protobuf-lite-test-common
protobuf-test-common
libprotoc
libprotobuf
GTest::gmock_main
${protobuf_ABSL_USED_TARGETS}
)
set(test_plugin_files
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/mock_code_generator.cc
@ -249,19 +275,30 @@ set(test_plugin_files
)
add_executable(test_plugin ${test_plugin_files})
target_link_libraries(test_plugin libprotoc libprotobuf GTest::gmock)
target_link_libraries(test_plugin
libprotoc
libprotobuf
GTest::gmock
${protobuf_ABSL_USED_TARGETS}
)
set(lite_test_files
${protobuf_SOURCE_DIR}/src/google/protobuf/lite_unittest.cc
)
add_executable(lite-test ${lite_test_files} ${common_lite_test_files} ${lite_test_proto_files})
target_link_libraries(lite-test libprotobuf-lite GTest::gmock_main)
add_executable(lite-test ${lite_test_files})
target_link_libraries(lite-test protobuf-lite-test-common libprotobuf-lite GTest::gmock_main)
add_test(NAME lite-test
COMMAND lite-test ${protobuf_GTEST_ARGS})
set(lite_arena_test_files
${protobuf_SOURCE_DIR}/src/google/protobuf/lite_arena_unittest.cc
)
add_executable(lite-arena-test ${lite_arena_test_files} ${common_lite_test_files} ${lite_test_proto_files})
target_link_libraries(lite-arena-test libprotobuf-lite GTest::gmock_main)
add_executable(lite-arena-test ${lite_arena_test_files})
target_link_libraries(lite-arena-test protobuf-lite-test-common libprotobuf-lite GTest::gmock_main)
add_test(NAME lite-arena-test
COMMAND lite-arena-test ${protobuf_GTEST_ARGS})
add_custom_target(check
COMMAND tests
@ -269,5 +306,5 @@ add_custom_target(check
WORKING_DIRECTORY ${protobuf_SOURCE_DIR})
add_test(NAME check
COMMAND tests
COMMAND tests ${protobuf_GTEST_ARGS}
WORKING_DIRECTORY "${protobuf_SOURCE_DIR}")

View File

@ -17,7 +17,7 @@ AC_PREREQ(2.59)
# In the SVN trunk, the version should always be the next anticipated release
# version with the "-pre" suffix. (We used to use "-SNAPSHOT" but this pushed
# the size of one file name in the dist tarfile over the 99-char limit.)
AC_INIT([Protocol Buffers],[3.20.0-rc-1],[protobuf@googlegroups.com],[protobuf])
AC_INIT([Protocol Buffers],[3.20.1-rc-1],[protobuf@googlegroups.com],[protobuf])
AM_MAINTAINER_MODE([enable])

View File

@ -57,10 +57,10 @@ Testing other Protocol Buffer implementations
To run these tests against a new Protocol Buffers implementation, write a
program in your language that uses the protobuf implementation you want
to test. This program should implement the testing protocol defined in
[conformance.proto](https://github.com/protocolbuffers/protobuf/blob/master/conformance/conformance.proto).
[conformance.proto](https://github.com/protocolbuffers/protobuf/blob/main/conformance/conformance.proto).
This is designed to be as easy as possible: the C++ version is only
150 lines and is a good example for what this program should look like
(see [conformance_cpp.cc](https://github.com/protocolbuffers/protobuf/blob/master/conformance/conformance_cpp.cc)).
(see [conformance_cpp.cc](https://github.com/protocolbuffers/protobuf/blob/main/conformance/conformance_cpp.cc)).
The program only needs to be able to read from stdin and write to stdout.
Portability

View File

@ -2226,11 +2226,11 @@ void BinaryAndJsonConformanceSuite::RunJsonTestsForNonRepeatedTypes() {
"optional_aliased_enum: ALIAS_BAZ");
RunValidJsonTest(
"EnumFieldWithAliasUseAlias", REQUIRED,
R"({"optionalAliasedEnum": "QUX"})",
R"({"optionalAliasedEnum": "MOO"})",
"optional_aliased_enum: ALIAS_BAZ");
RunValidJsonTest(
"EnumFieldWithAliasLowerCase", REQUIRED,
R"({"optionalAliasedEnum": "qux"})",
R"({"optionalAliasedEnum": "moo"})",
"optional_aliased_enum: ALIAS_BAZ");
RunValidJsonTest(
"EnumFieldWithAliasDifferentCase", REQUIRED,

17
csharp/.editorconfig Normal file
View File

@ -0,0 +1,17 @@
# Remove the line below if you want to inherit .editorconfig settings from higher directories
root = true
# C# files
[*.cs]
#### Core EditorConfig Options ####
# Indentation and spacing
indent_size = 4
indent_style = space
tab_width = 4
# New line preferences
end_of_line = lf
insert_final_newline = false
trim_trailing_whitespace = true

View File

@ -5,10 +5,10 @@
<title>Google Protocol Buffers tools</title>
<summary>Tools for Protocol Buffers - Google's data interchange format.</summary>
<description>See project site for more info.</description>
<version>3.20.0-rc1</version>
<version>3.20.1-rc1</version>
<authors>Google Inc.</authors>
<owners>protobuf-packages</owners>
<licenseUrl>https://github.com/protocolbuffers/protobuf/blob/master/LICENSE</licenseUrl>
<licenseUrl>https://github.com/protocolbuffers/protobuf/blob/main/LICENSE</licenseUrl>
<projectUrl>https://github.com/protocolbuffers/protobuf</projectUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<releaseNotes>Tools for Protocol Buffers</releaseNotes>

View File

@ -1,171 +1,171 @@
#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.Text;
using NUnit.Framework;
namespace Google.Protobuf
{
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]
public void EmptyByteStringHasZeroSize()
{
Assert.AreEqual(0, ByteString.Empty.Length);
}
[Test]
public void CopyFromStringWithExplicitEncoding()
{
ByteString bs = ByteString.CopyFrom("AB", Encoding.Unicode);
Assert.AreEqual(4, bs.Length);
Assert.AreEqual(65, bs[0]);
Assert.AreEqual(0, bs[1]);
Assert.AreEqual(66, bs[2]);
Assert.AreEqual(0, bs[3]);
}
[Test]
public void IsEmptyWhenEmpty()
{
Assert.IsTrue(ByteString.CopyFromUtf8("").IsEmpty);
}
[Test]
public void IsEmptyWhenNotEmpty()
{
Assert.IsFalse(ByteString.CopyFromUtf8("X").IsEmpty);
}
[Test]
public void CopyFromByteArrayCopiesContents()
{
byte[] data = new byte[1];
data[0] = 10;
ByteString bs = ByteString.CopyFrom(data);
Assert.AreEqual(10, bs[0]);
data[0] = 5;
Assert.AreEqual(10, bs[0]);
}
[Test]
public void ToByteArrayCopiesContents()
{
ByteString bs = ByteString.CopyFromUtf8("Hello");
byte[] data = bs.ToByteArray();
Assert.AreEqual((byte)'H', data[0]);
Assert.AreEqual((byte)'H', bs[0]);
data[0] = 0;
Assert.AreEqual(0, data[0]);
Assert.AreEqual((byte)'H', bs[0]);
}
[Test]
public void CopyFromUtf8UsesUtf8()
{
ByteString bs = ByteString.CopyFromUtf8("\u20ac");
Assert.AreEqual(3, bs.Length);
Assert.AreEqual(0xe2, bs[0]);
Assert.AreEqual(0x82, bs[1]);
Assert.AreEqual(0xac, bs[2]);
}
[Test]
public void CopyFromPortion()
{
byte[] data = new byte[] {0, 1, 2, 3, 4, 5, 6};
ByteString bs = ByteString.CopyFrom(data, 2, 3);
Assert.AreEqual(3, bs.Length);
Assert.AreEqual(2, bs[0]);
Assert.AreEqual(3, bs[1]);
}
[Test]
public void ToStringUtf8()
{
ByteString bs = ByteString.CopyFromUtf8("\u20ac");
Assert.AreEqual("\u20ac", bs.ToStringUtf8());
}
[Test]
public void ToStringWithExplicitEncoding()
{
ByteString bs = ByteString.CopyFrom("\u20ac", Encoding.Unicode);
Assert.AreEqual("\u20ac", bs.ToString(Encoding.Unicode));
}
[Test]
public void FromBase64_WithText()
{
byte[] data = new byte[] {0, 1, 2, 3, 4, 5, 6};
string base64 = Convert.ToBase64String(data);
ByteString bs = ByteString.FromBase64(base64);
Assert.AreEqual(data, bs.ToByteArray());
}
[Test]
public void FromBase64_Empty()
{
// Optimization which also fixes issue 61.
Assert.AreSame(ByteString.Empty, ByteString.FromBase64(""));
}
}
#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.Text;
using NUnit.Framework;
namespace Google.Protobuf
{
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]
public void EmptyByteStringHasZeroSize()
{
Assert.AreEqual(0, ByteString.Empty.Length);
}
[Test]
public void CopyFromStringWithExplicitEncoding()
{
ByteString bs = ByteString.CopyFrom("AB", Encoding.Unicode);
Assert.AreEqual(4, bs.Length);
Assert.AreEqual(65, bs[0]);
Assert.AreEqual(0, bs[1]);
Assert.AreEqual(66, bs[2]);
Assert.AreEqual(0, bs[3]);
}
[Test]
public void IsEmptyWhenEmpty()
{
Assert.IsTrue(ByteString.CopyFromUtf8("").IsEmpty);
}
[Test]
public void IsEmptyWhenNotEmpty()
{
Assert.IsFalse(ByteString.CopyFromUtf8("X").IsEmpty);
}
[Test]
public void CopyFromByteArrayCopiesContents()
{
byte[] data = new byte[1];
data[0] = 10;
ByteString bs = ByteString.CopyFrom(data);
Assert.AreEqual(10, bs[0]);
data[0] = 5;
Assert.AreEqual(10, bs[0]);
}
[Test]
public void ToByteArrayCopiesContents()
{
ByteString bs = ByteString.CopyFromUtf8("Hello");
byte[] data = bs.ToByteArray();
Assert.AreEqual((byte)'H', data[0]);
Assert.AreEqual((byte)'H', bs[0]);
data[0] = 0;
Assert.AreEqual(0, data[0]);
Assert.AreEqual((byte)'H', bs[0]);
}
[Test]
public void CopyFromUtf8UsesUtf8()
{
ByteString bs = ByteString.CopyFromUtf8("\u20ac");
Assert.AreEqual(3, bs.Length);
Assert.AreEqual(0xe2, bs[0]);
Assert.AreEqual(0x82, bs[1]);
Assert.AreEqual(0xac, bs[2]);
}
[Test]
public void CopyFromPortion()
{
byte[] data = new byte[] {0, 1, 2, 3, 4, 5, 6};
ByteString bs = ByteString.CopyFrom(data, 2, 3);
Assert.AreEqual(3, bs.Length);
Assert.AreEqual(2, bs[0]);
Assert.AreEqual(3, bs[1]);
}
[Test]
public void ToStringUtf8()
{
ByteString bs = ByteString.CopyFromUtf8("\u20ac");
Assert.AreEqual("\u20ac", bs.ToStringUtf8());
}
[Test]
public void ToStringWithExplicitEncoding()
{
ByteString bs = ByteString.CopyFrom("\u20ac", Encoding.Unicode);
Assert.AreEqual("\u20ac", bs.ToString(Encoding.Unicode));
}
[Test]
public void FromBase64_WithText()
{
byte[] data = new byte[] {0, 1, 2, 3, 4, 5, 6};
string base64 = Convert.ToBase64String(data);
ByteString bs = ByteString.FromBase64(base64);
Assert.AreEqual(data, bs.ToByteArray());
}
[Test]
public void FromBase64_Empty()
{
// Optimization which also fixes issue 61.
Assert.AreSame(ByteString.Empty, ByteString.FromBase64(""));
}
}
}

View File

@ -1,419 +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 System.IO;
using Google.Protobuf.TestProtos;
using NUnit.Framework;
namespace Google.Protobuf
{
public class CodedOutputStreamTest
{
/// <summary>
/// Writes the given value using WriteRawVarint32() and WriteRawVarint64() and
/// checks that the result matches the given bytes
/// </summary>
private static void AssertWriteVarint(byte[] data, ulong value)
{
// Only do 32-bit write if the value fits in 32 bits.
if ((value >> 32) == 0)
{
MemoryStream rawOutput = new MemoryStream();
CodedOutputStream output = new CodedOutputStream(rawOutput);
output.WriteRawVarint32((uint) value);
output.Flush();
Assert.AreEqual(data, rawOutput.ToArray());
// Also try computing size.
Assert.AreEqual(data.Length, CodedOutputStream.ComputeRawVarint32Size((uint) value));
}
{
MemoryStream rawOutput = new MemoryStream();
CodedOutputStream output = new CodedOutputStream(rawOutput);
output.WriteRawVarint64(value);
output.Flush();
Assert.AreEqual(data, rawOutput.ToArray());
// Also try computing size.
Assert.AreEqual(data.Length, CodedOutputStream.ComputeRawVarint64Size(value));
}
// Try different buffer sizes.
for (int bufferSize = 1; bufferSize <= 16; bufferSize *= 2)
{
// Only do 32-bit write if the value fits in 32 bits.
if ((value >> 32) == 0)
{
MemoryStream rawOutput = new MemoryStream();
CodedOutputStream output =
new CodedOutputStream(rawOutput, bufferSize);
output.WriteRawVarint32((uint) value);
output.Flush();
Assert.AreEqual(data, rawOutput.ToArray());
}
{
MemoryStream rawOutput = new MemoryStream();
CodedOutputStream output = new CodedOutputStream(rawOutput, bufferSize);
output.WriteRawVarint64(value);
output.Flush();
Assert.AreEqual(data, rawOutput.ToArray());
}
}
}
/// <summary>
/// Tests WriteRawVarint32() and WriteRawVarint64()
/// </summary>
[Test]
public void WriteVarint()
{
AssertWriteVarint(new byte[] {0x00}, 0);
AssertWriteVarint(new byte[] {0x01}, 1);
AssertWriteVarint(new byte[] {0x7f}, 127);
// 14882
AssertWriteVarint(new byte[] {0xa2, 0x74}, (0x22 << 0) | (0x74 << 7));
// 2961488830
AssertWriteVarint(new byte[] {0xbe, 0xf7, 0x92, 0x84, 0x0b},
(0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
(0x0bL << 28));
// 64-bit
// 7256456126
AssertWriteVarint(new byte[] {0xbe, 0xf7, 0x92, 0x84, 0x1b},
(0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
(0x1bL << 28));
// 41256202580718336
AssertWriteVarint(
new byte[] {0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49},
(0x00 << 0) | (0x66 << 7) | (0x6b << 14) | (0x1c << 21) |
(0x43UL << 28) | (0x49L << 35) | (0x24UL << 42) | (0x49UL << 49));
// 11964378330978735131
AssertWriteVarint(
new byte[] {0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01},
unchecked((ulong)
((0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) |
(0x3bL << 28) | (0x56L << 35) | (0x00L << 42) |
(0x05L << 49) | (0x26L << 56) | (0x01L << 63))));
}
/// <summary>
/// Parses the given bytes using WriteRawLittleEndian32() and checks
/// that the result matches the given value.
/// </summary>
private static void AssertWriteLittleEndian32(byte[] data, uint value)
{
MemoryStream rawOutput = new MemoryStream();
CodedOutputStream output = new CodedOutputStream(rawOutput);
output.WriteRawLittleEndian32(value);
output.Flush();
Assert.AreEqual(data, rawOutput.ToArray());
// Try different buffer sizes.
for (int bufferSize = 1; bufferSize <= 16; bufferSize *= 2)
{
rawOutput = new MemoryStream();
output = new CodedOutputStream(rawOutput, bufferSize);
output.WriteRawLittleEndian32(value);
output.Flush();
Assert.AreEqual(data, rawOutput.ToArray());
}
}
/// <summary>
/// Parses the given bytes using WriteRawLittleEndian64() and checks
/// that the result matches the given value.
/// </summary>
private static void AssertWriteLittleEndian64(byte[] data, ulong value)
{
MemoryStream rawOutput = new MemoryStream();
CodedOutputStream output = new CodedOutputStream(rawOutput);
output.WriteRawLittleEndian64(value);
output.Flush();
Assert.AreEqual(data, rawOutput.ToArray());
// Try different block sizes.
for (int blockSize = 1; blockSize <= 16; blockSize *= 2)
{
rawOutput = new MemoryStream();
output = new CodedOutputStream(rawOutput, blockSize);
output.WriteRawLittleEndian64(value);
output.Flush();
Assert.AreEqual(data, rawOutput.ToArray());
}
}
/// <summary>
/// Tests writeRawLittleEndian32() and writeRawLittleEndian64().
/// </summary>
[Test]
public void WriteLittleEndian()
{
AssertWriteLittleEndian32(new byte[] {0x78, 0x56, 0x34, 0x12}, 0x12345678);
AssertWriteLittleEndian32(new byte[] {0xf0, 0xde, 0xbc, 0x9a}, 0x9abcdef0);
AssertWriteLittleEndian64(
new byte[] {0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12},
0x123456789abcdef0L);
AssertWriteLittleEndian64(
new byte[] {0x78, 0x56, 0x34, 0x12, 0xf0, 0xde, 0xbc, 0x9a},
0x9abcdef012345678UL);
}
[Test]
public void WriteWholeMessage_VaryingBlockSizes()
{
TestAllTypes message = SampleMessages.CreateFullTestAllTypes();
byte[] rawBytes = message.ToByteArray();
// Try different block sizes.
for (int blockSize = 1; blockSize < 256; blockSize *= 2)
{
MemoryStream rawOutput = new MemoryStream();
CodedOutputStream output = new CodedOutputStream(rawOutput, blockSize);
message.WriteTo(output);
output.Flush();
Assert.AreEqual(rawBytes, rawOutput.ToArray());
}
}
[Test]
public void EncodeZigZag32()
{
Assert.AreEqual(0u, WritingPrimitives.EncodeZigZag32(0));
Assert.AreEqual(1u, WritingPrimitives.EncodeZigZag32(-1));
Assert.AreEqual(2u, WritingPrimitives.EncodeZigZag32(1));
Assert.AreEqual(3u, WritingPrimitives.EncodeZigZag32(-2));
Assert.AreEqual(0x7FFFFFFEu, WritingPrimitives.EncodeZigZag32(0x3FFFFFFF));
Assert.AreEqual(0x7FFFFFFFu, WritingPrimitives.EncodeZigZag32(unchecked((int) 0xC0000000)));
Assert.AreEqual(0xFFFFFFFEu, WritingPrimitives.EncodeZigZag32(0x7FFFFFFF));
Assert.AreEqual(0xFFFFFFFFu, WritingPrimitives.EncodeZigZag32(unchecked((int) 0x80000000)));
}
[Test]
public void EncodeZigZag64()
{
Assert.AreEqual(0u, WritingPrimitives.EncodeZigZag64(0));
Assert.AreEqual(1u, WritingPrimitives.EncodeZigZag64(-1));
Assert.AreEqual(2u, WritingPrimitives.EncodeZigZag64(1));
Assert.AreEqual(3u, WritingPrimitives.EncodeZigZag64(-2));
Assert.AreEqual(0x000000007FFFFFFEuL,
WritingPrimitives.EncodeZigZag64(unchecked((long) 0x000000003FFFFFFFUL)));
Assert.AreEqual(0x000000007FFFFFFFuL,
WritingPrimitives.EncodeZigZag64(unchecked((long) 0xFFFFFFFFC0000000UL)));
Assert.AreEqual(0x00000000FFFFFFFEuL,
WritingPrimitives.EncodeZigZag64(unchecked((long) 0x000000007FFFFFFFUL)));
Assert.AreEqual(0x00000000FFFFFFFFuL,
WritingPrimitives.EncodeZigZag64(unchecked((long) 0xFFFFFFFF80000000UL)));
Assert.AreEqual(0xFFFFFFFFFFFFFFFEL,
WritingPrimitives.EncodeZigZag64(unchecked((long) 0x7FFFFFFFFFFFFFFFUL)));
Assert.AreEqual(0xFFFFFFFFFFFFFFFFL,
WritingPrimitives.EncodeZigZag64(unchecked((long) 0x8000000000000000UL)));
}
[Test]
public void RoundTripZigZag32()
{
// Some easier-to-verify round-trip tests. The inputs (other than 0, 1, -1)
// were chosen semi-randomly via keyboard bashing.
Assert.AreEqual(0, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(0)));
Assert.AreEqual(1, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(1)));
Assert.AreEqual(-1, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(-1)));
Assert.AreEqual(14927, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(14927)));
Assert.AreEqual(-3612, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(-3612)));
}
[Test]
public void RoundTripZigZag64()
{
Assert.AreEqual(0, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(0)));
Assert.AreEqual(1, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(1)));
Assert.AreEqual(-1, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(-1)));
Assert.AreEqual(14927, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(14927)));
Assert.AreEqual(-3612, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(-3612)));
Assert.AreEqual(856912304801416L,
ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(856912304801416L)));
Assert.AreEqual(-75123905439571256L,
ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(-75123905439571256L)));
}
[Test]
public void TestNegativeEnumNoTag()
{
Assert.AreEqual(10, CodedOutputStream.ComputeInt32Size(-2));
Assert.AreEqual(10, CodedOutputStream.ComputeEnumSize((int) SampleEnum.NegativeValue));
byte[] bytes = new byte[10];
CodedOutputStream output = new CodedOutputStream(bytes);
output.WriteEnum((int) SampleEnum.NegativeValue);
Assert.AreEqual(0, output.SpaceLeft);
Assert.AreEqual("FE-FF-FF-FF-FF-FF-FF-FF-FF-01", BitConverter.ToString(bytes));
}
[Test]
public void TestCodedInputOutputPosition()
{
byte[] content = new byte[110];
for (int i = 0; i < content.Length; i++)
content[i] = (byte)i;
byte[] child = new byte[120];
{
MemoryStream ms = new MemoryStream(child);
CodedOutputStream cout = new CodedOutputStream(ms, 20);
// Field 11: numeric value: 500
cout.WriteTag(11, WireFormat.WireType.Varint);
Assert.AreEqual(1, cout.Position);
cout.WriteInt32(500);
Assert.AreEqual(3, cout.Position);
//Field 12: length delimited 120 bytes
cout.WriteTag(12, WireFormat.WireType.LengthDelimited);
Assert.AreEqual(4, cout.Position);
cout.WriteBytes(ByteString.CopyFrom(content));
Assert.AreEqual(115, cout.Position);
// Field 13: fixed numeric value: 501
cout.WriteTag(13, WireFormat.WireType.Fixed32);
Assert.AreEqual(116, cout.Position);
cout.WriteSFixed32(501);
Assert.AreEqual(120, cout.Position);
cout.Flush();
}
byte[] bytes = new byte[130];
{
CodedOutputStream cout = new CodedOutputStream(bytes);
// Field 1: numeric value: 500
cout.WriteTag(1, WireFormat.WireType.Varint);
Assert.AreEqual(1, cout.Position);
cout.WriteInt32(500);
Assert.AreEqual(3, cout.Position);
//Field 2: length delimited 120 bytes
cout.WriteTag(2, WireFormat.WireType.LengthDelimited);
Assert.AreEqual(4, cout.Position);
cout.WriteBytes(ByteString.CopyFrom(child));
Assert.AreEqual(125, cout.Position);
// Field 3: fixed numeric value: 500
cout.WriteTag(3, WireFormat.WireType.Fixed32);
Assert.AreEqual(126, cout.Position);
cout.WriteSFixed32(501);
Assert.AreEqual(130, cout.Position);
cout.Flush();
}
// Now test Input stream:
{
CodedInputStream cin = new CodedInputStream(new MemoryStream(bytes), new byte[50], 0, 0, false);
Assert.AreEqual(0, cin.Position);
// Field 1:
uint tag = cin.ReadTag();
Assert.AreEqual(1, tag >> 3);
Assert.AreEqual(1, cin.Position);
Assert.AreEqual(500, cin.ReadInt32());
Assert.AreEqual(3, cin.Position);
//Field 2:
tag = cin.ReadTag();
Assert.AreEqual(2, tag >> 3);
Assert.AreEqual(4, cin.Position);
int childlen = cin.ReadLength();
Assert.AreEqual(120, childlen);
Assert.AreEqual(5, cin.Position);
int oldlimit = cin.PushLimit((int)childlen);
Assert.AreEqual(5, cin.Position);
// Now we are reading child message
{
// Field 11: numeric value: 500
tag = cin.ReadTag();
Assert.AreEqual(11, tag >> 3);
Assert.AreEqual(6, cin.Position);
Assert.AreEqual(500, cin.ReadInt32());
Assert.AreEqual(8, cin.Position);
//Field 12: length delimited 120 bytes
tag = cin.ReadTag();
Assert.AreEqual(12, tag >> 3);
Assert.AreEqual(9, cin.Position);
ByteString bstr = cin.ReadBytes();
Assert.AreEqual(110, bstr.Length);
Assert.AreEqual((byte) 109, bstr[109]);
Assert.AreEqual(120, cin.Position);
// Field 13: fixed numeric value: 501
tag = cin.ReadTag();
Assert.AreEqual(13, tag >> 3);
// ROK - Previously broken here, this returned 126 failing to account for bufferSizeAfterLimit
Assert.AreEqual(121, cin.Position);
Assert.AreEqual(501, cin.ReadSFixed32());
Assert.AreEqual(125, cin.Position);
Assert.IsTrue(cin.IsAtEnd);
}
cin.PopLimit(oldlimit);
Assert.AreEqual(125, cin.Position);
// Field 3: fixed numeric value: 501
tag = cin.ReadTag();
Assert.AreEqual(3, tag >> 3);
Assert.AreEqual(126, cin.Position);
Assert.AreEqual(501, cin.ReadSFixed32());
Assert.AreEqual(130, cin.Position);
Assert.IsTrue(cin.IsAtEnd);
}
}
[Test]
public void Dispose_DisposesUnderlyingStream()
{
var memoryStream = new MemoryStream();
Assert.IsTrue(memoryStream.CanWrite);
using (var cos = new CodedOutputStream(memoryStream))
{
cos.WriteRawBytes(new byte[] {0});
Assert.AreEqual(0, memoryStream.Position); // Not flushed yet
}
Assert.AreEqual(1, memoryStream.ToArray().Length); // Flushed data from CodedOutputStream to MemoryStream
Assert.IsFalse(memoryStream.CanWrite); // Disposed
}
[Test]
public void Dispose_WithLeaveOpen()
{
var memoryStream = new MemoryStream();
Assert.IsTrue(memoryStream.CanWrite);
using (var cos = new CodedOutputStream(memoryStream, true))
{
cos.WriteRawBytes(new byte[] {0});
Assert.AreEqual(0, memoryStream.Position); // Not flushed yet
}
Assert.AreEqual(1, memoryStream.Position); // Flushed data from CodedOutputStream to MemoryStream
Assert.IsTrue(memoryStream.CanWrite); // We left the stream open
}
}
#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 Google.Protobuf.TestProtos;
using NUnit.Framework;
namespace Google.Protobuf
{
public class CodedOutputStreamTest
{
/// <summary>
/// Writes the given value using WriteRawVarint32() and WriteRawVarint64() and
/// checks that the result matches the given bytes
/// </summary>
private static void AssertWriteVarint(byte[] data, ulong value)
{
// Only do 32-bit write if the value fits in 32 bits.
if ((value >> 32) == 0)
{
MemoryStream rawOutput = new MemoryStream();
CodedOutputStream output = new CodedOutputStream(rawOutput);
output.WriteRawVarint32((uint) value);
output.Flush();
Assert.AreEqual(data, rawOutput.ToArray());
// Also try computing size.
Assert.AreEqual(data.Length, CodedOutputStream.ComputeRawVarint32Size((uint) value));
}
{
MemoryStream rawOutput = new MemoryStream();
CodedOutputStream output = new CodedOutputStream(rawOutput);
output.WriteRawVarint64(value);
output.Flush();
Assert.AreEqual(data, rawOutput.ToArray());
// Also try computing size.
Assert.AreEqual(data.Length, CodedOutputStream.ComputeRawVarint64Size(value));
}
// Try different buffer sizes.
for (int bufferSize = 1; bufferSize <= 16; bufferSize *= 2)
{
// Only do 32-bit write if the value fits in 32 bits.
if ((value >> 32) == 0)
{
MemoryStream rawOutput = new MemoryStream();
CodedOutputStream output =
new CodedOutputStream(rawOutput, bufferSize);
output.WriteRawVarint32((uint) value);
output.Flush();
Assert.AreEqual(data, rawOutput.ToArray());
}
{
MemoryStream rawOutput = new MemoryStream();
CodedOutputStream output = new CodedOutputStream(rawOutput, bufferSize);
output.WriteRawVarint64(value);
output.Flush();
Assert.AreEqual(data, rawOutput.ToArray());
}
}
}
/// <summary>
/// Tests WriteRawVarint32() and WriteRawVarint64()
/// </summary>
[Test]
public void WriteVarint()
{
AssertWriteVarint(new byte[] {0x00}, 0);
AssertWriteVarint(new byte[] {0x01}, 1);
AssertWriteVarint(new byte[] {0x7f}, 127);
// 14882
AssertWriteVarint(new byte[] {0xa2, 0x74}, (0x22 << 0) | (0x74 << 7));
// 2961488830
AssertWriteVarint(new byte[] {0xbe, 0xf7, 0x92, 0x84, 0x0b},
(0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
(0x0bL << 28));
// 64-bit
// 7256456126
AssertWriteVarint(new byte[] {0xbe, 0xf7, 0x92, 0x84, 0x1b},
(0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
(0x1bL << 28));
// 41256202580718336
AssertWriteVarint(
new byte[] {0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49},
(0x00 << 0) | (0x66 << 7) | (0x6b << 14) | (0x1c << 21) |
(0x43UL << 28) | (0x49L << 35) | (0x24UL << 42) | (0x49UL << 49));
// 11964378330978735131
AssertWriteVarint(
new byte[] {0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01},
unchecked((ulong)
((0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) |
(0x3bL << 28) | (0x56L << 35) | (0x00L << 42) |
(0x05L << 49) | (0x26L << 56) | (0x01L << 63))));
}
/// <summary>
/// Parses the given bytes using WriteRawLittleEndian32() and checks
/// that the result matches the given value.
/// </summary>
private static void AssertWriteLittleEndian32(byte[] data, uint value)
{
MemoryStream rawOutput = new MemoryStream();
CodedOutputStream output = new CodedOutputStream(rawOutput);
output.WriteRawLittleEndian32(value);
output.Flush();
Assert.AreEqual(data, rawOutput.ToArray());
// Try different buffer sizes.
for (int bufferSize = 1; bufferSize <= 16; bufferSize *= 2)
{
rawOutput = new MemoryStream();
output = new CodedOutputStream(rawOutput, bufferSize);
output.WriteRawLittleEndian32(value);
output.Flush();
Assert.AreEqual(data, rawOutput.ToArray());
}
}
/// <summary>
/// Parses the given bytes using WriteRawLittleEndian64() and checks
/// that the result matches the given value.
/// </summary>
private static void AssertWriteLittleEndian64(byte[] data, ulong value)
{
MemoryStream rawOutput = new MemoryStream();
CodedOutputStream output = new CodedOutputStream(rawOutput);
output.WriteRawLittleEndian64(value);
output.Flush();
Assert.AreEqual(data, rawOutput.ToArray());
// Try different block sizes.
for (int blockSize = 1; blockSize <= 16; blockSize *= 2)
{
rawOutput = new MemoryStream();
output = new CodedOutputStream(rawOutput, blockSize);
output.WriteRawLittleEndian64(value);
output.Flush();
Assert.AreEqual(data, rawOutput.ToArray());
}
}
/// <summary>
/// Tests writeRawLittleEndian32() and writeRawLittleEndian64().
/// </summary>
[Test]
public void WriteLittleEndian()
{
AssertWriteLittleEndian32(new byte[] {0x78, 0x56, 0x34, 0x12}, 0x12345678);
AssertWriteLittleEndian32(new byte[] {0xf0, 0xde, 0xbc, 0x9a}, 0x9abcdef0);
AssertWriteLittleEndian64(
new byte[] {0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12},
0x123456789abcdef0L);
AssertWriteLittleEndian64(
new byte[] {0x78, 0x56, 0x34, 0x12, 0xf0, 0xde, 0xbc, 0x9a},
0x9abcdef012345678UL);
}
[Test]
public void WriteWholeMessage_VaryingBlockSizes()
{
TestAllTypes message = SampleMessages.CreateFullTestAllTypes();
byte[] rawBytes = message.ToByteArray();
// Try different block sizes.
for (int blockSize = 1; blockSize < 256; blockSize *= 2)
{
MemoryStream rawOutput = new MemoryStream();
CodedOutputStream output = new CodedOutputStream(rawOutput, blockSize);
message.WriteTo(output);
output.Flush();
Assert.AreEqual(rawBytes, rawOutput.ToArray());
}
}
[Test]
public void EncodeZigZag32()
{
Assert.AreEqual(0u, WritingPrimitives.EncodeZigZag32(0));
Assert.AreEqual(1u, WritingPrimitives.EncodeZigZag32(-1));
Assert.AreEqual(2u, WritingPrimitives.EncodeZigZag32(1));
Assert.AreEqual(3u, WritingPrimitives.EncodeZigZag32(-2));
Assert.AreEqual(0x7FFFFFFEu, WritingPrimitives.EncodeZigZag32(0x3FFFFFFF));
Assert.AreEqual(0x7FFFFFFFu, WritingPrimitives.EncodeZigZag32(unchecked((int) 0xC0000000)));
Assert.AreEqual(0xFFFFFFFEu, WritingPrimitives.EncodeZigZag32(0x7FFFFFFF));
Assert.AreEqual(0xFFFFFFFFu, WritingPrimitives.EncodeZigZag32(unchecked((int) 0x80000000)));
}
[Test]
public void EncodeZigZag64()
{
Assert.AreEqual(0u, WritingPrimitives.EncodeZigZag64(0));
Assert.AreEqual(1u, WritingPrimitives.EncodeZigZag64(-1));
Assert.AreEqual(2u, WritingPrimitives.EncodeZigZag64(1));
Assert.AreEqual(3u, WritingPrimitives.EncodeZigZag64(-2));
Assert.AreEqual(0x000000007FFFFFFEuL,
WritingPrimitives.EncodeZigZag64(unchecked((long) 0x000000003FFFFFFFUL)));
Assert.AreEqual(0x000000007FFFFFFFuL,
WritingPrimitives.EncodeZigZag64(unchecked((long) 0xFFFFFFFFC0000000UL)));
Assert.AreEqual(0x00000000FFFFFFFEuL,
WritingPrimitives.EncodeZigZag64(unchecked((long) 0x000000007FFFFFFFUL)));
Assert.AreEqual(0x00000000FFFFFFFFuL,
WritingPrimitives.EncodeZigZag64(unchecked((long) 0xFFFFFFFF80000000UL)));
Assert.AreEqual(0xFFFFFFFFFFFFFFFEL,
WritingPrimitives.EncodeZigZag64(unchecked((long) 0x7FFFFFFFFFFFFFFFUL)));
Assert.AreEqual(0xFFFFFFFFFFFFFFFFL,
WritingPrimitives.EncodeZigZag64(unchecked((long) 0x8000000000000000UL)));
}
[Test]
public void RoundTripZigZag32()
{
// Some easier-to-verify round-trip tests. The inputs (other than 0, 1, -1)
// were chosen semi-randomly via keyboard bashing.
Assert.AreEqual(0, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(0)));
Assert.AreEqual(1, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(1)));
Assert.AreEqual(-1, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(-1)));
Assert.AreEqual(14927, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(14927)));
Assert.AreEqual(-3612, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(-3612)));
}
[Test]
public void RoundTripZigZag64()
{
Assert.AreEqual(0, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(0)));
Assert.AreEqual(1, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(1)));
Assert.AreEqual(-1, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(-1)));
Assert.AreEqual(14927, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(14927)));
Assert.AreEqual(-3612, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(-3612)));
Assert.AreEqual(856912304801416L,
ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(856912304801416L)));
Assert.AreEqual(-75123905439571256L,
ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(-75123905439571256L)));
}
[Test]
public void TestNegativeEnumNoTag()
{
Assert.AreEqual(10, CodedOutputStream.ComputeInt32Size(-2));
Assert.AreEqual(10, CodedOutputStream.ComputeEnumSize((int) SampleEnum.NegativeValue));
byte[] bytes = new byte[10];
CodedOutputStream output = new CodedOutputStream(bytes);
output.WriteEnum((int) SampleEnum.NegativeValue);
Assert.AreEqual(0, output.SpaceLeft);
Assert.AreEqual("FE-FF-FF-FF-FF-FF-FF-FF-FF-01", BitConverter.ToString(bytes));
}
[Test]
public void TestCodedInputOutputPosition()
{
byte[] content = new byte[110];
for (int i = 0; i < content.Length; i++)
content[i] = (byte)i;
byte[] child = new byte[120];
{
MemoryStream ms = new MemoryStream(child);
CodedOutputStream cout = new CodedOutputStream(ms, 20);
// Field 11: numeric value: 500
cout.WriteTag(11, WireFormat.WireType.Varint);
Assert.AreEqual(1, cout.Position);
cout.WriteInt32(500);
Assert.AreEqual(3, cout.Position);
//Field 12: length delimited 120 bytes
cout.WriteTag(12, WireFormat.WireType.LengthDelimited);
Assert.AreEqual(4, cout.Position);
cout.WriteBytes(ByteString.CopyFrom(content));
Assert.AreEqual(115, cout.Position);
// Field 13: fixed numeric value: 501
cout.WriteTag(13, WireFormat.WireType.Fixed32);
Assert.AreEqual(116, cout.Position);
cout.WriteSFixed32(501);
Assert.AreEqual(120, cout.Position);
cout.Flush();
}
byte[] bytes = new byte[130];
{
CodedOutputStream cout = new CodedOutputStream(bytes);
// Field 1: numeric value: 500
cout.WriteTag(1, WireFormat.WireType.Varint);
Assert.AreEqual(1, cout.Position);
cout.WriteInt32(500);
Assert.AreEqual(3, cout.Position);
//Field 2: length delimited 120 bytes
cout.WriteTag(2, WireFormat.WireType.LengthDelimited);
Assert.AreEqual(4, cout.Position);
cout.WriteBytes(ByteString.CopyFrom(child));
Assert.AreEqual(125, cout.Position);
// Field 3: fixed numeric value: 500
cout.WriteTag(3, WireFormat.WireType.Fixed32);
Assert.AreEqual(126, cout.Position);
cout.WriteSFixed32(501);
Assert.AreEqual(130, cout.Position);
cout.Flush();
}
// Now test Input stream:
{
CodedInputStream cin = new CodedInputStream(new MemoryStream(bytes), new byte[50], 0, 0, false);
Assert.AreEqual(0, cin.Position);
// Field 1:
uint tag = cin.ReadTag();
Assert.AreEqual(1, tag >> 3);
Assert.AreEqual(1, cin.Position);
Assert.AreEqual(500, cin.ReadInt32());
Assert.AreEqual(3, cin.Position);
//Field 2:
tag = cin.ReadTag();
Assert.AreEqual(2, tag >> 3);
Assert.AreEqual(4, cin.Position);
int childlen = cin.ReadLength();
Assert.AreEqual(120, childlen);
Assert.AreEqual(5, cin.Position);
int oldlimit = cin.PushLimit((int)childlen);
Assert.AreEqual(5, cin.Position);
// Now we are reading child message
{
// Field 11: numeric value: 500
tag = cin.ReadTag();
Assert.AreEqual(11, tag >> 3);
Assert.AreEqual(6, cin.Position);
Assert.AreEqual(500, cin.ReadInt32());
Assert.AreEqual(8, cin.Position);
//Field 12: length delimited 120 bytes
tag = cin.ReadTag();
Assert.AreEqual(12, tag >> 3);
Assert.AreEqual(9, cin.Position);
ByteString bstr = cin.ReadBytes();
Assert.AreEqual(110, bstr.Length);
Assert.AreEqual((byte) 109, bstr[109]);
Assert.AreEqual(120, cin.Position);
// Field 13: fixed numeric value: 501
tag = cin.ReadTag();
Assert.AreEqual(13, tag >> 3);
// ROK - Previously broken here, this returned 126 failing to account for bufferSizeAfterLimit
Assert.AreEqual(121, cin.Position);
Assert.AreEqual(501, cin.ReadSFixed32());
Assert.AreEqual(125, cin.Position);
Assert.IsTrue(cin.IsAtEnd);
}
cin.PopLimit(oldlimit);
Assert.AreEqual(125, cin.Position);
// Field 3: fixed numeric value: 501
tag = cin.ReadTag();
Assert.AreEqual(3, tag >> 3);
Assert.AreEqual(126, cin.Position);
Assert.AreEqual(501, cin.ReadSFixed32());
Assert.AreEqual(130, cin.Position);
Assert.IsTrue(cin.IsAtEnd);
}
}
[Test]
public void Dispose_DisposesUnderlyingStream()
{
var memoryStream = new MemoryStream();
Assert.IsTrue(memoryStream.CanWrite);
using (var cos = new CodedOutputStream(memoryStream))
{
cos.WriteRawBytes(new byte[] {0});
Assert.AreEqual(0, memoryStream.Position); // Not flushed yet
}
Assert.AreEqual(1, memoryStream.ToArray().Length); // Flushed data from CodedOutputStream to MemoryStream
Assert.IsFalse(memoryStream.CanWrite); // Disposed
}
[Test]
public void Dispose_WithLeaveOpen()
{
var memoryStream = new MemoryStream();
Assert.IsTrue(memoryStream.CanWrite);
using (var cos = new CodedOutputStream(memoryStream, true))
{
cos.WriteRawBytes(new byte[] {0});
Assert.AreEqual(0, memoryStream.Position); // Not flushed yet
}
Assert.AreEqual(1, memoryStream.Position); // Flushed data from CodedOutputStream to MemoryStream
Assert.IsTrue(memoryStream.CanWrite); // We left the stream open
}
}
}

View File

@ -1,55 +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"));
}
}
}
#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"));
}
}
}

View File

@ -1,82 +1,82 @@
#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.Reflection;
using UnitTest.Issues.TestProtos;
using NUnit.Framework;
namespace Google.Protobuf
{
/// <summary>
/// Tests for issues which aren't easily compartmentalized into other unit tests.
/// </summary>
public class IssuesTest
{
// Issue 45
[Test]
public void FieldCalledItem()
{
ItemField message = new ItemField { Item = 3 };
FieldDescriptor field = ItemField.Descriptor.FindFieldByName("item");
Assert.NotNull(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());
}
[Test]
public void JsonNameParseTest()
{
var settings = new JsonParser.Settings(10, TypeRegistry.FromFiles(UnittestIssuesReflection.Descriptor));
var parser = new JsonParser(settings);
// It is safe to use either original field name or explicitly specified json_name
Assert.AreEqual(new TestJsonName { Name = "test", Description = "test2", Guid = "test3" },
parser.Parse<TestJsonName>("{ \"name\": \"test\", \"desc\": \"test2\", \"guid\": \"test3\" }"));
}
[Test]
public void JsonNameFormatTest()
{
var message = new TestJsonName { Name = "test", Description = "test2", Guid = "test3" };
Assert.AreEqual("{ \"name\": \"test\", \"desc\": \"test2\", \"exid\": \"test3\" }",
JsonFormatter.Default.Format(message));
}
}
}
#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.Reflection;
using UnitTest.Issues.TestProtos;
using NUnit.Framework;
namespace Google.Protobuf
{
/// <summary>
/// Tests for issues which aren't easily compartmentalized into other unit tests.
/// </summary>
public class IssuesTest
{
// Issue 45
[Test]
public void FieldCalledItem()
{
ItemField message = new ItemField { Item = 3 };
FieldDescriptor field = ItemField.Descriptor.FindFieldByName("item");
Assert.NotNull(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());
}
[Test]
public void JsonNameParseTest()
{
var settings = new JsonParser.Settings(10, TypeRegistry.FromFiles(UnittestIssuesReflection.Descriptor));
var parser = new JsonParser(settings);
// It is safe to use either original field name or explicitly specified json_name
Assert.AreEqual(new TestJsonName { Name = "test", Description = "test2", Guid = "test3" },
parser.Parse<TestJsonName>("{ \"name\": \"test\", \"desc\": \"test2\", \"guid\": \"test3\" }"));
}
[Test]
public void JsonNameFormatTest()
{
var message = new TestJsonName { Name = "test", Description = "test2", Guid = "test3" };
Assert.AreEqual("{ \"name\": \"test\", \"desc\": \"test2\", \"exid\": \"test3\" }",
JsonFormatter.Default.Format(message));
}
}
}

View File

@ -1,62 +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.Zero, NegativeEnum.MinusOne, NegativeEnum.FiveBelow },
PackedValues = { NegativeEnum.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);
}
}
}
#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.Zero, NegativeEnum.MinusOne, NegativeEnum.FiveBelow },
PackedValues = { NegativeEnum.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);
}
}
}

View File

@ -13,7 +13,9 @@ pushd $(dirname $0)/..
# Windows and Unix.
if [ -z "$PROTOC" ]; then
# TODO(jonskeet): Use an array and a for loop instead?
if [ -x cmake/build/Debug/protoc.exe ]; then
if [ -x solution/Debug/protoc.exe ]; then
PROTOC=solution/Debug/protoc.exe
elif [ -x cmake/build/Debug/protoc.exe ]; then
PROTOC=cmake/build/Debug/protoc.exe
elif [ -x cmake/build/Release/protoc.exe ]; then
PROTOC=cmake/build/Release/protoc.exe

View File

@ -156,3 +156,17 @@ message MixedRegularAndOptional {
string regular_field = 1;
optional string optional_field = 2;
}
message OneofWithNoneField {
oneof test {
string x = 1;
string none = 2;
}
}
message OneofWithNoneName {
oneof none {
string x = 1;
string y = 2;
}
}

View File

@ -1,132 +1,132 @@
#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;
namespace Google.Protobuf.Examples.AddressBook
{
internal class AddPerson
{
/// <summary>
/// Builds a person based on user input
/// </summary>
private static Person PromptForAddress(TextReader input, TextWriter output)
{
Person person = new Person();
output.Write("Enter person ID: ");
person.Id = int.Parse(input.ReadLine());
output.Write("Enter name: ");
person.Name = input.ReadLine();
output.Write("Enter email address (blank for none): ");
string email = input.ReadLine();
if (email.Length > 0)
{
person.Email = email;
}
while (true)
{
output.Write("Enter a phone number (or leave blank to finish): ");
string number = input.ReadLine();
if (number.Length == 0)
{
break;
}
Person.Types.PhoneNumber phoneNumber = new Person.Types.PhoneNumber { Number = number };
output.Write("Is this a mobile, home, or work phone? ");
String type = input.ReadLine();
switch (type)
{
case "mobile":
phoneNumber.Type = Person.Types.PhoneType.Mobile;
break;
case "home":
phoneNumber.Type = Person.Types.PhoneType.Home;
break;
case "work":
phoneNumber.Type = Person.Types.PhoneType.Work;
break;
default:
output.Write("Unknown phone type. Using default.");
break;
}
person.Phones.Add(phoneNumber);
}
return person;
}
/// <summary>
/// Entry point - loads an existing addressbook or creates a new one,
/// then writes it back to the file.
/// </summary>
public static int Main(string[] args)
{
if (args.Length != 1)
{
Console.Error.WriteLine("Usage: AddPerson ADDRESS_BOOK_FILE");
return -1;
}
AddressBook addressBook;
if (File.Exists(args[0]))
{
using (Stream file = File.OpenRead(args[0]))
{
addressBook = AddressBook.Parser.ParseFrom(file);
}
}
else
{
Console.WriteLine("{0}: File not found. Creating a new file.", args[0]);
addressBook = new AddressBook();
}
// Add an address.
addressBook.People.Add(PromptForAddress(Console.In, Console.Out));
// Write the new address book back to disk.
using (Stream output = File.OpenWrite(args[0]))
{
addressBook.WriteTo(output);
}
return 0;
}
}
#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;
namespace Google.Protobuf.Examples.AddressBook
{
internal class AddPerson
{
/// <summary>
/// Builds a person based on user input
/// </summary>
private static Person PromptForAddress(TextReader input, TextWriter output)
{
Person person = new Person();
output.Write("Enter person ID: ");
person.Id = int.Parse(input.ReadLine());
output.Write("Enter name: ");
person.Name = input.ReadLine();
output.Write("Enter email address (blank for none): ");
string email = input.ReadLine();
if (email.Length > 0)
{
person.Email = email;
}
while (true)
{
output.Write("Enter a phone number (or leave blank to finish): ");
string number = input.ReadLine();
if (number.Length == 0)
{
break;
}
Person.Types.PhoneNumber phoneNumber = new Person.Types.PhoneNumber { Number = number };
output.Write("Is this a mobile, home, or work phone? ");
String type = input.ReadLine();
switch (type)
{
case "mobile":
phoneNumber.Type = Person.Types.PhoneType.Mobile;
break;
case "home":
phoneNumber.Type = Person.Types.PhoneType.Home;
break;
case "work":
phoneNumber.Type = Person.Types.PhoneType.Work;
break;
default:
output.Write("Unknown phone type. Using default.");
break;
}
person.Phones.Add(phoneNumber);
}
return person;
}
/// <summary>
/// Entry point - loads an existing addressbook or creates a new one,
/// then writes it back to the file.
/// </summary>
public static int Main(string[] args)
{
if (args.Length != 1)
{
Console.Error.WriteLine("Usage: AddPerson ADDRESS_BOOK_FILE");
return -1;
}
AddressBook addressBook;
if (File.Exists(args[0]))
{
using (Stream file = File.OpenRead(args[0]))
{
addressBook = AddressBook.Parser.ParseFrom(file);
}
}
else
{
Console.WriteLine("{0}: File not found. Creating a new file.", args[0]);
addressBook = new AddressBook();
}
// Add an address.
addressBook.People.Add(PromptForAddress(Console.In, Console.Out));
// Write the new address book back to disk.
using (Stream output = File.OpenWrite(args[0]))
{
addressBook.WriteTo(output);
}
return 0;
}
}
}

View File

@ -1,99 +1,99 @@
#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;
namespace Google.Protobuf.Examples.AddressBook
{
internal class ListPeople
{
/// <summary>
/// Iterates though all people in the AddressBook and prints info about them.
/// </summary>
private static void Print(AddressBook addressBook)
{
foreach (Person person in addressBook.People)
{
Console.WriteLine("Person ID: {0}", person.Id);
Console.WriteLine(" Name: {0}", person.Name);
if (person.Email != "")
{
Console.WriteLine(" E-mail address: {0}", person.Email);
}
foreach (Person.Types.PhoneNumber phoneNumber in person.Phones)
{
switch (phoneNumber.Type)
{
case Person.Types.PhoneType.Mobile:
Console.Write(" Mobile phone #: ");
break;
case Person.Types.PhoneType.Home:
Console.Write(" Home phone #: ");
break;
case Person.Types.PhoneType.Work:
Console.Write(" Work phone #: ");
break;
}
Console.WriteLine(phoneNumber.Number);
}
}
}
/// <summary>
/// Entry point - loads the addressbook and then displays it.
/// </summary>
public static int Main(string[] args)
{
if (args.Length != 1)
{
Console.Error.WriteLine("Usage: ListPeople ADDRESS_BOOK_FILE");
return 1;
}
if (!File.Exists(args[0]))
{
Console.WriteLine("{0} doesn't exist. Add a person to create the file first.", args[0]);
return 0;
}
// Read the existing address book.
using (Stream stream = File.OpenRead(args[0]))
{
AddressBook addressBook = AddressBook.Parser.ParseFrom(stream);
Print(addressBook);
}
return 0;
}
}
#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;
namespace Google.Protobuf.Examples.AddressBook
{
internal class ListPeople
{
/// <summary>
/// Iterates though all people in the AddressBook and prints info about them.
/// </summary>
private static void Print(AddressBook addressBook)
{
foreach (Person person in addressBook.People)
{
Console.WriteLine("Person ID: {0}", person.Id);
Console.WriteLine(" Name: {0}", person.Name);
if (person.Email != "")
{
Console.WriteLine(" E-mail address: {0}", person.Email);
}
foreach (Person.Types.PhoneNumber phoneNumber in person.Phones)
{
switch (phoneNumber.Type)
{
case Person.Types.PhoneType.Mobile:
Console.Write(" Mobile phone #: ");
break;
case Person.Types.PhoneType.Home:
Console.Write(" Home phone #: ");
break;
case Person.Types.PhoneType.Work:
Console.Write(" Work phone #: ");
break;
}
Console.WriteLine(phoneNumber.Number);
}
}
}
/// <summary>
/// Entry point - loads the addressbook and then displays it.
/// </summary>
public static int Main(string[] args)
{
if (args.Length != 1)
{
Console.Error.WriteLine("Usage: ListPeople ADDRESS_BOOK_FILE");
return 1;
}
if (!File.Exists(args[0]))
{
Console.WriteLine("{0} doesn't exist. Add a person to create the file first.", args[0]);
return 0;
}
// Read the existing address book.
using (Stream stream = File.OpenRead(args[0]))
{
AddressBook addressBook = AddressBook.Parser.ParseFrom(stream);
Print(addressBook);
}
return 0;
}
}
}

View File

@ -1,95 +1,95 @@
#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.Examples.AddressBook
{
/// <summary>
/// Entry point. Repeatedly prompts user for an action to take, delegating actual behaviour
/// to individual actions. Each action has its own Main method, so that it can be used as an
/// individual complete program.
/// </summary>
internal class Program
{
private static int Main(string[] args)
{
if (args.Length > 1)
{
Console.Error.WriteLine("Usage: AddressBook [file]");
Console.Error.WriteLine("If the filename isn't specified, \"addressbook.data\" is used instead.");
return 1;
}
string addressBookFile = args.Length > 0 ? args[0] : "addressbook.data";
bool stopping = false;
while (!stopping)
{
Console.WriteLine("Options:");
Console.WriteLine(" L: List contents");
Console.WriteLine(" A: Add new person");
Console.WriteLine(" Q: Quit");
Console.Write("Action? ");
Console.Out.Flush();
char choice = Console.ReadKey().KeyChar;
Console.WriteLine();
try
{
switch (choice)
{
case 'A':
case 'a':
AddPerson.Main(new string[] {addressBookFile});
break;
case 'L':
case 'l':
ListPeople.Main(new string[] {addressBookFile});
break;
case 'Q':
case 'q':
stopping = true;
break;
default:
Console.WriteLine("Unknown option: {0}", choice);
break;
}
}
catch (Exception e)
{
Console.WriteLine("Exception executing action: {0}", e);
}
Console.WriteLine();
}
return 0;
}
}
#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.Examples.AddressBook
{
/// <summary>
/// Entry point. Repeatedly prompts user for an action to take, delegating actual behaviour
/// to individual actions. Each action has its own Main method, so that it can be used as an
/// individual complete program.
/// </summary>
internal class Program
{
private static int Main(string[] args)
{
if (args.Length > 1)
{
Console.Error.WriteLine("Usage: AddressBook [file]");
Console.Error.WriteLine("If the filename isn't specified, \"addressbook.data\" is used instead.");
return 1;
}
string addressBookFile = args.Length > 0 ? args[0] : "addressbook.data";
bool stopping = false;
while (!stopping)
{
Console.WriteLine("Options:");
Console.WriteLine(" L: List contents");
Console.WriteLine(" A: Add new person");
Console.WriteLine(" Q: Quit");
Console.Write("Action? ");
Console.Out.Flush();
char choice = Console.ReadKey().KeyChar;
Console.WriteLine();
try
{
switch (choice)
{
case 'A':
case 'a':
AddPerson.Main(new string[] {addressBookFile});
break;
case 'L':
case 'l':
ListPeople.Main(new string[] {addressBookFile});
break;
case 'Q':
case 'q':
stopping = true;
break;
default:
Console.WriteLine("Unknown option: {0}", choice);
break;
}
}
catch (Exception e)
{
Console.WriteLine("Exception executing action: {0}", e);
}
Console.WriteLine();
}
return 0;
}
}
}

View File

@ -1,73 +1,73 @@
#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;
namespace Google.Protobuf.Examples.AddressBook
{
internal class SampleUsage
{
private static void Main()
{
byte[] bytes;
// Create a new person
Person person = new Person
{
Id = 1,
Name = "Foo",
Email = "foo@bar",
Phones = { new Person.Types.PhoneNumber { Number = "555-1212" } }
};
using (MemoryStream stream = new MemoryStream())
{
// Save the person to a stream
person.WriteTo(stream);
bytes = stream.ToArray();
}
Person copy = Person.Parser.ParseFrom(bytes);
AddressBook book = new AddressBook
{
People = { copy }
};
bytes = book.ToByteArray();
// And read the address book back again
AddressBook restored = AddressBook.Parser.ParseFrom(bytes);
// The message performs a deep-comparison on equality:
if (restored.People.Count != 1 || !person.Equals(restored.People[0]))
{
throw new Exception("There is a bad person in here!");
}
}
}
#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;
namespace Google.Protobuf.Examples.AddressBook
{
internal class SampleUsage
{
private static void Main()
{
byte[] bytes;
// Create a new person
Person person = new Person
{
Id = 1,
Name = "Foo",
Email = "foo@bar",
Phones = { new Person.Types.PhoneNumber { Number = "555-1212" } }
};
using (MemoryStream stream = new MemoryStream())
{
// Save the person to a stream
person.WriteTo(stream);
bytes = stream.ToArray();
}
Person copy = Person.Parser.ParseFrom(bytes);
AddressBook book = new AddressBook
{
People = { copy }
};
bytes = book.ToByteArray();
// And read the address book back again
AddressBook restored = AddressBook.Parser.ParseFrom(bytes);
// The message performs a deep-comparison on equality:
if (restored.People.Count != 1 || !person.Equals(restored.People[0]))
{
throw new Exception("There is a bad person in here!");
}
}
}
}

View File

@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<AssemblyOriginatorKeyFile>../../keys/Google.Protobuf.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
<IsPackable>False</IsPackable>
@ -15,7 +15,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.12.1" />
<PackageReference Include="BenchmarkDotNet" Version="0.13.1" />
<ProjectReference Include="..\Google.Protobuf\Google.Protobuf.csproj" />
</ItemGroup>

View File

@ -41,8 +41,8 @@ namespace Google.Protobuf.Benchmarks
/// Benchmark for serializing and deserializing of standard datasets that are also
/// measured by benchmarks in other languages.
/// Over time we may wish to test the various different approaches to serialization and deserialization separately.
/// See https://github.com/protocolbuffers/protobuf/blob/master/benchmarks/README.md
/// See https://github.com/protocolbuffers/protobuf/blob/master/docs/performance.md
/// See https://github.com/protocolbuffers/protobuf/blob/main/benchmarks/README.md
/// See https://github.com/protocolbuffers/protobuf/blob/main/docs/performance.md
/// </summary>
[MemoryDiagnoser]
public class GoogleMessageBenchmark

View File

@ -1,73 +1,73 @@
#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.Reflection;
namespace Google.Protobuf.ProtoDump
{
/// <summary>
/// Small utility to load a binary message and dump it in JSON format.
/// </summary>
internal class Program
{
private static int Main(string[] args)
{
if (args.Length != 2)
{
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("including assembly e.g. ProjectNamespace.Message,Company.Project");
return 1;
}
Type type = Type.GetType(args[0]);
if (type == null)
{
Console.Error.WriteLine("Unable to load type {0}.", args[0]);
return 1;
}
if (!typeof(IMessage).GetTypeInfo().IsAssignableFrom(type))
{
Console.Error.WriteLine("Type {0} doesn't implement IMessage.", args[0]);
return 1;
}
IMessage message = (IMessage) Activator.CreateInstance(type);
using (var input = File.OpenRead(args[1]))
{
message.MergeFrom(input);
}
Console.WriteLine(message);
return 0;
}
}
#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.Reflection;
namespace Google.Protobuf.ProtoDump
{
/// <summary>
/// Small utility to load a binary message and dump it in JSON format.
/// </summary>
internal class Program
{
private static int Main(string[] args)
{
if (args.Length != 2)
{
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("including assembly e.g. ProjectNamespace.Message,Company.Project");
return 1;
}
Type type = Type.GetType(args[0]);
if (type == null)
{
Console.Error.WriteLine("Unable to load type {0}.", args[0]);
return 1;
}
if (!typeof(IMessage).GetTypeInfo().IsAssignableFrom(type))
{
Console.Error.WriteLine("Type {0} doesn't implement IMessage.", args[0]);
return 1;
}
IMessage message = (IMessage) Activator.CreateInstance(type);
using (var input = File.OpenRead(args[1]))
{
message.MergeFrom(input);
}
Console.WriteLine(message);
return 0;
}
}
}

View File

@ -1,25 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">
<!--
This TestProtos project is kept separate from the original test project for many reasons.
It allows us to make sure code can compile on a separate compiler version, different frameworks,
and without the internal visibility from the test project (all of which have caused issues in the past).
-->
<PropertyGroup>
<TargetFrameworks>net45;netstandard1.1;netstandard2.0</TargetFrameworks>
<LangVersion>3.0</LangVersion>
<AssemblyOriginatorKeyFile>../../keys/Google.Protobuf.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
<IsPackable>False</IsPackable>
</PropertyGroup>
<!-- Needed for the net45 build to work on Unix. See https://github.com/dotnet/designs/pull/33 -->
<ItemGroup>
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.0" PrivateAssets="All" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Google.Protobuf\Google.Protobuf.csproj" />
</ItemGroup>
</Project>
<Project Sdk="Microsoft.NET.Sdk">
<!--
This TestProtos project is kept separate from the original test project for many reasons.
It allows us to make sure code can compile on a separate compiler version, different frameworks,
and without the internal visibility from the test project (all of which have caused issues in the past).
-->
<PropertyGroup>
<TargetFrameworks>net462;netstandard1.1;netstandard2.0</TargetFrameworks>
<LangVersion>3.0</LangVersion>
<AssemblyOriginatorKeyFile>../../keys/Google.Protobuf.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
<IsPackable>False</IsPackable>
</PropertyGroup>
<!-- Needed for the net45 build to work on Unix. See https://github.com/dotnet/designs/pull/33 -->
<ItemGroup>
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.2" PrivateAssets="All" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Google.Protobuf\Google.Protobuf.csproj" />
</ItemGroup>
</Project>

View File

@ -226,7 +226,7 @@ namespace ProtobufTestMessages.Proto3 {
"dG8zLkZvcmVpZ25FbnVtOgI4ASI5CgpOZXN0ZWRFbnVtEgcKA0ZPTxAAEgcK",
"A0JBUhABEgcKA0JBWhACEhAKA05FRxD///////////8BIlkKC0FsaWFzZWRF",
"bnVtEg0KCUFMSUFTX0ZPTxAAEg0KCUFMSUFTX0JBUhABEg0KCUFMSUFTX0JB",
"WhACEgcKA1FVWBACEgcKA3F1eBACEgcKA2JBehACGgIQAUINCgtvbmVvZl9m",
"WhACEgcKA01PTxACEgcKA21vbxACEgcKA2JBehACGgIQAUINCgtvbmVvZl9m",
"aWVsZEoGCPUDEP8DIhsKDkZvcmVpZ25NZXNzYWdlEgkKAWMYASABKAUiFgoU",
"TnVsbEh5cG90aGVzaXNQcm90bzMiLwoORW51bU9ubHlQcm90bzMiHQoEQm9v",
"bBIKCgZrRmFsc2UQABIJCgVrVHJ1ZRABKkAKC0ZvcmVpZ25FbnVtEg8KC0ZP",
@ -5432,8 +5432,8 @@ namespace ProtobufTestMessages.Proto3 {
[pbr::OriginalName("ALIAS_FOO")] AliasFoo = 0,
[pbr::OriginalName("ALIAS_BAR")] AliasBar = 1,
[pbr::OriginalName("ALIAS_BAZ")] AliasBaz = 2,
[pbr::OriginalName("QUX", PreferredAlias = false)] Qux = 2,
[pbr::OriginalName("qux", PreferredAlias = false)] Qux_ = 2,
[pbr::OriginalName("MOO", PreferredAlias = false)] Moo = 2,
[pbr::OriginalName("moo", PreferredAlias = false)] Moo_ = 2,
[pbr::OriginalName("bAz", PreferredAlias = false)] BAz = 2,
}

View File

@ -54,11 +54,13 @@ namespace UnitTest.Issues.TestProtos {
"dEluT25lb2YSLgoKbnVsbF92YWx1ZRgCIAEoDjIaLmdvb2dsZS5wcm90b2J1",
"Zi5OdWxsVmFsdWUiYAoXTWl4ZWRSZWd1bGFyQW5kT3B0aW9uYWwSFQoNcmVn",
"dWxhcl9maWVsZBgBIAEoCRIbCg5vcHRpb25hbF9maWVsZBgCIAEoCUgAiAEB",
"QhEKD19vcHRpb25hbF9maWVsZCpVCgxOZWdhdGl2ZUVudW0SFgoSTkVHQVRJ",
"VkVfRU5VTV9aRVJPEAASFgoJRml2ZUJlbG93EPv//////////wESFQoITWlu",
"dXNPbmUQ////////////ASouCg5EZXByZWNhdGVkRW51bRITCg9ERVBSRUNB",
"VEVEX1pFUk8QABIHCgNvbmUQAUIdqgIaVW5pdFRlc3QuSXNzdWVzLlRlc3RQ",
"cm90b3NiBnByb3RvMw=="));
"QhEKD19vcHRpb25hbF9maWVsZCI5ChJPbmVvZldpdGhOb25lRmllbGQSCwoB",
"eBgBIAEoCUgAEg4KBG5vbmUYAiABKAlIAEIGCgR0ZXN0IjUKEU9uZW9mV2l0",
"aE5vbmVOYW1lEgsKAXgYASABKAlIABILCgF5GAIgASgJSABCBgoEbm9uZSpV",
"CgxOZWdhdGl2ZUVudW0SFgoSTkVHQVRJVkVfRU5VTV9aRVJPEAASFgoJRml2",
"ZUJlbG93EPv//////////wESFQoITWludXNPbmUQ////////////ASouCg5E",
"ZXByZWNhdGVkRW51bRITCg9ERVBSRUNBVEVEX1pFUk8QABIHCgNvbmUQAUId",
"qgIaVW5pdFRlc3QuSXNzdWVzLlRlc3RQcm90b3NiBnByb3RvMw=="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.StructReflection.Descriptor, },
new pbr::GeneratedClrTypeInfo(new[] {typeof(global::UnitTest.Issues.TestProtos.NegativeEnum), typeof(global::UnitTest.Issues.TestProtos.DeprecatedEnum), }, null, new pbr::GeneratedClrTypeInfo[] {
@ -73,7 +75,9 @@ namespace UnitTest.Issues.TestProtos {
new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.OneofMerging), global::UnitTest.Issues.TestProtos.OneofMerging.Parser, new[]{ "Text", "Nested" }, new[]{ "Value" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.OneofMerging.Types.Nested), global::UnitTest.Issues.TestProtos.OneofMerging.Types.Nested.Parser, new[]{ "X", "Y" }, null, null, null, null)}),
new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.NullValueOutsideStruct), global::UnitTest.Issues.TestProtos.NullValueOutsideStruct.Parser, new[]{ "StringValue", "NullValue" }, new[]{ "Value" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.NullValueNotInOneof), global::UnitTest.Issues.TestProtos.NullValueNotInOneof.Parser, new[]{ "NullValue" }, null, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.MixedRegularAndOptional), global::UnitTest.Issues.TestProtos.MixedRegularAndOptional.Parser, new[]{ "RegularField", "OptionalField" }, new[]{ "OptionalField" }, null, null, null)
new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.MixedRegularAndOptional), global::UnitTest.Issues.TestProtos.MixedRegularAndOptional.Parser, new[]{ "RegularField", "OptionalField" }, new[]{ "OptionalField" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.OneofWithNoneField), global::UnitTest.Issues.TestProtos.OneofWithNoneField.Parser, new[]{ "X", "None" }, new[]{ "Test" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.OneofWithNoneName), global::UnitTest.Issues.TestProtos.OneofWithNoneName.Parser, new[]{ "X", "Y" }, new[]{ "None" }, null, null, null)
}));
}
#endregion
@ -3825,6 +3829,524 @@ namespace UnitTest.Issues.TestProtos {
}
public sealed partial class OneofWithNoneField : pb::IMessage<OneofWithNoneField>
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
, pb::IBufferMessage
#endif
{
private static readonly pb::MessageParser<OneofWithNoneField> _parser = new pb::MessageParser<OneofWithNoneField>(() => new OneofWithNoneField());
private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public static pb::MessageParser<OneofWithNoneField> Parser { get { return _parser; } }
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public static pbr::MessageDescriptor Descriptor {
get { return global::UnitTest.Issues.TestProtos.UnittestIssuesReflection.Descriptor.MessageTypes[12]; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public OneofWithNoneField() {
OnConstruction();
}
partial void OnConstruction();
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public OneofWithNoneField(OneofWithNoneField other) : this() {
switch (other.TestCase) {
case TestOneofCase.X:
X = other.X;
break;
case TestOneofCase.None_:
None = other.None;
break;
}
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public OneofWithNoneField Clone() {
return new OneofWithNoneField(this);
}
/// <summary>Field number for the "x" field.</summary>
public const int XFieldNumber = 1;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public string X {
get { return testCase_ == TestOneofCase.X ? (string) test_ : ""; }
set {
test_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
testCase_ = TestOneofCase.X;
}
}
/// <summary>Field number for the "none" field.</summary>
public const int NoneFieldNumber = 2;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public string None {
get { return testCase_ == TestOneofCase.None_ ? (string) test_ : ""; }
set {
test_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
testCase_ = TestOneofCase.None_;
}
}
private object test_;
/// <summary>Enum of possible cases for the "test" oneof.</summary>
public enum TestOneofCase {
None = 0,
X = 1,
None_ = 2,
}
private TestOneofCase testCase_ = TestOneofCase.None;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public TestOneofCase TestCase {
get { return testCase_; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public void ClearTest() {
testCase_ = TestOneofCase.None;
test_ = null;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public override bool Equals(object other) {
return Equals(other as OneofWithNoneField);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public bool Equals(OneofWithNoneField other) {
if (ReferenceEquals(other, null)) {
return false;
}
if (ReferenceEquals(other, this)) {
return true;
}
if (X != other.X) return false;
if (None != other.None) return false;
if (TestCase != other.TestCase) return false;
return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public override int GetHashCode() {
int hash = 1;
if (testCase_ == TestOneofCase.X) hash ^= X.GetHashCode();
if (testCase_ == TestOneofCase.None_) hash ^= None.GetHashCode();
hash ^= (int) testCase_;
if (_unknownFields != null) {
hash ^= _unknownFields.GetHashCode();
}
return hash;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public override string ToString() {
return pb::JsonFormatter.ToDiagnosticString(this);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (testCase_ == TestOneofCase.X) {
output.WriteRawTag(10);
output.WriteString(X);
}
if (testCase_ == TestOneofCase.None_) {
output.WriteRawTag(18);
output.WriteString(None);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (testCase_ == TestOneofCase.X) {
output.WriteRawTag(10);
output.WriteString(X);
}
if (testCase_ == TestOneofCase.None_) {
output.WriteRawTag(18);
output.WriteString(None);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public int CalculateSize() {
int size = 0;
if (testCase_ == TestOneofCase.X) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(X);
}
if (testCase_ == TestOneofCase.None_) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(None);
}
if (_unknownFields != null) {
size += _unknownFields.CalculateSize();
}
return size;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public void MergeFrom(OneofWithNoneField other) {
if (other == null) {
return;
}
switch (other.TestCase) {
case TestOneofCase.X:
X = other.X;
break;
case TestOneofCase.None_:
None = other.None;
break;
}
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public void MergeFrom(pb::CodedInputStream input) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
input.ReadRawMessage(this);
#else
uint tag;
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
X = input.ReadString();
break;
}
case 18: {
None = input.ReadString();
break;
}
}
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
break;
case 10: {
X = input.ReadString();
break;
}
case 18: {
None = input.ReadString();
break;
}
}
}
}
#endif
}
public sealed partial class OneofWithNoneName : pb::IMessage<OneofWithNoneName>
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
, pb::IBufferMessage
#endif
{
private static readonly pb::MessageParser<OneofWithNoneName> _parser = new pb::MessageParser<OneofWithNoneName>(() => new OneofWithNoneName());
private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public static pb::MessageParser<OneofWithNoneName> Parser { get { return _parser; } }
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public static pbr::MessageDescriptor Descriptor {
get { return global::UnitTest.Issues.TestProtos.UnittestIssuesReflection.Descriptor.MessageTypes[13]; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public OneofWithNoneName() {
OnConstruction();
}
partial void OnConstruction();
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public OneofWithNoneName(OneofWithNoneName other) : this() {
switch (other.NoneCase) {
case NoneOneofCase.X:
X = other.X;
break;
case NoneOneofCase.Y:
Y = other.Y;
break;
}
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public OneofWithNoneName Clone() {
return new OneofWithNoneName(this);
}
/// <summary>Field number for the "x" field.</summary>
public const int XFieldNumber = 1;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public string X {
get { return noneCase_ == NoneOneofCase.X ? (string) none_ : ""; }
set {
none_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
noneCase_ = NoneOneofCase.X;
}
}
/// <summary>Field number for the "y" field.</summary>
public const int YFieldNumber = 2;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public string Y {
get { return noneCase_ == NoneOneofCase.Y ? (string) none_ : ""; }
set {
none_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
noneCase_ = NoneOneofCase.Y;
}
}
private object none_;
/// <summary>Enum of possible cases for the "none" oneof.</summary>
public enum NoneOneofCase {
None = 0,
X = 1,
Y = 2,
}
private NoneOneofCase noneCase_ = NoneOneofCase.None;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public NoneOneofCase NoneCase {
get { return noneCase_; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public void ClearNone() {
noneCase_ = NoneOneofCase.None;
none_ = null;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public override bool Equals(object other) {
return Equals(other as OneofWithNoneName);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public bool Equals(OneofWithNoneName other) {
if (ReferenceEquals(other, null)) {
return false;
}
if (ReferenceEquals(other, this)) {
return true;
}
if (X != other.X) return false;
if (Y != other.Y) return false;
if (NoneCase != other.NoneCase) return false;
return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public override int GetHashCode() {
int hash = 1;
if (noneCase_ == NoneOneofCase.X) hash ^= X.GetHashCode();
if (noneCase_ == NoneOneofCase.Y) hash ^= Y.GetHashCode();
hash ^= (int) noneCase_;
if (_unknownFields != null) {
hash ^= _unknownFields.GetHashCode();
}
return hash;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public override string ToString() {
return pb::JsonFormatter.ToDiagnosticString(this);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (noneCase_ == NoneOneofCase.X) {
output.WriteRawTag(10);
output.WriteString(X);
}
if (noneCase_ == NoneOneofCase.Y) {
output.WriteRawTag(18);
output.WriteString(Y);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (noneCase_ == NoneOneofCase.X) {
output.WriteRawTag(10);
output.WriteString(X);
}
if (noneCase_ == NoneOneofCase.Y) {
output.WriteRawTag(18);
output.WriteString(Y);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public int CalculateSize() {
int size = 0;
if (noneCase_ == NoneOneofCase.X) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(X);
}
if (noneCase_ == NoneOneofCase.Y) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(Y);
}
if (_unknownFields != null) {
size += _unknownFields.CalculateSize();
}
return size;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public void MergeFrom(OneofWithNoneName other) {
if (other == null) {
return;
}
switch (other.NoneCase) {
case NoneOneofCase.X:
X = other.X;
break;
case NoneOneofCase.Y:
Y = other.Y;
break;
}
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public void MergeFrom(pb::CodedInputStream input) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
input.ReadRawMessage(this);
#else
uint tag;
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
X = input.ReadString();
break;
}
case 18: {
Y = input.ReadString();
break;
}
}
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
break;
case 10: {
X = input.ReadString();
break;
}
case 18: {
Y = input.ReadString();
break;
}
}
}
}
#endif
}
#endregion
}

View File

@ -1,439 +1,439 @@
#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.Text;
using NUnit.Framework;
using System.IO;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Buffers;
using System.Runtime.InteropServices;
using System.Threading;
using System.Runtime.CompilerServices;
#if !NET35
using System.Threading.Tasks;
#endif
namespace Google.Protobuf
{
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);
EqualityTester.AssertEquality(ByteString.Empty, ByteString.Empty);
#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);
Assert.IsTrue(ByteString.Empty == ByteString.Empty);
#pragma warning disable 1718
Assert.IsTrue(b1 != b3);
Assert.IsTrue(b1 != b4);
Assert.IsTrue(b1 != null);
Assert.IsFalse((ByteString) null != null);
}
[Test]
public void EmptyByteStringHasZeroSize()
{
Assert.AreEqual(0, ByteString.Empty.Length);
}
[Test]
public void CopyFromStringWithExplicitEncoding()
{
ByteString bs = ByteString.CopyFrom("AB", Encoding.Unicode);
Assert.AreEqual(4, bs.Length);
Assert.AreEqual(65, bs[0]);
Assert.AreEqual(0, bs[1]);
Assert.AreEqual(66, bs[2]);
Assert.AreEqual(0, bs[3]);
}
[Test]
public void IsEmptyWhenEmpty()
{
Assert.IsTrue(ByteString.CopyFromUtf8("").IsEmpty);
}
[Test]
public void IsEmptyWhenNotEmpty()
{
Assert.IsFalse(ByteString.CopyFromUtf8("X").IsEmpty);
}
[Test]
public void CopyFromByteArrayCopiesContents()
{
byte[] data = new byte[1];
data[0] = 10;
ByteString bs = ByteString.CopyFrom(data);
Assert.AreEqual(10, bs[0]);
data[0] = 5;
Assert.AreEqual(10, bs[0]);
}
[Test]
public void CopyFromReadOnlySpanCopiesContents()
{
byte[] data = new byte[1];
data[0] = 10;
ReadOnlySpan<byte> byteSpan = data;
var bs = ByteString.CopyFrom(byteSpan);
Assert.AreEqual(10, bs[0]);
data[0] = 5;
Assert.AreEqual(10, bs[0]);
}
[Test]
public void ToByteArrayCopiesContents()
{
ByteString bs = ByteString.CopyFromUtf8("Hello");
byte[] data = bs.ToByteArray();
Assert.AreEqual((byte)'H', data[0]);
Assert.AreEqual((byte)'H', bs[0]);
data[0] = 0;
Assert.AreEqual(0, data[0]);
Assert.AreEqual((byte)'H', bs[0]);
}
[Test]
public void CopyFromUtf8UsesUtf8()
{
ByteString bs = ByteString.CopyFromUtf8("\u20ac");
Assert.AreEqual(3, bs.Length);
Assert.AreEqual(0xe2, bs[0]);
Assert.AreEqual(0x82, bs[1]);
Assert.AreEqual(0xac, bs[2]);
}
[Test]
public void CopyFromPortion()
{
byte[] data = new byte[] {0, 1, 2, 3, 4, 5, 6};
ByteString bs = ByteString.CopyFrom(data, 2, 3);
Assert.AreEqual(3, bs.Length);
Assert.AreEqual(2, bs[0]);
Assert.AreEqual(3, bs[1]);
}
[Test]
public void CopyTo()
{
byte[] data = new byte[] { 0, 1, 2, 3, 4, 5, 6 };
ByteString bs = ByteString.CopyFrom(data);
byte[] dest = new byte[data.Length];
bs.CopyTo(dest, 0);
CollectionAssert.AreEqual(data, dest);
}
[Test]
public void GetEnumerator()
{
byte[] data = new byte[] { 0, 1, 2, 3, 4, 5, 6 };
ByteString bs = ByteString.CopyFrom(data);
IEnumerator<byte> genericEnumerator = bs.GetEnumerator();
Assert.IsTrue(genericEnumerator.MoveNext());
Assert.AreEqual(0, genericEnumerator.Current);
IEnumerator enumerator = ((IEnumerable)bs).GetEnumerator();
Assert.IsTrue(enumerator.MoveNext());
Assert.AreEqual(0, enumerator.Current);
// Call via LINQ
CollectionAssert.AreEqual(bs.Span.ToArray(), bs.ToArray());
}
[Test]
public void UnsafeWrap()
{
byte[] data = new byte[] { 0, 1, 2, 3, 4, 5, 6 };
ByteString bs = UnsafeByteOperations.UnsafeWrap(data.AsMemory(2, 3));
ReadOnlySpan<byte> s = bs.Span;
Assert.AreEqual(3, s.Length);
Assert.AreEqual(2, s[0]);
Assert.AreEqual(3, s[1]);
Assert.AreEqual(4, s[2]);
// Check that the value is not a copy
data[2] = byte.MaxValue;
Assert.AreEqual(byte.MaxValue, s[0]);
}
[Test]
public void CreateCodedInput_FromArraySegment()
{
byte[] data = new byte[] { 0, 1, 2, 3, 4, 5, 6 };
ByteString bs = UnsafeByteOperations.UnsafeWrap(data.AsMemory(2, 3));
CodedInputStream codedInputStream = bs.CreateCodedInput();
byte[] bytes = codedInputStream.ReadRawBytes(3);
Assert.AreEqual(3, bytes.Length);
Assert.AreEqual(2, bytes[0]);
Assert.AreEqual(3, bytes[1]);
Assert.AreEqual(4, bytes[2]);
Assert.IsTrue(codedInputStream.IsAtEnd);
}
[Test]
public void WriteToStream()
{
byte[] data = new byte[] { 0, 1, 2, 3, 4, 5, 6 };
ByteString bs = ByteString.CopyFrom(data);
MemoryStream ms = new MemoryStream();
bs.WriteTo(ms);
CollectionAssert.AreEqual(data, ms.ToArray());
}
[Test]
public void WriteToStream_Stackalloc()
{
byte[] data = Encoding.UTF8.GetBytes("Hello world");
Span<byte> s = stackalloc byte[data.Length];
data.CopyTo(s);
MemoryStream ms = new MemoryStream();
using (UnmanagedMemoryManager<byte> manager = new UnmanagedMemoryManager<byte>(s))
{
ByteString bs = ByteString.AttachBytes(manager.Memory);
bs.WriteTo(ms);
}
CollectionAssert.AreEqual(data, ms.ToArray());
}
[Test]
public void ToStringUtf8()
{
ByteString bs = ByteString.CopyFromUtf8("\u20ac");
Assert.AreEqual("\u20ac", bs.ToStringUtf8());
}
[Test]
public void ToStringWithExplicitEncoding()
{
ByteString bs = ByteString.CopyFrom("\u20ac", Encoding.Unicode);
Assert.AreEqual("\u20ac", bs.ToString(Encoding.Unicode));
}
[Test]
public void ToString_Stackalloc()
{
byte[] data = Encoding.UTF8.GetBytes("Hello world");
Span<byte> s = stackalloc byte[data.Length];
data.CopyTo(s);
using (UnmanagedMemoryManager<byte> manager = new UnmanagedMemoryManager<byte>(s))
{
ByteString bs = ByteString.AttachBytes(manager.Memory);
Assert.AreEqual("Hello world", bs.ToString(Encoding.UTF8));
}
}
[Test]
public void FromBase64_WithText()
{
byte[] data = new byte[] {0, 1, 2, 3, 4, 5, 6};
string base64 = Convert.ToBase64String(data);
ByteString bs = ByteString.FromBase64(base64);
Assert.AreEqual(data, bs.ToByteArray());
}
[Test]
public void FromBase64_Empty()
{
// Optimization which also fixes issue 61.
Assert.AreSame(ByteString.Empty, ByteString.FromBase64(""));
}
[Test]
public void ToBase64_Array()
{
ByteString bs = ByteString.CopyFrom(Encoding.UTF8.GetBytes("Hello world"));
Assert.AreEqual("SGVsbG8gd29ybGQ=", bs.ToBase64());
}
[Test]
public void ToBase64_Stackalloc()
{
byte[] data = Encoding.UTF8.GetBytes("Hello world");
Span<byte> s = stackalloc byte[data.Length];
data.CopyTo(s);
using (UnmanagedMemoryManager<byte> manager = new UnmanagedMemoryManager<byte>(s))
{
ByteString bs = ByteString.AttachBytes(manager.Memory);
Assert.AreEqual("SGVsbG8gd29ybGQ=", bs.ToBase64());
}
}
[Test]
public void FromStream_Seekable()
{
var stream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5 });
// Consume the first byte, just to test that it's "from current position"
stream.ReadByte();
var actual = ByteString.FromStream(stream);
ByteString expected = ByteString.CopyFrom(2, 3, 4, 5);
Assert.AreEqual(expected, actual, $"{expected.ToBase64()} != {actual.ToBase64()}");
}
[Test]
public void FromStream_NotSeekable()
{
var stream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5 });
// Consume the first byte, just to test that it's "from current position"
stream.ReadByte();
// Wrap the original stream in LimitedInputStream, which has CanSeek=false
var limitedStream = new LimitedInputStream(stream, 3);
var actual = ByteString.FromStream(limitedStream);
ByteString expected = ByteString.CopyFrom(2, 3, 4);
Assert.AreEqual(expected, actual, $"{expected.ToBase64()} != {actual.ToBase64()}");
}
#if !NET35
[Test]
public async Task FromStreamAsync_Seekable()
{
var stream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5 });
// Consume the first byte, just to test that it's "from current position"
stream.ReadByte();
var actual = await ByteString.FromStreamAsync(stream);
ByteString expected = ByteString.CopyFrom(2, 3, 4, 5);
Assert.AreEqual(expected, actual, $"{expected.ToBase64()} != {actual.ToBase64()}");
}
[Test]
public async Task FromStreamAsync_NotSeekable()
{
var stream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5 });
// Consume the first byte, just to test that it's "from current position"
stream.ReadByte();
// Wrap the original stream in LimitedInputStream, which has CanSeek=false
var limitedStream = new LimitedInputStream(stream, 3);
var actual = await ByteString.FromStreamAsync(limitedStream);
ByteString expected = ByteString.CopyFrom(2, 3, 4);
Assert.AreEqual(expected, actual, $"{expected.ToBase64()} != {actual.ToBase64()}");
}
#endif
[Test]
public void GetHashCode_Regression()
{
// We used to have an awful hash algorithm where only the last four
// bytes were relevant. This is a regression test for
// https://github.com/protocolbuffers/protobuf/issues/2511
ByteString b1 = ByteString.CopyFrom(100, 1, 2, 3, 4);
ByteString b2 = ByteString.CopyFrom(200, 1, 2, 3, 4);
Assert.AreNotEqual(b1.GetHashCode(), b2.GetHashCode());
}
[Test]
public void GetContentsAsReadOnlySpan()
{
var byteString = ByteString.CopyFrom(1, 2, 3, 4, 5);
var copied = byteString.Span.ToArray();
CollectionAssert.AreEqual(byteString, copied);
}
[Test]
public void GetContentsAsReadOnlyMemory()
{
var byteString = ByteString.CopyFrom(1, 2, 3, 4, 5);
var copied = byteString.Memory.ToArray();
CollectionAssert.AreEqual(byteString, copied);
}
// Create Memory<byte> from non-array source.
// Use by ByteString tests that have optimized path for array backed Memory<byte>.
private sealed unsafe class UnmanagedMemoryManager<T> : MemoryManager<T> where T : unmanaged
{
private readonly T* _pointer;
private readonly int _length;
public UnmanagedMemoryManager(Span<T> span)
{
fixed (T* ptr = &MemoryMarshal.GetReference(span))
{
_pointer = ptr;
_length = span.Length;
}
}
public override Span<T> GetSpan() => new Span<T>(_pointer, _length);
public override MemoryHandle Pin(int elementIndex = 0)
{
if (elementIndex < 0 || elementIndex >= _length)
{
throw new ArgumentOutOfRangeException(nameof(elementIndex));
}
return new MemoryHandle(_pointer + elementIndex);
}
public override void Unpin() { }
protected override void Dispose(bool disposing) { }
}
}
#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.Text;
using NUnit.Framework;
using System.IO;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Buffers;
using System.Runtime.InteropServices;
using System.Threading;
using System.Runtime.CompilerServices;
#if !NET35
using System.Threading.Tasks;
#endif
namespace Google.Protobuf
{
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);
EqualityTester.AssertEquality(ByteString.Empty, ByteString.Empty);
#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);
Assert.IsTrue(ByteString.Empty == ByteString.Empty);
#pragma warning disable 1718
Assert.IsTrue(b1 != b3);
Assert.IsTrue(b1 != b4);
Assert.IsTrue(b1 != null);
Assert.IsFalse((ByteString) null != null);
}
[Test]
public void EmptyByteStringHasZeroSize()
{
Assert.AreEqual(0, ByteString.Empty.Length);
}
[Test]
public void CopyFromStringWithExplicitEncoding()
{
ByteString bs = ByteString.CopyFrom("AB", Encoding.Unicode);
Assert.AreEqual(4, bs.Length);
Assert.AreEqual(65, bs[0]);
Assert.AreEqual(0, bs[1]);
Assert.AreEqual(66, bs[2]);
Assert.AreEqual(0, bs[3]);
}
[Test]
public void IsEmptyWhenEmpty()
{
Assert.IsTrue(ByteString.CopyFromUtf8("").IsEmpty);
}
[Test]
public void IsEmptyWhenNotEmpty()
{
Assert.IsFalse(ByteString.CopyFromUtf8("X").IsEmpty);
}
[Test]
public void CopyFromByteArrayCopiesContents()
{
byte[] data = new byte[1];
data[0] = 10;
ByteString bs = ByteString.CopyFrom(data);
Assert.AreEqual(10, bs[0]);
data[0] = 5;
Assert.AreEqual(10, bs[0]);
}
[Test]
public void CopyFromReadOnlySpanCopiesContents()
{
byte[] data = new byte[1];
data[0] = 10;
ReadOnlySpan<byte> byteSpan = data;
var bs = ByteString.CopyFrom(byteSpan);
Assert.AreEqual(10, bs[0]);
data[0] = 5;
Assert.AreEqual(10, bs[0]);
}
[Test]
public void ToByteArrayCopiesContents()
{
ByteString bs = ByteString.CopyFromUtf8("Hello");
byte[] data = bs.ToByteArray();
Assert.AreEqual((byte)'H', data[0]);
Assert.AreEqual((byte)'H', bs[0]);
data[0] = 0;
Assert.AreEqual(0, data[0]);
Assert.AreEqual((byte)'H', bs[0]);
}
[Test]
public void CopyFromUtf8UsesUtf8()
{
ByteString bs = ByteString.CopyFromUtf8("\u20ac");
Assert.AreEqual(3, bs.Length);
Assert.AreEqual(0xe2, bs[0]);
Assert.AreEqual(0x82, bs[1]);
Assert.AreEqual(0xac, bs[2]);
}
[Test]
public void CopyFromPortion()
{
byte[] data = new byte[] {0, 1, 2, 3, 4, 5, 6};
ByteString bs = ByteString.CopyFrom(data, 2, 3);
Assert.AreEqual(3, bs.Length);
Assert.AreEqual(2, bs[0]);
Assert.AreEqual(3, bs[1]);
}
[Test]
public void CopyTo()
{
byte[] data = new byte[] { 0, 1, 2, 3, 4, 5, 6 };
ByteString bs = ByteString.CopyFrom(data);
byte[] dest = new byte[data.Length];
bs.CopyTo(dest, 0);
CollectionAssert.AreEqual(data, dest);
}
[Test]
public void GetEnumerator()
{
byte[] data = new byte[] { 0, 1, 2, 3, 4, 5, 6 };
ByteString bs = ByteString.CopyFrom(data);
IEnumerator<byte> genericEnumerator = bs.GetEnumerator();
Assert.IsTrue(genericEnumerator.MoveNext());
Assert.AreEqual(0, genericEnumerator.Current);
IEnumerator enumerator = ((IEnumerable)bs).GetEnumerator();
Assert.IsTrue(enumerator.MoveNext());
Assert.AreEqual(0, enumerator.Current);
// Call via LINQ
CollectionAssert.AreEqual(bs.Span.ToArray(), bs.ToArray());
}
[Test]
public void UnsafeWrap()
{
byte[] data = new byte[] { 0, 1, 2, 3, 4, 5, 6 };
ByteString bs = UnsafeByteOperations.UnsafeWrap(data.AsMemory(2, 3));
ReadOnlySpan<byte> s = bs.Span;
Assert.AreEqual(3, s.Length);
Assert.AreEqual(2, s[0]);
Assert.AreEqual(3, s[1]);
Assert.AreEqual(4, s[2]);
// Check that the value is not a copy
data[2] = byte.MaxValue;
Assert.AreEqual(byte.MaxValue, s[0]);
}
[Test]
public void CreateCodedInput_FromArraySegment()
{
byte[] data = new byte[] { 0, 1, 2, 3, 4, 5, 6 };
ByteString bs = UnsafeByteOperations.UnsafeWrap(data.AsMemory(2, 3));
CodedInputStream codedInputStream = bs.CreateCodedInput();
byte[] bytes = codedInputStream.ReadRawBytes(3);
Assert.AreEqual(3, bytes.Length);
Assert.AreEqual(2, bytes[0]);
Assert.AreEqual(3, bytes[1]);
Assert.AreEqual(4, bytes[2]);
Assert.IsTrue(codedInputStream.IsAtEnd);
}
[Test]
public void WriteToStream()
{
byte[] data = new byte[] { 0, 1, 2, 3, 4, 5, 6 };
ByteString bs = ByteString.CopyFrom(data);
MemoryStream ms = new MemoryStream();
bs.WriteTo(ms);
CollectionAssert.AreEqual(data, ms.ToArray());
}
[Test]
public void WriteToStream_Stackalloc()
{
byte[] data = Encoding.UTF8.GetBytes("Hello world");
Span<byte> s = stackalloc byte[data.Length];
data.CopyTo(s);
MemoryStream ms = new MemoryStream();
using (UnmanagedMemoryManager<byte> manager = new UnmanagedMemoryManager<byte>(s))
{
ByteString bs = ByteString.AttachBytes(manager.Memory);
bs.WriteTo(ms);
}
CollectionAssert.AreEqual(data, ms.ToArray());
}
[Test]
public void ToStringUtf8()
{
ByteString bs = ByteString.CopyFromUtf8("\u20ac");
Assert.AreEqual("\u20ac", bs.ToStringUtf8());
}
[Test]
public void ToStringWithExplicitEncoding()
{
ByteString bs = ByteString.CopyFrom("\u20ac", Encoding.Unicode);
Assert.AreEqual("\u20ac", bs.ToString(Encoding.Unicode));
}
[Test]
public void ToString_Stackalloc()
{
byte[] data = Encoding.UTF8.GetBytes("Hello world");
Span<byte> s = stackalloc byte[data.Length];
data.CopyTo(s);
using (UnmanagedMemoryManager<byte> manager = new UnmanagedMemoryManager<byte>(s))
{
ByteString bs = ByteString.AttachBytes(manager.Memory);
Assert.AreEqual("Hello world", bs.ToString(Encoding.UTF8));
}
}
[Test]
public void FromBase64_WithText()
{
byte[] data = new byte[] {0, 1, 2, 3, 4, 5, 6};
string base64 = Convert.ToBase64String(data);
ByteString bs = ByteString.FromBase64(base64);
Assert.AreEqual(data, bs.ToByteArray());
}
[Test]
public void FromBase64_Empty()
{
// Optimization which also fixes issue 61.
Assert.AreSame(ByteString.Empty, ByteString.FromBase64(""));
}
[Test]
public void ToBase64_Array()
{
ByteString bs = ByteString.CopyFrom(Encoding.UTF8.GetBytes("Hello world"));
Assert.AreEqual("SGVsbG8gd29ybGQ=", bs.ToBase64());
}
[Test]
public void ToBase64_Stackalloc()
{
byte[] data = Encoding.UTF8.GetBytes("Hello world");
Span<byte> s = stackalloc byte[data.Length];
data.CopyTo(s);
using (UnmanagedMemoryManager<byte> manager = new UnmanagedMemoryManager<byte>(s))
{
ByteString bs = ByteString.AttachBytes(manager.Memory);
Assert.AreEqual("SGVsbG8gd29ybGQ=", bs.ToBase64());
}
}
[Test]
public void FromStream_Seekable()
{
var stream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5 });
// Consume the first byte, just to test that it's "from current position"
stream.ReadByte();
var actual = ByteString.FromStream(stream);
ByteString expected = ByteString.CopyFrom(2, 3, 4, 5);
Assert.AreEqual(expected, actual, $"{expected.ToBase64()} != {actual.ToBase64()}");
}
[Test]
public void FromStream_NotSeekable()
{
var stream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5 });
// Consume the first byte, just to test that it's "from current position"
stream.ReadByte();
// Wrap the original stream in LimitedInputStream, which has CanSeek=false
var limitedStream = new LimitedInputStream(stream, 3);
var actual = ByteString.FromStream(limitedStream);
ByteString expected = ByteString.CopyFrom(2, 3, 4);
Assert.AreEqual(expected, actual, $"{expected.ToBase64()} != {actual.ToBase64()}");
}
#if !NET35
[Test]
public async Task FromStreamAsync_Seekable()
{
var stream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5 });
// Consume the first byte, just to test that it's "from current position"
stream.ReadByte();
var actual = await ByteString.FromStreamAsync(stream);
ByteString expected = ByteString.CopyFrom(2, 3, 4, 5);
Assert.AreEqual(expected, actual, $"{expected.ToBase64()} != {actual.ToBase64()}");
}
[Test]
public async Task FromStreamAsync_NotSeekable()
{
var stream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5 });
// Consume the first byte, just to test that it's "from current position"
stream.ReadByte();
// Wrap the original stream in LimitedInputStream, which has CanSeek=false
var limitedStream = new LimitedInputStream(stream, 3);
var actual = await ByteString.FromStreamAsync(limitedStream);
ByteString expected = ByteString.CopyFrom(2, 3, 4);
Assert.AreEqual(expected, actual, $"{expected.ToBase64()} != {actual.ToBase64()}");
}
#endif
[Test]
public void GetHashCode_Regression()
{
// We used to have an awful hash algorithm where only the last four
// bytes were relevant. This is a regression test for
// https://github.com/protocolbuffers/protobuf/issues/2511
ByteString b1 = ByteString.CopyFrom(100, 1, 2, 3, 4);
ByteString b2 = ByteString.CopyFrom(200, 1, 2, 3, 4);
Assert.AreNotEqual(b1.GetHashCode(), b2.GetHashCode());
}
[Test]
public void GetContentsAsReadOnlySpan()
{
var byteString = ByteString.CopyFrom(1, 2, 3, 4, 5);
var copied = byteString.Span.ToArray();
CollectionAssert.AreEqual(byteString, copied);
}
[Test]
public void GetContentsAsReadOnlyMemory()
{
var byteString = ByteString.CopyFrom(1, 2, 3, 4, 5);
var copied = byteString.Memory.ToArray();
CollectionAssert.AreEqual(byteString, copied);
}
// Create Memory<byte> from non-array source.
// Use by ByteString tests that have optimized path for array backed Memory<byte>.
private sealed unsafe class UnmanagedMemoryManager<T> : MemoryManager<T> where T : unmanaged
{
private readonly T* _pointer;
private readonly int _length;
public UnmanagedMemoryManager(Span<T> span)
{
fixed (T* ptr = &MemoryMarshal.GetReference(span))
{
_pointer = ptr;
_length = span.Length;
}
}
public override Span<T> GetSpan() => new Span<T>(_pointer, _length);
public override MemoryHandle Pin(int elementIndex = 0)
{
if (elementIndex < 0 || elementIndex >= _length)
{
throw new ArgumentOutOfRangeException(nameof(elementIndex));
}
return new MemoryHandle(_pointer + elementIndex);
}
public override void Unpin() { }
protected override void Dispose(bool disposing) { }
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -625,8 +625,6 @@ namespace Google.Protobuf.Collections
output.WriteString("the_value");
output.Flush();
Console.WriteLine(BitConverter.ToString(memoryStream.ToArray()));
var field = new MapField<string, string>();
var mapCodec = new MapField<string, string>.Codec(FieldCodec.ForString(keyTag, ""), FieldCodec.ForString(valueTag, ""), 10);
var input = new CodedInputStream(memoryStream.ToArray());

View File

@ -1,55 +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"));
}
}
}
#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"));
}
}
}

View File

@ -1,137 +1,196 @@
using Google.Protobuf.TestProtos.Proto2;
using NUnit.Framework;
using static Google.Protobuf.TestProtos.Proto2.UnittestExtensions;
namespace Google.Protobuf
{
public class ExtensionSetTest
{
[Test]
public void EmptyExtensionSet()
{
ExtensionSet<TestAllExtensions> extensions = new ExtensionSet<TestAllExtensions>();
Assert.AreEqual(0, extensions.CalculateSize());
}
[Test]
public void MergeExtensionSet()
{
ExtensionSet<TestAllExtensions> extensions = null;
ExtensionSet.Set(ref extensions, OptionalBoolExtension, true);
ExtensionSet<TestAllExtensions> other = null;
Assert.IsFalse(ExtensionSet.Has(ref other, OptionalBoolExtension));
ExtensionSet.MergeFrom(ref other, extensions);
Assert.IsTrue(ExtensionSet.Has(ref other, OptionalBoolExtension));
}
[Test]
public void TestMergeCodedInput()
{
var message = new TestAllExtensions();
message.SetExtension(OptionalBoolExtension, true);
var serialized = message.ToByteArray();
MessageParsingHelpers.AssertWritingMessage(message);
MessageParsingHelpers.AssertReadingMessage(
TestAllExtensions.Parser.WithExtensionRegistry(new ExtensionRegistry() { OptionalBoolExtension }),
serialized,
other =>
{
Assert.AreEqual(message, other);
Assert.AreEqual(message.CalculateSize(), other.CalculateSize());
});
}
[Test]
public void TestMergeMessage()
{
var message = new TestAllExtensions();
message.SetExtension(OptionalBoolExtension, true);
var other = new TestAllExtensions();
Assert.AreNotEqual(message, other);
Assert.AreNotEqual(message.CalculateSize(), other.CalculateSize());
other.MergeFrom(message);
Assert.AreEqual(message, other);
Assert.AreEqual(message.CalculateSize(), other.CalculateSize());
}
[Test]
public void TryMergeFieldFrom_CodedInputStream()
{
var message = new TestAllExtensions();
message.SetExtension(OptionalStringExtension, "abcd");
var input = new CodedInputStream(message.ToByteArray());
input.ExtensionRegistry = new ExtensionRegistry() { OptionalStringExtension };
input.ReadTag(); // TryMergeFieldFrom expects that a tag was just read and will inspect the LastTag value
ExtensionSet<TestAllExtensions> extensionSet = null;
// test the legacy overload of TryMergeFieldFrom that takes a CodedInputStream
Assert.IsTrue(ExtensionSet.TryMergeFieldFrom(ref extensionSet, input));
Assert.AreEqual("abcd", ExtensionSet.Get(ref extensionSet, OptionalStringExtension));
}
[Test]
public void TestEquals()
{
var message = new TestAllExtensions();
message.SetExtension(OptionalBoolExtension, true);
var other = new TestAllExtensions();
Assert.AreNotEqual(message, other);
Assert.AreNotEqual(message.CalculateSize(), other.CalculateSize());
other.SetExtension(OptionalBoolExtension, true);
Assert.AreEqual(message, other);
Assert.AreEqual(message.CalculateSize(), other.CalculateSize());
}
[Test]
public void TestHashCode()
{
var message = new TestAllExtensions();
var hashCode = message.GetHashCode();
message.SetExtension(OptionalBoolExtension, true);
Assert.AreNotEqual(hashCode, message.GetHashCode());
}
[Test]
public void TestClone()
{
var message = new TestAllExtensions();
message.SetExtension(OptionalBoolExtension, true);
var other = message.Clone();
Assert.AreEqual(message, other);
Assert.AreEqual(message.CalculateSize(), other.CalculateSize());
}
[Test]
public void TestDefaultValueRoundTrip()
{
var message = new TestAllExtensions();
message.SetExtension(OptionalBoolExtension, false);
Assert.IsFalse(message.GetExtension(OptionalBoolExtension));
Assert.IsTrue(message.HasExtension(OptionalBoolExtension));
var bytes = message.ToByteArray();
var registry = new ExtensionRegistry { OptionalBoolExtension };
var parsed = TestAllExtensions.Parser.WithExtensionRegistry(registry).ParseFrom(bytes);
Assert.IsFalse(parsed.GetExtension(OptionalBoolExtension));
Assert.IsTrue(parsed.HasExtension(OptionalBoolExtension));
}
}
}
using System;
using System.Collections;
using Google.Protobuf.TestProtos.Proto2;
using NUnit.Framework;
using static Google.Protobuf.TestProtos.Proto2.UnittestExtensions;
namespace Google.Protobuf
{
public class ExtensionSetTest
{
[Test]
public void EmptyExtensionSet()
{
ExtensionSet<TestAllExtensions> extensions = new ExtensionSet<TestAllExtensions>();
Assert.AreEqual(0, extensions.CalculateSize());
}
[Test]
public void MergeExtensionSet()
{
ExtensionSet<TestAllExtensions> extensions = null;
ExtensionSet.Set(ref extensions, OptionalBoolExtension, true);
ExtensionSet<TestAllExtensions> other = null;
Assert.IsFalse(ExtensionSet.Has(ref other, OptionalBoolExtension));
ExtensionSet.MergeFrom(ref other, extensions);
Assert.IsTrue(ExtensionSet.Has(ref other, OptionalBoolExtension));
}
[Test]
public void TestMergeCodedInput()
{
var message = new TestAllExtensions();
message.SetExtension(OptionalBoolExtension, true);
var serialized = message.ToByteArray();
MessageParsingHelpers.AssertWritingMessage(message);
MessageParsingHelpers.AssertReadingMessage(
TestAllExtensions.Parser.WithExtensionRegistry(new ExtensionRegistry() { OptionalBoolExtension }),
serialized,
other =>
{
Assert.AreEqual(message, other);
Assert.AreEqual(message.CalculateSize(), other.CalculateSize());
});
}
[Test]
public void TestMergeMessage()
{
var message = new TestAllExtensions();
message.SetExtension(OptionalBoolExtension, true);
var other = new TestAllExtensions();
Assert.AreNotEqual(message, other);
Assert.AreNotEqual(message.CalculateSize(), other.CalculateSize());
other.MergeFrom(message);
Assert.AreEqual(message, other);
Assert.AreEqual(message.CalculateSize(), other.CalculateSize());
}
[Test]
public void TryMergeFieldFrom_CodedInputStream()
{
var message = new TestAllExtensions();
message.SetExtension(OptionalStringExtension, "abcd");
var input = new CodedInputStream(message.ToByteArray());
input.ExtensionRegistry = new ExtensionRegistry() { OptionalStringExtension };
input.ReadTag(); // TryMergeFieldFrom expects that a tag was just read and will inspect the LastTag value
ExtensionSet<TestAllExtensions> extensionSet = null;
// test the legacy overload of TryMergeFieldFrom that takes a CodedInputStream
Assert.IsTrue(ExtensionSet.TryMergeFieldFrom(ref extensionSet, input));
Assert.AreEqual("abcd", ExtensionSet.Get(ref extensionSet, OptionalStringExtension));
}
[Test]
public void GetSingle()
{
var extensionValue = new TestAllTypes.Types.NestedMessage() { Bb = 42 };
var untypedExtension = new Extension<TestAllExtensions, object>(OptionalNestedMessageExtension.FieldNumber, codec: null);
var wrongTypedExtension = new Extension<TestAllExtensions, TestAllTypes>(OptionalNestedMessageExtension.FieldNumber, codec: null);
var message = new TestAllExtensions();
var value1 = message.GetExtension(untypedExtension);
Assert.IsNull(value1);
message.SetExtension(OptionalNestedMessageExtension, extensionValue);
var value2 = message.GetExtension(untypedExtension);
Assert.IsNotNull(value2);
var valueBytes = ((IMessage)value2).ToByteArray();
var parsedValue = TestProtos.Proto2.TestAllTypes.Types.NestedMessage.Parser.ParseFrom(valueBytes);
Assert.AreEqual(extensionValue, parsedValue);
var ex = Assert.Throws<InvalidOperationException>(() => message.GetExtension(wrongTypedExtension));
var expectedMessage = "The stored extension value has a type of 'Google.Protobuf.TestProtos.Proto2.TestAllTypes+Types+NestedMessage, Google.Protobuf.Test.TestProtos, Version=1.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604'. " +
"This a different from the requested type of 'Google.Protobuf.TestProtos.Proto2.TestAllTypes, Google.Protobuf.Test.TestProtos, Version=1.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604'.";
Assert.AreEqual(expectedMessage, ex.Message);
}
[Test]
public void GetRepeated()
{
var extensionValue = new TestAllTypes.Types.NestedMessage() { Bb = 42 };
var untypedExtension = new Extension<TestAllExtensions, IList>(RepeatedNestedMessageExtension.FieldNumber, codec: null);
var wrongTypedExtension = new RepeatedExtension<TestAllExtensions, TestAllTypes>(RepeatedNestedMessageExtension.FieldNumber, codec: null);
var message = new TestAllExtensions();
var value1 = message.GetExtension(untypedExtension);
Assert.IsNull(value1);
var repeatedField = message.GetOrInitializeExtension<TestAllTypes.Types.NestedMessage>(RepeatedNestedMessageExtension);
repeatedField.Add(extensionValue);
var value2 = message.GetExtension(untypedExtension);
Assert.IsNotNull(value2);
Assert.AreEqual(1, value2.Count);
var valueBytes = ((IMessage)value2[0]).ToByteArray();
var parsedValue = TestProtos.Proto2.TestAllTypes.Types.NestedMessage.Parser.ParseFrom(valueBytes);
Assert.AreEqual(extensionValue, parsedValue);
var ex = Assert.Throws<InvalidOperationException>(() => message.GetExtension(wrongTypedExtension));
var expectedMessage = "The stored extension value has a type of 'Google.Protobuf.TestProtos.Proto2.TestAllTypes+Types+NestedMessage, Google.Protobuf.Test.TestProtos, Version=1.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604'. " +
"This a different from the requested type of 'Google.Protobuf.TestProtos.Proto2.TestAllTypes, Google.Protobuf.Test.TestProtos, Version=1.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604'.";
Assert.AreEqual(expectedMessage, ex.Message);
}
[Test]
public void TestEquals()
{
var message = new TestAllExtensions();
message.SetExtension(OptionalBoolExtension, true);
var other = new TestAllExtensions();
Assert.AreNotEqual(message, other);
Assert.AreNotEqual(message.CalculateSize(), other.CalculateSize());
other.SetExtension(OptionalBoolExtension, true);
Assert.AreEqual(message, other);
Assert.AreEqual(message.CalculateSize(), other.CalculateSize());
}
[Test]
public void TestHashCode()
{
var message = new TestAllExtensions();
var hashCode = message.GetHashCode();
message.SetExtension(OptionalBoolExtension, true);
Assert.AreNotEqual(hashCode, message.GetHashCode());
}
[Test]
public void TestClone()
{
var message = new TestAllExtensions();
message.SetExtension(OptionalBoolExtension, true);
var other = message.Clone();
Assert.AreEqual(message, other);
Assert.AreEqual(message.CalculateSize(), other.CalculateSize());
}
[Test]
public void TestDefaultValueRoundTrip()
{
var message = new TestAllExtensions();
message.SetExtension(OptionalBoolExtension, false);
Assert.IsFalse(message.GetExtension(OptionalBoolExtension));
Assert.IsTrue(message.HasExtension(OptionalBoolExtension));
var bytes = message.ToByteArray();
var registry = new ExtensionRegistry { OptionalBoolExtension };
var parsed = TestAllExtensions.Parser.WithExtensionRegistry(registry).ParseFrom(bytes);
Assert.IsFalse(parsed.GetExtension(OptionalBoolExtension));
Assert.IsTrue(parsed.HasExtension(OptionalBoolExtension));
}
}
}

View File

@ -1,397 +1,397 @@
using Google.Protobuf.TestProtos.Proto2;
using Proto2 = Google.Protobuf.TestProtos.Proto2;
using NUnit.Framework;
using static Google.Protobuf.TestProtos.Proto2.UnittestExtensions;
namespace Google.Protobuf
{
/// <summary>
/// Tests around the generated TestAllTypes message in unittest.proto
/// </summary>
public partial class GeneratedMessageTest
{
[Test]
public void DefaultProto2Values()
{
var message = new TestAllTypes();
Assert.AreEqual(false, message.OptionalBool);
Assert.AreEqual(ByteString.Empty, message.OptionalBytes);
Assert.AreEqual(0.0, message.OptionalDouble);
Assert.AreEqual(0, message.OptionalFixed32);
Assert.AreEqual(0L, message.OptionalFixed64);
Assert.AreEqual(0.0f, message.OptionalFloat);
Assert.AreEqual(ForeignEnum.ForeignFoo, message.OptionalForeignEnum);
Assert.IsNull(message.OptionalForeignMessage);
Assert.AreEqual(ImportEnum.ImportFoo, message.OptionalImportEnum);
Assert.IsNull(message.OptionalImportMessage);
Assert.AreEqual(0, message.OptionalInt32);
Assert.AreEqual(0L, message.OptionalInt64);
Assert.AreEqual(Proto2.TestAllTypes.Types.NestedEnum.Foo, message.OptionalNestedEnum);
Assert.IsNull(message.OptionalNestedMessage);
Assert.IsNull(message.OptionalPublicImportMessage);
Assert.AreEqual(0, message.OptionalSfixed32);
Assert.AreEqual(0L, message.OptionalSfixed64);
Assert.AreEqual(0, message.OptionalSint32);
Assert.AreEqual(0L, message.OptionalSint64);
Assert.AreEqual("", message.OptionalString);
Assert.AreEqual(0U, message.OptionalUint32);
Assert.AreEqual(0UL, message.OptionalUint64);
// 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.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(Proto2.TestAllTypes.OneofFieldOneofCase.None, message.OneofFieldCase);
Assert.AreEqual(0, message.OneofUint32);
Assert.AreEqual("", message.OneofString);
Assert.AreEqual(ByteString.Empty, message.OneofBytes);
Assert.IsNull(message.OneofNestedMessage);
Assert.AreEqual(true, message.DefaultBool);
Assert.AreEqual(ByteString.CopyFromUtf8("world"), message.DefaultBytes);
Assert.AreEqual("123", message.DefaultCord);
Assert.AreEqual(52e3, message.DefaultDouble);
Assert.AreEqual(47, message.DefaultFixed32);
Assert.AreEqual(48, message.DefaultFixed64);
Assert.AreEqual(51.5, message.DefaultFloat);
Assert.AreEqual(ForeignEnum.ForeignBar, message.DefaultForeignEnum);
Assert.AreEqual(ImportEnum.ImportBar, message.DefaultImportEnum);
Assert.AreEqual(41, message.DefaultInt32);
Assert.AreEqual(42, message.DefaultInt64);
Assert.AreEqual(Proto2.TestAllTypes.Types.NestedEnum.Bar, message.DefaultNestedEnum);
Assert.AreEqual(49, message.DefaultSfixed32);
Assert.AreEqual(-50, message.DefaultSfixed64);
Assert.AreEqual(-45, message.DefaultSint32);
Assert.AreEqual(46, message.DefaultSint64);
Assert.AreEqual("hello", message.DefaultString);
Assert.AreEqual("abc", message.DefaultStringPiece);
Assert.AreEqual(43, message.DefaultUint32);
Assert.AreEqual(44, message.DefaultUint64);
Assert.False(message.HasDefaultBool);
Assert.False(message.HasDefaultBytes);
Assert.False(message.HasDefaultCord);
Assert.False(message.HasDefaultDouble);
Assert.False(message.HasDefaultFixed32);
Assert.False(message.HasDefaultFixed64);
Assert.False(message.HasDefaultFloat);
Assert.False(message.HasDefaultForeignEnum);
Assert.False(message.HasDefaultImportEnum);
Assert.False(message.HasDefaultInt32);
Assert.False(message.HasDefaultInt64);
Assert.False(message.HasDefaultNestedEnum);
Assert.False(message.HasDefaultSfixed32);
Assert.False(message.HasDefaultSfixed64);
Assert.False(message.HasDefaultSint32);
Assert.False(message.HasDefaultSint64);
Assert.False(message.HasDefaultString);
Assert.False(message.HasDefaultStringPiece);
Assert.False(message.HasDefaultUint32);
Assert.False(message.HasDefaultUint64);
}
[Test]
public void DefaultExtensionValues()
{
var message = new TestAllExtensions();
Assert.AreEqual(false, message.GetExtension(OptionalBoolExtension));
Assert.AreEqual(ByteString.Empty, message.GetExtension(OptionalBytesExtension));
Assert.AreEqual(0.0, message.GetExtension(OptionalDoubleExtension));
Assert.AreEqual(0, message.GetExtension(OptionalFixed32Extension));
Assert.AreEqual(0L, message.GetExtension(OptionalFixed64Extension));
Assert.AreEqual(0.0f, message.GetExtension(OptionalFloatExtension));
Assert.AreEqual(ForeignEnum.ForeignFoo, message.GetExtension(OptionalForeignEnumExtension));
Assert.IsNull(message.GetExtension(OptionalForeignMessageExtension));
Assert.AreEqual(ImportEnum.ImportFoo, message.GetExtension(OptionalImportEnumExtension));
Assert.IsNull(message.GetExtension(OptionalImportMessageExtension));
Assert.AreEqual(0, message.GetExtension(OptionalInt32Extension));
Assert.AreEqual(0L, message.GetExtension(OptionalInt64Extension));
Assert.AreEqual(Proto2.TestAllTypes.Types.NestedEnum.Foo, message.GetExtension(OptionalNestedEnumExtension));
Assert.IsNull(message.GetExtension(OptionalNestedMessageExtension));
Assert.IsNull(message.GetExtension(OptionalPublicImportMessageExtension));
Assert.AreEqual(0, message.GetExtension(OptionalSfixed32Extension));
Assert.AreEqual(0L, message.GetExtension(OptionalSfixed64Extension));
Assert.AreEqual(0, message.GetExtension(OptionalSint32Extension));
Assert.AreEqual(0L, message.GetExtension(OptionalSint64Extension));
Assert.AreEqual("", message.GetExtension(OptionalStringExtension));
Assert.AreEqual(0U, message.GetExtension(OptionalUint32Extension));
Assert.AreEqual(0UL, message.GetExtension(OptionalUint64Extension));
// Repeated fields
Assert.IsNull(message.GetExtension(RepeatedBoolExtension));
Assert.IsNull(message.GetExtension(RepeatedBytesExtension));
Assert.IsNull(message.GetExtension(RepeatedDoubleExtension));
Assert.IsNull(message.GetExtension(RepeatedFixed32Extension));
Assert.IsNull(message.GetExtension(RepeatedFixed64Extension));
Assert.IsNull(message.GetExtension(RepeatedFloatExtension));
Assert.IsNull(message.GetExtension(RepeatedForeignEnumExtension));
Assert.IsNull(message.GetExtension(RepeatedForeignMessageExtension));
Assert.IsNull(message.GetExtension(RepeatedImportEnumExtension));
Assert.IsNull(message.GetExtension(RepeatedImportMessageExtension));
Assert.IsNull(message.GetExtension(RepeatedNestedEnumExtension));
Assert.IsNull(message.GetExtension(RepeatedNestedMessageExtension));
Assert.IsNull(message.GetExtension(RepeatedSfixed32Extension));
Assert.IsNull(message.GetExtension(RepeatedSfixed64Extension));
Assert.IsNull(message.GetExtension(RepeatedSint32Extension));
Assert.IsNull(message.GetExtension(RepeatedSint64Extension));
Assert.IsNull(message.GetExtension(RepeatedStringExtension));
Assert.IsNull(message.GetExtension(RepeatedUint32Extension));
Assert.IsNull(message.GetExtension(RepeatedUint64Extension));
// Oneof fields
Assert.AreEqual(0, message.GetExtension(OneofUint32Extension));
Assert.AreEqual("", message.GetExtension(OneofStringExtension));
Assert.AreEqual(ByteString.Empty, message.GetExtension(OneofBytesExtension));
Assert.IsNull(message.GetExtension(OneofNestedMessageExtension));
Assert.AreEqual(true, message.GetExtension(DefaultBoolExtension));
Assert.AreEqual(ByteString.CopyFromUtf8("world"), message.GetExtension(DefaultBytesExtension));
Assert.AreEqual("123", message.GetExtension(DefaultCordExtension));
Assert.AreEqual(52e3, message.GetExtension(DefaultDoubleExtension));
Assert.AreEqual(47, message.GetExtension(DefaultFixed32Extension));
Assert.AreEqual(48, message.GetExtension(DefaultFixed64Extension));
Assert.AreEqual(51.5, message.GetExtension(DefaultFloatExtension));
Assert.AreEqual(ForeignEnum.ForeignBar, message.GetExtension(DefaultForeignEnumExtension));
Assert.AreEqual(ImportEnum.ImportBar, message.GetExtension(DefaultImportEnumExtension));
Assert.AreEqual(41, message.GetExtension(DefaultInt32Extension));
Assert.AreEqual(42, message.GetExtension(DefaultInt64Extension));
Assert.AreEqual(Proto2.TestAllTypes.Types.NestedEnum.Bar, message.GetExtension(DefaultNestedEnumExtension));
Assert.AreEqual(49, message.GetExtension(DefaultSfixed32Extension));
Assert.AreEqual(-50, message.GetExtension(DefaultSfixed64Extension));
Assert.AreEqual(-45, message.GetExtension(DefaultSint32Extension));
Assert.AreEqual(46, message.GetExtension(DefaultSint64Extension));
Assert.AreEqual("hello", message.GetExtension(DefaultStringExtension));
Assert.AreEqual("abc", message.GetExtension(DefaultStringPieceExtension));
Assert.AreEqual(43, message.GetExtension(DefaultUint32Extension));
Assert.AreEqual(44, message.GetExtension(DefaultUint64Extension));
Assert.False(message.HasExtension(DefaultBoolExtension));
Assert.False(message.HasExtension(DefaultBytesExtension));
Assert.False(message.HasExtension(DefaultCordExtension));
Assert.False(message.HasExtension(DefaultDoubleExtension));
Assert.False(message.HasExtension(DefaultFixed32Extension));
Assert.False(message.HasExtension(DefaultFixed64Extension));
Assert.False(message.HasExtension(DefaultFloatExtension));
Assert.False(message.HasExtension(DefaultForeignEnumExtension));
Assert.False(message.HasExtension(DefaultImportEnumExtension));
Assert.False(message.HasExtension(DefaultInt32Extension));
Assert.False(message.HasExtension(DefaultInt64Extension));
Assert.False(message.HasExtension(DefaultNestedEnumExtension));
Assert.False(message.HasExtension(DefaultSfixed32Extension));
Assert.False(message.HasExtension(DefaultSfixed64Extension));
Assert.False(message.HasExtension(DefaultSint32Extension));
Assert.False(message.HasExtension(DefaultSint64Extension));
Assert.False(message.HasExtension(DefaultStringExtension));
Assert.False(message.HasExtension(DefaultStringPieceExtension));
Assert.False(message.HasExtension(DefaultUint32Extension));
Assert.False(message.HasExtension(DefaultUint64Extension));
}
[Test]
public void FieldPresence()
{
var message = new TestAllTypes();
Assert.False(message.HasOptionalBool);
Assert.False(message.OptionalBool);
message.OptionalBool = true;
Assert.True(message.HasOptionalBool);
Assert.True(message.OptionalBool);
message.OptionalBool = false;
Assert.True(message.HasOptionalBool);
Assert.False(message.OptionalBool);
message.ClearOptionalBool();
Assert.False(message.HasOptionalBool);
Assert.False(message.OptionalBool);
Assert.False(message.HasDefaultBool);
Assert.True(message.DefaultBool);
message.DefaultBool = false;
Assert.True(message.HasDefaultBool);
Assert.False(message.DefaultBool);
message.DefaultBool = true;
Assert.True(message.HasDefaultBool);
Assert.True(message.DefaultBool);
message.ClearDefaultBool();
Assert.False(message.HasDefaultBool);
Assert.True(message.DefaultBool);
}
[Test]
public void RequiredFields()
{
var message = new TestRequired();
Assert.False(message.IsInitialized());
message.A = 1;
message.B = 2;
message.C = 3;
Assert.True(message.IsInitialized());
}
/// <summary>
/// Code was accidentally left in message parser that threw exceptions when missing required fields after parsing.
/// We've decided to not throw exceptions on missing fields, instead leaving it up to the consumer how they
/// want to check and handle missing fields.
/// </summary>
[Test]
public void RequiredFieldsNoThrow()
{
Assert.DoesNotThrow(() => MessageParsingHelpers.AssertReadingMessage(TestRequired.Parser, new byte[0], m => { }));
Assert.DoesNotThrow(() => MessageParsingHelpers.AssertReadingMessage(TestRequired.Parser as MessageParser, new byte[0], m => { }));
}
[Test]
public void RequiredFieldsInExtensions()
{
var message = new TestAllExtensions();
Assert.True(message.IsInitialized());
message.SetExtension(TestRequired.Extensions.Single, new TestRequired());
Assert.False(message.IsInitialized());
var extensionMessage = message.GetExtension(TestRequired.Extensions.Single);
extensionMessage.A = 1;
extensionMessage.B = 2;
extensionMessage.C = 3;
Assert.True(message.IsInitialized());
message.GetOrInitializeExtension(TestRequired.Extensions.Multi);
Assert.True(message.IsInitialized());
message.GetExtension(TestRequired.Extensions.Multi).Add(new TestRequired());
Assert.False(message.IsInitialized());
extensionMessage = message.GetExtension(TestRequired.Extensions.Multi)[0];
extensionMessage.A = 1;
extensionMessage.B = 2;
extensionMessage.C = 3;
Assert.True(message.IsInitialized());
message.SetExtension(UnittestExtensions.OptionalBoolExtension, true);
Assert.True(message.IsInitialized());
message.GetOrInitializeExtension(UnittestExtensions.RepeatedBoolExtension).Add(true);
Assert.True(message.IsInitialized());
}
[Test]
public void RequiredFieldInNestedMessageMapValue()
{
var message = new TestRequiredMap();
message.Foo.Add(0, new TestRequiredMap.Types.NestedMessage());
Assert.False(message.IsInitialized());
message.Foo[0].RequiredInt32 = 12;
Assert.True(message.IsInitialized());
}
[Test]
public void RoundTrip_Groups()
{
var message = new TestAllTypes
{
OptionalGroup = new TestAllTypes.Types.OptionalGroup
{
A = 10
},
RepeatedGroup =
{
new TestAllTypes.Types.RepeatedGroup { A = 10 },
new TestAllTypes.Types.RepeatedGroup { A = 20 },
new TestAllTypes.Types.RepeatedGroup { A = 30 }
}
};
MessageParsingHelpers.AssertWritingMessage(message);
MessageParsingHelpers.AssertRoundtrip(Proto2.TestAllTypes.Parser, message);
}
[Test]
public void RoundTrip_ExtensionGroups()
{
var message = new TestAllExtensions();
message.SetExtension(UnittestExtensions.OptionalGroupExtension, new OptionalGroup_extension { A = 10 });
message.GetOrInitializeExtension(UnittestExtensions.RepeatedGroupExtension).AddRange(new[]
{
new RepeatedGroup_extension { A = 10 },
new RepeatedGroup_extension { A = 20 },
new RepeatedGroup_extension { A = 30 }
});
MessageParsingHelpers.AssertWritingMessage(message);
MessageParsingHelpers.AssertRoundtrip(
TestAllExtensions.Parser.WithExtensionRegistry(new ExtensionRegistry() { UnittestExtensions.OptionalGroupExtension, UnittestExtensions.RepeatedGroupExtension }),
message);
}
[Test]
public void RoundTrip_NestedExtensionGroup()
{
var message = new TestGroupExtension();
message.SetExtension(TestNestedExtension.Extensions.OptionalGroupExtension, new TestNestedExtension.Types.OptionalGroup_extension { A = 10 });
MessageParsingHelpers.AssertWritingMessage(message);
MessageParsingHelpers.AssertRoundtrip(
TestGroupExtension.Parser.WithExtensionRegistry(new ExtensionRegistry() { TestNestedExtension.Extensions.OptionalGroupExtension }),
message);
}
[Test]
public void RoundTrip_ParseUsingCodedInput()
{
var message = new TestAllExtensions();
message.SetExtension(UnittestExtensions.OptionalBoolExtension, true);
byte[] bytes = message.ToByteArray();
using (CodedInputStream input = new CodedInputStream(bytes))
{
var parsed = TestAllExtensions.Parser.WithExtensionRegistry(new ExtensionRegistry() { UnittestExtensions.OptionalBoolExtension }).ParseFrom(input);
Assert.AreEqual(message, parsed);
}
}
}
}
using Google.Protobuf.TestProtos.Proto2;
using Proto2 = Google.Protobuf.TestProtos.Proto2;
using NUnit.Framework;
using static Google.Protobuf.TestProtos.Proto2.UnittestExtensions;
namespace Google.Protobuf
{
/// <summary>
/// Tests around the generated TestAllTypes message in unittest.proto
/// </summary>
public partial class GeneratedMessageTest
{
[Test]
public void DefaultProto2Values()
{
var message = new TestAllTypes();
Assert.AreEqual(false, message.OptionalBool);
Assert.AreEqual(ByteString.Empty, message.OptionalBytes);
Assert.AreEqual(0.0, message.OptionalDouble);
Assert.AreEqual(0, message.OptionalFixed32);
Assert.AreEqual(0L, message.OptionalFixed64);
Assert.AreEqual(0.0f, message.OptionalFloat);
Assert.AreEqual(ForeignEnum.ForeignFoo, message.OptionalForeignEnum);
Assert.IsNull(message.OptionalForeignMessage);
Assert.AreEqual(ImportEnum.ImportFoo, message.OptionalImportEnum);
Assert.IsNull(message.OptionalImportMessage);
Assert.AreEqual(0, message.OptionalInt32);
Assert.AreEqual(0L, message.OptionalInt64);
Assert.AreEqual(Proto2.TestAllTypes.Types.NestedEnum.Foo, message.OptionalNestedEnum);
Assert.IsNull(message.OptionalNestedMessage);
Assert.IsNull(message.OptionalPublicImportMessage);
Assert.AreEqual(0, message.OptionalSfixed32);
Assert.AreEqual(0L, message.OptionalSfixed64);
Assert.AreEqual(0, message.OptionalSint32);
Assert.AreEqual(0L, message.OptionalSint64);
Assert.AreEqual("", message.OptionalString);
Assert.AreEqual(0U, message.OptionalUint32);
Assert.AreEqual(0UL, message.OptionalUint64);
// 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.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(Proto2.TestAllTypes.OneofFieldOneofCase.None, message.OneofFieldCase);
Assert.AreEqual(0, message.OneofUint32);
Assert.AreEqual("", message.OneofString);
Assert.AreEqual(ByteString.Empty, message.OneofBytes);
Assert.IsNull(message.OneofNestedMessage);
Assert.AreEqual(true, message.DefaultBool);
Assert.AreEqual(ByteString.CopyFromUtf8("world"), message.DefaultBytes);
Assert.AreEqual("123", message.DefaultCord);
Assert.AreEqual(52e3, message.DefaultDouble);
Assert.AreEqual(47, message.DefaultFixed32);
Assert.AreEqual(48, message.DefaultFixed64);
Assert.AreEqual(51.5, message.DefaultFloat);
Assert.AreEqual(ForeignEnum.ForeignBar, message.DefaultForeignEnum);
Assert.AreEqual(ImportEnum.ImportBar, message.DefaultImportEnum);
Assert.AreEqual(41, message.DefaultInt32);
Assert.AreEqual(42, message.DefaultInt64);
Assert.AreEqual(Proto2.TestAllTypes.Types.NestedEnum.Bar, message.DefaultNestedEnum);
Assert.AreEqual(49, message.DefaultSfixed32);
Assert.AreEqual(-50, message.DefaultSfixed64);
Assert.AreEqual(-45, message.DefaultSint32);
Assert.AreEqual(46, message.DefaultSint64);
Assert.AreEqual("hello", message.DefaultString);
Assert.AreEqual("abc", message.DefaultStringPiece);
Assert.AreEqual(43, message.DefaultUint32);
Assert.AreEqual(44, message.DefaultUint64);
Assert.False(message.HasDefaultBool);
Assert.False(message.HasDefaultBytes);
Assert.False(message.HasDefaultCord);
Assert.False(message.HasDefaultDouble);
Assert.False(message.HasDefaultFixed32);
Assert.False(message.HasDefaultFixed64);
Assert.False(message.HasDefaultFloat);
Assert.False(message.HasDefaultForeignEnum);
Assert.False(message.HasDefaultImportEnum);
Assert.False(message.HasDefaultInt32);
Assert.False(message.HasDefaultInt64);
Assert.False(message.HasDefaultNestedEnum);
Assert.False(message.HasDefaultSfixed32);
Assert.False(message.HasDefaultSfixed64);
Assert.False(message.HasDefaultSint32);
Assert.False(message.HasDefaultSint64);
Assert.False(message.HasDefaultString);
Assert.False(message.HasDefaultStringPiece);
Assert.False(message.HasDefaultUint32);
Assert.False(message.HasDefaultUint64);
}
[Test]
public void DefaultExtensionValues()
{
var message = new TestAllExtensions();
Assert.AreEqual(false, message.GetExtension(OptionalBoolExtension));
Assert.AreEqual(ByteString.Empty, message.GetExtension(OptionalBytesExtension));
Assert.AreEqual(0.0, message.GetExtension(OptionalDoubleExtension));
Assert.AreEqual(0, message.GetExtension(OptionalFixed32Extension));
Assert.AreEqual(0L, message.GetExtension(OptionalFixed64Extension));
Assert.AreEqual(0.0f, message.GetExtension(OptionalFloatExtension));
Assert.AreEqual(ForeignEnum.ForeignFoo, message.GetExtension(OptionalForeignEnumExtension));
Assert.IsNull(message.GetExtension(OptionalForeignMessageExtension));
Assert.AreEqual(ImportEnum.ImportFoo, message.GetExtension(OptionalImportEnumExtension));
Assert.IsNull(message.GetExtension(OptionalImportMessageExtension));
Assert.AreEqual(0, message.GetExtension(OptionalInt32Extension));
Assert.AreEqual(0L, message.GetExtension(OptionalInt64Extension));
Assert.AreEqual(Proto2.TestAllTypes.Types.NestedEnum.Foo, message.GetExtension(OptionalNestedEnumExtension));
Assert.IsNull(message.GetExtension(OptionalNestedMessageExtension));
Assert.IsNull(message.GetExtension(OptionalPublicImportMessageExtension));
Assert.AreEqual(0, message.GetExtension(OptionalSfixed32Extension));
Assert.AreEqual(0L, message.GetExtension(OptionalSfixed64Extension));
Assert.AreEqual(0, message.GetExtension(OptionalSint32Extension));
Assert.AreEqual(0L, message.GetExtension(OptionalSint64Extension));
Assert.AreEqual("", message.GetExtension(OptionalStringExtension));
Assert.AreEqual(0U, message.GetExtension(OptionalUint32Extension));
Assert.AreEqual(0UL, message.GetExtension(OptionalUint64Extension));
// Repeated fields
Assert.IsNull(message.GetExtension(RepeatedBoolExtension));
Assert.IsNull(message.GetExtension(RepeatedBytesExtension));
Assert.IsNull(message.GetExtension(RepeatedDoubleExtension));
Assert.IsNull(message.GetExtension(RepeatedFixed32Extension));
Assert.IsNull(message.GetExtension(RepeatedFixed64Extension));
Assert.IsNull(message.GetExtension(RepeatedFloatExtension));
Assert.IsNull(message.GetExtension(RepeatedForeignEnumExtension));
Assert.IsNull(message.GetExtension(RepeatedForeignMessageExtension));
Assert.IsNull(message.GetExtension(RepeatedImportEnumExtension));
Assert.IsNull(message.GetExtension(RepeatedImportMessageExtension));
Assert.IsNull(message.GetExtension(RepeatedNestedEnumExtension));
Assert.IsNull(message.GetExtension(RepeatedNestedMessageExtension));
Assert.IsNull(message.GetExtension(RepeatedSfixed32Extension));
Assert.IsNull(message.GetExtension(RepeatedSfixed64Extension));
Assert.IsNull(message.GetExtension(RepeatedSint32Extension));
Assert.IsNull(message.GetExtension(RepeatedSint64Extension));
Assert.IsNull(message.GetExtension(RepeatedStringExtension));
Assert.IsNull(message.GetExtension(RepeatedUint32Extension));
Assert.IsNull(message.GetExtension(RepeatedUint64Extension));
// Oneof fields
Assert.AreEqual(0, message.GetExtension(OneofUint32Extension));
Assert.AreEqual("", message.GetExtension(OneofStringExtension));
Assert.AreEqual(ByteString.Empty, message.GetExtension(OneofBytesExtension));
Assert.IsNull(message.GetExtension(OneofNestedMessageExtension));
Assert.AreEqual(true, message.GetExtension(DefaultBoolExtension));
Assert.AreEqual(ByteString.CopyFromUtf8("world"), message.GetExtension(DefaultBytesExtension));
Assert.AreEqual("123", message.GetExtension(DefaultCordExtension));
Assert.AreEqual(52e3, message.GetExtension(DefaultDoubleExtension));
Assert.AreEqual(47, message.GetExtension(DefaultFixed32Extension));
Assert.AreEqual(48, message.GetExtension(DefaultFixed64Extension));
Assert.AreEqual(51.5, message.GetExtension(DefaultFloatExtension));
Assert.AreEqual(ForeignEnum.ForeignBar, message.GetExtension(DefaultForeignEnumExtension));
Assert.AreEqual(ImportEnum.ImportBar, message.GetExtension(DefaultImportEnumExtension));
Assert.AreEqual(41, message.GetExtension(DefaultInt32Extension));
Assert.AreEqual(42, message.GetExtension(DefaultInt64Extension));
Assert.AreEqual(Proto2.TestAllTypes.Types.NestedEnum.Bar, message.GetExtension(DefaultNestedEnumExtension));
Assert.AreEqual(49, message.GetExtension(DefaultSfixed32Extension));
Assert.AreEqual(-50, message.GetExtension(DefaultSfixed64Extension));
Assert.AreEqual(-45, message.GetExtension(DefaultSint32Extension));
Assert.AreEqual(46, message.GetExtension(DefaultSint64Extension));
Assert.AreEqual("hello", message.GetExtension(DefaultStringExtension));
Assert.AreEqual("abc", message.GetExtension(DefaultStringPieceExtension));
Assert.AreEqual(43, message.GetExtension(DefaultUint32Extension));
Assert.AreEqual(44, message.GetExtension(DefaultUint64Extension));
Assert.False(message.HasExtension(DefaultBoolExtension));
Assert.False(message.HasExtension(DefaultBytesExtension));
Assert.False(message.HasExtension(DefaultCordExtension));
Assert.False(message.HasExtension(DefaultDoubleExtension));
Assert.False(message.HasExtension(DefaultFixed32Extension));
Assert.False(message.HasExtension(DefaultFixed64Extension));
Assert.False(message.HasExtension(DefaultFloatExtension));
Assert.False(message.HasExtension(DefaultForeignEnumExtension));
Assert.False(message.HasExtension(DefaultImportEnumExtension));
Assert.False(message.HasExtension(DefaultInt32Extension));
Assert.False(message.HasExtension(DefaultInt64Extension));
Assert.False(message.HasExtension(DefaultNestedEnumExtension));
Assert.False(message.HasExtension(DefaultSfixed32Extension));
Assert.False(message.HasExtension(DefaultSfixed64Extension));
Assert.False(message.HasExtension(DefaultSint32Extension));
Assert.False(message.HasExtension(DefaultSint64Extension));
Assert.False(message.HasExtension(DefaultStringExtension));
Assert.False(message.HasExtension(DefaultStringPieceExtension));
Assert.False(message.HasExtension(DefaultUint32Extension));
Assert.False(message.HasExtension(DefaultUint64Extension));
}
[Test]
public void FieldPresence()
{
var message = new TestAllTypes();
Assert.False(message.HasOptionalBool);
Assert.False(message.OptionalBool);
message.OptionalBool = true;
Assert.True(message.HasOptionalBool);
Assert.True(message.OptionalBool);
message.OptionalBool = false;
Assert.True(message.HasOptionalBool);
Assert.False(message.OptionalBool);
message.ClearOptionalBool();
Assert.False(message.HasOptionalBool);
Assert.False(message.OptionalBool);
Assert.False(message.HasDefaultBool);
Assert.True(message.DefaultBool);
message.DefaultBool = false;
Assert.True(message.HasDefaultBool);
Assert.False(message.DefaultBool);
message.DefaultBool = true;
Assert.True(message.HasDefaultBool);
Assert.True(message.DefaultBool);
message.ClearDefaultBool();
Assert.False(message.HasDefaultBool);
Assert.True(message.DefaultBool);
}
[Test]
public void RequiredFields()
{
var message = new TestRequired();
Assert.False(message.IsInitialized());
message.A = 1;
message.B = 2;
message.C = 3;
Assert.True(message.IsInitialized());
}
/// <summary>
/// Code was accidentally left in message parser that threw exceptions when missing required fields after parsing.
/// We've decided to not throw exceptions on missing fields, instead leaving it up to the consumer how they
/// want to check and handle missing fields.
/// </summary>
[Test]
public void RequiredFieldsNoThrow()
{
Assert.DoesNotThrow(() => MessageParsingHelpers.AssertReadingMessage(TestRequired.Parser, new byte[0], m => { }));
Assert.DoesNotThrow(() => MessageParsingHelpers.AssertReadingMessage(TestRequired.Parser as MessageParser, new byte[0], m => { }));
}
[Test]
public void RequiredFieldsInExtensions()
{
var message = new TestAllExtensions();
Assert.True(message.IsInitialized());
message.SetExtension(TestRequired.Extensions.Single, new TestRequired());
Assert.False(message.IsInitialized());
var extensionMessage = message.GetExtension(TestRequired.Extensions.Single);
extensionMessage.A = 1;
extensionMessage.B = 2;
extensionMessage.C = 3;
Assert.True(message.IsInitialized());
message.GetOrInitializeExtension(TestRequired.Extensions.Multi);
Assert.True(message.IsInitialized());
message.GetExtension(TestRequired.Extensions.Multi).Add(new TestRequired());
Assert.False(message.IsInitialized());
extensionMessage = message.GetExtension(TestRequired.Extensions.Multi)[0];
extensionMessage.A = 1;
extensionMessage.B = 2;
extensionMessage.C = 3;
Assert.True(message.IsInitialized());
message.SetExtension(UnittestExtensions.OptionalBoolExtension, true);
Assert.True(message.IsInitialized());
message.GetOrInitializeExtension(UnittestExtensions.RepeatedBoolExtension).Add(true);
Assert.True(message.IsInitialized());
}
[Test]
public void RequiredFieldInNestedMessageMapValue()
{
var message = new TestRequiredMap();
message.Foo.Add(0, new TestRequiredMap.Types.NestedMessage());
Assert.False(message.IsInitialized());
message.Foo[0].RequiredInt32 = 12;
Assert.True(message.IsInitialized());
}
[Test]
public void RoundTrip_Groups()
{
var message = new TestAllTypes
{
OptionalGroup = new TestAllTypes.Types.OptionalGroup
{
A = 10
},
RepeatedGroup =
{
new TestAllTypes.Types.RepeatedGroup { A = 10 },
new TestAllTypes.Types.RepeatedGroup { A = 20 },
new TestAllTypes.Types.RepeatedGroup { A = 30 }
}
};
MessageParsingHelpers.AssertWritingMessage(message);
MessageParsingHelpers.AssertRoundtrip(Proto2.TestAllTypes.Parser, message);
}
[Test]
public void RoundTrip_ExtensionGroups()
{
var message = new TestAllExtensions();
message.SetExtension(UnittestExtensions.OptionalGroupExtension, new OptionalGroup_extension { A = 10 });
message.GetOrInitializeExtension(UnittestExtensions.RepeatedGroupExtension).AddRange(new[]
{
new RepeatedGroup_extension { A = 10 },
new RepeatedGroup_extension { A = 20 },
new RepeatedGroup_extension { A = 30 }
});
MessageParsingHelpers.AssertWritingMessage(message);
MessageParsingHelpers.AssertRoundtrip(
TestAllExtensions.Parser.WithExtensionRegistry(new ExtensionRegistry() { UnittestExtensions.OptionalGroupExtension, UnittestExtensions.RepeatedGroupExtension }),
message);
}
[Test]
public void RoundTrip_NestedExtensionGroup()
{
var message = new TestGroupExtension();
message.SetExtension(TestNestedExtension.Extensions.OptionalGroupExtension, new TestNestedExtension.Types.OptionalGroup_extension { A = 10 });
MessageParsingHelpers.AssertWritingMessage(message);
MessageParsingHelpers.AssertRoundtrip(
TestGroupExtension.Parser.WithExtensionRegistry(new ExtensionRegistry() { TestNestedExtension.Extensions.OptionalGroupExtension }),
message);
}
[Test]
public void RoundTrip_ParseUsingCodedInput()
{
var message = new TestAllExtensions();
message.SetExtension(UnittestExtensions.OptionalBoolExtension, true);
byte[] bytes = message.ToByteArray();
using (CodedInputStream input = new CodedInputStream(bytes))
{
var parsed = TestAllExtensions.Parser.WithExtensionRegistry(new ExtensionRegistry() { UnittestExtensions.OptionalBoolExtension }).ParseFrom(input);
Assert.AreEqual(message, parsed);
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net451;netcoreapp3.1;net60</TargetFrameworks>
<TargetFrameworks>net462;netcoreapp3.1;net60</TargetFrameworks>
<AssemblyOriginatorKeyFile>../../keys/Google.Protobuf.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
<IsPackable>False</IsPackable>
@ -14,14 +14,14 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
<PackageReference Include="NUnit" Version="3.9.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.9.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.2.1" />
</ItemGroup>
<!-- Needed for the net45 build to work on Unix. See https://github.com/dotnet/designs/pull/33 -->
<ItemGroup>
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.0" PrivateAssets="All" />
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.2" PrivateAssets="All" />
</ItemGroup>
<ItemGroup>

View File

@ -1,116 +1,132 @@
#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.Reflection;
using UnitTest.Issues.TestProtos;
using NUnit.Framework;
using System.IO;
using static UnitTest.Issues.TestProtos.OneofMerging.Types;
namespace Google.Protobuf
{
/// <summary>
/// Tests for issues which aren't easily compartmentalized into other unit tests.
/// </summary>
public class IssuesTest
{
// Issue 45
[Test]
public void FieldCalledItem()
{
ItemField message = new ItemField { Item = 3 };
FieldDescriptor field = ItemField.Descriptor.FindFieldByName("item");
Assert.NotNull(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());
}
[Test]
public void JsonNameParseTest()
{
var settings = new JsonParser.Settings(10, TypeRegistry.FromFiles(UnittestIssuesReflection.Descriptor));
var parser = new JsonParser(settings);
// It is safe to use either original field name or explicitly specified json_name
Assert.AreEqual(new TestJsonName { Name = "test", Description = "test2", Guid = "test3" },
parser.Parse<TestJsonName>("{ \"name\": \"test\", \"desc\": \"test2\", \"guid\": \"test3\" }"));
}
[Test]
public void JsonNameFormatTest()
{
var message = new TestJsonName { Name = "test", Description = "test2", Guid = "test3" };
Assert.AreEqual("{ \"name\": \"test\", \"desc\": \"test2\", \"exid\": \"test3\" }",
JsonFormatter.Default.Format(message));
}
[Test]
public void OneofMerging()
{
var message1 = new OneofMerging { Nested = new Nested { X = 10 } };
var message2 = new OneofMerging { Nested = new Nested { Y = 20 } };
var expected = new OneofMerging { Nested = new Nested { X = 10, Y = 20 } };
var merged = message1.Clone();
merged.MergeFrom(message2);
Assert.AreEqual(expected, merged);
}
// Check that a tag immediately followed by end of limit can still be read.
[Test]
public void CodedInputStream_LimitReachedRightAfterTag()
{
MemoryStream ms = new MemoryStream();
var cos = new CodedOutputStream(ms);
cos.WriteTag(11, WireFormat.WireType.Varint);
Assert.AreEqual(1, cos.Position);
cos.WriteString("some extra padding"); // ensure is currentLimit distinct from the end of the buffer.
cos.Flush();
var cis = new CodedInputStream(ms.ToArray());
cis.PushLimit(1); // make sure we reach the limit right after reading the tag.
// we still must read the tag correctly, even though the tag is at the very end of our limited input
// (which is a corner case and will most likely result in an error when trying to read value of the field
// described by this tag, but it would be a logical error not to read the tag that's actually present).
// See https://github.com/protocolbuffers/protobuf/pull/7289
cis.AssertNextTag(WireFormat.MakeTag(11, WireFormat.WireType.Varint));
}
}
}
#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.Reflection;
using UnitTest.Issues.TestProtos;
using NUnit.Framework;
using System.IO;
using static UnitTest.Issues.TestProtos.OneofMerging.Types;
namespace Google.Protobuf
{
/// <summary>
/// Tests for issues which aren't easily compartmentalized into other unit tests.
/// </summary>
public class IssuesTest
{
// Issue 45
[Test]
public void FieldCalledItem()
{
ItemField message = new ItemField { Item = 3 };
FieldDescriptor field = ItemField.Descriptor.FindFieldByName("item");
Assert.NotNull(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());
}
[Test]
public void JsonNameParseTest()
{
var settings = new JsonParser.Settings(10, TypeRegistry.FromFiles(UnittestIssuesReflection.Descriptor));
var parser = new JsonParser(settings);
// It is safe to use either original field name or explicitly specified json_name
Assert.AreEqual(new TestJsonName { Name = "test", Description = "test2", Guid = "test3" },
parser.Parse<TestJsonName>("{ \"name\": \"test\", \"desc\": \"test2\", \"guid\": \"test3\" }"));
}
[Test]
public void JsonNameFormatTest()
{
var message = new TestJsonName { Name = "test", Description = "test2", Guid = "test3" };
Assert.AreEqual("{ \"name\": \"test\", \"desc\": \"test2\", \"exid\": \"test3\" }",
JsonFormatter.Default.Format(message));
}
[Test]
public void OneofMerging()
{
var message1 = new OneofMerging { Nested = new Nested { X = 10 } };
var message2 = new OneofMerging { Nested = new Nested { Y = 20 } };
var expected = new OneofMerging { Nested = new Nested { X = 10, Y = 20 } };
var merged = message1.Clone();
merged.MergeFrom(message2);
Assert.AreEqual(expected, merged);
}
// Check that a tag immediately followed by end of limit can still be read.
[Test]
public void CodedInputStream_LimitReachedRightAfterTag()
{
MemoryStream ms = new MemoryStream();
var cos = new CodedOutputStream(ms);
cos.WriteTag(11, WireFormat.WireType.Varint);
Assert.AreEqual(1, cos.Position);
cos.WriteString("some extra padding"); // ensure is currentLimit distinct from the end of the buffer.
cos.Flush();
var cis = new CodedInputStream(ms.ToArray());
cis.PushLimit(1); // make sure we reach the limit right after reading the tag.
// we still must read the tag correctly, even though the tag is at the very end of our limited input
// (which is a corner case and will most likely result in an error when trying to read value of the field
// described by this tag, but it would be a logical error not to read the tag that's actually present).
// See https://github.com/protocolbuffers/protobuf/pull/7289
cis.AssertNextTag(WireFormat.MakeTag(11, WireFormat.WireType.Varint));
}
[Test]
public void NoneFieldInOneof()
{
var message = new OneofWithNoneField();
var emptyHashCode = message.GetHashCode();
Assert.AreEqual(OneofWithNoneField.TestOneofCase.None, message.TestCase);
message.None = "test";
Assert.AreEqual(OneofWithNoneField.TestOneofCase.None_, message.TestCase);
Assert.AreNotEqual(emptyHashCode, message.GetHashCode());
var bytes = message.ToByteArray();
var parsed = OneofWithNoneField.Parser.ParseFrom(bytes);
Assert.AreEqual(message, parsed);
Assert.AreEqual("test", parsed.None);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -60,7 +60,7 @@ namespace Google.Protobuf
var currentAssemblyDir = Path.GetDirectoryName(typeof(RefStructCompatibilityTest).GetTypeInfo().Assembly.Location);
var testProtosProjectDir = Path.GetFullPath(Path.Combine(currentAssemblyDir, "..", "..", "..", "..", "Google.Protobuf.Test.TestProtos"));
var testProtosOutputDir = (currentAssemblyDir.Contains("bin/Debug/") || currentAssemblyDir.Contains("bin\\Debug\\")) ? "bin\\Debug\\net45" : "bin\\Release\\net45";
var testProtosOutputDir = (currentAssemblyDir.Contains("bin/Debug/") || currentAssemblyDir.Contains("bin\\Debug\\")) ? "bin\\Debug\\net462" : "bin\\Release\\net462";
// If "ref struct" types are used in the generated code, compilation with an old compiler will fail with the following error:
// "XYZ is obsolete: 'Types with embedded references are not supported in this version of your compiler.'"

View File

@ -1,62 +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.Zero, NegativeEnum.MinusOne, NegativeEnum.FiveBelow },
PackedValues = { NegativeEnum.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);
}
}
}
#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.Zero, NegativeEnum.MinusOne, NegativeEnum.FiveBelow },
PackedValues = { NegativeEnum.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);
}
}
}

View File

@ -1,4 +1,4 @@
#region Copyright notice and license
#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/
@ -142,16 +142,16 @@ namespace Google.Protobuf.WellKnownTypes
}
[Test]
public void IsWrongType()
{
var any = Any.Pack(SampleMessages.CreateFullTestAllTypes());
Assert.False(any.Is(TestOneof.Descriptor));
public void IsWrongType()
{
var any = Any.Pack(SampleMessages.CreateFullTestAllTypes());
Assert.False(any.Is(TestOneof.Descriptor));
}
public void IsRightType()
{
var any = Any.Pack(SampleMessages.CreateFullTestAllTypes());
Assert.True(any.Is(TestAllTypes.Descriptor));
public void IsRightType()
{
var any = Any.Pack(SampleMessages.CreateFullTestAllTypes());
Assert.True(any.Is(TestAllTypes.Descriptor));
}
}
}

View File

@ -1,79 +1,79 @@
#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
{
/// <summary>
/// Provides a utility routine to copy small arrays much more quickly than Buffer.BlockCopy
/// </summary>
internal static class ByteArray
{
/// <summary>
/// The threshold above which you should use Buffer.BlockCopy rather than ByteArray.Copy
/// </summary>
private const int CopyThreshold = 12;
/// <summary>
/// Determines which copy routine to use based on the number of bytes to be copied.
/// </summary>
internal static void Copy(byte[] src, int srcOffset, byte[] dst, int dstOffset, int count)
{
if (count > CopyThreshold)
{
Buffer.BlockCopy(src, srcOffset, dst, dstOffset, count);
}
else
{
int stop = srcOffset + count;
for (int i = srcOffset; i < stop; i++)
{
dst[dstOffset++] = src[i];
}
}
}
/// <summary>
/// Reverses the order of bytes in the array
/// </summary>
internal static void Reverse(byte[] bytes)
{
for (int first = 0, last = bytes.Length - 1; first < last; first++, last--)
{
byte temp = bytes[first];
bytes[first] = bytes[last];
bytes[last] = temp;
}
}
}
#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
{
/// <summary>
/// Provides a utility routine to copy small arrays much more quickly than Buffer.BlockCopy
/// </summary>
internal static class ByteArray
{
/// <summary>
/// The threshold above which you should use Buffer.BlockCopy rather than ByteArray.Copy
/// </summary>
private const int CopyThreshold = 12;
/// <summary>
/// Determines which copy routine to use based on the number of bytes to be copied.
/// </summary>
internal static void Copy(byte[] src, int srcOffset, byte[] dst, int dstOffset, int count)
{
if (count > CopyThreshold)
{
Buffer.BlockCopy(src, srcOffset, dst, dstOffset, count);
}
else
{
int stop = srcOffset + count;
for (int i = srcOffset; i < stop; i++)
{
dst[dstOffset++] = src[i];
}
}
}
/// <summary>
/// Reverses the order of bytes in the array
/// </summary>
internal static void Reverse(byte[] bytes)
{
for (int first = 0, last = bytes.Length - 1; first < last; first++, last--)
{
byte temp = bytes[first];
bytes[first] = bytes[last];
bytes[last] = temp;
}
}
}
}

View File

@ -1,434 +1,434 @@
#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.Collections;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
#if !NET35
using System.Threading;
using System.Threading.Tasks;
#endif
#if NET35
using Google.Protobuf.Compatibility;
#endif
namespace Google.Protobuf
{
/// <summary>
/// Immutable array of bytes.
/// </summary>
[SecuritySafeCritical]
public sealed class ByteString : IEnumerable<byte>, IEquatable<ByteString>
{
private static readonly ByteString empty = new ByteString(new byte[0]);
private readonly ReadOnlyMemory<byte> bytes;
/// <summary>
/// Internal use only. Ensure that the provided memory is not mutated and belongs to this instance.
/// </summary>
internal static ByteString AttachBytes(ReadOnlyMemory<byte> bytes)
{
return new ByteString(bytes);
}
/// <summary>
/// Internal use only. Ensure that the provided memory is not mutated and belongs to this instance.
/// This method encapsulates converting array to memory. Reduces need for SecuritySafeCritical
/// in .NET Framework.
/// </summary>
internal static ByteString AttachBytes(byte[] bytes)
{
return AttachBytes(bytes.AsMemory());
}
/// <summary>
/// Constructs a new ByteString from the given memory. The memory is
/// *not* copied, and must not be modified after this constructor is called.
/// </summary>
private ByteString(ReadOnlyMemory<byte> bytes)
{
this.bytes = bytes;
}
/// <summary>
/// Returns an empty ByteString.
/// </summary>
public static ByteString Empty
{
get { return empty; }
}
/// <summary>
/// Returns the length of this ByteString in bytes.
/// </summary>
public int Length
{
get { return bytes.Length; }
}
/// <summary>
/// Returns <c>true</c> if this byte string is empty, <c>false</c> otherwise.
/// </summary>
public bool IsEmpty
{
get { return Length == 0; }
}
/// <summary>
/// Provides read-only access to the data of this <see cref="ByteString"/>.
/// No data is copied so this is the most efficient way of accessing.
/// </summary>
public ReadOnlySpan<byte> Span
{
get { return bytes.Span; }
}
/// <summary>
/// Provides read-only access to the data of this <see cref="ByteString"/>.
/// No data is copied so this is the most efficient way of accessing.
/// </summary>
public ReadOnlyMemory<byte> Memory
{
get { return bytes; }
}
/// <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()
{
return bytes.ToArray();
}
/// <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()
{
if (MemoryMarshal.TryGetArray(bytes, out ArraySegment<byte> segment))
{
// Fast path. ByteString was created with an array, so pass the underlying array.
return Convert.ToBase64String(segment.Array, segment.Offset, segment.Count);
}
else
{
// Slow path. BytesString is not an array. Convert memory and pass result to ToBase64String.
return Convert.ToBase64String(bytes.ToArray());
}
}
/// <summary>
/// Constructs a <see cref="ByteString" /> from the Base64 Encoded String.
/// </summary>
public static ByteString FromBase64(string bytes)
{
// By handling the empty string explicitly, we not only optimize but we fix a
// problem on CF 2.0. See issue 61 for details.
return bytes == "" ? Empty : new ByteString(Convert.FromBase64String(bytes));
}
/// <summary>
/// Constructs a <see cref="ByteString"/> from data in the given stream, synchronously.
/// </summary>
/// <remarks>If successful, <paramref name="stream"/> will be read completely, from the position
/// at the start of the call.</remarks>
/// <param name="stream">The stream to copy into a ByteString.</param>
/// <returns>A ByteString with content read from the given stream.</returns>
public static ByteString FromStream(Stream stream)
{
ProtoPreconditions.CheckNotNull(stream, nameof(stream));
int capacity = stream.CanSeek ? checked((int) (stream.Length - stream.Position)) : 0;
var memoryStream = new MemoryStream(capacity);
stream.CopyTo(memoryStream);
#if NETSTANDARD1_1 || NETSTANDARD2_0
byte[] bytes = memoryStream.ToArray();
#else
// Avoid an extra copy if we can.
byte[] bytes = memoryStream.Length == memoryStream.Capacity ? memoryStream.GetBuffer() : memoryStream.ToArray();
#endif
return AttachBytes(bytes);
}
#if !NET35
/// <summary>
/// Constructs a <see cref="ByteString"/> from data in the given stream, asynchronously.
/// </summary>
/// <remarks>If successful, <paramref name="stream"/> will be read completely, from the position
/// at the start of the call.</remarks>
/// <param name="stream">The stream to copy into a ByteString.</param>
/// <param name="cancellationToken">The cancellation token to use when reading from the stream, if any.</param>
/// <returns>A ByteString with content read from the given stream.</returns>
public static Task<ByteString> FromStreamAsync(Stream stream, CancellationToken cancellationToken = default(CancellationToken))
{
ProtoPreconditions.CheckNotNull(stream, nameof(stream));
return ByteStringAsync.FromStreamAsyncCore(stream, cancellationToken);
}
#endif
/// <summary>
/// Constructs a <see cref="ByteString" /> from the given array. The contents
/// are copied, so further modifications to the array will not
/// 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>
public static ByteString CopyFrom(params byte[] bytes)
{
return new ByteString((byte[]) bytes.Clone());
}
/// <summary>
/// Constructs a <see cref="ByteString" /> from a portion of a byte array.
/// </summary>
public static ByteString CopyFrom(byte[] bytes, int offset, int count)
{
byte[] portion = new byte[count];
ByteArray.Copy(bytes, offset, portion, 0, count);
return new ByteString(portion);
}
/// <summary>
/// Constructs a <see cref="ByteString" /> from a read only span. The contents
/// are copied, so further modifications to the span will not
/// be reflected in the returned <see cref="ByteString" />.
/// </summary>
public static ByteString CopyFrom(ReadOnlySpan<byte> bytes)
{
return new ByteString(bytes.ToArray());
}
/// <summary>
/// Creates a new <see cref="ByteString" /> by encoding the specified text with
/// the given encoding.
/// </summary>
public static ByteString CopyFrom(string text, Encoding encoding)
{
return new ByteString(encoding.GetBytes(text));
}
/// <summary>
/// Creates a new <see cref="ByteString" /> by encoding the specified text in UTF-8.
/// </summary>
public static ByteString CopyFromUtf8(string text)
{
return CopyFrom(text, Encoding.UTF8);
}
/// <summary>
/// Returns the byte at the given index.
/// </summary>
public byte this[int index]
{
get { return bytes.Span[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)
{
if (MemoryMarshal.TryGetArray(bytes, out ArraySegment<byte> segment))
{
// Fast path. ByteString was created with an array.
return encoding.GetString(segment.Array, segment.Offset, segment.Count);
}
else
{
// Slow path. BytesString is not an array. Convert memory and pass result to GetString.
// TODO: Consider using GetString overload that takes a pointer.
byte[] array = bytes.ToArray();
return encoding.GetString(array, 0, array.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()
{
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>
[SecuritySafeCritical]
public IEnumerator<byte> GetEnumerator()
{
return MemoryMarshal.ToEnumerable(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()
{
return GetEnumerator();
}
/// <summary>
/// Creates a CodedInputStream from this ByteString's data.
/// </summary>
public CodedInputStream CreateCodedInput()
{
// We trust CodedInputStream not to reveal the provided byte array or modify it
if (MemoryMarshal.TryGetArray(bytes, out ArraySegment<byte> segment) && segment.Count == bytes.Length)
{
// Fast path. ByteString was created with a complete array.
return new CodedInputStream(segment.Array, segment.Offset, segment.Count);
}
else
{
// Slow path. BytesString is not an array, or is a slice of an array.
// Convert memory and pass result to WriteRawBytes.
return new CodedInputStream(bytes.ToArray());
}
}
/// <summary>
/// Compares two byte strings for equality.
/// </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)
{
if (ReferenceEquals(lhs, rhs))
{
return true;
}
if (ReferenceEquals(lhs, null) || ReferenceEquals(rhs, null))
{
return false;
}
return lhs.bytes.Span.SequenceEqual(rhs.bytes.Span);
}
/// <summary>
/// Compares two byte strings for inequality.
/// </summary>
/// <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)
{
return !(lhs == rhs);
}
/// <summary>
/// Compares this byte string with another object.
/// </summary>
/// <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>
[SecuritySafeCritical]
public override bool Equals(object obj)
{
return this == (obj as ByteString);
}
/// <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>
[SecuritySafeCritical]
public override int GetHashCode()
{
ReadOnlySpan<byte> b = bytes.Span;
int ret = 23;
for (int i = 0; i < b.Length; i++)
{
ret = (ret * 31) + b[i];
}
return ret;
}
/// <summary>
/// Compares this byte string with another.
/// </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>
/// Copies the entire byte array to the destination array provided at the offset specified.
/// </summary>
public void CopyTo(byte[] array, int position)
{
bytes.CopyTo(array.AsMemory(position));
}
/// <summary>
/// Writes the entire byte array to the provided stream
/// </summary>
public void WriteTo(Stream outputStream)
{
if (MemoryMarshal.TryGetArray(bytes, out ArraySegment<byte> segment))
{
// Fast path. ByteString was created with an array, so pass the underlying array.
outputStream.Write(segment.Array, segment.Offset, segment.Count);
}
else
{
// Slow path. BytesString is not an array. Convert memory and pass result to WriteRawBytes.
var array = bytes.ToArray();
outputStream.Write(array, 0, array.Length);
}
}
}
#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.Collections;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
#if !NET35
using System.Threading;
using System.Threading.Tasks;
#endif
#if NET35
using Google.Protobuf.Compatibility;
#endif
namespace Google.Protobuf
{
/// <summary>
/// Immutable array of bytes.
/// </summary>
[SecuritySafeCritical]
public sealed class ByteString : IEnumerable<byte>, IEquatable<ByteString>
{
private static readonly ByteString empty = new ByteString(new byte[0]);
private readonly ReadOnlyMemory<byte> bytes;
/// <summary>
/// Internal use only. Ensure that the provided memory is not mutated and belongs to this instance.
/// </summary>
internal static ByteString AttachBytes(ReadOnlyMemory<byte> bytes)
{
return new ByteString(bytes);
}
/// <summary>
/// Internal use only. Ensure that the provided memory is not mutated and belongs to this instance.
/// This method encapsulates converting array to memory. Reduces need for SecuritySafeCritical
/// in .NET Framework.
/// </summary>
internal static ByteString AttachBytes(byte[] bytes)
{
return AttachBytes(bytes.AsMemory());
}
/// <summary>
/// Constructs a new ByteString from the given memory. The memory is
/// *not* copied, and must not be modified after this constructor is called.
/// </summary>
private ByteString(ReadOnlyMemory<byte> bytes)
{
this.bytes = bytes;
}
/// <summary>
/// Returns an empty ByteString.
/// </summary>
public static ByteString Empty
{
get { return empty; }
}
/// <summary>
/// Returns the length of this ByteString in bytes.
/// </summary>
public int Length
{
get { return bytes.Length; }
}
/// <summary>
/// Returns <c>true</c> if this byte string is empty, <c>false</c> otherwise.
/// </summary>
public bool IsEmpty
{
get { return Length == 0; }
}
/// <summary>
/// Provides read-only access to the data of this <see cref="ByteString"/>.
/// No data is copied so this is the most efficient way of accessing.
/// </summary>
public ReadOnlySpan<byte> Span
{
get { return bytes.Span; }
}
/// <summary>
/// Provides read-only access to the data of this <see cref="ByteString"/>.
/// No data is copied so this is the most efficient way of accessing.
/// </summary>
public ReadOnlyMemory<byte> Memory
{
get { return bytes; }
}
/// <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()
{
return bytes.ToArray();
}
/// <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()
{
if (MemoryMarshal.TryGetArray(bytes, out ArraySegment<byte> segment))
{
// Fast path. ByteString was created with an array, so pass the underlying array.
return Convert.ToBase64String(segment.Array, segment.Offset, segment.Count);
}
else
{
// Slow path. BytesString is not an array. Convert memory and pass result to ToBase64String.
return Convert.ToBase64String(bytes.ToArray());
}
}
/// <summary>
/// Constructs a <see cref="ByteString" /> from the Base64 Encoded String.
/// </summary>
public static ByteString FromBase64(string bytes)
{
// By handling the empty string explicitly, we not only optimize but we fix a
// problem on CF 2.0. See issue 61 for details.
return bytes == "" ? Empty : new ByteString(Convert.FromBase64String(bytes));
}
/// <summary>
/// Constructs a <see cref="ByteString"/> from data in the given stream, synchronously.
/// </summary>
/// <remarks>If successful, <paramref name="stream"/> will be read completely, from the position
/// at the start of the call.</remarks>
/// <param name="stream">The stream to copy into a ByteString.</param>
/// <returns>A ByteString with content read from the given stream.</returns>
public static ByteString FromStream(Stream stream)
{
ProtoPreconditions.CheckNotNull(stream, nameof(stream));
int capacity = stream.CanSeek ? checked((int) (stream.Length - stream.Position)) : 0;
var memoryStream = new MemoryStream(capacity);
stream.CopyTo(memoryStream);
#if NETSTANDARD1_1 || NETSTANDARD2_0
byte[] bytes = memoryStream.ToArray();
#else
// Avoid an extra copy if we can.
byte[] bytes = memoryStream.Length == memoryStream.Capacity ? memoryStream.GetBuffer() : memoryStream.ToArray();
#endif
return AttachBytes(bytes);
}
#if !NET35
/// <summary>
/// Constructs a <see cref="ByteString"/> from data in the given stream, asynchronously.
/// </summary>
/// <remarks>If successful, <paramref name="stream"/> will be read completely, from the position
/// at the start of the call.</remarks>
/// <param name="stream">The stream to copy into a ByteString.</param>
/// <param name="cancellationToken">The cancellation token to use when reading from the stream, if any.</param>
/// <returns>A ByteString with content read from the given stream.</returns>
public static Task<ByteString> FromStreamAsync(Stream stream, CancellationToken cancellationToken = default(CancellationToken))
{
ProtoPreconditions.CheckNotNull(stream, nameof(stream));
return ByteStringAsync.FromStreamAsyncCore(stream, cancellationToken);
}
#endif
/// <summary>
/// Constructs a <see cref="ByteString" /> from the given array. The contents
/// are copied, so further modifications to the array will not
/// 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>
public static ByteString CopyFrom(params byte[] bytes)
{
return new ByteString((byte[]) bytes.Clone());
}
/// <summary>
/// Constructs a <see cref="ByteString" /> from a portion of a byte array.
/// </summary>
public static ByteString CopyFrom(byte[] bytes, int offset, int count)
{
byte[] portion = new byte[count];
ByteArray.Copy(bytes, offset, portion, 0, count);
return new ByteString(portion);
}
/// <summary>
/// Constructs a <see cref="ByteString" /> from a read only span. The contents
/// are copied, so further modifications to the span will not
/// be reflected in the returned <see cref="ByteString" />.
/// </summary>
public static ByteString CopyFrom(ReadOnlySpan<byte> bytes)
{
return new ByteString(bytes.ToArray());
}
/// <summary>
/// Creates a new <see cref="ByteString" /> by encoding the specified text with
/// the given encoding.
/// </summary>
public static ByteString CopyFrom(string text, Encoding encoding)
{
return new ByteString(encoding.GetBytes(text));
}
/// <summary>
/// Creates a new <see cref="ByteString" /> by encoding the specified text in UTF-8.
/// </summary>
public static ByteString CopyFromUtf8(string text)
{
return CopyFrom(text, Encoding.UTF8);
}
/// <summary>
/// Returns the byte at the given index.
/// </summary>
public byte this[int index]
{
get { return bytes.Span[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)
{
if (MemoryMarshal.TryGetArray(bytes, out ArraySegment<byte> segment))
{
// Fast path. ByteString was created with an array.
return encoding.GetString(segment.Array, segment.Offset, segment.Count);
}
else
{
// Slow path. BytesString is not an array. Convert memory and pass result to GetString.
// TODO: Consider using GetString overload that takes a pointer.
byte[] array = bytes.ToArray();
return encoding.GetString(array, 0, array.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()
{
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>
[SecuritySafeCritical]
public IEnumerator<byte> GetEnumerator()
{
return MemoryMarshal.ToEnumerable(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()
{
return GetEnumerator();
}
/// <summary>
/// Creates a CodedInputStream from this ByteString's data.
/// </summary>
public CodedInputStream CreateCodedInput()
{
// We trust CodedInputStream not to reveal the provided byte array or modify it
if (MemoryMarshal.TryGetArray(bytes, out ArraySegment<byte> segment) && segment.Count == bytes.Length)
{
// Fast path. ByteString was created with a complete array.
return new CodedInputStream(segment.Array, segment.Offset, segment.Count);
}
else
{
// Slow path. BytesString is not an array, or is a slice of an array.
// Convert memory and pass result to WriteRawBytes.
return new CodedInputStream(bytes.ToArray());
}
}
/// <summary>
/// Compares two byte strings for equality.
/// </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)
{
if (ReferenceEquals(lhs, rhs))
{
return true;
}
if (ReferenceEquals(lhs, null) || ReferenceEquals(rhs, null))
{
return false;
}
return lhs.bytes.Span.SequenceEqual(rhs.bytes.Span);
}
/// <summary>
/// Compares two byte strings for inequality.
/// </summary>
/// <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)
{
return !(lhs == rhs);
}
/// <summary>
/// Compares this byte string with another object.
/// </summary>
/// <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>
[SecuritySafeCritical]
public override bool Equals(object obj)
{
return this == (obj as ByteString);
}
/// <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>
[SecuritySafeCritical]
public override int GetHashCode()
{
ReadOnlySpan<byte> b = bytes.Span;
int ret = 23;
for (int i = 0; i < b.Length; i++)
{
ret = (ret * 31) + b[i];
}
return ret;
}
/// <summary>
/// Compares this byte string with another.
/// </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>
/// Copies the entire byte array to the destination array provided at the offset specified.
/// </summary>
public void CopyTo(byte[] array, int position)
{
bytes.CopyTo(array.AsMemory(position));
}
/// <summary>
/// Writes the entire byte array to the provided stream
/// </summary>
public void WriteTo(Stream outputStream)
{
if (MemoryMarshal.TryGetArray(bytes, out ArraySegment<byte> segment))
{
// Fast path. ByteString was created with an array, so pass the underlying array.
outputStream.Write(segment.Array, segment.Offset, segment.Count);
}
else
{
// Slow path. BytesString is not an array. Convert memory and pass result to WriteRawBytes.
var array = bytes.ToArray();
outputStream.Write(array, 0, array.Length);
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,308 +1,308 @@
#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;
internal const int DoubleSize = LittleEndian64Size;
internal const int FloatSize = LittleEndian32Size;
internal const int BoolSize = 1;
/// <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 DoubleSize;
}
/// <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 FloatSize;
}
/// <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 BoolSize;
}
/// <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 = WritingPrimitives.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(WritingPrimitives.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(WritingPrimitives.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));
}
}
#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;
internal const int DoubleSize = LittleEndian64Size;
internal const int FloatSize = LittleEndian32Size;
internal const int BoolSize = 1;
/// <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 DoubleSize;
}
/// <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 FloatSize;
}
/// <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 BoolSize;
}
/// <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 = WritingPrimitives.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(WritingPrimitives.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(WritingPrimitives.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));
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,147 +1,147 @@
#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.Collections;
using System.Collections.Generic;
namespace Google.Protobuf.Collections
{
/// <summary>
/// Read-only wrapper around another dictionary.
/// </summary>
internal sealed class ReadOnlyDictionary<TKey, TValue> : IDictionary<TKey, TValue>
{
private readonly IDictionary<TKey, TValue> wrapped;
public ReadOnlyDictionary(IDictionary<TKey, TValue> wrapped)
{
this.wrapped = wrapped;
}
public void Add(TKey key, TValue value)
{
throw new InvalidOperationException();
}
public bool ContainsKey(TKey key)
{
return wrapped.ContainsKey(key);
}
public ICollection<TKey> Keys
{
get { return wrapped.Keys; }
}
public bool Remove(TKey key)
{
throw new InvalidOperationException();
}
public bool TryGetValue(TKey key, out TValue value)
{
return wrapped.TryGetValue(key, out value);
}
public ICollection<TValue> Values
{
get { return wrapped.Values; }
}
public TValue this[TKey key]
{
get { return wrapped[key]; }
set { throw new InvalidOperationException(); }
}
public void Add(KeyValuePair<TKey, TValue> item)
{
throw new InvalidOperationException();
}
public void Clear()
{
throw new InvalidOperationException();
}
public bool Contains(KeyValuePair<TKey, TValue> item)
{
return wrapped.Contains(item);
}
public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
{
wrapped.CopyTo(array, arrayIndex);
}
public int Count
{
get { return wrapped.Count; }
}
public bool IsReadOnly
{
get { return true; }
}
public bool Remove(KeyValuePair<TKey, TValue> item)
{
throw new InvalidOperationException();
}
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
{
return wrapped.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable) wrapped).GetEnumerator();
}
public override bool Equals(object obj)
{
return wrapped.Equals(obj);
}
public override int GetHashCode()
{
return wrapped.GetHashCode();
}
public override string ToString()
{
return wrapped.ToString();
}
}
#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.Collections;
using System.Collections.Generic;
namespace Google.Protobuf.Collections
{
/// <summary>
/// Read-only wrapper around another dictionary.
/// </summary>
internal sealed class ReadOnlyDictionary<TKey, TValue> : IDictionary<TKey, TValue>
{
private readonly IDictionary<TKey, TValue> wrapped;
public ReadOnlyDictionary(IDictionary<TKey, TValue> wrapped)
{
this.wrapped = wrapped;
}
public void Add(TKey key, TValue value)
{
throw new InvalidOperationException();
}
public bool ContainsKey(TKey key)
{
return wrapped.ContainsKey(key);
}
public ICollection<TKey> Keys
{
get { return wrapped.Keys; }
}
public bool Remove(TKey key)
{
throw new InvalidOperationException();
}
public bool TryGetValue(TKey key, out TValue value)
{
return wrapped.TryGetValue(key, out value);
}
public ICollection<TValue> Values
{
get { return wrapped.Values; }
}
public TValue this[TKey key]
{
get { return wrapped[key]; }
set { throw new InvalidOperationException(); }
}
public void Add(KeyValuePair<TKey, TValue> item)
{
throw new InvalidOperationException();
}
public void Clear()
{
throw new InvalidOperationException();
}
public bool Contains(KeyValuePair<TKey, TValue> item)
{
return wrapped.Contains(item);
}
public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
{
wrapped.CopyTo(array, arrayIndex);
}
public int Count
{
get { return wrapped.Count; }
}
public bool IsReadOnly
{
get { return true; }
}
public bool Remove(KeyValuePair<TKey, TValue> item)
{
throw new InvalidOperationException();
}
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
{
return wrapped.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable) wrapped).GetEnumerator();
}
public override bool Equals(object obj)
{
return wrapped.Equals(obj);
}
public override int GetHashCode()
{
return wrapped.GetHashCode();
}
public override string ToString()
{
return wrapped.ToString();
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -77,7 +77,7 @@ namespace Google.Protobuf
this.codec = codec;
}
internal TValue DefaultValue => codec.DefaultValue;
internal TValue DefaultValue => codec != null ? codec.DefaultValue : default(TValue);
internal override Type TargetType => typeof(TTarget);

View File

@ -1,377 +1,428 @@
#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.Collections.Generic;
using System.Linq;
using System.Security;
namespace Google.Protobuf
{
/// <summary>
/// Methods for managing <see cref="ExtensionSet{TTarget}"/>s with null checking.
///
/// Most users will not use this class directly and its API is experimental and subject to change.
/// </summary>
public static class ExtensionSet
{
private static bool TryGetValue<TTarget>(ref ExtensionSet<TTarget> set, Extension extension, out IExtensionValue value) where TTarget : IExtendableMessage<TTarget>
{
if (set == null)
{
value = null;
return false;
}
return set.ValuesByNumber.TryGetValue(extension.FieldNumber, out value);
}
/// <summary>
/// Gets the value of the specified extension
/// </summary>
public static TValue Get<TTarget, TValue>(ref ExtensionSet<TTarget> set, Extension<TTarget, TValue> extension) where TTarget : IExtendableMessage<TTarget>
{
IExtensionValue value;
if (TryGetValue(ref set, extension, out value))
{
return ((ExtensionValue<TValue>)value).GetValue();
}
else
{
return extension.DefaultValue;
}
}
/// <summary>
/// Gets the value of the specified repeated extension or null if it doesn't exist in this set
/// </summary>
public static RepeatedField<TValue> Get<TTarget, TValue>(ref ExtensionSet<TTarget> set, RepeatedExtension<TTarget, TValue> extension) where TTarget : IExtendableMessage<TTarget>
{
IExtensionValue value;
if (TryGetValue(ref set, extension, out value))
{
return ((RepeatedExtensionValue<TValue>)value).GetValue();
}
else
{
return null;
}
}
/// <summary>
/// Gets the value of the specified repeated extension, registering it if it doesn't exist
/// </summary>
public static RepeatedField<TValue> GetOrInitialize<TTarget, TValue>(ref ExtensionSet<TTarget> set, RepeatedExtension<TTarget, TValue> extension) where TTarget : IExtendableMessage<TTarget>
{
IExtensionValue value;
if (set == null)
{
value = extension.CreateValue();
set = new ExtensionSet<TTarget>();
set.ValuesByNumber.Add(extension.FieldNumber, value);
}
else
{
if (!set.ValuesByNumber.TryGetValue(extension.FieldNumber, out value))
{
value = extension.CreateValue();
set.ValuesByNumber.Add(extension.FieldNumber, value);
}
}
return ((RepeatedExtensionValue<TValue>)value).GetValue();
}
/// <summary>
/// Sets the value of the specified extension. This will make a new instance of ExtensionSet if the set is null.
/// </summary>
public static void Set<TTarget, TValue>(ref ExtensionSet<TTarget> set, Extension<TTarget, TValue> extension, TValue value) where TTarget : IExtendableMessage<TTarget>
{
ProtoPreconditions.CheckNotNullUnconstrained(value, nameof(value));
IExtensionValue extensionValue;
if (set == null)
{
extensionValue = extension.CreateValue();
set = new ExtensionSet<TTarget>();
set.ValuesByNumber.Add(extension.FieldNumber, extensionValue);
}
else
{
if (!set.ValuesByNumber.TryGetValue(extension.FieldNumber, out extensionValue))
{
extensionValue = extension.CreateValue();
set.ValuesByNumber.Add(extension.FieldNumber, extensionValue);
}
}
((ExtensionValue<TValue>)extensionValue).SetValue(value);
}
/// <summary>
/// Gets whether the value of the specified extension is set
/// </summary>
public static bool Has<TTarget, TValue>(ref ExtensionSet<TTarget> set, Extension<TTarget, TValue> extension) where TTarget : IExtendableMessage<TTarget>
{
IExtensionValue value;
return TryGetValue(ref set, extension, out value);
}
/// <summary>
/// Clears the value of the specified extension
/// </summary>
public static void Clear<TTarget, TValue>(ref ExtensionSet<TTarget> set, Extension<TTarget, TValue> extension) where TTarget : IExtendableMessage<TTarget>
{
if (set == null)
{
return;
}
set.ValuesByNumber.Remove(extension.FieldNumber);
if (set.ValuesByNumber.Count == 0)
{
set = null;
}
}
/// <summary>
/// Clears the value of the specified extension
/// </summary>
public static void Clear<TTarget, TValue>(ref ExtensionSet<TTarget> set, RepeatedExtension<TTarget, TValue> extension) where TTarget : IExtendableMessage<TTarget>
{
if (set == null)
{
return;
}
set.ValuesByNumber.Remove(extension.FieldNumber);
if (set.ValuesByNumber.Count == 0)
{
set = null;
}
}
/// <summary>
/// Tries to merge a field from the coded input, returning true if the field was merged.
/// If the set is null or the field was not otherwise merged, this returns false.
/// </summary>
public static bool TryMergeFieldFrom<TTarget>(ref ExtensionSet<TTarget> set, CodedInputStream stream) where TTarget : IExtendableMessage<TTarget>
{
ParseContext.Initialize(stream, out ParseContext ctx);
try
{
return TryMergeFieldFrom<TTarget>(ref set, ref ctx);
}
finally
{
ctx.CopyStateTo(stream);
}
}
/// <summary>
/// Tries to merge a field from the coded input, returning true if the field was merged.
/// If the set is null or the field was not otherwise merged, this returns false.
/// </summary>
public static bool TryMergeFieldFrom<TTarget>(ref ExtensionSet<TTarget> set, ref ParseContext ctx) where TTarget : IExtendableMessage<TTarget>
{
Extension extension;
int lastFieldNumber = WireFormat.GetTagFieldNumber(ctx.LastTag);
IExtensionValue extensionValue;
if (set != null && set.ValuesByNumber.TryGetValue(lastFieldNumber, out extensionValue))
{
extensionValue.MergeFrom(ref ctx);
return true;
}
else if (ctx.ExtensionRegistry != null && ctx.ExtensionRegistry.ContainsInputField(ctx.LastTag, typeof(TTarget), out extension))
{
IExtensionValue value = extension.CreateValue();
value.MergeFrom(ref ctx);
set = (set ?? new ExtensionSet<TTarget>());
set.ValuesByNumber.Add(extension.FieldNumber, value);
return true;
}
else
{
return false;
}
}
/// <summary>
/// Merges the second set into the first set, creating a new instance if first is null
/// </summary>
public static void MergeFrom<TTarget>(ref ExtensionSet<TTarget> first, ExtensionSet<TTarget> second) where TTarget : IExtendableMessage<TTarget>
{
if (second == null)
{
return;
}
if (first == null)
{
first = new ExtensionSet<TTarget>();
}
foreach (var pair in second.ValuesByNumber)
{
IExtensionValue value;
if (first.ValuesByNumber.TryGetValue(pair.Key, out value))
{
value.MergeFrom(pair.Value);
}
else
{
var cloned = pair.Value.Clone();
first.ValuesByNumber[pair.Key] = cloned;
}
}
}
/// <summary>
/// Clones the set into a new set. If the set is null, this returns null
/// </summary>
public static ExtensionSet<TTarget> Clone<TTarget>(ExtensionSet<TTarget> set) where TTarget : IExtendableMessage<TTarget>
{
if (set == null)
{
return null;
}
var newSet = new ExtensionSet<TTarget>();
foreach (var pair in set.ValuesByNumber)
{
var cloned = pair.Value.Clone();
newSet.ValuesByNumber[pair.Key] = cloned;
}
return newSet;
}
}
/// <summary>
/// Used for keeping track of extensions in messages.
/// <see cref="IExtendableMessage{T}"/> methods route to this set.
///
/// Most users will not need to use this class directly
/// </summary>
/// <typeparam name="TTarget">The message type that extensions in this set target</typeparam>
public sealed class ExtensionSet<TTarget> where TTarget : IExtendableMessage<TTarget>
{
internal Dictionary<int, IExtensionValue> ValuesByNumber { get; } = new Dictionary<int, IExtensionValue>();
/// <summary>
/// Gets a hash code of the set
/// </summary>
public override int GetHashCode()
{
int ret = typeof(TTarget).GetHashCode();
foreach (KeyValuePair<int, IExtensionValue> field in ValuesByNumber)
{
// Use ^ here to make the field order irrelevant.
int hash = field.Key.GetHashCode() ^ field.Value.GetHashCode();
ret ^= hash;
}
return ret;
}
/// <summary>
/// Returns whether this set is equal to the other object
/// </summary>
public override bool Equals(object other)
{
if (ReferenceEquals(this, other))
{
return true;
}
ExtensionSet<TTarget> otherSet = other as ExtensionSet<TTarget>;
if (ValuesByNumber.Count != otherSet.ValuesByNumber.Count)
{
return false;
}
foreach (var pair in ValuesByNumber)
{
IExtensionValue secondValue;
if (!otherSet.ValuesByNumber.TryGetValue(pair.Key, out secondValue))
{
return false;
}
if (!pair.Value.Equals(secondValue))
{
return false;
}
}
return true;
}
/// <summary>
/// Calculates the size of this extension set
/// </summary>
public int CalculateSize()
{
int size = 0;
foreach (var value in ValuesByNumber.Values)
{
size += value.CalculateSize();
}
return size;
}
/// <summary>
/// Writes the extension values in this set to the output stream
/// </summary>
public void WriteTo(CodedOutputStream stream)
{
WriteContext.Initialize(stream, out WriteContext ctx);
try
{
WriteTo(ref ctx);
}
finally
{
ctx.CopyStateTo(stream);
}
}
/// <summary>
/// Writes the extension values in this set to the write context
/// </summary>
[SecuritySafeCritical]
public void WriteTo(ref WriteContext ctx)
{
foreach (var value in ValuesByNumber.Values)
{
value.WriteTo(ref ctx);
}
}
internal bool IsInitialized()
{
return ValuesByNumber.Values.All(v => v.IsInitialized());
}
}
}
#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.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Security;
namespace Google.Protobuf
{
/// <summary>
/// Methods for managing <see cref="ExtensionSet{TTarget}"/>s with null checking.
///
/// Most users will not use this class directly and its API is experimental and subject to change.
/// </summary>
public static class ExtensionSet
{
private static bool TryGetValue<TTarget>(ref ExtensionSet<TTarget> set, Extension extension, out IExtensionValue value) where TTarget : IExtendableMessage<TTarget>
{
if (set == null)
{
value = null;
return false;
}
return set.ValuesByNumber.TryGetValue(extension.FieldNumber, out value);
}
/// <summary>
/// Gets the value of the specified extension
/// </summary>
public static TValue Get<TTarget, TValue>(ref ExtensionSet<TTarget> set, Extension<TTarget, TValue> extension) where TTarget : IExtendableMessage<TTarget>
{
IExtensionValue value;
if (TryGetValue(ref set, extension, out value))
{
// The stored ExtensionValue can be a different type to what is being requested.
// This happens when the same extension proto is compiled in different assemblies.
// To allow consuming assemblies to still get the value when the TValue type is
// different, this get method:
// 1. Attempts to cast the value to the expected ExtensionValue<TValue>.
// This is the usual case. It is used first because it avoids possibly boxing the value.
// 2. Fallback to get the value as object from IExtensionValue then casting.
// This allows for someone to specify a TValue of object. They can then convert
// the values to bytes and reparse using expected value.
// 3. If neither of these work, throw a user friendly error that the types aren't compatible.
if (value is ExtensionValue<TValue> extensionValue)
{
return extensionValue.GetValue();
}
else if (value.GetValue() is TValue underlyingValue)
{
return underlyingValue;
}
else
{
var valueType = value.GetType().GetTypeInfo();
if (valueType.IsGenericType && valueType.GetGenericTypeDefinition() == typeof(ExtensionValue<>))
{
var storedType = valueType.GenericTypeArguments[0];
throw new InvalidOperationException(
"The stored extension value has a type of '" + storedType.AssemblyQualifiedName + "'. " +
"This a different from the requested type of '" + typeof(TValue).AssemblyQualifiedName + "'.");
}
else
{
throw new InvalidOperationException("Unexpected extension value type: " + valueType.AssemblyQualifiedName);
}
}
}
else
{
return extension.DefaultValue;
}
}
/// <summary>
/// Gets the value of the specified repeated extension or null if it doesn't exist in this set
/// </summary>
public static RepeatedField<TValue> Get<TTarget, TValue>(ref ExtensionSet<TTarget> set, RepeatedExtension<TTarget, TValue> extension) where TTarget : IExtendableMessage<TTarget>
{
IExtensionValue value;
if (TryGetValue(ref set, extension, out value))
{
if (value is RepeatedExtensionValue<TValue> extensionValue)
{
return extensionValue.GetValue();
}
else
{
var valueType = value.GetType().GetTypeInfo();
if (valueType.IsGenericType && valueType.GetGenericTypeDefinition() == typeof(RepeatedExtensionValue<>))
{
var storedType = valueType.GenericTypeArguments[0];
throw new InvalidOperationException(
"The stored extension value has a type of '" + storedType.AssemblyQualifiedName + "'. " +
"This a different from the requested type of '" + typeof(TValue).AssemblyQualifiedName + "'.");
}
else
{
throw new InvalidOperationException("Unexpected extension value type: " + valueType.AssemblyQualifiedName);
}
}
}
else
{
return null;
}
}
/// <summary>
/// Gets the value of the specified repeated extension, registering it if it doesn't exist
/// </summary>
public static RepeatedField<TValue> GetOrInitialize<TTarget, TValue>(ref ExtensionSet<TTarget> set, RepeatedExtension<TTarget, TValue> extension) where TTarget : IExtendableMessage<TTarget>
{
IExtensionValue value;
if (set == null)
{
value = extension.CreateValue();
set = new ExtensionSet<TTarget>();
set.ValuesByNumber.Add(extension.FieldNumber, value);
}
else
{
if (!set.ValuesByNumber.TryGetValue(extension.FieldNumber, out value))
{
value = extension.CreateValue();
set.ValuesByNumber.Add(extension.FieldNumber, value);
}
}
return ((RepeatedExtensionValue<TValue>)value).GetValue();
}
/// <summary>
/// Sets the value of the specified extension. This will make a new instance of ExtensionSet if the set is null.
/// </summary>
public static void Set<TTarget, TValue>(ref ExtensionSet<TTarget> set, Extension<TTarget, TValue> extension, TValue value) where TTarget : IExtendableMessage<TTarget>
{
ProtoPreconditions.CheckNotNullUnconstrained(value, nameof(value));
IExtensionValue extensionValue;
if (set == null)
{
extensionValue = extension.CreateValue();
set = new ExtensionSet<TTarget>();
set.ValuesByNumber.Add(extension.FieldNumber, extensionValue);
}
else
{
if (!set.ValuesByNumber.TryGetValue(extension.FieldNumber, out extensionValue))
{
extensionValue = extension.CreateValue();
set.ValuesByNumber.Add(extension.FieldNumber, extensionValue);
}
}
((ExtensionValue<TValue>)extensionValue).SetValue(value);
}
/// <summary>
/// Gets whether the value of the specified extension is set
/// </summary>
public static bool Has<TTarget, TValue>(ref ExtensionSet<TTarget> set, Extension<TTarget, TValue> extension) where TTarget : IExtendableMessage<TTarget>
{
IExtensionValue value;
return TryGetValue(ref set, extension, out value);
}
/// <summary>
/// Clears the value of the specified extension
/// </summary>
public static void Clear<TTarget, TValue>(ref ExtensionSet<TTarget> set, Extension<TTarget, TValue> extension) where TTarget : IExtendableMessage<TTarget>
{
if (set == null)
{
return;
}
set.ValuesByNumber.Remove(extension.FieldNumber);
if (set.ValuesByNumber.Count == 0)
{
set = null;
}
}
/// <summary>
/// Clears the value of the specified extension
/// </summary>
public static void Clear<TTarget, TValue>(ref ExtensionSet<TTarget> set, RepeatedExtension<TTarget, TValue> extension) where TTarget : IExtendableMessage<TTarget>
{
if (set == null)
{
return;
}
set.ValuesByNumber.Remove(extension.FieldNumber);
if (set.ValuesByNumber.Count == 0)
{
set = null;
}
}
/// <summary>
/// Tries to merge a field from the coded input, returning true if the field was merged.
/// If the set is null or the field was not otherwise merged, this returns false.
/// </summary>
public static bool TryMergeFieldFrom<TTarget>(ref ExtensionSet<TTarget> set, CodedInputStream stream) where TTarget : IExtendableMessage<TTarget>
{
ParseContext.Initialize(stream, out ParseContext ctx);
try
{
return TryMergeFieldFrom<TTarget>(ref set, ref ctx);
}
finally
{
ctx.CopyStateTo(stream);
}
}
/// <summary>
/// Tries to merge a field from the coded input, returning true if the field was merged.
/// If the set is null or the field was not otherwise merged, this returns false.
/// </summary>
public static bool TryMergeFieldFrom<TTarget>(ref ExtensionSet<TTarget> set, ref ParseContext ctx) where TTarget : IExtendableMessage<TTarget>
{
Extension extension;
int lastFieldNumber = WireFormat.GetTagFieldNumber(ctx.LastTag);
IExtensionValue extensionValue;
if (set != null && set.ValuesByNumber.TryGetValue(lastFieldNumber, out extensionValue))
{
extensionValue.MergeFrom(ref ctx);
return true;
}
else if (ctx.ExtensionRegistry != null && ctx.ExtensionRegistry.ContainsInputField(ctx.LastTag, typeof(TTarget), out extension))
{
IExtensionValue value = extension.CreateValue();
value.MergeFrom(ref ctx);
set = (set ?? new ExtensionSet<TTarget>());
set.ValuesByNumber.Add(extension.FieldNumber, value);
return true;
}
else
{
return false;
}
}
/// <summary>
/// Merges the second set into the first set, creating a new instance if first is null
/// </summary>
public static void MergeFrom<TTarget>(ref ExtensionSet<TTarget> first, ExtensionSet<TTarget> second) where TTarget : IExtendableMessage<TTarget>
{
if (second == null)
{
return;
}
if (first == null)
{
first = new ExtensionSet<TTarget>();
}
foreach (var pair in second.ValuesByNumber)
{
IExtensionValue value;
if (first.ValuesByNumber.TryGetValue(pair.Key, out value))
{
value.MergeFrom(pair.Value);
}
else
{
var cloned = pair.Value.Clone();
first.ValuesByNumber[pair.Key] = cloned;
}
}
}
/// <summary>
/// Clones the set into a new set. If the set is null, this returns null
/// </summary>
public static ExtensionSet<TTarget> Clone<TTarget>(ExtensionSet<TTarget> set) where TTarget : IExtendableMessage<TTarget>
{
if (set == null)
{
return null;
}
var newSet = new ExtensionSet<TTarget>();
foreach (var pair in set.ValuesByNumber)
{
var cloned = pair.Value.Clone();
newSet.ValuesByNumber[pair.Key] = cloned;
}
return newSet;
}
}
/// <summary>
/// Used for keeping track of extensions in messages.
/// <see cref="IExtendableMessage{T}"/> methods route to this set.
///
/// Most users will not need to use this class directly
/// </summary>
/// <typeparam name="TTarget">The message type that extensions in this set target</typeparam>
public sealed class ExtensionSet<TTarget> where TTarget : IExtendableMessage<TTarget>
{
internal Dictionary<int, IExtensionValue> ValuesByNumber { get; } = new Dictionary<int, IExtensionValue>();
/// <summary>
/// Gets a hash code of the set
/// </summary>
public override int GetHashCode()
{
int ret = typeof(TTarget).GetHashCode();
foreach (KeyValuePair<int, IExtensionValue> field in ValuesByNumber)
{
// Use ^ here to make the field order irrelevant.
int hash = field.Key.GetHashCode() ^ field.Value.GetHashCode();
ret ^= hash;
}
return ret;
}
/// <summary>
/// Returns whether this set is equal to the other object
/// </summary>
public override bool Equals(object other)
{
if (ReferenceEquals(this, other))
{
return true;
}
ExtensionSet<TTarget> otherSet = other as ExtensionSet<TTarget>;
if (ValuesByNumber.Count != otherSet.ValuesByNumber.Count)
{
return false;
}
foreach (var pair in ValuesByNumber)
{
IExtensionValue secondValue;
if (!otherSet.ValuesByNumber.TryGetValue(pair.Key, out secondValue))
{
return false;
}
if (!pair.Value.Equals(secondValue))
{
return false;
}
}
return true;
}
/// <summary>
/// Calculates the size of this extension set
/// </summary>
public int CalculateSize()
{
int size = 0;
foreach (var value in ValuesByNumber.Values)
{
size += value.CalculateSize();
}
return size;
}
/// <summary>
/// Writes the extension values in this set to the output stream
/// </summary>
public void WriteTo(CodedOutputStream stream)
{
WriteContext.Initialize(stream, out WriteContext ctx);
try
{
WriteTo(ref ctx);
}
finally
{
ctx.CopyStateTo(stream);
}
}
/// <summary>
/// Writes the extension values in this set to the write context
/// </summary>
[SecuritySafeCritical]
public void WriteTo(ref WriteContext ctx)
{
foreach (var value in ValuesByNumber.Values)
{
value.WriteTo(ref ctx);
}
}
internal bool IsInitialized()
{
return ValuesByNumber.Values.All(v => v.IsInitialized());
}
}
}

View File

@ -44,6 +44,7 @@ namespace Google.Protobuf
void WriteTo(ref WriteContext ctx);
int CalculateSize();
bool IsInitialized();
object GetValue();
}
internal sealed class ExtensionValue<T> : IExtensionValue
@ -118,6 +119,8 @@ namespace Google.Protobuf
public T GetValue() => field;
object IExtensionValue.GetValue() => field;
public void SetValue(T value)
{
field = value;
@ -201,6 +204,8 @@ namespace Google.Protobuf
public RepeatedField<T> GetValue() => field;
object IExtensionValue.GetValue() => field;
public bool IsInitialized()
{
for (int i = 0; i < field.Count; i++)

View File

@ -1,49 +1,49 @@
#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.Text.RegularExpressions;
namespace Google.Protobuf
{
/// <summary>
/// Class containing helpful workarounds for various platform compatibility
/// </summary>
internal static class FrameworkPortability
{
// The value of RegexOptions.Compiled is 8. We can test for the presence at
// execution time using Enum.IsDefined, so a single build will do the right thing
// on each platform. (RegexOptions.Compiled isn't supported by PCLs.)
internal static readonly RegexOptions CompiledRegexWhereAvailable =
Enum.IsDefined(typeof(RegexOptions), 8) ? (RegexOptions)8 : RegexOptions.None;
}
#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.Text.RegularExpressions;
namespace Google.Protobuf
{
/// <summary>
/// Class containing helpful workarounds for various platform compatibility
/// </summary>
internal static class FrameworkPortability
{
// The value of RegexOptions.Compiled is 8. We can test for the presence at
// execution time using Enum.IsDefined, so a single build will do the right thing
// on each platform. (RegexOptions.Compiled isn't supported by PCLs.)
internal static readonly RegexOptions CompiledRegexWhereAvailable =
Enum.IsDefined(typeof(RegexOptions), 8) ? (RegexOptions)8 : RegexOptions.None;
}
}

View File

@ -4,7 +4,7 @@
<Description>C# runtime library for Protocol Buffers - Google's data interchange format.</Description>
<Copyright>Copyright 2015, Google Inc.</Copyright>
<AssemblyTitle>Google Protocol Buffers</AssemblyTitle>
<VersionPrefix>3.20.0-rc1</VersionPrefix>
<VersionPrefix>3.20.1-rc1</VersionPrefix>
<!-- C# 7.2 is required for Span/BufferWriter/ReadOnlySequence -->
<LangVersion>7.2</LangVersion>
<Authors>Google Inc.</Authors>

View File

@ -1,87 +1,87 @@
#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.Reflection;
namespace Google.Protobuf
{
/// <summary>
/// Interface for a Protocol Buffers message, supporting
/// basic operations required for serialization.
/// </summary>
public interface IMessage
{
/// <summary>
/// Merges the data from the specified coded input stream with the current message.
/// </summary>
/// <remarks>See the user guide for precise merge semantics.</remarks>
/// <param name="input"></param>
void MergeFrom(CodedInputStream input);
/// <summary>
/// Writes the data to the given coded output stream.
/// </summary>
/// <param name="output">Coded output stream to write the data to. Must not be null.</param>
void WriteTo(CodedOutputStream output);
/// <summary>
/// Calculates the size of this message in Protocol Buffer wire format, in bytes.
/// </summary>
/// <returns>The number of bytes required to write this message
/// to a coded output stream.</returns>
int CalculateSize();
/// <summary>
/// Descriptor for this message. All instances are expected to return the same descriptor,
/// and for generated types this will be an explicitly-implemented member, returning the
/// same value as the static property declared on the type.
/// </summary>
MessageDescriptor Descriptor { get; }
}
/// <summary>
/// Generic interface for a Protocol Buffers message,
/// where the type parameter is expected to be the same type as
/// the implementation class.
/// </summary>
/// <typeparam name="T">The message type.</typeparam>
public interface IMessage<T> : IMessage, IEquatable<T>, IDeepCloneable<T> where T : IMessage<T>
{
/// <summary>
/// Merges the given message into this one.
/// </summary>
/// <remarks>See the user guide for precise merge semantics.</remarks>
/// <param name="message">The message to merge with this one. Must not be null.</param>
void MergeFrom(T message);
}
}
#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.Reflection;
namespace Google.Protobuf
{
/// <summary>
/// Interface for a Protocol Buffers message, supporting
/// basic operations required for serialization.
/// </summary>
public interface IMessage
{
/// <summary>
/// Merges the data from the specified coded input stream with the current message.
/// </summary>
/// <remarks>See the user guide for precise merge semantics.</remarks>
/// <param name="input"></param>
void MergeFrom(CodedInputStream input);
/// <summary>
/// Writes the data to the given coded output stream.
/// </summary>
/// <param name="output">Coded output stream to write the data to. Must not be null.</param>
void WriteTo(CodedOutputStream output);
/// <summary>
/// Calculates the size of this message in Protocol Buffer wire format, in bytes.
/// </summary>
/// <returns>The number of bytes required to write this message
/// to a coded output stream.</returns>
int CalculateSize();
/// <summary>
/// Descriptor for this message. All instances are expected to return the same descriptor,
/// and for generated types this will be an explicitly-implemented member, returning the
/// same value as the static property declared on the type.
/// </summary>
MessageDescriptor Descriptor { get; }
}
/// <summary>
/// Generic interface for a Protocol Buffers message,
/// where the type parameter is expected to be the same type as
/// the implementation class.
/// </summary>
/// <typeparam name="T">The message type.</typeparam>
public interface IMessage<T> : IMessage, IEquatable<T>, IDeepCloneable<T> where T : IMessage<T>
{
/// <summary>
/// Merges the given message into this one.
/// </summary>
/// <remarks>See the user guide for precise merge semantics.</remarks>
/// <param name="message">The message to merge with this one. Must not be null.</param>
void MergeFrom(T message);
}
}

View File

@ -1,140 +1,140 @@
#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;
namespace Google.Protobuf
{
/// <summary>
/// Thrown when a protocol message being parsed is invalid in some way,
/// e.g. it contains a malformed varint or a negative byte length.
/// </summary>
public sealed class InvalidProtocolBufferException : IOException
{
internal InvalidProtocolBufferException(string message)
: base(message)
{
}
internal InvalidProtocolBufferException(string message, Exception innerException)
: base(message, innerException)
{
}
internal static InvalidProtocolBufferException MoreDataAvailable()
{
return new InvalidProtocolBufferException(
"Completed reading a message while more data was available in the stream.");
}
internal static InvalidProtocolBufferException TruncatedMessage()
{
return new InvalidProtocolBufferException(
"While parsing a protocol message, the input ended unexpectedly " +
"in the middle of a field. This could mean either that the " +
"input has been truncated or that an embedded message " +
"misreported its own length.");
}
internal static InvalidProtocolBufferException NegativeSize()
{
return new InvalidProtocolBufferException(
"CodedInputStream encountered an embedded string or message " +
"which claimed to have negative size.");
}
internal static InvalidProtocolBufferException MalformedVarint()
{
return new InvalidProtocolBufferException(
"CodedInputStream encountered a malformed varint.");
}
/// <summary>
/// Creates an exception for an error condition of an invalid tag being encountered.
/// </summary>
internal static InvalidProtocolBufferException InvalidTag()
{
return new InvalidProtocolBufferException(
"Protocol message contained an invalid tag (zero).");
}
internal static InvalidProtocolBufferException InvalidWireType()
{
return new InvalidProtocolBufferException(
"Protocol message contained a tag with an invalid wire type.");
}
internal static InvalidProtocolBufferException InvalidBase64(Exception innerException)
{
return new InvalidProtocolBufferException("Invalid base64 data", innerException);
}
internal static InvalidProtocolBufferException InvalidEndTag()
{
return new InvalidProtocolBufferException(
"Protocol message end-group tag did not match expected tag.");
}
internal static InvalidProtocolBufferException RecursionLimitExceeded()
{
return new InvalidProtocolBufferException(
"Protocol message had too many levels of nesting. May be malicious. " +
"Use CodedInputStream.SetRecursionLimit() to increase the depth limit.");
}
internal static InvalidProtocolBufferException JsonRecursionLimitExceeded()
{
return new InvalidProtocolBufferException(
"Protocol message had too many levels of nesting. May be malicious. " +
"Use JsonParser.Settings to increase the depth limit.");
}
internal static InvalidProtocolBufferException SizeLimitExceeded()
{
return new InvalidProtocolBufferException(
"Protocol message was too large. May be malicious. " +
"Use CodedInputStream.SetSizeLimit() to increase the size limit.");
}
internal static InvalidProtocolBufferException InvalidMessageStreamTag()
{
return new InvalidProtocolBufferException(
"Stream of protocol messages had invalid tag. Expected tag is length-delimited field 1.");
}
internal static InvalidProtocolBufferException MissingFields()
{
return new InvalidProtocolBufferException("Message was missing required fields");
}
}
#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;
namespace Google.Protobuf
{
/// <summary>
/// Thrown when a protocol message being parsed is invalid in some way,
/// e.g. it contains a malformed varint or a negative byte length.
/// </summary>
public sealed class InvalidProtocolBufferException : IOException
{
internal InvalidProtocolBufferException(string message)
: base(message)
{
}
internal InvalidProtocolBufferException(string message, Exception innerException)
: base(message, innerException)
{
}
internal static InvalidProtocolBufferException MoreDataAvailable()
{
return new InvalidProtocolBufferException(
"Completed reading a message while more data was available in the stream.");
}
internal static InvalidProtocolBufferException TruncatedMessage()
{
return new InvalidProtocolBufferException(
"While parsing a protocol message, the input ended unexpectedly " +
"in the middle of a field. This could mean either that the " +
"input has been truncated or that an embedded message " +
"misreported its own length.");
}
internal static InvalidProtocolBufferException NegativeSize()
{
return new InvalidProtocolBufferException(
"CodedInputStream encountered an embedded string or message " +
"which claimed to have negative size.");
}
internal static InvalidProtocolBufferException MalformedVarint()
{
return new InvalidProtocolBufferException(
"CodedInputStream encountered a malformed varint.");
}
/// <summary>
/// Creates an exception for an error condition of an invalid tag being encountered.
/// </summary>
internal static InvalidProtocolBufferException InvalidTag()
{
return new InvalidProtocolBufferException(
"Protocol message contained an invalid tag (zero).");
}
internal static InvalidProtocolBufferException InvalidWireType()
{
return new InvalidProtocolBufferException(
"Protocol message contained a tag with an invalid wire type.");
}
internal static InvalidProtocolBufferException InvalidBase64(Exception innerException)
{
return new InvalidProtocolBufferException("Invalid base64 data", innerException);
}
internal static InvalidProtocolBufferException InvalidEndTag()
{
return new InvalidProtocolBufferException(
"Protocol message end-group tag did not match expected tag.");
}
internal static InvalidProtocolBufferException RecursionLimitExceeded()
{
return new InvalidProtocolBufferException(
"Protocol message had too many levels of nesting. May be malicious. " +
"Use CodedInputStream.SetRecursionLimit() to increase the depth limit.");
}
internal static InvalidProtocolBufferException JsonRecursionLimitExceeded()
{
return new InvalidProtocolBufferException(
"Protocol message had too many levels of nesting. May be malicious. " +
"Use JsonParser.Settings to increase the depth limit.");
}
internal static InvalidProtocolBufferException SizeLimitExceeded()
{
return new InvalidProtocolBufferException(
"Protocol message was too large. May be malicious. " +
"Use CodedInputStream.SetSizeLimit() to increase the size limit.");
}
internal static InvalidProtocolBufferException InvalidMessageStreamTag()
{
return new InvalidProtocolBufferException(
"Stream of protocol messages had invalid tag. Expected tag is length-delimited field 1.");
}
internal static InvalidProtocolBufferException MissingFields()
{
return new InvalidProtocolBufferException("Message was missing required fields");
}
}
}

View File

@ -1,4 +1,4 @@
#region Copyright notice and license
#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/
@ -233,13 +233,13 @@ namespace Google.Protobuf
writer.Write(PropertySeparator);
}
if (settings.PreserveProtoFieldNames)
{
WriteString(writer, accessor.Descriptor.Name);
if (settings.PreserveProtoFieldNames)
{
WriteString(writer, accessor.Descriptor.Name);
}
else
{
WriteString(writer, accessor.Descriptor.JsonName);
else
{
WriteString(writer, accessor.Descriptor.JsonName);
}
writer.Write(NameValueSeparator);
WriteValue(writer, value);
@ -823,8 +823,8 @@ namespace Google.Protobuf
/// </summary>
public bool FormatEnumsAsIntegers { get; }
/// <summary>
/// Whether to use the original proto field names as defined in the .proto file. Defaults to false.
/// <summary>
/// Whether to use the original proto field names as defined in the .proto file. Defaults to false.
/// </summary>
public bool PreserveProtoFieldNames { get; }
@ -884,9 +884,9 @@ namespace Google.Protobuf
/// <param name="formatEnumsAsIntegers"><c>true</c> to format the enums as integers; <c>false</c> to format enums as enum names.</param>
public Settings WithFormatEnumsAsIntegers(bool formatEnumsAsIntegers) => new Settings(FormatDefaultValues, TypeRegistry, formatEnumsAsIntegers, PreserveProtoFieldNames);
/// <summary>
/// Creates a new <see cref="Settings"/> object with the specified field name formatting option and the current settings.
/// </summary>
/// <summary>
/// Creates a new <see cref="Settings"/> object with the specified field name formatting option and the current settings.
/// </summary>
/// <param name="preserveProtoFieldNames"><c>true</c> to preserve proto field names; <c>false</c> to convert them to lowerCamelCase.</param>
public Settings WithPreserveProtoFieldNames(bool preserveProtoFieldNames) => new Settings(FormatDefaultValues, TypeRegistry, FormatEnumsAsIntegers, preserveProtoFieldNames);
}

View File

@ -1,40 +1,40 @@
using System;
namespace Google.Protobuf
{
using System;
namespace Google.Protobuf
{
/// <summary>
/// Struct used to hold the keys for the fieldByNumber table in DescriptorPool and the keys for the
/// extensionByNumber table in ExtensionRegistry.
/// </summary>
internal struct ObjectIntPair<T> : IEquatable<ObjectIntPair<T>> where T : class
{
private readonly int number;
private readonly T obj;
internal ObjectIntPair(T obj, int number)
{
this.number = number;
this.obj = obj;
}
public bool Equals(ObjectIntPair<T> other)
{
return obj == other.obj
&& number == other.number;
}
public override bool Equals(object obj)
{
if (obj is ObjectIntPair<T>)
{
return Equals((ObjectIntPair<T>)obj);
}
return false;
}
public override int GetHashCode()
{
return obj.GetHashCode() * ((1 << 16) - 1) + number;
}
}
}
/// </summary>
internal struct ObjectIntPair<T> : IEquatable<ObjectIntPair<T>> where T : class
{
private readonly int number;
private readonly T obj;
internal ObjectIntPair(T obj, int number)
{
this.number = number;
this.obj = obj;
}
public bool Equals(ObjectIntPair<T> other)
{
return obj == other.obj
&& number == other.number;
}
public override bool Equals(object obj)
{
if (obj is ObjectIntPair<T>)
{
return Equals((ObjectIntPair<T>)obj);
}
return false;
}
public override int GetHashCode()
{
return obj.GetHashCode() * ((1 << 16) - 1) + number;
}
}
}

View File

@ -1,56 +1,56 @@
#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.Runtime.CompilerServices;
using System.Security;
// 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.
#if !NCRUNCH
[assembly: AllowPartiallyTrustedCallers]
#endif
[assembly: InternalsVisibleTo("Google.Protobuf.Test, PublicKey=" +
"002400000480000094000000060200000024000052534131000400000100010025800fbcfc63a1" +
"7c66b303aae80b03a6beaa176bb6bef883be436f2a1579edd80ce23edf151a1f4ced97af83abcd" +
"981207041fd5b2da3b498346fcfcd94910d52f25537c4a43ce3fbe17dc7d43e6cbdb4d8f1242dc" +
"b6bd9b5906be74da8daa7d7280f97130f318a16c07baf118839b156299a48522f9fae2371c9665" +
"c5ae9cb6")]
[assembly: InternalsVisibleTo("Google.Protobuf.Benchmarks, PublicKey=" +
"002400000480000094000000060200000024000052534131000400000100010025800fbcfc63a1" +
"7c66b303aae80b03a6beaa176bb6bef883be436f2a1579edd80ce23edf151a1f4ced97af83abcd" +
"981207041fd5b2da3b498346fcfcd94910d52f25537c4a43ce3fbe17dc7d43e6cbdb4d8f1242dc" +
"b6bd9b5906be74da8daa7d7280f97130f318a16c07baf118839b156299a48522f9fae2371c9665" +
"c5ae9cb6")]
#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.Runtime.CompilerServices;
using System.Security;
// 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.
#if !NCRUNCH
[assembly: AllowPartiallyTrustedCallers]
#endif
[assembly: InternalsVisibleTo("Google.Protobuf.Test, PublicKey=" +
"002400000480000094000000060200000024000052534131000400000100010025800fbcfc63a1" +
"7c66b303aae80b03a6beaa176bb6bef883be436f2a1579edd80ce23edf151a1f4ced97af83abcd" +
"981207041fd5b2da3b498346fcfcd94910d52f25537c4a43ce3fbe17dc7d43e6cbdb4d8f1242dc" +
"b6bd9b5906be74da8daa7d7280f97130f318a16c07baf118839b156299a48522f9fae2371c9665" +
"c5ae9cb6")]
[assembly: InternalsVisibleTo("Google.Protobuf.Benchmarks, PublicKey=" +
"002400000480000094000000060200000024000052534131000400000100010025800fbcfc63a1" +
"7c66b303aae80b03a6beaa176bb6bef883be436f2a1579edd80ce23edf151a1f4ced97af83abcd" +
"981207041fd5b2da3b498346fcfcd94910d52f25537c4a43ce3fbe17dc7d43e6cbdb4d8f1242dc" +
"b6bd9b5906be74da8daa7d7280f97130f318a16c07baf118839b156299a48522f9fae2371c9665" +
"c5ae9cb6")]

View File

@ -1,79 +1,79 @@
#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
{
/// <summary>
/// Helper methods for throwing exceptions when preconditions are not met.
/// </summary>
/// <remarks>
/// This class is used internally and by generated code; it is not particularly
/// expected to be used from application code, although nothing prevents it
/// from being used that way.
/// </remarks>
public static class ProtoPreconditions
{
/// <summary>
/// Throws an ArgumentNullException if the given value is null, otherwise
/// return the value to the caller.
/// </summary>
public static T CheckNotNull<T>(T value, string name) where T : class
{
if (value == null)
{
throw new ArgumentNullException(name);
}
return value;
}
/// <summary>
/// Throws an ArgumentNullException if the given value is null, otherwise
/// return the value to the caller.
/// </summary>
/// <remarks>
/// This is equivalent to <see cref="CheckNotNull{T}(T, string)"/> but without the type parameter
/// constraint. In most cases, the constraint is useful to prevent you from calling CheckNotNull
/// with a value type - but it gets in the way if either you want to use it with a nullable
/// value type, or you want to use it with an unconstrained type parameter.
/// </remarks>
internal static T CheckNotNullUnconstrained<T>(T value, string name)
{
if (value == null)
{
throw new ArgumentNullException(name);
}
return value;
}
}
#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
{
/// <summary>
/// Helper methods for throwing exceptions when preconditions are not met.
/// </summary>
/// <remarks>
/// This class is used internally and by generated code; it is not particularly
/// expected to be used from application code, although nothing prevents it
/// from being used that way.
/// </remarks>
public static class ProtoPreconditions
{
/// <summary>
/// Throws an ArgumentNullException if the given value is null, otherwise
/// return the value to the caller.
/// </summary>
public static T CheckNotNull<T>(T value, string name) where T : class
{
if (value == null)
{
throw new ArgumentNullException(name);
}
return value;
}
/// <summary>
/// Throws an ArgumentNullException if the given value is null, otherwise
/// return the value to the caller.
/// </summary>
/// <remarks>
/// This is equivalent to <see cref="CheckNotNull{T}(T, string)"/> but without the type parameter
/// constraint. In most cases, the constraint is useful to prevent you from calling CheckNotNull
/// with a value type - but it gets in the way if either you want to use it with a nullable
/// value type, or you want to use it with an unconstrained type parameter.
/// </remarks>
internal static T CheckNotNullUnconstrained<T>(T value, string name)
{
if (value == null)
{
throw new ArgumentNullException(name);
}
return value;
}
}
}

View File

@ -9611,8 +9611,8 @@ namespace Google.Protobuf.Reflection {
/// The name of the uninterpreted option. Each string represents a segment in
/// a dot-separated name. is_extension is true iff a segment represents an
/// extension (denoted with parentheses in options specs in .proto files).
/// E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents
/// "foo.(bar.baz).qux".
/// E.g.,{ ["foo", false], ["bar.baz", true], ["moo", false] } represents
/// "foo.(bar.baz).moo".
/// </summary>
public sealed partial class NamePart : pb::IMessage<NamePart>
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
@ -10241,13 +10241,13 @@ namespace Google.Protobuf.Reflection {
/// // Comment attached to baz.
/// // Another line attached to baz.
///
/// // Comment attached to qux.
/// // Comment attached to moo.
/// //
/// // Another line attached to qux.
/// optional double qux = 4;
/// // Another line attached to moo.
/// optional double moo = 4;
///
/// // Detached comment for corge. This is not leading or trailing comments
/// // to qux or corge because there are blank lines separating it from
/// // to moo or corge because there are blank lines separating it from
/// // both.
///
/// // Detached comment for corge paragraph 2.

View File

@ -1,4 +1,4 @@
#region Copyright notice and license
#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/
@ -67,15 +67,15 @@ namespace Google.Protobuf.WellKnownTypes
return lastSlash == -1 ? "" : typeUrl.Substring(lastSlash + 1);
}
/// <summary>
/// Returns a bool indictating whether this Any message is of the target message type
/// </summary>
/// <param name="descriptor">The descriptor of the message type</param>
/// <summary>
/// Returns a bool indictating whether this Any message is of the target message type
/// </summary>
/// <param name="descriptor">The descriptor of the message type</param>
/// <returns><c>true</c> if the type name matches the descriptor's full name or <c>false</c> otherwise</returns>
public bool Is(MessageDescriptor descriptor)
{
ProtoPreconditions.CheckNotNull(descriptor, nameof(descriptor));
return GetTypeName(TypeUrl) == descriptor.FullName;
public bool Is(MessageDescriptor descriptor)
{
ProtoPreconditions.CheckNotNull(descriptor, nameof(descriptor));
return GetTypeName(TypeUrl) == descriptor.FullName;
}
/// <summary>

View File

@ -47,8 +47,6 @@ namespace Google.Protobuf.WellKnownTypes {
/// service Foo {
/// rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty);
/// }
///
/// The JSON representation for `Empty` is empty JSON object `{}`.
/// </summary>
public sealed partial class Empty : pb::IMessage<Empty>
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE

View File

@ -1,104 +1,104 @@
#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
namespace Google.Protobuf
{
/// <summary>
/// This class is used internally by the Protocol Buffer Library and generated
/// message implementations. It is public only for the sake of those generated
/// messages. Others should not use this class directly.
/// <para>
/// This class contains constants and helper functions useful for dealing with
/// the Protocol Buffer wire format.
/// </para>
/// </summary>
public static class WireFormat
{
/// <summary>
/// Wire types within protobuf encoding.
/// </summary>
public enum WireType : uint
{
/// <summary>
/// Variable-length integer.
/// </summary>
Varint = 0,
/// <summary>
/// A fixed-length 64-bit value.
/// </summary>
Fixed64 = 1,
/// <summary>
/// A length-delimited value, i.e. a length followed by that many bytes of data.
/// </summary>
LengthDelimited = 2,
/// <summary>
/// A "start group" value
/// </summary>
StartGroup = 3,
/// <summary>
/// An "end group" value
/// </summary>
EndGroup = 4,
/// <summary>
/// A fixed-length 32-bit value.
/// </summary>
Fixed32 = 5
}
private const int TagTypeBits = 3;
private const uint TagTypeMask = (1 << TagTypeBits) - 1;
/// <summary>
/// Given a tag value, determines the wire type (lower 3 bits).
/// </summary>
public static WireType GetTagWireType(uint tag)
{
return (WireType) (tag & TagTypeMask);
}
/// <summary>
/// Given a tag value, determines the field number (the upper 29 bits).
/// </summary>
public static int GetTagFieldNumber(uint tag)
{
return (int) (tag >> TagTypeBits);
}
/// <summary>
/// Makes a tag value given a field number and wire type.
/// </summary>
public static uint MakeTag(int fieldNumber, WireType wireType)
{
return (uint) (fieldNumber << TagTypeBits) | (uint) wireType;
}
}
#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
namespace Google.Protobuf
{
/// <summary>
/// This class is used internally by the Protocol Buffer Library and generated
/// message implementations. It is public only for the sake of those generated
/// messages. Others should not use this class directly.
/// <para>
/// This class contains constants and helper functions useful for dealing with
/// the Protocol Buffer wire format.
/// </para>
/// </summary>
public static class WireFormat
{
/// <summary>
/// Wire types within protobuf encoding.
/// </summary>
public enum WireType : uint
{
/// <summary>
/// Variable-length integer.
/// </summary>
Varint = 0,
/// <summary>
/// A fixed-length 64-bit value.
/// </summary>
Fixed64 = 1,
/// <summary>
/// A length-delimited value, i.e. a length followed by that many bytes of data.
/// </summary>
LengthDelimited = 2,
/// <summary>
/// A "start group" value
/// </summary>
StartGroup = 3,
/// <summary>
/// An "end group" value
/// </summary>
EndGroup = 4,
/// <summary>
/// A fixed-length 32-bit value.
/// </summary>
Fixed32 = 5
}
private const int TagTypeBits = 3;
private const uint TagTypeMask = (1 << TagTypeBits) - 1;
/// <summary>
/// Given a tag value, determines the wire type (lower 3 bits).
/// </summary>
public static WireType GetTagWireType(uint tag)
{
return (WireType) (tag & TagTypeMask);
}
/// <summary>
/// Given a tag value, determines the field number (the upper 29 bits).
/// </summary>
public static int GetTagFieldNumber(uint tag)
{
return (int) (tag >> TagTypeBits);
}
/// <summary>
/// Makes a tag value given a field number and wire type.
/// </summary>
public static uint MakeTag(int fieldNumber, WireType wireType)
{
return (uint) (fieldNumber << TagTypeBits) | (uint) wireType;
}
}
}

View File

@ -30,7 +30,7 @@ Presence tracking was added to proto3 in response to user feedback, both from
inside Google and [from open-source
users](https://github.com/protocolbuffers/protobuf/issues/1606). The [proto3
wrapper
types](https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/wrappers.proto)
types](https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/wrappers.proto)
were previously the only supported presence mechanism for proto3. Users have
pointed to both efficiency and usability issues with the wrapper types.

View File

@ -4,7 +4,7 @@ Ahead Of Time (AOT) compilation build tools such as those provided by [GraalVM's
Protobuf for the JVM uses reflection and some of its target classes are not possible to determine in advance.
Historically, there were good reasons to use reflection based on APIs that were published effectively requiring them, and this situation is unlikely to change.
[The Lite version of protobuf for the JVM](https://github.com/protocolbuffers/protobuf/blob/master/java/lite.md)
[The Lite version of protobuf for the JVM](https://github.com/protocolbuffers/protobuf/blob/main/java/lite.md)
avoids reflection and may be better suited for use with AOT compilation tooling. This Lite version was originally targeted for use on Android which has similar AOT compilation
goals as GraalVM's native-image tool.

View File

@ -304,3 +304,15 @@ with info about your project (name and website) so we can add an entry for you.
1. Embedded Proto
* Website: https://EmbeddedProto.com
* Extension: 1141
1. Protoc-gen-fieldmask
* Website: https://github.com/yeqown/protoc-gen-fieldmask
* Extension: 1142
1. Google Gnostic
* Website: https://github.com/google/gnostic
* Extension: 1143
1. Protoc-gen-go-micro
* Website: https://github.com/unistack-org/protoc-gen-go-micro
* Extension: 1144

View File

@ -301,4 +301,4 @@ This table contains the results of three separate languages:
</tr>
</tbody></table>
\* The cpp performance can be improved by using [tcmalloc](https://gperftools.github.io/gperftools/tcmalloc.html), please follow the (instruction)[https://github.com/protocolbuffers/protobuf/blob/master/benchmarks/README.md] to link with tcmalloc to get the faster result.
\* The cpp performance can be improved by using [tcmalloc](https://gperftools.github.io/gperftools/tcmalloc.html), please follow the (instruction)[https://github.com/protocolbuffers/protobuf/blob/main/benchmarks/README.md] to link with tcmalloc to get the faster result.

View File

@ -71,6 +71,7 @@ These are projects we know about implementing Protocol Buffers for other program
* Kotlin: https://github.com/Kotlin/kotlinx.serialization
* Kotlin: https://github.com/ButterCam/sisyphus
* Kotlin: https://github.com/open-toast/protokt
* Kotlin Multiplatform: https://github.com/streem/pbandk
* Lua: https://code.google.com/p/protoc-gen-lua/
* Lua: http://github.com/indygreg/lua-protobuf
* Lua: https://github.com/Neopallium/lua-pb

View File

@ -10,8 +10,8 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
#
# http_archive(
# name = "com_google_protobuf",
# strip_prefix = "protobuf-master",
# urls = ["https://github.com/protocolbuffers/protobuf/archive/master.zip"],
# strip_prefix = "protobuf-main",
# urls = ["https://github.com/protocolbuffers/protobuf/archive/main.zip"],
# )
local_repository(
name = "com_google_protobuf",

View File

@ -23,7 +23,7 @@ If you are using Maven, use the following:
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.20.0-rc-1</version>
<version>3.20.1-rc-1</version>
</dependency>
```
@ -37,7 +37,7 @@ protobuf-java-util package:
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java-util</artifactId>
<version>3.20.0-rc-1</version>
<version>3.20.1-rc-1</version>
</dependency>
```
@ -45,7 +45,7 @@ protobuf-java-util package:
If you are using Gradle, add the following to your `build.gradle` file's dependencies:
```
implementation 'com.google.protobuf:protobuf-java:3.20.0-rc-1'
implementation 'com.google.protobuf:protobuf-java:3.20.1-rc-1'
```
Again, be sure to check that the version number matches (or is newer than) the version number of protoc that you are using.

View File

@ -4,7 +4,7 @@
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-bom</artifactId>
<version>3.20.0-rc-1</version>
<version>3.20.1-rc-1</version>
<packaging>pom</packaging>
<name>Protocol Buffers [BOM]</name>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-parent</artifactId>
<version>3.20.0-rc-1</version>
<version>3.20.1-rc-1</version>
</parent>
<artifactId>protobuf-java</artifactId>

View File

@ -94,13 +94,13 @@ public abstract class AbstractMessage
return MessageReflection.delimitWithCommas(findInitializationErrors());
}
/** TODO(jieluo): Clear it when all subclasses have implemented this method. */
// TODO(jieluo): Clear it when all subclasses have implemented this method.
@Override
public boolean hasOneof(OneofDescriptor oneof) {
throw new UnsupportedOperationException("hasOneof() is not implemented.");
}
/** TODO(jieluo): Clear it when all subclasses have implemented this method. */
// TODO(jieluo): Clear it when all subclasses have implemented this method.
@Override
public FieldDescriptor getOneofFieldDescriptor(OneofDescriptor oneof) {
throw new UnsupportedOperationException("getOneofFieldDescriptor() is not implemented.");

View File

@ -996,8 +996,6 @@ public abstract class CodedOutputStream extends ByteOutput {
writeLazy(bytes, 0, bytes.length);
} catch (IndexOutOfBoundsException e) {
throw new OutOfSpaceException(e);
} catch (OutOfSpaceException e) {
throw e;
}
}
@ -1345,49 +1343,19 @@ public abstract class CodedOutputStream extends ByteOutput {
@Override
public final void writeUInt32NoTag(int value) throws IOException {
if (HAS_UNSAFE_ARRAY_OPERATIONS
&& !Android.isOnAndroidDevice()
&& spaceLeft() >= MAX_VARINT32_SIZE) {
if ((value & ~0x7F) == 0) {
UnsafeUtil.putByte(buffer, position++, (byte) value);
return;
}
UnsafeUtil.putByte(buffer, position++, (byte) (value | 0x80));
value >>>= 7;
if ((value & ~0x7F) == 0) {
UnsafeUtil.putByte(buffer, position++, (byte) value);
return;
}
UnsafeUtil.putByte(buffer, position++, (byte) (value | 0x80));
value >>>= 7;
if ((value & ~0x7F) == 0) {
UnsafeUtil.putByte(buffer, position++, (byte) value);
return;
}
UnsafeUtil.putByte(buffer, position++, (byte) (value | 0x80));
value >>>= 7;
if ((value & ~0x7F) == 0) {
UnsafeUtil.putByte(buffer, position++, (byte) value);
return;
}
UnsafeUtil.putByte(buffer, position++, (byte) (value | 0x80));
value >>>= 7;
UnsafeUtil.putByte(buffer, position++, (byte) value);
} else {
try {
while (true) {
if ((value & ~0x7F) == 0) {
buffer[position++] = (byte) value;
return;
} else {
buffer[position++] = (byte) ((value & 0x7F) | 0x80);
value >>>= 7;
}
try {
while (true) {
if ((value & ~0x7F) == 0) {
buffer[position++] = (byte) value;
return;
} else {
buffer[position++] = (byte) ((value & 0x7F) | 0x80);
value >>>= 7;
}
} catch (IndexOutOfBoundsException e) {
throw new OutOfSpaceException(
String.format("Pos: %d, limit: %d, len: %d", position, limit, 1), e);
}
} catch (IndexOutOfBoundsException e) {
throw new OutOfSpaceException(
String.format("Pos: %d, limit: %d, len: %d", position, limit, 1), e);
}
}

View File

@ -150,7 +150,7 @@ final class DescriptorMessageInfoFactory implements MessageInfoFactory {
* <p>This class is thread-safe.
*/
// <p>The code is adapted from the C++ implementation:
// https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/compiler/java/java_helpers.h
// https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/compiler/java/java_helpers.h
static class IsInitializedCheckAnalyzer {
private final Map<Descriptor, Boolean> resultCache =

View File

@ -814,7 +814,7 @@ public final class Descriptors {
/**
* Finds a nested message type by name.
*
* @param name The unqualified name of the nested type (e.g. "Foo").
* @param name The unqualified name of the nested type such as "Foo"
* @return The types's descriptor, or {@code null} if not found.
*/
public Descriptor findNestedTypeByName(final String name) {
@ -829,7 +829,7 @@ public final class Descriptors {
/**
* Finds a nested enum type by name.
*
* @param name The unqualified name of the nested type (e.g. "Foo").
* @param name The unqualified name of the nested type such as "Foo"
* @return The types's descriptor, or {@code null} if not found.
*/
public EnumDescriptor findEnumTypeByName(final String name) {
@ -1202,7 +1202,7 @@ public final class Descriptors {
}
}
/** Can this field be packed? i.e. is it a repeated primitive field? */
/** Can this field be packed? That is, is it a repeated primitive field? */
public boolean isPackable() {
return isRepeated() && getLiteType().isPackable();
}
@ -1295,13 +1295,13 @@ public final class Descriptors {
* }
* message Bar {
* extend Foo {
* optional int32 qux = 4321;
* optional int32 moo = 4321;
* }
* }
* </pre>
*
* Both {@code baz}'s and {@code qux}'s containing type is {@code Foo}. However, {@code baz}'s
* extension scope is {@code null} while {@code qux}'s extension scope is {@code Bar}.
* Both {@code baz}'s and {@code moo}'s containing type is {@code Foo}. However, {@code baz}'s
* extension scope is {@code null} while {@code moo}'s extension scope is {@code Bar}.
*/
public Descriptor getExtensionScope() {
if (!isExtension()) {
@ -1332,11 +1332,11 @@ public final class Descriptors {
/**
* Compare with another {@code FieldDescriptor}. This orders fields in "canonical" order, which
* simply means ascending order by field number. {@code other} must be a field of the same type
* -- i.e. {@code getContainingType()} must return the same {@code Descriptor} for both fields.
* simply means ascending order by field number. {@code other} must be a field of the same type.
* That is, {@code getContainingType()} must return the same {@code Descriptor} for both fields.
*
* @return negative, zero, or positive if {@code this} is less than, equal to, or greater than
* {@code other}, respectively.
* {@code other}, respectively
*/
@Override
public int compareTo(final FieldDescriptor other) {
@ -1791,8 +1791,8 @@ public final class Descriptors {
/**
* Find an enum value by name.
*
* @param name The unqualified name of the value (e.g. "FOO").
* @return the value's descriptor, or {@code null} if not found.
* @param name the unqualified name of the value such as "FOO"
* @return the value's descriptor, or {@code null} if not found
*/
public EnumValueDescriptor findValueByName(final String name) {
final GenericDescriptor result = file.pool.findSymbol(fullName + '.' + name);
@ -2102,8 +2102,8 @@ public final class Descriptors {
/**
* Find a method by name.
*
* @param name The unqualified name of the method (e.g. "Foo").
* @return the method's descriptor, or {@code null} if not found.
* @param name the unqualified name of the method such as "Foo"
* @return the method's descriptor, or {@code null} if not found
*/
public MethodDescriptor findMethodByName(final String name) {
final GenericDescriptor result = file.pool.findSymbol(fullName + '.' + name);
@ -2676,8 +2676,8 @@ public final class Descriptors {
}
/**
* Verifies that the descriptor's name is valid (i.e. it contains only letters, digits, and
* underscores, and does not start with a digit).
* Verifies that the descriptor's name is valid. That is, it contains only letters, digits, and
* underscores, and does not start with a digit.
*/
static void validateSymbolName(final GenericDescriptor descriptor)
throws DescriptorValidationException {
@ -2705,7 +2705,7 @@ public final class Descriptors {
}
}
/** Describes an oneof of a message type. */
/** Describes a oneof of a message type. */
public static final class OneofDescriptor extends GenericDescriptor {
/** Get the index of this descriptor within its parent. */
public int getIndex() {

View File

@ -336,13 +336,17 @@ public final class MapEntry<K, V> extends AbstractMessage {
@Override
public Builder<K, V> setField(FieldDescriptor field, Object value) {
checkFieldDescriptor(field);
if (value == null) {
throw new NullPointerException(field.getFullName() + " is null");
}
if (field.getNumber() == 1) {
setKey((K) value);
} else {
if (field.getType() == FieldDescriptor.Type.ENUM) {
value = ((EnumValueDescriptor) value).getNumber();
} else if (field.getType() == FieldDescriptor.Type.MESSAGE) {
if (value != null && !metadata.defaultValue.getClass().isInstance(value)) {
if (!metadata.defaultValue.getClass().isInstance(value)) {
// The value is not the exact right message type. However, if it
// is an alternative implementation of the same type -- e.g. a
// DynamicMessage -- we should accept it. In this case we can make

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